summaryrefslogtreecommitdiff
path: root/src/user
diff options
context:
space:
mode:
Diffstat (limited to 'src/user')
-rw-r--r--src/user/lib/elfload.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index 565dfa2..c32232e 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -62,6 +62,16 @@ static size_t elf_spread(const void *elf) {
return high - low;
}
+/* frees memory outside of [low; high] and jumps to *entry */
+static void freejmp(void *entry, void *low, void *high) {
+ uint64_t buf[] = {
+ EXECBUF_SYSCALL, _SYSCALL_MEMFLAG, 0, (uintptr_t)low, 0, 0,
+ EXECBUF_SYSCALL, _SYSCALL_MEMFLAG, (uintptr_t)high, ~0 - 0xF000 - (uintptr_t)high, 0, 0,
+ EXECBUF_JMP, (uintptr_t)entry,
+ };
+ _syscall_execbuf(buf, sizeof buf);
+}
+
void elf_exec(void *base) {
struct Elf64_Ehdr *ehdr = base;
void *exebase;
@@ -86,11 +96,6 @@ void elf_exec(void *base) {
return;
}
- uint64_t buf[] = {
- // TODO free lower memory
- //EXECBUF_SYSCALL, _SYSCALL_MEMFLAG, exebase + spread, ~0 - 0xF0000, 0, 0, // free upper memory
- EXECBUF_JMP, (uintptr_t)exebase + ehdr->e_entry,
- };
- _syscall_execbuf(buf, sizeof buf);
+ freejmp(exebase + ehdr->e_entry, exebase, exebase + spread + 0x1000);
printf("elf: execbuf failed?");
}