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:
Corinna Vinschen
2015-06-19 15:58:23 +02:00
parent 715ac1e872
commit 22465796ed
9 changed files with 215 additions and 153 deletions

View File

@@ -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;
}