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);