diff options
Diffstat (limited to 'src/thread/nt64')
-rw-r--r-- | src/thread/nt64/clone.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/thread/nt64/clone.c b/src/thread/nt64/clone.c index d460855..c3a968b 100644 --- a/src/thread/nt64/clone.c +++ b/src/thread/nt64/clone.c @@ -1,5 +1,10 @@ #include <syscall.h> +/* take advantage of winnt's x64 vararg abi */ +#define __clone ____clone +#include "pthread_impl.h" +#undef __clone + struct pt_regs { unsigned long r15; unsigned long r14; @@ -22,6 +27,9 @@ struct pt_regs { unsigned long eflags; unsigned long rsp; unsigned long ss; + uintptr_t sbase; + uintptr_t slimit; + uintptr_t sbottom; }; typedef long __sys_clone( @@ -31,12 +39,10 @@ typedef long __sys_clone( void * ctid, struct pt_regs *regs); -typedef int __entry_point(void *); - extern unsigned long ** __syscall_vtbl; -int __clone( - __entry_point * fn, +hidden int __clone( + int (*fn)(void *), void * child_stack, int flags, void * arg, @@ -46,6 +52,7 @@ int __clone( { struct pt_regs regs; __sys_clone * pfn_clone; + pthread_t pthread; regs.rip = (unsigned long)fn; regs.rcx = (unsigned long)arg; @@ -53,6 +60,11 @@ int __clone( pfn_clone = (__sys_clone *)(__syscall_vtbl[SYS_clone]); + pthread = (pthread_t)pthread_self_addr; + regs.sbase = (unsigned long)pthread->stack; + regs.slimit = regs.sbase - pthread->stack_size; + regs.sbottom = regs.slimit - pthread->guard_size; + return (int)pfn_clone( flags, child_stack, |