summaryrefslogtreecommitdiff
path: root/sys/kern/exec_elf64.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/exec_elf64.c')
-rw-r--r--sys/kern/exec_elf64.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/sys/kern/exec_elf64.c b/sys/kern/exec_elf64.c
index 0fafc02..9706e77 100644
--- a/sys/kern/exec_elf64.c
+++ b/sys/kern/exec_elf64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,7 @@
#include <sys/elf.h>
#include <sys/exec.h>
#include <sys/param.h>
+#include <sys/syslog.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/vnode.h>
@@ -42,14 +43,49 @@
#include <string.h>
#include <machine/pcb.h>
+#define pr_trace(fmt, ...) kprintf("elf64: " fmt, ##__VA_ARGS__)
+#define pr_error(...) pr_trace(__VA_ARGS__)
+
#define PHDR(HDRP, IDX) \
(void *)((uintptr_t)HDRP + (HDRP)->e_phoff + (HDRP->e_phentsize * IDX))
+#define SHDR(HDRP, IDX) \
+ (void *)((uintptr_t)HDRP + (HDRP)->e_shoff + (HDRP->e_shentsize * IDX))
+
struct elf_file {
char *data;
size_t size;
};
+static int
+elf_parse_shdrs(Elf64_Ehdr *eh)
+{
+ Elf64_Shdr *shp;
+ uint32_t nshdr;
+
+ if (eh == NULL) {
+ return -EINVAL;
+ }
+
+ nshdr = eh->e_shnum;
+ for (uint32_t i = 0; i < nshdr; ++i) {
+ shp = SHDR(eh, i);
+
+ /* Drop null entries */
+ if (shp->sh_type == SHT_NULL) {
+ continue;
+ }
+
+ switch (shp->sh_type) {
+ case SHT_NOBITS:
+ memset((void *)shp->sh_addr, 0x0, shp->sh_size);
+ break;
+ }
+ }
+
+ return 0;
+}
+
/*
* Load the file and give back an "elf_file"
* structure.
@@ -188,6 +224,7 @@ elf64_load(const char *pathname, struct proc *td, struct exec_prog *prog)
if ((status = elf64_verify(hdr)) != 0)
goto done;
+ memset(loadmap, 0, sizeof(loadmap));
pcbp = &td->pcb;
start = -1;
end = 0;
@@ -209,6 +246,7 @@ elf64_load(const char *pathname, struct proc *td, struct exec_prog *prog)
/* Try to allocate page frames */
physmem = vm_alloc_frame(page_count);
if (physmem == 0) {
+ pr_error("out of physical memory\n");
status = -ENOMEM;
break;
}
@@ -237,6 +275,7 @@ elf64_load(const char *pathname, struct proc *td, struct exec_prog *prog)
}
}
+ elf_parse_shdrs(hdr);
memcpy(prog->loadmap, loadmap, sizeof(loadmap));
prog->start = start;
prog->end = end;