Skip to content

Commit

Permalink
Preliminary infrastructure to implement alternate stack
Browse files Browse the repository at this point in the history
	* 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>
  • Loading branch information
github-cygwin committed Jun 19, 2015
1 parent 715ac1e commit 2246579
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 153 deletions.
13 changes: 7 additions & 6 deletions newlib/libc/include/sys/signal.h
Expand Up @@ -120,11 +120,6 @@ struct sigaction {
#define SIGSTKSZ 8192
#endif

/*
* Possible values for ss_flags in stack_t below.
*/
#define SS_ONSTACK 0x1
#define SS_DISABLE 0x2
#endif

#elif defined(__CYGWIN__)
Expand All @@ -142,6 +137,12 @@ struct sigaction
};
#endif /* defined(__rtems__) */

/*
* Possible values for ss_flags in stack_t below.
*/
#define SS_ONSTACK 0x1
#define SS_DISABLE 0x2

/*
* Structure used in sigaltstack call.
*/
Expand Down Expand Up @@ -196,7 +197,7 @@ int _EXFUN(sigpending, (sigset_t *));
int _EXFUN(sigsuspend, (const sigset_t *));
int _EXFUN(sigpause, (int));

#ifdef __rtems__
#if defined(__CYGWIN__) || defined(__rtems__)
#if __BSD_VISIBLE || __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
int _EXFUN(sigaltstack, (const stack_t *__restrict, stack_t *__restrict));
#endif
Expand Down
1 change: 1 addition & 0 deletions winsup/cygwin/common.din
Expand Up @@ -1099,6 +1099,7 @@ shmget SIGFE
shutdown = cygwin_shutdown SIGFE
sigaction SIGFE
sigaddset SIGFE
sigaltstack SIGFE
sigdelset SIGFE
sigemptyset NOSIGFE
sigfillset NOSIGFE
Expand Down
1 change: 1 addition & 0 deletions winsup/cygwin/cygtls.cc
Expand Up @@ -125,6 +125,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
memset (this, 0, sizeof (*this));
_REENT_INIT_PTR (&local_clib);
stackptr = stack;
altstack.ss_flags = SS_DISABLE;
if (_GLOBAL_REENT)
{
local_clib._stdin = _GLOBAL_REENT->_stdin;
Expand Down
13 changes: 7 additions & 6 deletions winsup/cygwin/cygtls.h
Expand Up @@ -167,7 +167,7 @@ extern "C" int __ljfault (jmp_buf, int);

/*gentls_offsets*/

typedef uintptr_t __stack_t;
typedef uintptr_t __tlsstack_t;

class _cygtls
{
Expand All @@ -188,6 +188,7 @@ class _cygtls
int *errno_addr;
sigset_t sigmask;
sigset_t sigwait_mask;
stack_t altstack;
siginfo_t *sigwait_info;
HANDLE signal_arrived;
bool will_wait_for_signal;
Expand All @@ -202,17 +203,17 @@ class _cygtls
unsigned incyg;
unsigned spinning;
unsigned stacklock;
__stack_t *stackptr;
__stack_t stack[TLS_STACK_SIZE];
__tlsstack_t *stackptr;
__tlsstack_t stack[TLS_STACK_SIZE];
unsigned initialized;

/*gentls_offsets*/
void init_thread (void *, DWORD (*) (void *, void *));
static void call (DWORD (*) (void *, void *), void *);
void remove (DWORD);
void push (__stack_t addr) {*stackptr++ = (__stack_t) addr;}
__stack_t __reg1 pop ();
__stack_t retaddr () {return stackptr[-1];}
void push (__tlsstack_t addr) {*stackptr++ = (__tlsstack_t) addr;}
__tlsstack_t __reg1 pop ();
__tlsstack_t retaddr () {return stackptr[-1];}
bool isinitialized () const
{
return initialized == CYGTLS_INITIALIZED;
Expand Down
14 changes: 10 additions & 4 deletions winsup/cygwin/exceptions.cc
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions winsup/cygwin/include/cygwin/signal.h
Expand Up @@ -332,12 +332,18 @@ struct sigaction
int sa_flags;
};

#define MINSIGSTKSZ 32768
#define SIGSTKSZ 65536

#define SA_NOCLDSTOP 1 /* Do not generate SIGCHLD when children
stop */
#define SA_SIGINFO 2 /* Invoke the signal catching function
with three arguments instead of one
*/
#define SA_RESTART 0x10000000 /* Restart syscall on signal return */
#define SA_ONSTACK 0x20000000 /* Call signal handler on alternate
signal stack provided by
sigaltstack(2). */
#define SA_NODEFER 0x40000000 /* Don't automatically block the signal
when its handler is being executed */
#define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler */
Expand Down
40 changes: 39 additions & 1 deletion winsup/cygwin/signal.cc
Expand Up @@ -587,7 +587,7 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
*info = _my_tls.infodata;
res = _my_tls.infodata.si_signo;
_my_tls.sig = 0;
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
if (_my_tls.retaddr () == (__tlsstack_t) sigdelayed)
_my_tls.pop ();
_my_tls.unlock ();
}
Expand Down Expand Up @@ -624,3 +624,41 @@ sigqueue (pid_t pid, int sig, const union sigval value)
si.si_value = value;
return sig_send (dest, si);
}

