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>
This commit is contained in:
parent
757c0871f7
commit
2cd7eb7f60
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue