diff options
-rw-r--r-- | src/thread/nt32/clone.c | 28 | ||||
-rw-r--r-- | src/thread/nt64/clone.c | 20 |
2 files changed, 38 insertions, 10 deletions
diff --git a/src/thread/nt32/clone.c b/src/thread/nt32/clone.c index fb53501..f5ad5f8 100644 --- a/src/thread/nt32/clone.c +++ b/src/thread/nt32/clone.c @@ -1,19 +1,31 @@ #include <syscall.h> +/* take advantage of i686 vararg abi */ +#define __clone ____clone +#include "pthread_impl.h" +#undef __clone + struct pt_regs { - unsigned long ebp; unsigned long ebx; - unsigned long eax; unsigned long ecx; unsigned long edx; unsigned long esi; unsigned long edi; + unsigned long ebp; + unsigned long eax; + unsigned long xds; + unsigned long xes; + unsigned long xfs; + unsigned long xgs; unsigned long orig_eax; unsigned long eip; - unsigned long cs; + unsigned long xcs; unsigned long eflags; unsigned long esp; - unsigned long ss; + unsigned long xss; + unsigned long sbase; + unsigned long slimit; + unsigned long sbottom; }; typedef long __sys_clone( @@ -23,8 +35,6 @@ typedef long __sys_clone( void * ctid, struct pt_regs *regs); -typedef int __entry_point(void *); - extern unsigned long ** __syscall_vtbl; int __clone( @@ -38,6 +48,7 @@ int __clone( { struct pt_regs regs; __sys_clone * pfn_clone; + pthread_t pthread; regs.eip = (unsigned long)fn; regs.ecx = (unsigned long)arg; @@ -45,6 +56,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, 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, |