execute signal handlers on separate signal stack, if it's been provided

This commit is contained in:
jdolecek 2001-07-15 20:02:21 +00:00
parent 2285430c7e
commit 318fdc0c37

@ -1,4 +1,4 @@
/* $NetBSD: linux_machdep.c,v 1.65 2001/06/17 21:01:38 sommerfeld Exp $ */
/* $NetBSD: linux_machdep.c,v 1.66 2001/07/15 20:02:21 jdolecek Exp $ */
/*-
* Copyright (c) 1995, 2000 The NetBSD Foundation, Inc.
@ -150,12 +150,21 @@ linux_sendsig(catcher, sig, mask, code)
struct proc *p = curproc;
struct trapframe *tf;
struct linux_sigframe *fp, frame;
int onstack;
tf = p->p_md.md_regs;
/* Do we need to jump onto the signal stack? */
onstack =
(p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
(SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
/* Allocate space for the signal handler context. */
/* XXX Linux doesn't support the signal stack. */
fp = (struct linux_sigframe *)tf->tf_esp;
if (onstack)
fp = (struct linux_sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp +
p->p_sigctx.ps_sigstk.ss_size);
else
fp = (struct linux_sigframe *)tf->tf_esp;
fp--;
/* Build stack frame for signal trampoline. */
@ -194,7 +203,7 @@ linux_sendsig(catcher, sig, mask, code)
frame.sf_sc.sc_trapno = tf->tf_trapno;
/* Save signal stack. */
/* XXX Linux doesn't support the signal stack. */
/* Linux doesn't save the onstack flag in sigframe */
/* Save signal mask. */
native_to_linux_old_sigset(mask, &frame.sf_sc.sc_mask);
@ -220,7 +229,8 @@ linux_sendsig(catcher, sig, mask, code)
tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
/* Remember that we're now on the signal stack. */
/* XXX Linux doesn't support the signal stack. */
if (onstack)
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
}
/*
@ -255,6 +265,7 @@ linux_sys_sigreturn(p, v, retval)
struct linux_sigcontext *scp, context;
struct trapframe *tf;
sigset_t mask;
ssize_t ss_gap;
/*
* The trampoline code hands us the context.
@ -305,7 +316,16 @@ linux_sys_sigreturn(p, v, retval)
tf->tf_ss = context.sc_ss;
/* Restore signal stack. */
p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
/*
* Linux really does it this way; it doesn't have space in sigframe
* to save the onstack flag.
*/
ss_gap = (ssize_t)
((caddr_t) context.sc_esp_at_signal - (caddr_t) p->p_sigctx.ps_sigstk.ss_sp);
if (ss_gap >= 0 && ss_gap < p->p_sigctx.ps_sigstk.ss_size)
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
/* Restore signal mask. */
linux_old_to_native_sigset(&context.sc_mask, &mask);