extern "C" int
sigaltstack (const stack_t *ss, stack_t *oss)
{
_cygtls& me = _my_tls;

if (ss)
{
if (me.altstack.ss_flags == SS_ONSTACK)
{
set_errno (EPERM);
return -1;
}
if (ss->ss_flags == SS_DISABLE)
{
me.altstack.ss_sp = NULL;
me.altstack.ss_flags = 0;
me.altstack.ss_size = 0;
}
else
{
if (ss->ss_flags)
{
set_errno (EINVAL);
return -1;
}
if (ss->ss_size < MINSIGSTKSZ)
{
set_errno (ENOMEM);
return -1;
}
memcpy (&me.altstack, ss, sizeof *ss);
}
}
if (oss)
memcpy (oss, &me.altstack, sizeof *oss);
return 0;
}
140 changes: 72 additions & 68 deletions winsup/cygwin/tlsoffsets.h
Expand Up @@ -23,40 +23,42 @@
//; $tls::psigmask = 2832;
//; $tls::sigwait_mask = -9864;
//; $tls::psigwait_mask = 2836;
//; $tls::sigwait_info = -9860;
//; $tls::psigwait_info = 2840;
//; $tls::signal_arrived = -9856;
//; $tls::psignal_arrived = 2844;
//; $tls::will_wait_for_signal = -9852;
//; $tls::pwill_wait_for_signal = 2848;
//; $tls::thread_context = -9848;
//; $tls::pthread_context = 2852;
//; $tls::thread_id = -9132;
//; $tls::pthread_id = 3568;
//; $tls::infodata = -9128;
//; $tls::pinfodata = 3572;
//; $tls::tid = -8980;
//; $tls::ptid = 3720;
//; $tls::_ctinfo = -8976;
//; $tls::p_ctinfo = 3724;
//; $tls::andreas = -8972;
//; $tls::pandreas = 3728;
//; $tls::wq = -8968;
//; $tls::pwq = 3732;
//; $tls::sig = -8940;
//; $tls::psig = 3760;
//; $tls::incyg = -8936;
//; $tls::pincyg = 3764;
//; $tls::spinning = -8932;
//; $tls::pspinning = 3768;
//; $tls::stacklock = -8928;
//; $tls::pstacklock = 3772;
//; $tls::stackptr = -8924;
//; $tls::pstackptr = 3776;
//; $tls::stack = -8920;
//; $tls::pstack = 3780;
//; $tls::initialized = -7896;
//; $tls::pinitialized = 4804;
//; $tls::altstack = -9860;
//; $tls::paltstack = 2840;
//; $tls::sigwait_info = -9848;
//; $tls::psigwait_info = 2852;
//; $tls::signal_arrived = -9844;
//; $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;
//; __DATA__

#define tls_locals (-12700)
Expand All @@ -81,37 +83,39 @@
#define tls_psigmask (2832)
#define tls_sigwait_mask (-9864)
#define tls_psigwait_mask (2836)
#define tls_sigwait_info (-9860)
#define tls_psigwait_info (2840)
#define tls_signal_arrived (-9856)
#define tls_psignal_arrived (2844)
#define tls_will_wait_for_signal (-9852)
#define tls_pwill_wait_for_signal (2848)
#define tls_thread_context (-9848)
#define tls_pthread_context (2852)
#define tls_thread_id (-9132)
#define tls_pthread_id (3568)
#define tls_infodata (-9128)
#define tls_pinfodata (3572)
#define tls_tid (-8980)
#define tls_ptid (3720)
#define tls__ctinfo (-8976)
#define tls_p_ctinfo (3724)
#define tls_andreas (-8972)
#define tls_pandreas (3728)
#define tls_wq (-8968)
#define tls_pwq (3732)
#define tls_sig (-8940)
#define tls_psig (3760)
#define tls_incyg (-8936)
#define tls_pincyg (3764)
#define tls_spinning (-8932)
#define tls_pspinning (3768)
#define tls_stacklock (-8928)
#define tls_pstacklock (3772)
#define tls_stackptr (-8924)
#define tls_pstackptr (3776)
#define tls_stack (-8920)
#define tls_pstack (3780)
#define tls_initialized (-7896)
#define tls_pinitialized (4804)
#define tls_altstack (-9860)
#define tls_paltstack (2840)
#define tls_sigwait_info (-9848)
#define tls_psigwait_info (2852)
#define tls_signal_arrived (-9844)
#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)

0 comments on commit 2246579

Please sign in to comment.