From 21a122bcffcd4863a7f56b9680396919b909d232 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 7 Mar 2024 16:21:12 -0500 Subject: kernel: Require VAS arg in vm + loader refactor This commit adds vas argument to VM mapping functions as well as changing how mapping is done in the loader. This commit also fixes weird error handling and parses needed PHDRs within the loader Signed-off-by: Ian Moffett --- sys/kern/kern_loader.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/kern_loader.c b/sys/kern/kern_loader.c index cf51c72..73dc8c7 100644 --- a/sys/kern/kern_loader.c +++ b/sys/kern/kern_loader.c @@ -32,9 +32,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -51,14 +53,15 @@ __KERNEL_META("$Hyra$: kern_loader.c, Ian Marco Moffett, " #define PHDR(hdrptr, IDX) \ (void *)((uintptr_t)hdr + (hdrptr)->e_phoff + (hdrptr->e_phentsize*IDX)) -int -loader_load(const void *dataptr, struct auxval *auxv) +int loader_load(struct vas vas, const void *dataptr, struct auxval *auxv, + size_t load_base, char **ld_path) { const Elf64_Ehdr *hdr = dataptr; Elf64_Phdr *phdr; vm_prot_t prot = 0; uintptr_t physmem; + uintptr_t map_addr; size_t misalign, page_count; int status; @@ -92,20 +95,50 @@ loader_load(const void *dataptr, struct auxval *auxv) page_count = __DIV_ROUNDUP(phdr->p_memsz + misalign, GRANULE); physmem = vm_alloc_pageframe(page_count); - __assert(physmem != 0); /* TODO: Handle better */ - status = vm_map_create(phdr->p_vaddr, physmem, prot, - page_count * GRANULE); + /* Do we not have enough page frames? */ + if (physmem == 0) { + DBG("Failed to allocate physical memory\n"); + vm_free_pageframe(physmem, page_count); + return -ENOMEM; + } + + map_addr = phdr->p_vaddr + load_base; + status = vm_map_create(vas, map_addr, physmem, prot, page_count*GRANULE); - __assert(status == 0); /* TODO: Handle better */ + if (status != 0) { + DBG("Failed to map 0x%p - 0x%p\n", + phdr->p_vaddr + load_base, + (phdr->p_vaddr + load_base) + (page_count * GRANULE)); + + return status; + } /* Now we want to copy the data */ tmp_ptr = (void *)((uintptr_t)hdr + phdr->p_offset); - memcpy((void *)phdr->p_vaddr, tmp_ptr, phdr->p_filesz); + memcpy(PHYS_TO_VIRT(physmem), tmp_ptr, phdr->p_filesz); + break; + case PT_INTERP: + if (ld_path == NULL) { + break; + } + + *ld_path = dynalloc(phdr->p_filesz); + + if (ld_path == NULL) { + DBG("Failed to allocate memory for PT_INTERP path\n"); + return -ENOMEM; + } + + memcpy(*ld_path, (char *)hdr + phdr->p_offset, phdr->p_filesz); + break; + case PT_PHDR: + auxv->at_phdr = phdr->p_vaddr + load_base; + break; } } - auxv->at_entry = hdr->e_entry; + auxv->at_entry = hdr->e_entry + load_base; auxv->at_phent = hdr->e_phentsize; auxv->at_phnum = hdr->e_phnum; return 0; -- cgit v1.2.3