Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-07-04 23:49:30 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-07-04 23:49:30 +0300
commit2cd7eb7f60208b0ffd51a9e117a8846c33b4ad41 (patch)
tree0ebf0d1b51a4bd5642c288b0572939399df962a4
parent757c0871f74c3a2d682398490bcae8873d1fafd4 (diff)
Fix original stack when running signal handler on alternate stack
* autoload.cc (SetThreadStackGuarantee): Import. * cygtls.h (struct _cygtls): Replace thread_context with a ucontext_t called context. * exceptions.cc (exception::handle): Exit from process via signal_exit in case sig_send returns from handling a stack overflow SIGSEGV. Explain why. (dumpstack_overflow_wrapper): Thread wrapper to create a stackdump from another thread. (signal_exit): Fix argument list to reflect three-arg signal handler. In case we have to create a stackdump for a stack overflow condition, do so from a separate thread. Explain why. (sigpacket::process): Don't run signal_exit on alternate stack. (altstack_wrapper): Wrapper function to do stack correction when calling the signal handler on an alternate stack to handle a stack overflow. Make sure to have lots of comments. (_cygtls::call_signal_handler): Drop local context variable to reduce stack pressure. Use this->context instead. Change inline assembler to call altstack_wrapper. (_cygtls::signal_debugger): Accommodate aforementioned change to struct _cygtls. * tlsoffset.h: Regenerate. * tlsoffset64.h: Regenerate. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/ChangeLog25
-rw-r--r--winsup/cygwin/autoload.cc1
-rw-r--r--winsup/cygwin/cygtls.h4
-rw-r--r--winsup/cygwin/exceptions.cc142
-rw-r--r--winsup/cygwin/tlsoffsets.h116
-rw-r--r--winsup/cygwin/tlsoffsets64.h116
-rw-r--r--winsup/cygwin/wincap.cc14
-rw-r--r--winsup/cygwin/wincap.h7
8 files changed, 291 insertions, 134 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index eaa62a086..909996c47 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,28 @@
+2015-07-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc (SetThreadStackGuarantee): Import.
+ * cygtls.h (struct _cygtls): Replace thread_context with a ucontext_t
+ called context.
+ * exceptions.cc (exception::handle): Exit from process via signal_exit
+ in case sig_send returns from handling a stack overflow SIGSEGV.
+ Explain why.
+ (dumpstack_overflow_wrapper): Thread wrapper to create a stackdump
+ from another thread.
+ (signal_exit): Fix argument list to reflect three-arg signal handler.
+ In case we have to create a stackdump for a stack overflow condition,
+ do so from a separate thread. Explain why.
+ (sigpacket::process): Don't run signal_exit on alternate stack.
+ (altstack_wrapper): Wrapper function to do stack correction when
+ calling the signal handler on an alternate stack to handle a stack
+ overflow. Make sure to have lots of comments.
+ (_cygtls::call_signal_handler): Drop local context variable to reduce
+ stack pressure. Use this->context instead. Change inline assembler
+ to call altstack_wrapper.
+ (_cygtls::signal_debugger): Accommodate aforementioned change to
+ struct _cygtls.
+ * tlsoffset.h: Regenerate.
+ * tlsoffset64.h: Regenerate.
+
2015-07-01 Corinna Vinschen <corinna@vinschen.de>
* fork.cc (frok::parent): Set stacktop value based on requested stack
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 5832e27bf..6423a67a6 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -581,6 +581,7 @@ LoadDLLfunc (GetSystemTimePreciseAsFileTime, 4, kernel32)
LoadDLLfuncEx (IdnToAscii, 20, kernel32, 1)
LoadDLLfuncEx (IdnToUnicode, 20, kernel32, 1)
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
+LoadDLLfunc (SetThreadStackGuarantee, 4, kernel32)
/* ldap functions are cdecl! */
#pragma push_macro ("mangle")
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 0944811b0..3dfffbbff 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -17,6 +17,7 @@ details. */
#include <mntent.h>
#undef _NOMNTENT_FUNCS
#include <setjmp.h>
+#include <ucontext.h>
#define CYGTLS_INITIALIZED 0xc763173f
@@ -192,7 +193,8 @@ public:
siginfo_t *sigwait_info;
HANDLE signal_arrived;
bool will_wait_for_signal;
- CONTEXT thread_context;
+ long __align; /* Needed to align context to 16 byte. */
+ ucontext_t context;
DWORD thread_id;
siginfo_t infodata;
struct pthread *tid;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 90a8ff25d..0ce22d9b3 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -800,6 +800,19 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
? (void *) e->ExceptionInformation[1] : (void *) in->_GR(ip);
me.incyg++;
sig_send (NULL, si, &me); /* Signal myself */
+ if ((NTSTATUS) e->ExceptionCode == STATUS_STACK_OVERFLOW)
+ {
+ /* If we catched a stack overflow, and if the signal handler didn't exit
+ or longjmp, we're back here and about to continue, supposed to run the
+ offending instruction again. That works on Linux, but not on Windows.
+ In case of a stack overflow we're not immediately returning to the
+ system exception handler, but to NTDLL::__stkchk. __stkchk will then
+ terminate the applicaton. So what we do here is to signal our current
+ process again, but this time with SIG_DFL action. This creates a
+ stackdump and then exits through our own means. */
+ global_sigs[SIGSEGV].sa_handler = SIG_DFL;
+ sig_send (NULL, si, &me);
+ }
me.incyg--;
e->ExceptionFlags = 0;
return ExceptionContinueExecution;
@@ -1237,10 +1250,20 @@ set_signal_mask (sigset_t& setmask, sigset_t newmask)
sig_dispatch_pending (true);
}
+
+DWORD WINAPI
+dumpstack_overflow_wrapper (PVOID arg)
+{
+ cygwin_exception *exc = (cygwin_exception *) arg;
+
+ exc->dumpstack ();
+ return 0;
+}
+
/* Exit due to a signal. Should only be called from the signal thread. */
extern "C" {
static void
-signal_exit (int sig, siginfo_t *si)
+signal_exit (int sig, siginfo_t *si, void *)
{
debug_printf ("exiting due to signal %d", sig);
exit_state = ES_SIGNAL_EXIT;
@@ -1262,7 +1285,27 @@ signal_exit (int sig, siginfo_t *si)
if (try_to_debug ())
break;
if (si->si_code != SI_USER && si->si_cyg)
- ((cygwin_exception *) si->si_cyg)->dumpstack ();
+ {
+ cygwin_exception *exc = (cygwin_exception *) si->si_cyg;
+ if ((NTSTATUS) exc->exception_record ()->ExceptionCode
+ == STATUS_STACK_OVERFLOW)
+ {
+ /* We're handling a stack overflow so we're running low
+ on stack (surprise!) The dumpstack method needs lots
+ of stack for buffers. So what we do here is to run
+ dumpstack in another thread with its own stack. */
+ HANDLE thread = CreateThread (&sec_none_nih, 0,
+ dumpstack_overflow_wrapper,
+ exc, 0, NULL);
+ if (thread)
+ {
+ WaitForSingleObject (thread, INFINITE);
+ CloseHandle (thread);
+ }
+ }
+ else
+ ((cygwin_exception *) si->si_cyg)->dumpstack ();
+ }
else
{
CONTEXT c;
@@ -1470,6 +1513,8 @@ stop:
exit_sig:
handler = (void *) signal_exit;
thissig.sa_flags |= SA_SIGINFO;
+ /* Don't run signal_exit on alternate stack. */
+ thissig.sa_flags &= ~SA_ONSTACK;
dosig:
if (have_execed)
@@ -1488,6 +1533,58 @@ done:
}
+static void
+altstack_wrapper (int sig, siginfo_t *siginfo, ucontext_t *sigctx,
+ void (*handler) (int, siginfo_t *, void *))
+{
+ siginfo_t si = *siginfo;
+ ULONG guard_size = 0;
+ DWORD old_prot = (DWORD) -1;
+ PTEB teb = NtCurrentTeb ();
+ PVOID old_limit = NULL;
+
+ /* Check if we're just handling a stack overflow. If so... */
+ if (sig == SIGSEGV && si.si_cyg
+ && ((cygwin_exception *) si.si_cyg)->exception_record ()->ExceptionCode
+ == (DWORD) STATUS_STACK_OVERFLOW)
+ {
+ /* ...restore guard pages in original stack as if MSVCRT::_resetstkovlw
+ has been called.
+
+ Compute size of guard pages. If SetThreadStackGuarantee isn't
+ supported, or if it returns 0, use the default guard page size. */
+ if (wincap.has_set_thread_stack_guarantee ())
+ SetThreadStackGuarantee (&guard_size);
+ if (!guard_size)
+ guard_size = wincap.def_guard_page_size ();
+ else
+ guard_size += wincap.page_size ();
+ old_limit = teb->Tib.StackLimit;
+ /* Amazing but true: This VirtualProtect call automatically fixes the
+ value of teb->Tib.StackLimit on some systems.*/
+ if (VirtualProtect (teb->Tib.StackLimit, guard_size,
+ PAGE_READWRITE | PAGE_GUARD, &old_prot)
+ && old_limit == teb->Tib.StackLimit)
+ teb->Tib.StackLimit = (caddr_t) old_limit + guard_size;
+ }
+ handler (sig, &si, sigctx);
+ if (old_prot != (DWORD) -1)
+ {
+ /* Typically the handler would exit or at least perform a siglongjmp
+ trying to overcome a SEGV condition. However, if we return from a
+ segv handler after a stack overflow, we're dead. While on Linux the
+ process returns to the offending code and thus the handler is called
+ ad infinitum, on Windows the NTDLL::__stkchk function will simply kill
+ the process. So what we do here is to remove the guard pages again so
+ we can return to exception::handle. exception::handle will then call
+ sig_send again, this time with SIG_DFL action, so at least we get a
+ stackdump. */
+ if (VirtualProtect ((caddr_t) teb->Tib.StackLimit - guard_size,
+ guard_size, old_prot, &old_prot))
+ teb->Tib.StackLimit = old_limit;
+ }
+}
+
int
_cygtls::call_signal_handler ()
{
@@ -1516,7 +1613,6 @@ _cygtls::call_signal_handler ()
siginfo_t thissi = infodata;
void (*thisfunc) (int, siginfo_t *, void *) = func;
- ucontext_t context;
ucontext_t *thiscontext = NULL;
/* Only make a context for SA_SIGINFO handlers */
@@ -1596,9 +1692,8 @@ _cygtls::call_signal_handler ()
/* Compute new stackbase. We start from the high address, aligned
to 16 byte. */
- uintptr_t new_sp = (uintptr_t) _my_tls.altstack.ss_sp
- + _my_tls.altstack.ss_size;
- new_sp &= ~0xf;
+ uintptr_t new_sp = ((uintptr_t) _my_tls.altstack.ss_sp
+ + _my_tls.altstack.ss_size) & ~0xf;
/* In assembler: Save regs on new stack, move to alternate stack,
call thisfunc, revert stack regs. */
#ifdef __x86_64__
@@ -1620,8 +1715,9 @@ _cygtls::call_signal_handler ()
leaq %[SI], %%rdx # &thissi to 2nd arg reg \n\
movq %[CTX], %%r8 # thiscontext to 3rd arg reg \n\
movq %[FUNC], %%r9 # thisfunc to r9 \n\
+ leaq %[WRAPPER], %%r10 # wrapper address to r10 \n\
movq %%rax, %%rsp # Move alt stack into rsp \n\
- call *%%r9 # Call thisfunc \n\
+ call *%%r10 # Call wrapper \n\
movq %%rsp, %%rax # Restore clobbered regs \n\
movq 0x58(%%rax), %%rsp \n\
movq 0x50(%%rax), %%rbp \n\
@@ -1635,38 +1731,42 @@ _cygtls::call_signal_handler ()
[SIG] "o" (thissig),
[SI] "o" (thissi),
[CTX] "o" (thiscontext),
- [FUNC] "o" (thisfunc)
+ [FUNC] "o" (thisfunc),
+ [WRAPPER] "o" (altstack_wrapper)
: "memory");
#else
/* Clobbered regs: ecx, edx, ebp, esp */
__asm__ ("\n\
movl %[NEW_SP], %%eax # Load alt stack into eax \n\
- subl $28, %%eax # Make room on alt stack for \n\
+ subl $32, %%eax # Make room on alt stack for \n\
# clobbered regs and args to \n\
# signal handler \n\
- movl %%ecx, 12(%%eax) # Save other clobbered regs \n\
- movl %%edx, 16(%%eax) \n\
- movl %%ebp, 20(%%eax) \n\
- movl %%esp, 24(%%eax) \n\
+ movl %%ecx, 16(%%eax) # Save clobbered regs \n\
+ movl %%edx, 20(%%eax) \n\
+ movl %%ebp, 24(%%eax) \n\
+ movl %%esp, 28(%%eax) \n\
movl %[SIG], %%ecx # thissig to 1st arg slot \n\
movl %%ecx, (%%eax) \n\
leal %[SI], %%ecx # &thissi to 2nd arg slot \n\
movl %%ecx, 4(%%eax) \n\
movl %[CTX], %%ecx # thiscontext to 3rd arg slot\n\
movl %%ecx, 8(%%eax) \n\
- movl %[FUNC], %%ecx # thisfunc to ecx \n\
+ movl %[FUNC], %%ecx # thisfunc to 4th arg slot \n\
+ movl %%ecx, 12(%%eax) \n\
+ leal %[WRAPPER], %%ecx # thisfunc to ecx \n\
movl %%eax, %%esp # Move alt stack into esp \n\
call *%%ecx # Call thisfunc \n\
movl %%esp, %%eax # Restore clobbered regs \n\
- movl 24(%%eax), %%esp \n\
- movl 20(%%eax), %%ebp \n\
- movl 16(%%eax), %%edx \n\
- movl 12(%%eax), %%eax \n"
+ movl 28(%%eax), %%esp \n\
+ movl 24(%%eax), %%ebp \n\
+ movl 20(%%eax), %%edx \n\
+ movl 16(%%eax), %%eax \n"
: : [NEW_SP] "o" (new_sp),
[SIG] "o" (thissig),
[SI] "o" (thissi),
[CTX] "o" (thiscontext),
- [FUNC] "o" (thisfunc)
+ [FUNC] "o" (thisfunc),
+ [WRAPPER] "o" (altstack_wrapper)
: "memory");
#endif
}
@@ -1708,12 +1808,12 @@ _cygtls::signal_debugger (siginfo_t& si)
#else
c.Eip = retaddr ();
#endif
- memcpy (&thread_context, &c, sizeof (CONTEXT));
+ memcpy (&context.uc_mcontext, &c, sizeof (CONTEXT));
/* Enough space for 32/64 bit addresses */
char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING
" ffffffff ffffffffffffffff")];
__small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %y %p",
- si.si_signo, thread_id, &thread_context);
+ si.si_signo, thread_id, &context.uc_mcontext);
OutputDebugString (sigmsg);
}
ResumeThread (th);
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index daf610f19..13d1003e3 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -31,34 +31,36 @@
//; $tls::psignal_arrived = 2856;
//; $tls::will_wait_for_signal = -9840;
//; $tls::pwill_wait_for_signal = 2860;
-//; $tls::thread_context = -9836;
-//; $tls::pthread_context = 2864;
-//; $tls::thread_id = -9120;
-//; $tls::pthread_id = 3580;
-//; $tls::infodata = -9116;
-//; $tls::pinfodata = 3584;
-//; $tls::tid = -8968;
-//; $tls::ptid = 3732;
-//; $tls::_ctinfo = -8964;
-//; $tls::p_ctinfo = 3736;
-//; $tls::andreas = -8960;
-//; $tls::pandreas = 3740;
-//; $tls::wq = -8956;
-//; $tls::pwq = 3744;
-//; $tls::sig = -8928;
-//; $tls::psig = 3772;
-//; $tls::incyg = -8924;
-//; $tls::pincyg = 3776;
-//; $tls::spinning = -8920;
-//; $tls::pspinning = 3780;
-//; $tls::stacklock = -8916;
-//; $tls::pstacklock = 3784;
-//; $tls::stackptr = -8912;
-//; $tls::pstackptr = 3788;
-//; $tls::stack = -8908;
-//; $tls::pstack = 3792;
-//; $tls::initialized = -7884;
-//; $tls::pinitialized = 4816;
+//; $tls::__align = -9836;
+//; $tls::p__align = 2864;
+//; $tls::context = -9832;
+//; $tls::pcontext = 2868;
+//; $tls::thread_id = -9084;
+//; $tls::pthread_id = 3616;
+//; $tls::infodata = -9080;
+//; $tls::pinfodata = 3620;
+//; $tls::tid = -8932;
+//; $tls::ptid = 3768;
+//; $tls::_ctinfo = -8928;
+//; $tls::p_ctinfo = 3772;
+//; $tls::andreas = -8924;
+//; $tls::pandreas = 3776;
+//; $tls::wq = -8920;
+//; $tls::pwq = 3780;
+//; $tls::sig = -8892;
+//; $tls::psig = 3808;
+//; $tls::incyg = -8888;
+//; $tls::pincyg = 3812;
+//; $tls::spinning = -8884;
+//; $tls::pspinning = 3816;
+//; $tls::stacklock = -8880;
+//; $tls::pstacklock = 3820;
+//; $tls::stackptr = -8876;
+//; $tls::pstackptr = 3824;
+//; $tls::stack = -8872;
+//; $tls::pstack = 3828;
+//; $tls::initialized = -7848;
+//; $tls::pinitialized = 4852;
//; __DATA__
#define tls_locals (-12700)
@@ -91,31 +93,33 @@
#define tls_psignal_arrived (2856)
#define tls_will_wait_for_signal (-9840)
#define tls_pwill_wait_for_signal (2860)
-#define tls_thread_context (-9836)
-#define tls_pthread_context (2864)
-#define tls_thread_id (-9120)
-#define tls_pthread_id (3580)
-#define tls_infodata (-9116)
-#define tls_pinfodata (3584)
-#define tls_tid (-8968)
-#define tls_ptid (3732)
-#define tls__ctinfo (-8964)
-#define tls_p_ctinfo (3736)
-#define tls_andreas (-8960)
-#define tls_pandreas (3740)
-#define tls_wq (-8956)
-#define tls_pwq (3744)
-#define tls_sig (-8928)
-#define tls_psig (3772)
-#define tls_incyg (-8924)
-#define tls_pincyg (3776)
-#define tls_spinning (-8920)
-#define tls_pspinning (3780)
-#define tls_stacklock (-8916)
-#define tls_pstacklock (3784)
-#define tls_stackptr (-8912)
-#define tls_pstackptr (3788)
-#define tls_stack (-8908)
-#define tls_pstack (3792)
-#define tls_initialized (-7884)
-#define tls_pinitialized (4816)
+#define tls___align (-9836)
+#define tls_p__align (2864)
+#define tls_context (-9832)
+#define tls_pcontext (2868)
+#define tls_thread_id (-9084)
+#define tls_pthread_id (3616)
+#define tls_infodata (-9080)
+#define tls_pinfodata (3620)
+#define tls_tid (-8932)
+#define tls_ptid (3768)
+#define tls__ctinfo (-8928)
+#define tls_p_ctinfo (3772)
+#define tls_andreas (-8924)
+#define tls_pandreas (3776)
+#define tls_wq (-8920)
+#define tls_pwq (3780)
+#define tls_sig (-8892)
+#define tls_psig (3808)
+#define tls_incyg (-8888)
+#define tls_pincyg (3812)
+#define tls_spinning (-8884)
+#define tls_pspinning (3816)
+#define tls_stacklock (-8880)
+#define tls_pstacklock (3820)
+#define tls_stackptr (-8876)
+#define tls_pstackptr (3824)
+#define tls_stack (-8872)
+#define tls_pstack (3828)
+#define tls_initialized (-7848)
+#define tls_pinitialized (4852)
diff --git a/winsup/cygwin/tlsoffsets64.h b/winsup/cygwin/tlsoffsets64.h
index 3f171b0ff..d137408d0 100644
--- a/winsup/cygwin/tlsoffsets64.h
+++ b/winsup/cygwin/tlsoffsets64.h
@@ -31,34 +31,36 @@
//; $tls::psignal_arrived = 4152;
//; $tls::will_wait_for_signal = -8640;
//; $tls::pwill_wait_for_signal = 4160;
-//; $tls::thread_context = -8632;
-//; $tls::pthread_context = 4168;
-//; $tls::thread_id = -7400;
-//; $tls::pthread_id = 5400;
-//; $tls::infodata = -7396;
-//; $tls::pinfodata = 5404;
-//; $tls::tid = -7248;
-//; $tls::ptid = 5552;
-//; $tls::_ctinfo = -7240;
-//; $tls::p_ctinfo = 5560;
-//; $tls::andreas = -7232;
-//; $tls::pandreas = 5568;
-//; $tls::wq = -7224;
-//; $tls::pwq = 5576;
-//; $tls::sig = -7176;
-//; $tls::psig = 5624;
-//; $tls::incyg = -7172;
-//; $tls::pincyg = 5628;
-//; $tls::spinning = -7168;
-//; $tls::pspinning = 5632;
-//; $tls::stacklock = -7164;
-//; $tls::pstacklock = 5636;
-//; $tls::stackptr = -7160;
-//; $tls::pstackptr = 5640;
-//; $tls::stack = -7152;
-//; $tls::pstack = 5648;
-//; $tls::initialized = -5104;
-//; $tls::pinitialized = 7696;
+//; $tls::__align = -8632;
+//; $tls::p__align = 4168;
+//; $tls::context = -8624;
+//; $tls::pcontext = 4176;
+//; $tls::thread_id = -7328;
+//; $tls::pthread_id = 5472;
+//; $tls::infodata = -7324;
+//; $tls::pinfodata = 5476;
+//; $tls::tid = -7176;
+//; $tls::ptid = 5624;
+//; $tls::_ctinfo = -7168;
+//; $tls::p_ctinfo = 5632;
+//; $tls::andreas = -7160;
+//; $tls::pandreas = 5640;
+//; $tls::wq = -7152;
+//; $tls::pwq = 5648;
+//; $tls::sig = -7104;
+//; $tls::psig = 5696;
+//; $tls::incyg = -7100;
+//; $tls::pincyg = 5700;
+//; $tls::spinning = -7096;
+//; $tls::pspinning = 5704;
+//; $tls::stacklock = -7092;
+//; $tls::pstacklock = 5708;
+//; $tls::stackptr = -7088;
+//; $tls::pstackptr = 5712;
+//; $tls::stack = -7080;
+//; $tls::pstack = 5720;
+//; $tls::initialized = -5032;
+//; $tls::pinitialized = 7768;
//; __DATA__
#define tls_locals (-12800)
@@ -91,31 +93,33 @@
#define tls_psignal_arrived (4152)
#define tls_will_wait_for_signal (-8640)
#define tls_pwill_wait_for_signal (4160)
-#define tls_thread_context (-8632)
-#define tls_pthread_context (4168)
-#define tls_thread_id (-7400)
-#define tls_pthread_id (5400)
-#define tls_infodata (-7396)
-#define tls_pinfodata (5404)
-#define tls_tid (-7248)
-#define tls_ptid (5552)
-#define tls__ctinfo (-7240)
-#define tls_p_ctinfo (5560)
-#define tls_andreas (-7232)
-#define tls_pandreas (5568)
-#define tls_wq (-7224)
-#define tls_pwq (5576)
-#define tls_sig (-7176)
-#define tls_psig (5624)
-#define tls_incyg (-7172)
-#define tls_pincyg (5628)
-#define tls_spinning (-7168)
-#define tls_pspinning (5632)
-#define tls_stacklock (-7164)
-#define tls_pstacklock (5636)
-#define tls_stackptr (-7160)
-#define tls_pstackptr (5640)
-#define tls_stack (-7152)
-#define tls_pstack (5648)
-#define tls_initialized (-5104)
-#define tls_pinitialized (7696)
+#define tls___align (-8632)
+#define tls_p__align (4168)
+#define tls_context (-8624)
+#define tls_pcontext (4176)
+#define tls_thread_id (-7328)
+#define tls_pthread_id (5472)
+#define tls_infodata (-7324)
+#define tls_pinfodata (5476)
+#define tls_tid (-7176)
+#define tls_ptid (5624)
+#define tls__ctinfo (-7168)
+#define tls_p_ctinfo (5632)
+#define tls_andreas (-7160)
+#define tls_pandreas (5640)
+#define tls_wq (-7152)
+#define tls_pwq (5648)
+#define tls_sig (-7104)
+#define tls_psig (5696)
+#define tls_incyg (-7100)
+#define tls_pincyg (5700)
+#define tls_spinning (-7096)
+#define tls_pspinning (5704)
+#define tls_stacklock (-7092)
+#define tls_pstacklock (5708)
+#define tls_stackptr (-7088)
+#define tls_pstackptr (5712)
+#define tls_stack (-7080)
+#define tls_pstack (5720)
+#define tls_initialized (-5032)
+#define tls_pinitialized (7768)
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 279754a9c..2c5880e96 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -21,6 +21,7 @@ details. */
puzzled that this has never been noticed before... */
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
+ def_guard_pages:1,
max_sys_priv:SE_CREATE_GLOBAL_PRIVILEGE,
is_server:false,
has_mandatory_integrity_control:false,
@@ -46,9 +47,11 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
terminate_thread_frees_stack:false,
has_precise_system_time:false,
has_microsoft_accounts:false,
+ has_set_thread_stack_guarantee:false,
};
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
+ def_guard_pages:1,
max_sys_priv:SE_CREATE_GLOBAL_PRIVILEGE,
is_server:false,
has_mandatory_integrity_control:false,
@@ -74,9 +77,11 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
terminate_thread_frees_stack:false,
has_precise_system_time:false,
has_microsoft_accounts:false,
+ has_set_thread_stack_guarantee:true,
};
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
+ def_guard_pages:1,
max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
is_server:false,
has_mandatory_integrity_control:true,
@@ -102,9 +107,11 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
terminate_thread_frees_stack:true,
has_precise_system_time:false,
has_microsoft_accounts:false,
+ has_set_thread_stack_guarantee:true,
};
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
+ def_guard_pages:1,
max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
is_server:false,
has_mandatory_integrity_control:true,
@@ -130,9 +137,11 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
terminate_thread_frees_stack:true,
has_precise_system_time:false,
has_microsoft_accounts:false,
+ has_set_thread_stack_guarantee:true,
};
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
+ def_guard_pages:2,
max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
is_server:false,
has_mandatory_integrity_control:true,
@@ -158,9 +167,11 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
terminate_thread_frees_stack:true,
has_precise_system_time:true,
has_microsoft_accounts:true,
+ has_set_thread_stack_guarantee:true,
};
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
+ def_guard_pages:2,
max_sys_priv:SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
is_server:false,
has_mandatory_integrity_control:true,
@@ -186,6 +197,7 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
terminate_thread_frees_stack:true,
has_precise_system_time:true,
has_microsoft_accounts:true,
+ has_set_thread_stack_guarantee:true,
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
@@ -240,6 +252,8 @@ wincapc::init ()
((wincaps *)caps)->is_server = (version.wProductType != VER_NT_WORKSTATION);
#ifdef __x86_64__
wow64 = 0;
+ /* 64 bit systems have one more guard page than their 32 bit counterpart. */
+ ++((wincaps *)caps)->def_guard_pages;
#else
if (NT_SUCCESS (NtQueryInformationProcess (NtCurrentProcess (),
ProcessWow64Information,
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index b41a2c625..160085d77 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -14,6 +14,7 @@ details. */
struct wincaps
{
+ DWORD def_guard_pages;
DWORD max_sys_priv;
unsigned is_server : 1;
unsigned has_mandatory_integrity_control : 1;
@@ -39,6 +40,7 @@ struct wincaps
unsigned terminate_thread_frees_stack : 1;
unsigned has_precise_system_time : 1;
unsigned has_microsoft_accounts : 1;
+ unsigned has_set_thread_stack_guarantee : 1;
};
class wincapc
@@ -64,6 +66,10 @@ public:
#define IMPLEMENT(cap) cap() const { return ((wincaps *) this->caps)->cap; }
+ DWORD def_guard_page_size () const
+ {
+ return ((wincaps *) this->caps)->def_guard_pages * page_size ();
+ }
DWORD IMPLEMENT (max_sys_priv)
bool IMPLEMENT (is_server)
bool IMPLEMENT (has_mandatory_integrity_control)
@@ -89,6 +95,7 @@ public:
bool IMPLEMENT (terminate_thread_frees_stack)
bool IMPLEMENT (has_precise_system_time)
bool IMPLEMENT (has_microsoft_accounts)
+ bool IMPLEMENT (has_set_thread_stack_guarantee)
#undef IMPLEMENT
};