diff options
author | midipix <writeonce@midipix.org> | 2024-03-06 00:08:11 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2024-03-06 01:22:38 +0000 |
commit | 659ac4d3f99d7eca878e4f043ac883fdeaa0aa4a (patch) | |
tree | 6760c4abbd80191498312a9ee1b940803ac7b714 /src/thread/nt64 | |
parent | 09a5b8ecf27ce8fad4f89519b2f07f4cdd32c332 (diff) | |
download | mmglue-659ac4d3f99d7eca878e4f043ac883fdeaa0aa4a.tar.bz2 mmglue-659ac4d3f99d7eca878e4f043ac883fdeaa0aa4a.tar.xz |
__clone(): align user-provided stack pointers on a 16-byte boundary.
Diffstat (limited to 'src/thread/nt64')
-rw-r--r-- | src/thread/nt64/clone.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/thread/nt64/clone.c b/src/thread/nt64/clone.c index d1b6603..8d9ca5f 100644 --- a/src/thread/nt64/clone.c +++ b/src/thread/nt64/clone.c @@ -59,6 +59,11 @@ hidden int __clone( void * pthread_self_addr, int * ctid) { + uintptr_t sbase; + uintptr_t slimit; + uintptr_t sbottom; + void * stack; + struct pt_regs regs; __sys_clone * pfn_clone; pthread_t pthread; @@ -69,6 +74,10 @@ hidden int __clone( pfn_clone = (__sys_clone *)(__syscall_vtbl[SYS_clone]); + sbase = (uintptr_t)child_stack; + sbase &= ~(uintptr_t)(0xf); + stack = (void *)sbase; + if (flags == (CLONE_VM|CLONE_VFORK|SIGCHLD)) { regs.sbase = 0; regs.slimit = 0; @@ -76,18 +85,27 @@ hidden int __clone( return (int)pfn_clone( flags, - child_stack, + stack, 0,0,®s); } - 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; + pthread = (pthread_t)pthread_self_addr; + sbase = (uintptr_t)pthread->stack; + slimit = sbase - pthread->stack_size; + sbottom = slimit - pthread->guard_size; + + sbase &= ~(uintptr_t)(0xf); + slimit += 0xf; + slimit |= 0xf; + slimit ^= 0xf; + + regs.sbase = sbase; + regs.slimit = slimit; + regs.sbottom = sbottom; return (int)pfn_clone( flags, - child_stack, + stack, ptid, ctid, ®s); |