From 96f41ff64d8113307f1b60d2eb6852423db34d14 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Mon, 18 Jul 2022 23:55:58 +0200 Subject: syscalls: implement execbuf i have been planning to implement something like this for a while now. it should be faster when doing consecutive syscalls (to be tested). it will also be helpful in writing the elf loader --- src/kernel/execbuf.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/kernel/execbuf.c (limited to 'src/kernel/execbuf.c') diff --git a/src/kernel/execbuf.c b/src/kernel/execbuf.c new file mode 100644 index 0000000..6136d0e --- /dev/null +++ b/src/kernel/execbuf.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include + +_Noreturn static void halt(struct process *proc) { + kfree(proc->execbuf.buf); + proc->execbuf.buf = NULL; + process_switch_any(); +} + +static void try_fetch(struct process *proc, uint64_t *buf, size_t amt) { + size_t bytes = amt * sizeof(uint64_t); + if (proc->execbuf.pos + bytes > proc->execbuf.len) + halt(proc); + memcpy(buf, proc->execbuf.buf + proc->execbuf.pos, bytes); + proc->execbuf.pos += bytes; +} + +_Noreturn void execbuf_run(struct process *proc) { + uint64_t buf[5]; + assert(proc == process_current); // idiotic, but needed because of _syscall. + assert(proc->state == PS_RUNNING); + assert(proc->execbuf.buf); + + for (;;) { + try_fetch(proc, buf, 1); + switch (buf[0]) { + case EXECBUF_SYSCALL: + try_fetch(proc, buf, 5); + _syscall(buf[0], buf[1], buf[2], buf[3], buf[4]); + break; + default: + halt(proc); + } + } +} -- cgit v1.2.3