Preliminary infrastructure to implement alternate stack
* libc/include/sys/signal.h: Define SS_ONSTACK and SS_DISABLE unconditionally. (sigaltstack): Enable prototype on Cygwin. * common.din (sigaltstack): Export. * cygtls.cc (_cygtls::init_thread): Initialize altstack. * cygtls.h (__tlsstack_t): Rename from __stack_t to distinguish more clearly from stack_t. Accommodate throughout. (_cygtls): Add altstack member. * exceptions.cc (exception::handle): Set SIGSEGV handler to SIG_DFL if we encounter a stack overflow, and no alternate stack has been defined. * include/cygwin/signal.h (MINSIGSTKSZ): Define (SIGSTKSZ): Define. (SA_ONSTACK): Define. * signal.cc (sigaltstack): New function. * tlsoffset.h: Regenerate. * tlsoffset64.h: Ditto. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
@ -232,7 +232,7 @@ class stack_info
|
||||
#ifdef __x86_64__
|
||||
CONTEXT c;
|
||||
UNWIND_HISTORY_TABLE hist;
|
||||
__stack_t *sigstackptr;
|
||||
__tlsstack_t *sigstackptr;
|
||||
#endif
|
||||
public:
|
||||
STACKFRAME sf; /* For storing the stack information */
|
||||
@ -696,11 +696,17 @@ exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
}
|
||||
break;
|
||||
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
/* If we encounter a stack overflow, and if the thread has no alternate
|
||||
stack, don't even try to call a signal handler. This is in line with
|
||||
Linux behaviour and also makes a lot of sense on Windows. */
|
||||
if (me.altstack.ss_flags)
|
||||
global_sigs[SIGSEGV].sa_handler = SIG_DFL;
|
||||
/*FALLTHRU*/
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
case STATUS_IN_PAGE_ERROR:
|
||||
case STATUS_NO_MEMORY:
|
||||
case STATUS_INVALID_DISPOSITION:
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
si.si_signo = SIGSEGV;
|
||||
si.si_code = SEGV_MAPERR;
|
||||
break;
|
||||
@ -894,7 +900,7 @@ _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler,
|
||||
void __reg3
|
||||
_cygtls::interrupt_setup (siginfo_t& si, void *handler, struct sigaction& siga)
|
||||
{
|
||||
push ((__stack_t) sigdelayed);
|
||||
push ((__tlsstack_t) sigdelayed);
|
||||
deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
|
||||
sa_flags = siga.sa_flags;
|
||||
func = (void (*) (int, siginfo_t *, void *)) handler;
|
||||
@ -1497,7 +1503,7 @@ _cygtls::call_signal_handler ()
|
||||
|
||||
/* Pop the stack if the next "return address" is sigdelayed, since
|
||||
this function is doing what sigdelayed would have done anyway. */
|
||||
if (retaddr () == (__stack_t) sigdelayed)
|
||||
if (retaddr () == (__tlsstack_t) sigdelayed)
|
||||
pop ();
|
||||
|
||||
debug_only_printf ("dealing with signal %d", sig);
|
||||
|
Reference in New Issue
Block a user