summaryrefslogtreecommitdiff
path: root/src/kernel/syscalls.c
diff options
context:
space:
mode:
authordzwdz2022-07-18 23:55:58 +0200
committerdzwdz2022-07-18 23:55:58 +0200
commit96f41ff64d8113307f1b60d2eb6852423db34d14 (patch)
tree5a85a9706a2a11d047f7f5c91f4964bd2167b1ee /src/kernel/syscalls.c
parent121794214fd5ae36609c30418dfaf1a073b8784c (diff)
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
Diffstat (limited to 'src/kernel/syscalls.c')
-rw-r--r--src/kernel/syscalls.c26
1 files changed, 25 insertions, 1 deletions
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;