diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-12-02 07:03:33 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-12-02 07:03:33 +0000 |
commit | 15c7623306062239f832ef81bd0bdfc804b4d186 (patch) | |
tree | d4c341f7fa4f162d4c4cd1ede1db5c9089f0afb6 /sys/arch/alpha | |
parent | b02dfe0ab7aae6700f0c15419373891118eab134 (diff) |
Determine whether we're currently on the alternative signal stack
dynamically, by comparing the stack pointer against the altstack
base and size, so that you get the correct answer if you longjmp
out of the signal handler, as tested by regress/sys/kern/stackjmp/.
Also, fix alt stack handling on vax, where it was completely broken.
Testing and corrections by miod@, krw@, tobiasu@, pirofti@
Diffstat (limited to 'sys/arch/alpha')
-rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 26 | ||||
-rw-r--r-- | sys/arch/alpha/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/alpha/include/signal.h | 4 |
3 files changed, 15 insertions, 18 deletions
diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 264180a6993..a66a81c01d0 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.139 2012/11/01 21:09:17 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.140 2012/12/02 07:03:30 guenther Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -1431,11 +1431,12 @@ sendsig(catcher, sig, mask, code, type, val) struct fpreg *fpregs = (struct fpreg *)&ksc.sc_fpregs; struct trapframe *frame; struct sigacts *psp = p->p_sigacts; - int oonstack, fsize, rndfsize, kscsize; + unsigned long oldsp; + int fsize, rndfsize, kscsize; siginfo_t *sip, ksi; + oldsp = alpha_pal_rdusp(); frame = p->p_md.md_tf; - oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; fsize = sizeof ksc; rndfsize = ((fsize + 15) / 16) * 16; kscsize = rndfsize; @@ -1451,25 +1452,24 @@ sendsig(catcher, sig, mask, code, type, val) * will fail if the process has not already allocated * the space with a `brk'. */ - if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !oonstack && - (psp->ps_sigonstack & sigmask(sig))) { + if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && + !sigonstack(oldsp) && (psp->ps_sigonstack & sigmask(sig))) scp = (struct sigcontext *)(p->p_sigstk.ss_sp + p->p_sigstk.ss_size - rndfsize); - p->p_sigstk.ss_flags |= SS_ONSTACK; - } else - scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize); + else + scp = (struct sigcontext *)(oldsp - rndfsize); if ((u_long)scp <= USRSTACK - ptoa(p->p_vmspace->vm_ssize)) (void)uvm_grow(p, (u_long)scp); #ifdef DEBUG if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, - sig, &oonstack, scp); + sig, &ksc, scp); #endif /* * Build the signal context to be used by sigreturn. */ - ksc.sc_onstack = oonstack; + bzero(&ksc, sizeof(ksc)); ksc.sc_mask = mask; ksc.sc_pc = frame->tf_regs[FRAME_PC]; ksc.sc_ps = frame->tf_regs[FRAME_PS]; @@ -1477,7 +1477,7 @@ sendsig(catcher, sig, mask, code, type, val) /* copy the registers. */ frametoreg(frame, (struct reg *)ksc.sc_regs); ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */ - ksc.sc_regs[R_SP] = alpha_pal_rdusp(); + ksc.sc_regs[R_SP] = oldsp; /* save the floating-point state, if necessary, then copy it. */ if (p->p_addr->u_pcb.pcb_fpcpu != NULL) @@ -1588,10 +1588,6 @@ sys_sigreturn(p, v, retval) /* * Restore the user-supplied information */ - if (ksc.sc_onstack) - p->p_sigstk.ss_flags |= SS_ONSTACK; - else - p->p_sigstk.ss_flags &= ~SS_ONSTACK; p->p_sigmask = ksc.sc_mask &~ sigcantmask; p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc; diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h index 24c3f2c755f..689df5d258a 100644 --- a/sys/arch/alpha/include/cpu.h +++ b/sys/arch/alpha/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.45 2012/11/01 21:09:17 miod Exp $ */ +/* $OpenBSD: cpu.h,v 1.46 2012/12/02 07:03:30 guenther Exp $ */ /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */ /*- @@ -275,6 +275,7 @@ struct clockframe { * This is used during profiling to integrate system time. */ #define PROC_PC(p) ((p)->p_md.md_tf->tf_regs[FRAME_PC]) +#define PROC_STACK(p) (alpha_pal_rdusp()) /*XXX only works for curproc */ /* * Preempt the current process if in interrupt from user mode, diff --git a/sys/arch/alpha/include/signal.h b/sys/arch/alpha/include/signal.h index 1f446e22e1b..a5bf019502b 100644 --- a/sys/arch/alpha/include/signal.h +++ b/sys/arch/alpha/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.7 2011/03/23 16:54:34 pirofti Exp $ */ +/* $OpenBSD: signal.h,v 1.8 2012/12/02 07:03:31 guenther Exp $ */ /* $NetBSD: signal.h,v 1.2 1995/02/16 03:08:08 cgd Exp $ */ /* @@ -47,7 +47,7 @@ typedef int sig_atomic_t; * representations of 'struct reg' and 'struct fpreg', respectively. */ struct sigcontext { - long sc_onstack; /* sigstack state to restore */ + long __sc_ununsed; long sc_mask; /* signal mask to restore */ long sc_pc; /* pc to restore */ long sc_ps; /* ps to restore */ |