The diff below changes the alt sig stack logic to dynamically determine 
whether the thread is currently on the alt stack, 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 changed: the logic on vax for deciding whether to switch stacks was 
completely broken, such that it would never switch.  This updates it to 
match the other platforms, which should make it happier.

Tested on amd64, sparc64, and i386; needs testing on the other platforms 
at the least.


I'm not sure if the PROC_STACK() macro is the best API.  In particular, my 
current implementation on alpha will only work on curproc, which is all 
that it's currently needed for.  The obvious change to make it just always 
operate on curproc is less than idea, as curproc isn't cheap on all 
platforms and the caller in this case at least will always have it 
handy...


Philip Guenther

Index: sys/arch/alpha/alpha/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.139
diff -u -p -r1.139 machdep.c
--- sys/arch/alpha/alpha/machdep.c      1 Nov 2012 21:09:17 -0000       1.139
+++ sys/arch/alpha/alpha/machdep.c      16 Nov 2012 17:58:58 -0000
@@ -1431,11 +1431,12 @@ sendsig(catcher, sig, mask, code, type, 
        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, 
         * 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, 
        /* 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;
Index: sys/arch/alpha/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/alpha/include/cpu.h,v
retrieving revision 1.45
diff -u -p -r1.45 cpu.h
--- sys/arch/alpha/include/cpu.h        1 Nov 2012 21:09:17 -0000       1.45
+++ sys/arch/alpha/include/cpu.h        16 Nov 2012 17:58:58 -0000
@@ -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,
Index: sys/arch/alpha/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/alpha/include/signal.h,v
retrieving revision 1.7
diff -u -p -r1.7 signal.h
--- sys/arch/alpha/include/signal.h     23 Mar 2011 16:54:34 -0000      1.7
+++ sys/arch/alpha/include/signal.h     16 Nov 2012 17:58:58 -0000
@@ -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 */
Index: sys/arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.158
diff -u -p -r1.158 machdep.c
--- sys/arch/amd64/amd64/machdep.c      19 Oct 2012 16:38:30 -0000      1.158
+++ sys/arch/amd64/amd64/machdep.c      16 Nov 2012 17:58:58 -0000
@@ -557,16 +557,14 @@ sendsig(sig_t catcher, int sig, int mask
 #endif
 
        bcopy(tf, &ksc, sizeof(*tf));
-       ksc.sc_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+       bzero((char *)&ksc + sizeof(*tf), sizeof(ksc) - sizeof(*tf));
        ksc.sc_mask = mask;
-       ksc.sc_fpstate = NULL;
 
        /* Allocate space for the signal handler context. */
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !ksc.sc_onstack &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(tf->tf_rsp) && (psp->ps_sigonstack & sigmask(sig)))
                sp = (register_t)p->p_sigstk.ss_sp + p->p_sigstk.ss_size;
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                sp = tf->tf_rsp - 128;
 
        sp &= ~15ULL;   /* just in case */
@@ -672,11 +670,7 @@ sys_sigreturn(struct proc *p, void *v, r
        ksc.sc_err = tf->tf_err;
        bcopy(&ksc, tf, sizeof(*tf));
 
-       /* Restore signal stack. */
-       if (ksc.sc_onstack)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+       /* Restore signal mask. */
        p->p_sigmask = ksc.sc_mask & ~sigcantmask;
 
        /*
Index: sys/arch/amd64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/cpu.h,v
retrieving revision 1.75
diff -u -p -r1.75 cpu.h
--- sys/arch/amd64/include/cpu.h        10 Nov 2012 09:45:05 -0000      1.75
+++ sys/arch/amd64/include/cpu.h        16 Nov 2012 17:58:59 -0000
@@ -146,6 +146,7 @@ struct cpu_info {
 #define CPUF_GO                0x8000          /* CPU should start running */
 
 #define PROC_PC(p)     ((p)->p_md.md_regs->tf_rip)
+#define PROC_STACK(p)  ((p)->p_md.md_regs->tf_rsp)
 
 extern struct cpu_info cpu_info_primary;
 extern struct cpu_info *cpu_info_list;
Index: sys/arch/amd64/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/signal.h,v
retrieving revision 1.6
diff -u -p -r1.6 signal.h
--- sys/arch/amd64/include/signal.h     23 Mar 2011 16:54:34 -0000      1.6
+++ sys/arch/amd64/include/signal.h     16 Nov 2012 17:58:59 -0000
@@ -81,7 +81,7 @@ struct sigcontext {
        long    sc_ss;
 
        struct fxsave64 *sc_fpstate;
-       int     sc_onstack;
+       int     __sc_unused;
        int     sc_mask;
 };
 #endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */
Index: sys/arch/arm/arm/sig_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/sig_machdep.c,v
retrieving revision 1.7
diff -u -p -r1.7 sig_machdep.c
--- sys/arch/arm/arm/sig_machdep.c      20 Sep 2011 22:02:11 -0000      1.7
+++ sys/arch/arm/arm/sig_machdep.c      16 Nov 2012 17:58:59 -0000
@@ -65,9 +65,6 @@ process_frame(struct proc *p)
        return p->p_addr->u_pcb.pcb_tf;
 }
 
-void *getframe(struct proc *p, int sig, int *onstack);
-
-
 /*
  * Send an interrupt to process.
  *
@@ -85,21 +82,19 @@ sendsig(sig_t catcher, int sig, int retu
        struct trapframe *tf;
        struct sigframe *fp, frame;
        struct sigacts *psp = p->p_sigacts;
-       int oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-       int onstack = 0;
 
        tf = process_frame(p);
 
        /* Do we need to jump onto the signal stack? */
 
        /* Allocate space for the signal handler context. */
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !oonstack &&
-           (psp->ps_sigonstack & sigmask(sig))) {
-               onstack = 1;
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(tf->tf_usr_sp) && (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
                    p->p_sigstk.ss_size);
-       } else
+       else
                fp = (struct sigframe *)tf->tf_usr_sp;
+
        /* make room on the stack */
        fp--;
 
