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
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-06-19 16:58:23 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-06-19 17:12:45 +0300
commit22465796edbfd6f156ca2930f56b3345cc54b164 (patch)
treea463488dc43aa43c698bf806602ba54975890889 /winsup
parent715ac1e872e495496f9a540a75e8b1f4cbcdf321 (diff)
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>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/common.din1
-rw-r--r--winsup/cygwin/cygtls.cc1
-rw-r--r--winsup/cygwin/cygtls.h13
-rw-r--r--winsup/cygwin/exceptions.cc14
-rw-r--r--winsup/cygwin/include/cygwin/signal.h6
-rw-r--r--winsup/cygwin/signal.cc40
-rw-r--r--winsup/cygwin/tlsoffsets.h140
-rw-r--r--winsup/cygwin/tlsoffsets64.h140
8 files changed, 208 insertions, 147 deletions
diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din
index dd9bb2576..644eb2eae 100644
--- a/winsup/cygwin/common.din
+++ b/winsup/cygwin/common.din
@@ -1099,6 +1099,7 @@ shmget SIGFE
shutdown = cygwin_shutdown SIGFE
sigaction SIGFE
sigaddset SIGFE
+sigaltstack SIGFE
sigdelset SIGFE
sigemptyset NOSIGFE
sigfillset NOSIGFE
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
index 84170ca01..dc9a698f7 100644
--- a/winsup/cygwin/cygtls.cc
+++ b/winsup/cygwin/cygtls.cc
@@ -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;
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 97e403dea..0944811b0 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -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
{
@@ -188,6 +188,7 @@ public:
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;
@@ -202,17 +203,17 @@ public:
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;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 27b571ee1..112d79206 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -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);
diff --git a/winsup/cygwin/include/cygwin/signal.h b/winsup/cygwin/include/cygwin/signal.h
index ef29baf7b..2db0a8069 100644
--- a/winsup/cygwin/include/cygwin/signal.h
+++ b/winsup/cygwin/include/cygwin/signal.h
@@ -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 */
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index d2ca81e00..7cb668cda 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -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 ();
}
@@ -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;
+}
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index a74e22f69..daf610f19 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -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)
@@ -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)
diff --git a/winsup/cygwin/tlsoffsets64.h b/winsup/cygwin/tlsoffsets64.h
index e43dea7e2..3f171b0ff 100644
--- a/winsup/cygwin/tlsoffsets64.h
+++ b/winsup/cygwin/tlsoffsets64.h
@@ -23,40 +23,42 @@
//; $tls::psigmask = 4104;
//; $tls::sigwait_mask = -8688;
//; $tls::psigwait_mask = 4112;
-//; $tls::sigwait_info = -8680;
-//; $tls::psigwait_info = 4120;
-//; $tls::signal_arrived = -8672;
-//; $tls::psignal_arrived = 4128;
-//; $tls::will_wait_for_signal = -8664;
-//; $tls::pwill_wait_for_signal = 4136;
-//; $tls::thread_context = -8656;
-//; $tls::pthread_context = 4144;
-//; $tls::thread_id = -7424;
-//; $tls::pthread_id = 5376;
-//; $tls::infodata = -7420;
-//; $tls::pinfodata = 5380;
-//; $tls::tid = -7272;
-//; $tls::ptid = 5528;
-//; $tls::_ctinfo = -7264;
-//; $tls::p_ctinfo = 5536;
-//; $tls::andreas = -7256;
-//; $tls::pandreas = 5544;
-//; $tls::wq = -7248;
-//; $tls::pwq = 5552;
-//; $tls::sig = -7200;
-//; $tls::psig = 5600;
-//; $tls::incyg = -7196;
-//; $tls::pincyg = 5604;
-//; $tls::spinning = -7192;
-//; $tls::pspinning = 5608;
-//; $tls::stacklock = -7188;
-//; $tls::pstacklock = 5612;
-//; $tls::stackptr = -7184;
-//; $tls::pstackptr = 5616;
-//; $tls::stack = -7176;
-//; $tls::pstack = 5624;
-//; $tls::initialized = -5128;
-//; $tls::pinitialized = 7672;
+//; $tls::altstack = -8680;
+//; $tls::paltstack = 4120;
+//; $tls::sigwait_info = -8656;
+//; $tls::psigwait_info = 4144;
+//; $tls::signal_arrived = -8648;
+//; $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;
//; __DATA__
#define tls_locals (-12800)
@@ -81,37 +83,39 @@
#define tls_psigmask (4104)
#define tls_sigwait_mask (-8688)
#define tls_psigwait_mask (4112)
-#define tls_sigwait_info (-8680)
-#define tls_psigwait_info (4120)
-#define tls_signal_arrived (-8672)
-#define tls_psignal_arrived (4128)
-#define tls_will_wait_for_signal (-8664)
-#define tls_pwill_wait_for_signal (4136)
-#define tls_thread_context (-8656)
-#define tls_pthread_context (4144)
-#define tls_thread_id (-7424)
-#define tls_pthread_id (5376)
-#define tls_infodata (-7420)
-#define tls_pinfodata (5380)
-#define tls_tid (-7272)
-#define tls_ptid (5528)
-#define tls__ctinfo (-7264)
-#define tls_p_ctinfo (5536)
-#define tls_andreas (-7256)
-#define tls_pandreas (5544)
-#define tls_wq (-7248)
-#define tls_pwq (5552)
-#define tls_sig (-7200)
-#define tls_psig (5600)
-#define tls_incyg (-7196)
-#define tls_pincyg (5604)
-#define tls_spinning (-7192)
-#define tls_pspinning (5608)
-#define tls_stacklock (-7188)
-#define tls_pstacklock (5612)
-#define tls_stackptr (-7184)
-#define tls_pstackptr (5616)
-#define tls_stack (-7176)
-#define tls_pstack (5624)
-#define tls_initialized (-5128)
-#define tls_pinitialized (7672)
+#define tls_altstack (-8680)
+#define tls_paltstack (4120)
+#define tls_sigwait_info (-8656)
+#define tls_psigwait_info (4144)
+#define tls_signal_arrived (-8648)
+#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)