summaryrefslogtreecommitdiff
path: root/src/user/lib/thread.S
diff options
context:
space:
mode:
authordzwdz2022-08-20 00:00:52 +0200
committerdzwdz2022-08-20 00:00:52 +0200
commit2a16c1f6f9118e7127d532421ae19b959b3f1d87 (patch)
treea1b5134cc4a460e38e02e4bb2103a7c06d255198 /src/user/lib/thread.S
parent040bb34290c9a4305e13637e002060411e5a8385 (diff)
user/libc: don't access the old stack from the new thread at all
Diffstat (limited to 'src/user/lib/thread.S')
-rw-r--r--src/user/lib/thread.S46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/user/lib/thread.S b/src/user/lib/thread.S
index 3cd3500..1a27c30 100644
--- a/src/user/lib/thread.S
+++ b/src/user/lib/thread.S
@@ -1,8 +1,40 @@
+#define ASM_FILE 1
+#include <camellia/syscalls.h>
+#include <camellia/flags.h>
+
.section .text
-.global chstack
-.type chstack, @function
-// _Noreturn void chstack(void *arg, void (*fn)(void*), void *esp);
-chstack:
- mov %rdx, %rsp
- call *%rsi
- jmp 0 // "exit"
+.global thread_creates
+.type thread_creates, @function
+// void thread_creates(int flags, void (*fn)(void*), void *arg, void *stack);
+thread_creates:
+ push %r12
+ push %r13
+ push %r14
+
+ /* save fn, arg, stack */
+ mov %rsi, %r12
+ mov %rdx, %r13
+ mov %rcx, %r14
+
+ mov %rdi, %rsi
+ or $(FORK_SHAREMEM | FORK_SHAREHANDLE), %rsi
+ mov $_SYSCALL_FORK, %rdi
+ xor %rdx, %rdx
+ syscall
+
+ test %rax, %rax
+ jz 1f
+ /* in parent, return normally */
+ pop %r14
+ pop %r13
+ pop %r12
+ ret
+1: /* in child */
+ mov %r14, %rsp
+ mov %r13, %rdi
+ call *%r12
+
+ mov $_SYSCALL_EXIT, %rdi
+ xor %rsi, %rsi
+ syscall
+ hlt /* if all else fails... */