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/syscalls.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/kernel/syscalls.c') diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 786578a..a2ae5dd 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -361,6 +361,25 @@ long _syscall_pipe(handle_t __user user_ends[2], int flags) { SYSCALL_RETURN(0); } +long _syscall_execbuf(void __user *ubuf, size_t len) { + if (len == 0) SYSCALL_RETURN(0); + if (len > sizeof(uint64_t) * 6 * 4) // TODO specify max size somewhere + SYSCALL_RETURN(-1); + if (process_current->execbuf.buf) + SYSCALL_RETURN(-1); /* no nesting */ + // actually TODO, nesting makes sense for infinite loops. maybe + + char *kbuf = kmalloc(len); + if (!virt_cpy_from(process_current->pages, kbuf, ubuf, len)) { + kfree(kbuf); + SYSCALL_RETURN(-1); + } + process_current->execbuf.buf = kbuf; + process_current->execbuf.len = len; + process_current->execbuf.pos = 0; + SYSCALL_RETURN(0); +} + void _syscall_debug_klog(const void __user *buf, size_t len) { (void)buf; (void)len; // static char kbuf[256]; @@ -371,10 +390,12 @@ void _syscall_debug_klog(const void __user *buf, size_t len) { } long _syscall(long num, long a, long b, long c, long d) { + /* note: this isn't the only place where syscalls get called from! + * see execbuf */ switch (num) { case _SYSCALL_EXIT: _syscall_exit(a); - // _syscall_exit doesn't exit + // _syscall_exit doesn't return case _SYSCALL_AWAIT: _syscall_await(); break; @@ -411,6 +432,9 @@ long _syscall(long num, long a, long b, long c, long d) { case _SYSCALL_PIPE: _syscall_pipe((userptr_t)a, b); break; + case _SYSCALL_EXECBUF: + _syscall_execbuf((userptr_t)a, b); + break; case _SYSCALL_DEBUG_KLOG: _syscall_debug_klog((userptr_t)a, b); break; -- cgit v1.2.3