aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_loader.c
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-03-07 16:21:12 -0500
committerIan Moffett <ian@osmora.org>2024-03-07 16:26:25 -0500
commit21a122bcffcd4863a7f56b9680396919b909d232 (patch)
treeb153a2dcb006b8057264ea6bac1ceffe6b750bb1 /sys/kern/kern_loader.c
parentf621116fcaf15cd5dc0c53dab9a88f53f0effcd8 (diff)
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 <ian@osmora.org>
Diffstat (limited to 'sys/kern/kern_loader.c')
-rw-r--r--sys/kern/kern_loader.c49
1 files changed, 41 insertions, 8 deletions
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 <sys/elf.h>
#include <sys/types.h>
#include <sys/syslog.h>
+#include <sys/errno.h>
#include <vm/vm.h>
#include <vm/map.h>
#include <vm/physseg.h>
+#include <vm/dynalloc.h>
#include <string.h>
#include <assert.h>
@@ -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;