@@ -107,6 +102,7 @@ sendsig(sig_t catcher, int sig, int retu
        fp = (void *)STACKALIGN(fp);
 
        /* Build stack frame for signal trampoline. */
+       bzero(&frame, sizeof(frame));
        frame.sf_signum = sig;
        frame.sf_sip = NULL;
        frame.sf_scp = &fp->sf_sc;
@@ -132,9 +128,6 @@ sendsig(sig_t catcher, int sig, int retu
        frame.sf_sc.sc_pc     = tf->tf_pc;
        frame.sf_sc.sc_spsr   = tf->tf_spsr;
 
-       /* Save signal stack. */
-       frame.sf_sc.sc_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-
        /* Save signal mask. */
        frame.sf_sc.sc_mask = returnmask;
 
@@ -172,28 +165,7 @@ sendsig(sig_t catcher, int sig, int retu
        tf->tf_usr_lr = (int)p->p_sigcode;
        /* XXX This should not be needed. */
        cpu_icache_sync_all();
-
-       /* Remember that we're now on the signal stack. */
-       if (onstack)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-}
-
-#if 0
-void *
-getframe(struct proc *p, int sig, int *onstack)
-{
-       struct sigctx *ctx = &p->p_sigctx;
-       struct trapframe *tf = process_frame(l);
-
-       /* Do we need to jump onto the signal stack? */
-       *onstack = (ctx->ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0
-           && (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
-       if (*onstack)
-               return (char *)ctx->ps_sigstk.ss_sp + ctx->ps_sigstk.ss_size;
-       return (void *)tf->tf_usr_sp;
 }
-#endif
-
 
 /*
  * System call to cleanup state after a signal
@@ -258,12 +230,6 @@ sys_sigreturn(struct proc *p, void *v, r
        tf->tf_svc_lr = context.sc_svc_lr;
        tf->tf_pc    = context.sc_pc;
        tf->tf_spsr  = context.sc_spsr;
-
-       /* Restore signal stack. */
-       if (context.sc_onstack & SS_ONSTACK)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
 
        /* Restore signal mask. */
        p->p_sigmask = context.sc_mask & ~sigcantmask;
Index: sys/arch/arm/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/cpu.h,v
retrieving revision 1.30
diff -u -p -r1.30 cpu.h
--- sys/arch/arm/include/cpu.h  16 Nov 2011 20:50:18 -0000      1.30
+++ sys/arch/arm/include/cpu.h  16 Nov 2012 17:58:59 -0000
@@ -154,6 +154,7 @@ extern int current_intr_depth;
  * PROC_PC: Find out the program counter for the given process.
  */
 #define PROC_PC(p)     ((p)->p_addr->u_pcb.pcb_tf->tf_pc)
+#define PROC_STACK(p)  ((p)->p_addr->u_pcb.pcb_tf->tf_usr_sp)
 
 /* The address of the vector page. */
 extern vaddr_t vector_page;
Index: sys/arch/arm/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/signal.h,v
retrieving revision 1.7
diff -u -p -r1.7 signal.h
--- sys/arch/arm/include/signal.h       20 Sep 2011 22:02:13 -0000      1.7
+++ sys/arch/arm/include/signal.h       16 Nov 2012 17:58:59 -0000
@@ -61,7 +61,7 @@ typedef int sig_atomic_t;
  * a non-standard exit is performed.
  */
 struct sigcontext {
-       int     sc_onstack;             /* sigstack state to restore */
+       int     __sc_unused;
        int     sc_mask;                /* signal mask to restore (old style) */
 
        unsigned int sc_spsr;
Index: sys/arch/hppa/hppa/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/machdep.c,v
retrieving revision 1.209
diff -u -p -r1.209 machdep.c
--- sys/arch/hppa/hppa/machdep.c        26 Oct 2012 12:32:48 -0000      1.209
+++ sys/arch/hppa/hppa/machdep.c        16 Nov 2012 17:58:59 -0000
@@ -1226,16 +1226,13 @@ sendsig(sig_t catcher, int sig, int mask
        /* Save the FPU context first. */
        fpu_proc_save(p);
 
-       ksc.sc_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-
        /*
         * Allocate space for the signal handler context.
         */
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !ksc.sc_onstack &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(tf->tf_sp) && (psp->ps_sigonstack & sigmask(sig)))
                scp = (register_t)p->p_sigstk.ss_sp;
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                scp = (tf->tf_sp + 63) & ~63;
 
        sss = (sizeof(ksc) + 63) & ~63;
@@ -1251,6 +1248,7 @@ sendsig(sig_t catcher, int sig, int mask
                    tf->tf_iioq_head, tf->tf_iioq_tail, tf->tf_ipsw, PSL_BITS);
 #endif
 
+       bzero(&ksc, sizeof(ksc));
        ksc.sc_mask = mask;
        ksc.sc_fp = scp + sss;
        ksc.sc_ps = tf->tf_ipsw;
@@ -1353,10 +1351,6 @@ sys_sigreturn(struct proc *p, void *v, r
        if ((ksc.sc_ps & (PSL_MBS|PSL_MBZ)) != PSL_MBS)
                return (EINVAL);
 
-       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;
 
        tf->tf_t1 = ksc.sc_regs[0];             /* r22 */
Index: sys/arch/hppa/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa/include/cpu.h,v
retrieving revision 1.80
diff -u -p -r1.80 cpu.h
--- sys/arch/hppa/include/cpu.h 20 Sep 2011 21:44:09 -0000      1.80
+++ sys/arch/hppa/include/cpu.h 16 Nov 2012 17:58:59 -0000
@@ -202,6 +202,7 @@ extern int cpu_hvers;
 
 #define        need_proftick(p)        setsoftast(p)
 #define        PROC_PC(p)              ((p)->p_md.md_regs->tf_iioq_head)
+#define        PROC_STACK(p)           ((p)->p_md.md_regs->tf_sp)
 
 #ifndef _LOCORE
 #ifdef _KERNEL
Index: sys/arch/hppa/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa/include/signal.h,v
retrieving revision 1.9
diff -u -p -r1.9 signal.h
--- sys/arch/hppa/include/signal.h      14 Nov 2011 14:29:53 -0000      1.9
+++ sys/arch/hppa/include/signal.h      16 Nov 2012 17:58:59 -0000
@@ -47,7 +47,7 @@ typedef int sig_atomic_t;
  * a non-standard exit is performed.
  */
 struct sigcontext {
-       unsigned long   sc_onstack;     /* sigstack state to restore */
+       unsigned long   __sc_unused;
        unsigned long   sc_mask;        /* signal mask to restore */
        unsigned long   sc_ps;          /* psl to restore */
        unsigned long   sc_fp;          /* fp to restore */
Index: sys/arch/hppa64/hppa64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa64/hppa64/machdep.c,v
retrieving revision 1.49
diff -u -p -r1.49 machdep.c
--- sys/arch/hppa64/hppa64/machdep.c    8 Oct 2012 21:47:48 -0000       1.49
+++ sys/arch/hppa64/hppa64/machdep.c    16 Nov 2012 17:58:59 -0000
@@ -854,16 +854,13 @@ sendsig(sig_t catcher, int sig, int mask
        /* Save the FPU context first. */
        fpu_proc_save(p);
 
-       ksc.sc_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-
        /*
         * Allocate space for the signal handler context.
         */
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !ksc.sc_onstack &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(tf->tf_sp) && (psp->ps_sigonstack & sigmask(sig)))
                scp = (register_t)p->p_sigstk.ss_sp;
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                scp = (tf->tf_sp + 63) & ~63;
 
        sss = (sizeof(ksc) + 63) & ~63;
@@ -879,6 +876,7 @@ sendsig(sig_t catcher, int sig, int mask
                    tf->tf_iioq[0], tf->tf_iioq[1], tf->tf_ipsw, PSL_BITS);
 #endif
 
+       bzero(&ksc, sizeof(ksc));
        ksc.sc_mask = mask;
        ksc.sc_fp = scp + sss;
        ksc.sc_ps = tf->tf_ipsw;
@@ -951,10 +949,6 @@ sys_sigreturn(struct proc *p, void *v, r
        if ((ksc.sc_ps & (PSL_MBS|PSL_MBZ)) != PSL_MBS)
                return (EINVAL);
 
-       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;
 
        tf->tf_sar = ksc.sc_regs[0];
Index: sys/arch/hppa64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa64/include/cpu.h,v
retrieving revision 1.27
diff -u -p -r1.27 cpu.h
--- sys/arch/hppa64/include/cpu.h       16 Aug 2011 17:36:37 -0000      1.27
+++ sys/arch/hppa64/include/cpu.h       16 Nov 2012 17:58:59 -0000
@@ -163,6 +163,9 @@ extern int cpu_hvers;
 #define clear_resched(ci)      want_resched = 0
 #define        need_proftick(p)        setsoftast()
 
+#define        PROC_PC(p)              ((p)->p_md.md_regs->tf_iioq[0])
+#define        PROC_STACK(p)           ((p)->p_md.md_regs->tf_sp)
+
 #ifndef _LOCORE
 #ifdef _KERNEL
 
Index: sys/arch/hppa64/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/hppa64/include/signal.h,v
retrieving revision 1.4
diff -u -p -r1.4 signal.h
--- sys/arch/hppa64/include/signal.h    23 Mar 2011 16:54:35 -0000      1.4
+++ sys/arch/hppa64/include/signal.h    16 Nov 2012 17:58:59 -0000
@@ -47,7 +47,7 @@ typedef int sig_atomic_t;
  * a non-standard exit is performed.
  */
 struct sigcontext {
-       unsigned long   sc_onstack;     /* sigstack state to restore */
+       unsigned long   __sc_unused;
        unsigned long   sc_mask;        /* signal mask to restore */
        unsigned long   sc_ps;          /* psl to restore */
        unsigned long   sc_fp;          /* fp to restore */
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.517
diff -u -p -r1.517 machdep.c
--- sys/arch/i386/i386/machdep.c        10 Nov 2012 09:45:05 -0000      1.517
+++ sys/arch/i386/i386/machdep.c        16 Nov 2012 17:59:00 -0000
@@ -2315,21 +2315,20 @@ sendsig(sig_t catcher, int sig, int mask
        struct sigframe *fp, frame;
        struct sigacts *psp = p->p_sigacts;
        register_t sp;
-       int oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
 
        /*
         * Build the argument list for the signal handler.
         */
+       bzero(&frame, sizeof(frame));
        frame.sf_signum = sig;
 
        /*
         * Allocate space for the signal handler context.
         */
-       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(tf->tf_esp) && (psp->ps_sigonstack & sigmask(sig)))
                sp = (long)p->p_sigstk.ss_sp + p->p_sigstk.ss_size;
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                sp = tf->tf_esp;
 
        frame.sf_sc.sc_fpstate = NULL;
@@ -2356,7 +2355,6 @@ sendsig(sig_t catcher, int sig, int mask
         */
        frame.sf_sc.sc_err = tf->tf_err;
        frame.sf_sc.sc_trapno = tf->tf_trapno;
-       frame.sf_sc.sc_onstack = oonstack;
        frame.sf_sc.sc_mask = mask;
 #ifdef VM86
        if (tf->tf_eflags & PSL_VM) {
@@ -2502,10 +2500,6 @@ sys_sigreturn(struct proc *p, void *v, r
                p->p_md.md_flags |= MDP_USEDFPU;
        }
 
-       if (context.sc_onstack & 01)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = context.sc_mask & ~sigcantmask;
 
        return (EJUSTRETURN);
Index: sys/arch/i386/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.124
diff -u -p -r1.124 cpu.h
--- sys/arch/i386/include/cpu.h 10 Nov 2012 09:45:05 -0000      1.124
+++ sys/arch/i386/include/cpu.h 16 Nov 2012 17:59:00 -0000
@@ -248,6 +248,7 @@ extern void need_resched(struct cpu_info
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)              ((p)->p_md.md_regs->tf_eip)
+#define        PROC_STACK(p)           ((p)->p_md.md_regs->tf_esp)
 
 /*
  * Give a profiling tick to the current process when the user profiling
Index: sys/arch/i386/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/signal.h,v
retrieving revision 1.8
diff -u -p -r1.8 signal.h
--- sys/arch/i386/include/signal.h      23 Mar 2011 16:54:35 -0000      1.8
+++ sys/arch/i386/include/signal.h      16 Nov 2012 17:59:00 -0000
@@ -73,7 +73,7 @@ struct        sigcontext {
        int     sc_esp;
        int     sc_ss;
 
-       int     sc_onstack;             /* sigstack state to restore */
+       int     __sc_unused;
        int     sc_mask;                /* signal mask to restore */
 
        int     sc_trapno;              /* XXX should be above */
Index: sys/arch/m68k/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/m68k/include/cpu.h,v
retrieving revision 1.25
diff -u -p -r1.25 cpu.h
--- sys/arch/m68k/include/cpu.h 16 Nov 2011 20:50:18 -0000      1.25
+++ sys/arch/m68k/include/cpu.h 16 Nov 2012 17:59:00 -0000
@@ -253,6 +253,7 @@ int cachectl(struct proc *, int, vaddr_t
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)      (((struct trapframe 
*)((p)->p_md.md_regs))->tf_pc)
+#define        PROC_STACK(p)   (((struct trapframe 
*)((p)->p_md.md_regs))->tf_regs[SP])
 
 #define        cpu_idle_enter()        do { /* nothing */ } while (0)
 #define        cpu_idle_leave()        do { /* nothing */ } while (0)
Index: sys/arch/m68k/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/m68k/include/signal.h,v
retrieving revision 1.5
diff -u -p -r1.5 signal.h
--- sys/arch/m68k/include/signal.h      8 Jan 2006 14:20:17 -0000       1.5
+++ sys/arch/m68k/include/signal.h      16 Nov 2012 17:59:00 -0000
@@ -55,7 +55,7 @@ typedef int sig_atomic_t;
  * a non-standard exit is performed.
  */
 struct sigcontext {
-       int     sc_onstack;             /* sigstack state to restore */
+       int     __sc_unused;
        int     sc_mask;                /* signal mask to restore */
        int     sc_sp;                  /* sp to restore */
        int     sc_fp;                  /* fp to restore */
Index: sys/arch/m68k/m68k/sig_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/m68k/m68k/sig_machdep.c,v
retrieving revision 1.26
diff -u -p -r1.26 sig_machdep.c
--- sys/arch/m68k/m68k/sig_machdep.c    22 Aug 2012 13:33:32 -0000      1.26
+++ sys/arch/m68k/m68k/sig_machdep.c    16 Nov 2012 17:59:00 -0000
@@ -131,11 +131,10 @@ sendsig(catcher, sig, mask, code, type, 
        struct frame *frame;
        struct sigacts *psp = p->p_sigacts;
        short ft;
-       int oonstack, fsize;
+       int fsize;
 
        frame = (struct frame *)p->p_md.md_regs;
        ft = frame->f_format;
-       oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
 
        /*
         * Allocate and validate space for the signal handler
@@ -145,22 +144,22 @@ sendsig(catcher, sig, mask, code, type, 
         * the space with a `brk'.
         */
        fsize = sizeof(struct sigframe);
-       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(frame->f_regs[SP]) &&
+           (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp +
                                         p->p_sigstk.ss_size - fsize);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
        if ((unsigned)fp <= USRSTACK - ptoa(p->p_vmspace->vm_ssize)) 
                (void)uvm_grow(p, (unsigned)fp);
 #ifdef DEBUG
        if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
                printf("sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
-                      p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
+                      p->p_pid, sig, &fsize, fp, &fp->sf_sc, ft);
 #endif
        kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP,
-           M_WAITOK | M_CANFAIL);
+           M_WAITOK | M_CANFAIL | M_ZERO);
        if (kfp == NULL) {
                /* Better halt the process in its track than panicing */
                sigexit(p, SIGILL);
@@ -226,7 +225,6 @@ sendsig(catcher, sig, mask, code, type, 
        /*
         * Build the signal context to be used by sigreturn.
         */
-       kfp->sf_sc.sc_onstack = oonstack;
        kfp->sf_sc.sc_mask = mask;
        kfp->sf_sc.sc_sp = frame->f_regs[SP];
        kfp->sf_sc.sc_fp = frame->f_regs[A6];
@@ -320,10 +318,6 @@ sys_sigreturn(p, v, retval)
        /*
         * Restore the user supplied information
         */
-       if (scp->sc_onstack & 1)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = scp->sc_mask &~ sigcantmask;
        frame = (struct frame *) p->p_md.md_regs;
        frame->f_regs[SP] = scp->sc_sp;
Index: sys/arch/m88k/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/m88k/include/cpu.h,v
retrieving revision 1.54
diff -u -p -r1.54 cpu.h
--- sys/arch/m88k/include/cpu.h 25 Oct 2011 18:38:06 -0000      1.54
+++ sys/arch/m88k/include/cpu.h 16 Nov 2012 17:59:00 -0000
@@ -266,6 +266,7 @@ struct clockframe {
          ((regs)->snip & NIP_V ? (regs)->snip & NIP_ADDR :             \
                                   (regs)->sfip & FIP_ADDR)))
 #define        PROC_PC(p)      PC_REGS((struct reg *)((p)->p_md.md_tf))
+#define        PROC_STACK(p)   ((p)->p_md.md_tf->tf_sp)
 
 #define clear_resched(ci)      (ci)->ci_want_resched = 0
 
Index: sys/arch/m88k/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/m88k/include/signal.h,v
retrieving revision 1.6
diff -u -p -r1.6 signal.h
--- sys/arch/m88k/include/signal.h      9 May 2012 21:25:33 -0000       1.6
+++ sys/arch/m88k/include/signal.h      16 Nov 2012 17:59:00 -0000
@@ -45,11 +45,9 @@ typedef int sig_atomic_t;
  * execution of the signal handler. It is also made available
  * to the handler to allow it to restore state properly if
  * a non-standard exit is performed.
- *
- * All machines must have an sc_onstack and sc_mask.
  */
 struct  sigcontext {
-        int     sc_onstack;             /* sigstack state to restore */
+        int     __sc_unused;
         int     sc_mask;                /* signal mask to restore */
        /* begin machine dependent portion */
        unsigned int sc_regs[32 + 25];
Index: sys/arch/m88k/m88k/sig_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/m88k/m88k/sig_machdep.c,v
retrieving revision 1.15
diff -u -p -r1.15 sig_machdep.c
--- sys/arch/m88k/m88k/sig_machdep.c    22 Aug 2012 13:33:32 -0000      1.15
+++ sys/arch/m88k/m88k/sig_machdep.c    16 Nov 2012 17:59:00 -0000
@@ -90,12 +90,12 @@ sendsig(sig_t catcher, int sig, int mask
        struct trapframe *tf;
        struct sigacts *psp = p->p_sigacts;
        struct sigframe *fp;
-       int oonstack, fsize;
+       int fsize;
        struct sigframe sf;
        vaddr_t addr;
 
        tf = p->p_md.md_tf;
-       oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+
        /*
         * Allocate and validate space for the signal handler
         * context. Note that if the stack is in data space, the
@@ -105,12 +105,10 @@ sendsig(sig_t catcher, int sig, int mask
         */
        fsize = sizeof(struct sigframe);
        if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
-           (p->p_sigstk.ss_flags & SS_ONSTACK) == 0 &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+           !sigonstack(tf->tf_r[31]) && (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp +
                                         p->p_sigstk.ss_size - fsize);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)(tf->tf_r[31] - fsize);
 
        /* make sure the frame is aligned on a 8 byte boundary */
@@ -124,13 +122,13 @@ sendsig(sig_t catcher, int sig, int mask
        if ((sigdebug & SDB_FOLLOW) ||
            ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
                printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",
-                      p->p_pid, sig, &oonstack, fp, &fp->sf_sc);
+                      p->p_pid, sig, &sf, fp, &fp->sf_sc);
 #endif
        /*
         * Build the signal context to be used by sigreturn.
         */
+       bzero(&sf, sizeof(sf));
        sf.sf_scp = &fp->sf_sc;
-       sf.sf_sc.sc_onstack = oonstack;
        sf.sf_sc.sc_mask = mask;
 
        if (psp->ps_siginfo & sigmask(sig)) {
@@ -222,10 +220,6 @@ sys_sigreturn(struct proc *p, void *v, r
        /*
         * Restore the user supplied information
         */
-       if (scp->sc_onstack & SS_ONSTACK)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = scp->sc_mask & ~sigcantmask;
 
        /*
Index: sys/arch/macppc/macppc/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/machdep.c,v
retrieving revision 1.133
diff -u -p -r1.133 machdep.c
--- sys/arch/macppc/macppc/machdep.c    8 Oct 2012 21:47:48 -0000       1.133
+++ sys/arch/macppc/macppc/machdep.c    16 Nov 2012 17:59:00 -0000
@@ -558,23 +558,21 @@ sendsig(sig_t catcher, int sig, int mask
        struct trapframe *tf;
        struct sigframe *fp, frame;
        struct sigacts *psp = p->p_sigacts;
-       int oldonstack;
 
+       bzero(&frame, sizeof(frame));
        frame.sf_signum = sig;
 
        tf = trapframe(p);
-       oldonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
 
        /*
         * Allocate stack space for signal handler.
         */
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0
-           && !oldonstack
-           && (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(tf->tf_fixreg[1]) &&
+           (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp
                                         + p->p_sigstk.ss_size);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)tf->fixreg[1];
 
        fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
@@ -582,7 +580,6 @@ sendsig(sig_t catcher, int sig, int mask
        /*
         * Generate signal context for SYS_sigreturn.
         */
-       frame.sf_sc.sc_onstack = oldonstack;
        frame.sf_sc.sc_mask = mask;
        frame.sf_sip = NULL;
        bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
@@ -628,10 +625,6 @@ sys_sigreturn(struct proc *p, void *v, r
        if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
                return EINVAL;
        bcopy(&sc.sc_frame, tf, sizeof *tf);
-       if (sc.sc_onstack & 1)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = sc.sc_mask & ~sigcantmask;
        return EJUSTRETURN;
 }
Index: sys/arch/mips64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/mips64/include/cpu.h,v
retrieving revision 1.90
diff -u -p -r1.90 cpu.h
--- sys/arch/mips64/include/cpu.h       3 Oct 2012 11:18:23 -0000       1.90
+++ sys/arch/mips64/include/cpu.h       16 Nov 2012 17:59:00 -0000
@@ -268,6 +268,7 @@ void        cp0_calibrate(struct cpu_info *);
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)      ((p)->p_md.md_regs->pc)
+#define        PROC_STACK(p)   ((p)->p_md.md_regs->sp)
 
 /*
  * Preempt the current process if in interrupt from user mode,
Index: sys/arch/mips64/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/mips64/include/signal.h,v
retrieving revision 1.9
diff -u -p -r1.9 signal.h
--- sys/arch/mips64/include/signal.h    23 Mar 2011 16:54:36 -0000      1.9
+++ sys/arch/mips64/include/signal.h    16 Nov 2012 17:59:00 -0000
@@ -56,7 +56,7 @@ typedef int sig_atomic_t;
  * a non-standard exit is performed.
  */
 struct sigcontext {
-       long    sc_onstack;     /* sigstack state to restore */
+       long    __sc_unused;
        long     sc_mask;       /* signal mask to restore */
        __register_t sc_pc;     /* pc at time of signal */
        __register_t sc_regs[32]; /* processor regs 0 to 31 */
Index: sys/arch/mips64/mips64/sendsig.c
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/sendsig.c,v
retrieving revision 1.19
diff -u -p -r1.19 sendsig.c
--- sys/arch/mips64/mips64/sendsig.c    3 Oct 2012 11:18:23 -0000       1.19
+++ sys/arch/mips64/mips64/sendsig.c    16 Nov 2012 17:59:00 -0000
@@ -112,11 +112,11 @@ sendsig(catcher, sig, mask, code, type, 
        struct sigframe *fp;
        struct trap_frame *regs;
        struct sigacts *psp = p->p_sigacts;
-       int oonstack, fsize;
+       int fsize;
        struct sigcontext ksc;
 
        regs = p->p_md.md_regs;
-       oonstack = p->p_sigstk.ss_flags & SA_ONSTACK;
+
        /*
         * Allocate and validate space for the signal handler
         * context. Note that if the stack is in data space, the
@@ -128,12 +128,10 @@ sendsig(catcher, sig, mask, code, type, 
        if (!(psp->ps_siginfo & sigmask(sig)))
                fsize -= sizeof(siginfo_t);
        if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
-           (p->p_sigstk.ss_flags & SA_ONSTACK) == 0 &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+           !sigonstack(regs->sp) && (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp +
                                         p->p_sigstk.ss_size - fsize);
-               p->p_sigstk.ss_flags |= SA_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)(regs->sp - fsize);
        if ((vaddr_t)fp <= USRSTACK - ptoa(p->p_vmspace->vm_ssize))
                (void)uvm_grow(p, (vaddr_t)fp);
@@ -141,12 +139,12 @@ sendsig(catcher, sig, mask, code, type, 
        if ((sigdebug & SDB_FOLLOW) ||
            ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid)))
                printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",
-                      p->p_pid, sig, &oonstack, fp, &fp->sf_sc);
+                      p->p_pid, sig, &ksc, fp, &fp->sf_sc);
 #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 = regs->pc;
        ksc.mullo = regs->mullo;
@@ -255,10 +253,6 @@ sys_sigreturn(p, v, retval)
        /*
         * Restore the user supplied information
         */
-       if (scp->sc_onstack & SA_ONSTACK)
-               p->p_sigstk.ss_flags |= SA_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SA_ONSTACK;
        p->p_sigmask = scp->sc_mask &~ sigcantmask;
        regs->pc = scp->sc_pc;
        regs->mullo = scp->mullo;
Index: sys/arch/powerpc/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.46
diff -u -p -r1.46 cpu.h
--- sys/arch/powerpc/include/cpu.h      28 Sep 2010 20:27:55 -0000      1.46
+++ sys/arch/powerpc/include/cpu.h      16 Nov 2012 17:59:00 -0000
@@ -150,6 +150,7 @@ extern struct cpu_info cpu_info[PPC_MAXP
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)              (trapframe(p)->srr0)
+#define        PROC_STACK(p)           (trapframe(p)->fixreg[1])
 
 void   delay(unsigned);
 #define        DELAY(n)                delay(n)
Index: sys/arch/powerpc/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/include/signal.h,v
retrieving revision 1.7
diff -u -p -r1.7 signal.h
--- sys/arch/powerpc/include/signal.h   8 Jan 2006 14:20:17 -0000       1.7
+++ sys/arch/powerpc/include/signal.h   16 Nov 2012 17:59:00 -0000
@@ -64,7 +64,7 @@ struct trapframe {
 };
 
 struct sigcontext {
-       int sc_onstack;                 /* saved onstack flag */
+       int __sc_unused;
        int sc_mask;                    /* saved signal mask */
        struct trapframe sc_frame;      /* saved registers */
 };
Index: sys/arch/sh/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/sh/include/cpu.h,v
retrieving revision 1.21
diff -u -p -r1.21 cpu.h
--- sys/arch/sh/include/cpu.h   28 Sep 2010 20:27:55 -0000      1.21
+++ sys/arch/sh/include/cpu.h   16 Nov 2012 17:59:00 -0000
@@ -97,8 +97,8 @@ struct clockframe {
  * This is used during profiling to integrate system time.  It can safely
  * assume that the process is resident.
  */
-#define        PROC_PC(p)                                                      
\
-       (((struct trapframe *)(p)->p_md.md_regs)->tf_spc)
+#define        PROC_PC(p)      ((p)->p_md.md_regs->tf_spc)
+#define        PROC_STACK(p)   ((p)->p_md.md_regs->tf_r15)
 
 /*
  * Preempt the current process if in interrupt from user mode,
Index: sys/arch/sh/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/sh/include/signal.h,v
retrieving revision 1.5
diff -u -p -r1.5 signal.h
--- sys/arch/sh/include/signal.h        27 Apr 2012 17:39:47 -0000      1.5
+++ sys/arch/sh/include/signal.h        16 Nov 2012 17:59:00 -0000
@@ -52,7 +52,7 @@ struct sigcontext {
        int     sc_reg[21];
        int     sc_fpreg[34];
 
-       int     sc_onstack;     /* sigstack state to restore */
+       int     __sc_unused;
 
        int     sc_expevt;      /* XXX should be above */
        int     sc_err;
Index: sys/arch/sh/sh/sh_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/sh_machdep.c,v
retrieving revision 1.32
diff -u -p -r1.32 sh_machdep.c
--- sys/arch/sh/sh/sh_machdep.c 13 Apr 2012 18:09:01 -0000      1.32
+++ sys/arch/sh/sh/sh_machdep.c 16 Nov 2012 17:59:00 -0000
@@ -462,15 +462,13 @@ sendsig(sig_t catcher, int sig, int mask
        struct trapframe *tf = p->p_md.md_regs;
        struct sigacts *psp = p->p_sigacts;
        siginfo_t *sip;
-       int onstack;
 
-       onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && onstack == 0 &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(p->p_md.md_regs->tf_r15) &&
+           (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)((vaddr_t)p->p_sigstk.ss_sp +
                    p->p_sigstk.ss_size);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (void *)p->p_md.md_regs->tf_r15;
        --fp;
 
@@ -490,7 +488,6 @@ sendsig(sig_t catcher, int sig, int mask
                fpu_save((struct fpreg *)&frame.sf_uc.sc_fpreg);
 #endif
 
-       frame.sf_uc.sc_onstack = onstack;
        frame.sf_uc.sc_expevt = tf->tf_expevt;
        /* frame.sf_uc.sc_err = 0; */
        frame.sf_uc.sc_mask = mask;
@@ -555,11 +552,6 @@ sys_sigreturn(struct proc *p, void *v, r
                fpu_restore((struct fpreg *)&context.sc_fpreg);
 #endif
 
-       /* Restore signal stack. */
-       if (context.sc_onstack)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        /* Restore signal mask. */
        p->p_sigmask = context.sc_mask & ~sigcantmask;
 
Index: sys/arch/socppc/socppc/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/socppc/socppc/machdep.c,v
retrieving revision 1.35
diff -u -p -r1.35 machdep.c
--- sys/arch/socppc/socppc/machdep.c    8 Oct 2012 21:47:50 -0000       1.35
+++ sys/arch/socppc/socppc/machdep.c    16 Nov 2012 17:59:00 -0000
@@ -881,23 +881,21 @@ sendsig(sig_t catcher, int sig, int mask
        struct trapframe *tf;
        struct sigframe *fp, frame;
        struct sigacts *psp = p->p_sigacts;
-       int oldonstack;
 
+       bzero(&frame, sizeof(frame));
        frame.sf_signum = sig;
 
        tf = trapframe(p);
-       oldonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
 
        /*
         * Allocate stack space for signal handler.
         */
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0
-           && !oldonstack
-           && (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(tf->tf_fixreg[1]) &&
+           (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp
                                         + p->p_sigstk.ss_size);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)tf->fixreg[1];
 
        fp = (struct sigframe *)((int)(fp - 1) & ~0xf);
@@ -905,7 +903,6 @@ sendsig(sig_t catcher, int sig, int mask
        /*
         * Generate signal context for SYS_sigreturn.
         */
-       frame.sf_sc.sc_onstack = oldonstack;
        frame.sf_sc.sc_mask = mask;
        frame.sf_sip = NULL;
        bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf);
@@ -949,10 +946,6 @@ sys_sigreturn(struct proc *p, void *v, r
        if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC))
                return EINVAL;
        bcopy(&sc.sc_frame, tf, sizeof *tf);
-       if (sc.sc_onstack & 1)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = sc.sc_mask & ~sigcantmask;
        return EJUSTRETURN;
 }
Index: sys/arch/solbourne/solbourne/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/solbourne/solbourne/machdep.c,v
retrieving revision 1.24
diff -u -p -r1.24 machdep.c
--- sys/arch/solbourne/solbourne/machdep.c      8 Oct 2012 21:47:50 -0000       
1.24
+++ sys/arch/solbourne/solbourne/machdep.c      16 Nov 2012 17:59:01 -0000
@@ -364,22 +364,21 @@ sendsig(catcher, sig, mask, code, type, 
        struct sigacts *psp = p->p_sigacts;
        struct sigframe *fp;
        struct trapframe *tf;
-       int caddr, oonstack, oldsp, newsp;
+       int caddr, oldsp, newsp;
        struct sigframe sf;
 
        tf = p->p_md.md_tf;
        oldsp = tf->tf_out[6];
-       oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+
        /*
         * Compute new user stack addresses, subtract off
         * one signal frame, and align.
         */
-       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)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp +
                                         p->p_sigstk.ss_size);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)oldsp;
        fp = (struct sigframe *)((int)(fp - 1) & ~7);
 
@@ -393,13 +392,13 @@ sendsig(catcher, sig, mask, code, type, 
         * and then copy it out.  We probably ought to just build it
         * directly in user space....
         */
+       bzero(&sf, sizeof(sf));
        sf.sf_signo = sig;
        sf.sf_sip = NULL;
 
        /*
         * Build the signal context to be used by sigreturn.
         */
-       sf.sf_sc.sc_onstack = oonstack;
        sf.sf_sc.sc_mask = mask;
        sf.sf_sc.sc_sp = oldsp;
        sf.sf_sc.sc_pc = tf->tf_pc;
@@ -508,10 +507,6 @@ sys_sigreturn(p, v, retval)
        tf->tf_global[1] = ksc.sc_g1;
        tf->tf_out[0] = ksc.sc_o0;
        tf->tf_out[6] = ksc.sc_sp;
-       if (ksc.sc_onstack & 1)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = ksc.sc_mask & ~sigcantmask;
        return (EJUSTRETURN);
 }
Index: sys/arch/sparc/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc/include/cpu.h,v
retrieving revision 1.34
diff -u -p -r1.34 cpu.h
--- sys/arch/sparc/include/cpu.h        23 Mar 2011 16:54:37 -0000      1.34
+++ sys/arch/sparc/include/cpu.h        16 Nov 2012 17:59:01 -0000
@@ -106,6 +106,7 @@ extern int  want_ast;
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)              ((p)->p_md.md_tf->tf_pc)
+#define        PROC_STACK(p)           ((p)->p_md.md_tf->tf_out[6])
 
 /*
  * Give a profiling tick to the current process when the user profiling
Index: sys/arch/sparc/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc/include/signal.h,v
retrieving revision 1.9
diff -u -p -r1.9 signal.h
--- sys/arch/sparc/include/signal.h     23 Mar 2011 16:54:37 -0000      1.9
+++ sys/arch/sparc/include/signal.h     16 Nov 2012 17:59:01 -0000
@@ -56,11 +56,9 @@ typedef int sig_atomic_t;
  * execution of the signal handler.  It is also made available
  * to the handler to allow it to restore state properly if
  * a non-standard exit is performed.
- *
- * All machines must have an sc_onstack and sc_mask.
  */
 struct sigcontext {
-       int     sc_onstack;             /* sigstack state to restore */
+       int     __sc_unused;
        int     sc_mask;                /* signal mask to restore */
        /* begin machine dependent portion */
        int     sc_sp;                  /* %sp to restore */
Index: sys/arch/sparc/sparc/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc/sparc/machdep.c,v
retrieving revision 1.143
diff -u -p -r1.143 machdep.c
--- sys/arch/sparc/sparc/machdep.c      5 Nov 2012 13:20:16 -0000       1.143
+++ sys/arch/sparc/sparc/machdep.c      16 Nov 2012 17:59:01 -0000
@@ -373,22 +373,21 @@ sendsig(catcher, sig, mask, code, type, 
        struct sigacts *psp = p->p_sigacts;
        struct sigframe *fp;
        struct trapframe *tf;
-       int caddr, oonstack, oldsp, newsp;
+       int caddr, oldsp, newsp;
        struct sigframe sf;
 
        tf = p->p_md.md_tf;
        oldsp = tf->tf_out[6];
-       oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+
        /*
         * Compute new user stack addresses, subtract off
         * one signal frame, and align.
         */
-       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)))
                fp = (struct sigframe *)(p->p_sigstk.ss_sp +
                                         p->p_sigstk.ss_size);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)oldsp;
        fp = (struct sigframe *)((int)(fp - 1) & ~7);
 
@@ -402,13 +401,13 @@ sendsig(catcher, sig, mask, code, type, 
         * and then copy it out.  We probably ought to just build it
         * directly in user space....
         */
+       bzero(&sf, sizeof(sf));
        sf.sf_signo = sig;
        sf.sf_sip = NULL;
 
        /*
         * Build the signal context to be used by sigreturn.
         */
-       sf.sf_sc.sc_onstack = oonstack;
        sf.sf_sc.sc_mask = mask;
        sf.sf_sc.sc_sp = oldsp;
        sf.sf_sc.sc_pc = tf->tf_pc;
@@ -517,10 +516,6 @@ sys_sigreturn(p, v, retval)
        tf->tf_global[1] = ksc.sc_g1;
        tf->tf_out[0] = ksc.sc_o0;
        tf->tf_out[6] = ksc.sc_sp;
-       if (ksc.sc_onstack & 1)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        p->p_sigmask = ksc.sc_mask & ~sigcantmask;
        return (EJUSTRETURN);
 }
Index: sys/arch/sparc64/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/cpu.h,v
retrieving revision 1.78
diff -u -p -r1.78 cpu.h
--- sys/arch/sparc64/include/cpu.h      6 Jul 2011 22:26:44 -0000       1.78
+++ sys/arch/sparc64/include/cpu.h      16 Nov 2012 17:59:01 -0000
@@ -238,6 +238,7 @@ extern void need_resched(struct cpu_info
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)      ((p)->p_md.md_tf->tf_pc)
+#define        PROC_STACK(p)   ((p)->p_md.md_tf->tf_out[6] + (2048-1)) /* BIAS 
*/
 
 /*
  * Give a profiling tick to the current process when the user profiling
Index: sys/arch/sparc64/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/include/signal.h,v
retrieving revision 1.9
diff -u -p -r1.9 signal.h
--- sys/arch/sparc64/include/signal.h   23 Mar 2011 16:54:37 -0000      1.9
+++ sys/arch/sparc64/include/signal.h   16 Nov 2012 17:59:01 -0000
@@ -56,11 +56,9 @@ typedef int sig_atomic_t;
  * execution of the signal handler.  It is also made available
  * to the handler to allow it to restore state properly if
  * a non-standard exit is performed.
- *
- * All machines must have an sc_onstack and sc_mask.
  */
 struct sigcontext {
-       int             sc_onstack;     /* sigstack state to restore */
+       int             __sc_unused;
        int             __sc_mask13;    /* signal mask to restore (old style) */
        /* begin machine dependent portion */
        long            sc_sp;          /* %sp to restore */
Index: sys/arch/sparc64/sparc64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/machdep.c,v
retrieving revision 1.142
diff -u -p -r1.142 machdep.c
--- sys/arch/sparc64/sparc64/machdep.c  22 Oct 2012 17:27:19 -0000      1.142
+++ sys/arch/sparc64/sparc64/machdep.c  16 Nov 2012 17:59:01 -0000
@@ -430,26 +430,21 @@ sendsig(catcher, sig, mask, code, type, 
        struct sigacts *psp = p->p_sigacts;
        struct sigframe *fp;
        struct trapframe64 *tf;
-       vaddr_t addr; 
-       struct rwindow *oldsp, *newsp;
+       vaddr_t addr, oldsp, newsp;
        struct sigframe sf;
-       int onstack;
 
        tf = p->p_md.md_tf;
-       oldsp = (struct rwindow *)(u_long)(tf->tf_out[6] + STACK_OFFSET);
+       oldsp = tf->tf_out[6] + STACK_OFFSET;
 
        /*
         * Compute new user stack addresses, subtract off
         * one signal frame, and align.
         */
-       onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
-
-       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 && !onstack &&
-           (psp->ps_sigonstack & sigmask(sig))) {
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(oldsp) && (psp->ps_sigonstack & sigmask(sig)))
                fp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
                    p->p_sigstk.ss_size);
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       } else
+       else
                fp = (struct sigframe *)oldsp;
        /* Allocate an aligned sigframe */
        fp = (struct sigframe *)((long)(fp - 1) & ~0x0f);
@@ -459,13 +454,13 @@ sendsig(catcher, sig, mask, code, type, 
         * and then copy it out.  We probably ought to just build it
         * directly in user space....
         */
+       bzero(&sf, sizeof(sf));
        sf.sf_signo = sig;
        sf.sf_sip = NULL;
 
        /*
         * Build the signal context to be used by sigreturn.
         */
-       sf.sf_sc.sc_onstack = onstack;
        sf.sf_sc.sc_mask = mask;
        /* Save register context. */
        sf.sf_sc.sc_sp = (long)tf->tf_out[6];
@@ -489,7 +484,7 @@ sendsig(catcher, sig, mask, code, type, 
         * joins seamlessly with the frame it was in when the signal occurred,
         * so that the debugger and _longjmp code can back up through it.
         */
-       newsp = (struct rwindow *)((vaddr_t)fp - sizeof(struct rwindow));
+       newsp = (vaddr_t)fp - sizeof(struct rwindow);
        write_user_windows();
 
        /* XXX do not copyout siginfo if not needed */
@@ -522,7 +517,7 @@ sendsig(catcher, sig, mask, code, type, 
        tf->tf_global[1] = (vaddr_t)catcher;
        tf->tf_pc = addr;
        tf->tf_npc = addr + 4;
-       tf->tf_out[6] = (vaddr_t)newsp - STACK_OFFSET;
+       tf->tf_out[6] = newsp - STACK_OFFSET;
 }
 
 /*
@@ -591,12 +586,6 @@ sys_sigreturn(p, v, retval)
        tf->tf_global[1] = (u_int64_t)scp->sc_g1;
        tf->tf_out[0] = (u_int64_t)scp->sc_o0;
        tf->tf_out[6] = (u_int64_t)scp->sc_sp;
-
-       /* Restore signal stack. */
-       if (sc.sc_onstack & SS_ONSTACK)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
 
        /* Restore signal mask. */
        p->p_sigmask = scp->sc_mask & ~sigcantmask;
Index: sys/arch/vax/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/vax/include/cpu.h,v
retrieving revision 1.40
diff -u -p -r1.40 cpu.h
--- sys/arch/vax/include/cpu.h  15 Sep 2011 00:48:24 -0000      1.40
+++ sys/arch/vax/include/cpu.h  16 Nov 2012 17:59:01 -0000
@@ -123,6 +123,7 @@ extern      int     want_resched;   /* resched() wa
  * This is used during profiling to integrate system time.
  */
 #define        PROC_PC(p)      (((struct trapframe 
*)((p)->p_addr->u_pcb.framep))->pc)
+#define        PROC_STACK(p)   (((struct trapframe 
*)((p)->p_addr->u_pcb.framep))->sp)
 
 /*
  * Give a profiling tick to the current process when the user profiling
Index: sys/arch/vax/include/signal.h
===================================================================
RCS file: /cvs/src/sys/arch/vax/include/signal.h,v
retrieving revision 1.7
diff -u -p -r1.7 signal.h
--- sys/arch/vax/include/signal.h       23 Mar 2011 16:54:37 -0000      1.7
+++ sys/arch/vax/include/signal.h       16 Nov 2012 17:59:01 -0000
@@ -50,7 +50,7 @@ typedef int sig_atomic_t;
  * a non-standard exit is performed.
  */
 struct sigcontext {
-       int     sc_onstack;             /* sigstack state to restore */
+       int     __sc_unused;
        int     sc_mask;                /* signal mask to restore */
        int     sc_sp;                  /* sp to restore */
        int     sc_fp;                  /* fp to restore */
Index: sys/arch/vax/vax/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/vax/vax/machdep.c,v
retrieving revision 1.122
diff -u -p -r1.122 machdep.c
--- sys/arch/vax/vax/machdep.c  8 Oct 2012 21:47:50 -0000       1.122
+++ sys/arch/vax/vax/machdep.c  16 Nov 2012 17:59:01 -0000
@@ -346,7 +346,7 @@ consinit()
  * Old sigcontext structure, still used by userland until setjmp is fixed.
  */
 struct osigcontext {
-       int     sc_onstack;             /* sigstack state to restore */
+       int     __sc_unused;
        int     sc_mask;                /* signal mask to restore */
        int     sc_sp;                  /* sp to restore */
        int     sc_fp;                  /* fp to restore */
@@ -394,10 +394,6 @@ sys_sigreturn(p, v, retval)
            (ksc.sc_ps & PSL_CM)) {
                return (EINVAL);
        }
-       if (ksc.sc_onstack & 01)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigstk.ss_flags &= ~SS_ONSTACK;
        /* Restore signal mask. */
        p->p_sigmask = ksc.sc_mask & ~sigcantmask;
 
@@ -450,13 +446,12 @@ sendsig(catcher, sig, mask, code, type, 
        struct  trapframe *syscf;
        struct  sigframe *sigf, gsigf;
        unsigned int    cursp;
-       int     onstack;
 
        syscf = p->p_addr->u_pcb.framep;
-       onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
 
        /* Allocate space for the signal handler context. */
-       if (onstack)
+       if ((p->p_sigstk.ss_flags & SS_DISABLE) == 0 &&
+           !sigonstack(syscf->sp) && (psp->ps_sigonstack & sigmask(sig)))
                cursp = ((int)p->p_sigstk.ss_sp + p->p_sigstk.ss_size);
        else
                cursp = syscf->sp;
@@ -475,7 +470,6 @@ sendsig(catcher, sig, mask, code, type, 
                initsiginfo(&gsigf.sf_si, sig, code, type, val);
        }
 
-       gsigf.sf_sc.sc_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
        gsigf.sf_sc.sc_mask = mask;
        gsigf.sf_sc.sc_sp = syscf->sp; 
        gsigf.sf_sc.sc_fp = syscf->fp; 
@@ -508,9 +502,6 @@ sendsig(catcher, sig, mask, code, type, 
         */
        syscf->sp = (unsigned)sigf;
        syscf->ap = (unsigned)sigf + offsetof(struct sigframe, sf_pc);
-
-       if (onstack)
-               p->p_sigstk.ss_flags |= SS_ONSTACK;
 }
 
 int    waittime = -1;
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.144
diff -u -p -r1.144 kern_sig.c
--- sys/kern/kern_sig.c 17 Oct 2012 04:48:52 -0000      1.144
+++ sys/kern/kern_sig.c 16 Nov 2012 17:59:02 -0000
@@ -494,6 +494,15 @@ sys_sigsuspend(struct proc *p, void *v, 
 }
 
 int
+sigonstack(size_t stack)
+{
+       const struct sigaltstack *ss = &curproc->p_sigstk;
+
+       return (ss->ss_flags & SS_DISABLE ? 0 :
+           (stack - (size_t)ss->ss_sp < ss->ss_size));
+}
+
+int
 sys_sigaltstack(struct proc *p, void *v, register_t *retval)
 {
        struct sys_sigaltstack_args /* {
@@ -503,19 +512,25 @@ sys_sigaltstack(struct proc *p, void *v,
        struct sigaltstack ss;
        const struct sigaltstack *nss;
        struct sigaltstack *oss;
+       int onstack = sigonstack(PROC_STACK(p));
        int error;
 
        nss = SCARG(uap, nss);
        oss = SCARG(uap, oss);
 
-       if (oss && (error = copyout(&p->p_sigstk, oss, sizeof(p->p_sigstk))))
-               return (error);
+       if (oss != NULL) {
+               ss = p->p_sigstk;
+               if (onstack)
+                       ss.ss_flags |= SS_ONSTACK;
+               if ((error = copyout(&ss, oss, sizeof(ss))))
+                       return (error);
+       }
        if (nss == NULL)
                return (0);
        error = copyin(nss, &ss, sizeof(ss));
        if (error)
                return (error);
-       if (p->p_sigstk.ss_flags & SS_ONSTACK)
+       if (onstack)
                return (EPERM);
        if (ss.ss_flags & ~SS_DISABLE)
                return (EINVAL);
Index: sys/sys/signalvar.h
===================================================================
RCS file: /cvs/src/sys/sys/signalvar.h,v
retrieving revision 1.25
diff -u -p -r1.25 signalvar.h
--- sys/sys/signalvar.h 20 Feb 2012 22:23:39 -0000      1.25
+++ sys/sys/signalvar.h 16 Nov 2012 17:59:02 -0000
@@ -164,6 +164,7 @@ void        siginit(struct proc *p);
 void   trapsignal(struct proc *p, int sig, u_long code, int type,
            union sigval val);
 void   sigexit(struct proc *, int);
+int    sigonstack(size_t);
 void   setsigvec(struct proc *, int, struct sigaction *);
 int    killpg1(struct proc *, int, int, int);

Reply via email to