summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/user/lib/elfload.c20
-rw-r--r--src/usertestelf.c2
2 files changed, 20 insertions, 2 deletions
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index deb7b44..c490325 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -48,6 +48,19 @@ static bool load_phdr(const void *elf, void *exebase, size_t idx) {
return true;
}
+static size_t elf_spread(const void *elf) {
+ const struct Elf64_Ehdr *ehdr = elf;
+ uintptr_t high = 0, low = ~0;
+ for (size_t phi = 0; phi < ehdr->e_phnum; phi++) {
+ const struct Elf64_Phdr *phdr = elf + ehdr->e_phoff + phi * ehdr->e_phentsize;
+ if (high < phdr->p_vaddr + phdr->p_memsz)
+ high = phdr->p_vaddr + phdr->p_memsz;
+ if (low > phdr->p_vaddr)
+ low = phdr->p_vaddr;
+ }
+ return high - low;
+}
+
void elf_exec(void *base) {
struct Elf64_Ehdr *ehdr = base;
void *exebase;
@@ -57,7 +70,11 @@ void elf_exec(void *base) {
exebase = (void*)0;
break;
case ET_DYN:
- exebase = (void*)0x800000; // TODO search for free memory
+ exebase = _syscall_memflag((void*)0x1000, elf_spread(base), MEMFLAG_FINDFREE);
+ if (!exebase) {
+ printf("elf: out of memory\n");
+ _syscall_exit(1);
+ }
break;
default:
return;
@@ -66,6 +83,7 @@ void elf_exec(void *base) {
if (!load_phdr(base, exebase, phi))
return;
}
+ // TODO free memory
((void(*)())exebase + ehdr->e_entry)();
_syscall_exit(1);
}
diff --git a/src/usertestelf.c b/src/usertestelf.c
index c3ab289..54a397c 100644
--- a/src/usertestelf.c
+++ b/src/usertestelf.c
@@ -33,7 +33,6 @@ static struct Elf64_Dyn *dyn_gettag(Elf64_Xword tag) {
}
static void reloc(void) {
- printf("hi?\n");
// TODO DT_REL
if (dyn_gettag(DT_PLTGOT) || dyn_gettag(DT_JMPREL)) {
printf("elf: unimplemented tag in _DYNAMIC\n");
@@ -61,6 +60,7 @@ static void reloc(void) {
}
int main(void) {
+ printf("loaded at %x\n", &_image_base);
reloc();
printf(str);
printf(str2);