summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/execbuf.c4
-rw-r--r--src/shared/execbuf.h2
-rw-r--r--src/user/lib/elfload.c15
3 files changed, 17 insertions, 4 deletions
diff --git a/src/kernel/execbuf.c b/src/kernel/execbuf.c
index 6136d0e..b96188d 100644
--- a/src/kernel/execbuf.c
+++ b/src/kernel/execbuf.c
@@ -31,6 +31,10 @@ _Noreturn void execbuf_run(struct process *proc) {
try_fetch(proc, buf, 5);
_syscall(buf[0], buf[1], buf[2], buf[3], buf[4]);
break;
+ case EXECBUF_JMP:
+ try_fetch(proc, buf, 1);
+ proc->regs.rcx = buf[0];
+ break;
default:
halt(proc);
}
diff --git a/src/shared/execbuf.h b/src/shared/execbuf.h
index 70ea35c..c9d444d 100644
--- a/src/shared/execbuf.h
+++ b/src/shared/execbuf.h
@@ -3,3 +3,5 @@
/* takes 5 arguments */
#define EXECBUF_SYSCALL 0xF0000001
+/* takes 1 argument, changes %rip */
+#define EXECBUF_JMP 0xF0000002
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index c490325..565dfa2 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -1,3 +1,4 @@
+#include <shared/execbuf.h>
#include <shared/flags.h>
#include <shared/syscalls.h>
#include <user/lib/elf.h>
@@ -65,12 +66,13 @@ void elf_exec(void *base) {
struct Elf64_Ehdr *ehdr = base;
void *exebase;
if (!valid_ehdr(ehdr)) return;
+ size_t spread = elf_spread(base);
switch (ehdr->e_type) {
case ET_EXEC:
exebase = (void*)0;
break;
case ET_DYN:
- exebase = _syscall_memflag((void*)0x1000, elf_spread(base), MEMFLAG_FINDFREE);
+ exebase = _syscall_memflag((void*)0x1000, spread, MEMFLAG_FINDFREE);
if (!exebase) {
printf("elf: out of memory\n");
_syscall_exit(1);
@@ -83,7 +85,12 @@ void elf_exec(void *base) {
if (!load_phdr(base, exebase, phi))
return;
}
- // TODO free memory
- ((void(*)())exebase + ehdr->e_entry)();
- _syscall_exit(1);
+
+ 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);
+ printf("elf: execbuf failed?");
}