diff options
Diffstat (limited to 'winsup/cygwin/miscfuncs.cc')
-rw-r--r-- | winsup/cygwin/miscfuncs.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index cb3459630..320a3c2f3 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -760,6 +760,47 @@ public: }; 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 HANDLE WINAPI |