Always move 64 bit main thread stack to defined pthread stack area
x86_64 only: * dcrt0.cc (_dll_crt0): Always move stack to pthread stack area. Explain why. * miscfuncs.cc (create_new_main_thread_stack): New function to create OS-like stack for main thread in pthread stack area. * miscfuncs.cc (create_new_main_thread_stack): Declare. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
81e6c7515d
commit
8a14e51901
|
@ -1,3 +1,12 @@
|
||||||
|
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
x86_64 only:
|
||||||
|
* dcrt0.cc (_dll_crt0): Always move stack to pthread stack area.
|
||||||
|
Explain why.
|
||||||
|
* miscfuncs.cc (create_new_main_thread_stack): New function to create
|
||||||
|
OS-like stack for main thread in pthread stack area.
|
||||||
|
* miscfuncs.cc (create_new_main_thread_stack): Declare.
|
||||||
|
|
||||||
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
2015-12-03 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* dcrt0.cc (child_info_fork::alloc_stack): Fix formatting.
|
* dcrt0.cc (child_info_fork::alloc_stack): Fix formatting.
|
||||||
|
|
|
@ -1093,6 +1093,35 @@ _dll_crt0 ()
|
||||||
/* Fall back to respawn if wow64_revert_to_original_stack fails. */
|
/* Fall back to respawn if wow64_revert_to_original_stack fails. */
|
||||||
wow64_respawn_process ();
|
wow64_respawn_process ();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* Starting with Windows 10 rel 1511, the main stack of an application is
|
||||||
|
not reproducible if a 64 bit process has been started from a 32 bit
|
||||||
|
process. Given that we have enough virtual address space on 64 bit
|
||||||
|
anyway, we now move the main thread stack to the stack area reserved for
|
||||||
|
pthread stacks. This allows a reproducible stack space under our own
|
||||||
|
control and avoids collision with the OS. */
|
||||||
|
if (!in_forkee && !dynamically_loaded)
|
||||||
|
{
|
||||||
|
/* Must be static since it's referenced after the stack and frame
|
||||||
|
pointer registers have been changed. */
|
||||||
|
static PVOID allocationbase;
|
||||||
|
|
||||||
|
PVOID stackaddr = create_new_main_thread_stack (allocationbase);
|
||||||
|
if (stackaddr)
|
||||||
|
{
|
||||||
|
/* 2nd half of the stack move. Set stack pointer to new address.
|
||||||
|
Don't set frame pointer to 0 since x86_64 uses the stack while
|
||||||
|
evaluating NtCurrentTeb (). */
|
||||||
|
__asm__ ("\n\
|
||||||
|
movq %[ADDR], %%rsp \n\
|
||||||
|
movq %%rsp, %%rbp \n"
|
||||||
|
: : [ADDR] "r" (stackaddr));
|
||||||
|
/* Now we're back on the new stack. Free up space taken by the
|
||||||
|
former main thread stack and set DeallocationStack correctly. */
|
||||||
|
VirtualFree (NtCurrentTeb ()->DeallocationStack, 0, MEM_RELEASE);
|
||||||
|
NtCurrentTeb ()->DeallocationStack = allocationbase;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* !__x86_64__ */
|
#endif /* !__x86_64__ */
|
||||||
_feinitialise ();
|
_feinitialise ();
|
||||||
#ifndef __x86_64__
|
#ifndef __x86_64__
|
||||||
|
|
|
@ -760,6 +760,47 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_allocator thr_alloc NO_COPY;
|
thread_allocator thr_alloc NO_COPY;
|
||||||
|
|
||||||
|
/* Just set up a system-like main thread stack from the pthread stack area
|
||||||
|
maintained by the thr_alloc class. See the description in the x86_64-only
|
||||||
|
code in _dll_crt0 to understand why we have to do this. */
|
||||||
|
PVOID
|
||||||
|
create_new_main_thread_stack (PVOID &allocationbase)
|
||||||
|
{
|
||||||
|
PIMAGE_DOS_HEADER dosheader;
|
||||||
|
PIMAGE_NT_HEADERS ntheader;
|
||||||
|
SIZE_T stacksize;
|
||||||
|
ULONG guardsize;
|
||||||
|
ULONG commitsize;
|
||||||
|
PBYTE stacklimit;
|
||||||
|
|
||||||
|
dosheader = (PIMAGE_DOS_HEADER) GetModuleHandle (NULL);
|
||||||
|
ntheader = (PIMAGE_NT_HEADERS)
|
||||||
|
((PBYTE) dosheader + dosheader->e_lfanew);
|
||||||
|
stacksize = ntheader->OptionalHeader.SizeOfStackReserve;
|
||||||
|
stacksize = roundup2 (stacksize, wincap.allocation_granularity ());
|
||||||
|
|
||||||
|
allocationbase
|
||||||
|
= thr_alloc.alloc (ntheader->OptionalHeader.SizeOfStackReserve);
|
||||||
|
guardsize = wincap.def_guard_page_size ();
|
||||||
|
commitsize = ntheader->OptionalHeader.SizeOfStackCommit;
|
||||||
|
commitsize = roundup2 (commitsize, wincap.page_size ());
|
||||||
|
if (commitsize > stacksize - guardsize - wincap.page_size ())
|
||||||
|
commitsize = stacksize - guardsize - wincap.page_size ();
|
||||||
|
stacklimit = (PBYTE) allocationbase + stacksize - commitsize - guardsize;
|
||||||
|
/* Setup guardpage. */
|
||||||
|
if (!VirtualAlloc (stacklimit, guardsize,
|
||||||
|
MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD))
|
||||||
|
return NULL;
|
||||||
|
/* Setup committed region. */
|
||||||
|
stacklimit += guardsize;
|
||||||
|
if (!VirtualAlloc (stacklimit, commitsize, MEM_COMMIT, PAGE_READWRITE))
|
||||||
|
return NULL;
|
||||||
|
NtCurrentTeb()->Tib.StackBase = ((PBYTE) allocationbase + stacksize);
|
||||||
|
NtCurrentTeb()->Tib.StackLimit = stacklimit;
|
||||||
|
_main_tls = &_my_tls;
|
||||||
|
return stacklimit - 64;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HANDLE WINAPI
|
HANDLE WINAPI
|
||||||
|
|
|
@ -70,6 +70,10 @@ ssize_t __reg3 check_iovec (const struct iovec *, int, bool);
|
||||||
#define check_iovec_for_read(a, b) check_iovec ((a), (b), false)
|
#define check_iovec_for_read(a, b) check_iovec ((a), (b), false)
|
||||||
#define check_iovec_for_write(a, b) check_iovec ((a), (b), true)
|
#define check_iovec_for_write(a, b) check_iovec ((a), (b), true)
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
extern PVOID create_new_main_thread_stack (PVOID &allocationbase);
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" DWORD WINAPI pthread_wrapper (PVOID arg);
|
extern "C" DWORD WINAPI pthread_wrapper (PVOID arg);
|
||||||
extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func,
|
extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func,
|
||||||
PVOID thread_arg, PVOID stackaddr,
|
PVOID thread_arg, PVOID stackaddr,
|
||||||
|
|
Loading…
Reference in New Issue