aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/machdep.c19
-rw-r--r--sys/alpha/include/cpu.h2
-rw-r--r--sys/alpha/osf1/osf1_signal.c4
-rw-r--r--sys/amd64/amd64/machdep.c22
-rw-r--r--sys/amd64/include/cpu.h3
-rw-r--r--sys/compat/svr4/svr4_signal.c2
-rw-r--r--sys/i386/i386/machdep.c22
-rw-r--r--sys/i386/include/cpu.h3
-rw-r--r--sys/i386/linux/linux.h1
-rw-r--r--sys/i386/linux/linux_machdep.c2
-rw-r--r--sys/i386/linux/linux_sysvec.c29
-rw-r--r--sys/i386/svr4/svr4_machdep.c2
-rw-r--r--sys/ia64/ia64/machdep.c10
-rw-r--r--sys/ia64/include/cpu.h2
-rw-r--r--sys/kern/kern_sig.c64
-rw-r--r--sys/pc98/i386/machdep.c22
-rw-r--r--sys/pc98/pc98/machdep.c22
-rw-r--r--sys/sys/proc.h14
18 files changed, 166 insertions, 79 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index f048bbbc483d..9c3ace5ff704 100644
--- a/sys/alpha/alpha/machdep.c
+++ b/sys/alpha/alpha/machdep.c
@@ -1258,7 +1258,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
int oonstack, fsize, rndfsize;
frame = p->p_md.md_tf;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(alpha_pal_rdusp());
fsize = sizeof ksi;
rndfsize = ((fsize + 15) / 16) * 16;
@@ -1273,7 +1273,9 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sip = (osiginfo_t *)((caddr_t)p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - rndfsize);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize);
@@ -1294,7 +1296,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Build the signal context to be used by sigreturn.
*/
- ksi.si_sc.sc_onstack = oonstack;
+ ksi.si_sc.sc_onstack = (oonstack) ? 1 : 0;
SIG2OSIG(*mask, ksi.si_sc.sc_mask);
ksi.si_sc.sc_pc = frame->tf_regs[FRAME_PC];
ksi.si_sc.sc_ps = frame->tf_regs[FRAME_PS];
@@ -1358,14 +1360,16 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
}
frame = p->p_md.md_tf;
- oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
+ oonstack = sigonstack(alpha_pal_rdusp());
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
/* save user context */
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = p->p_sigstk;
- sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
fill_regs(p, (struct reg *)sf.sf_uc.uc_mcontext.mc_regs);
sf.sf_uc.uc_mcontext.mc_regs[R_SP] = alpha_pal_rdusp();
@@ -1390,7 +1394,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - rndfsize);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
sfp = (struct sigframe *)(alpha_pal_rdusp() - rndfsize);
@@ -1503,6 +1509,8 @@ osigreturn(struct proc *p,
*/
if (ksc.sc_regs[R_ZERO] != 0xACEDBADE) /* magic number */
return (EINVAL);
+
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
/*
* Restore the user-supplied information
*/
@@ -1510,6 +1518,7 @@ osigreturn(struct proc *p,
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
/*
* longjmp is still implemented by calling osigreturn. The new
@@ -1571,10 +1580,12 @@ sigreturn(struct proc *p,
p->p_md.md_tf->tf_regs[FRAME_PC] = uc.uc_mcontext.mc_regs[R_PC];
alpha_pal_wrusp(uc.uc_mcontext.mc_regs[R_SP]);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
if (uc.uc_mcontext.mc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
p->p_sigmask = uc.uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/alpha/include/cpu.h b/sys/alpha/include/cpu.h
index a0be38fe0f51..3da213f66d1c 100644
--- a/sys/alpha/include/cpu.h
+++ b/sys/alpha/include/cpu.h
@@ -52,6 +52,8 @@
#include <machine/frame.h>
+#define cpu_getstack(p) (alpha_pal_rdusp())
+
/*
* Arguments to hardclock and gatherstats encapsulate the previous
* machine state in an opaque clockframe. One the Alpha, we use
diff --git a/sys/alpha/osf1/osf1_signal.c b/sys/alpha/osf1/osf1_signal.c
index 738b0a45d055..770ccf32d010 100644
--- a/sys/alpha/osf1/osf1_signal.c
+++ b/sys/alpha/osf1/osf1_signal.c
@@ -583,7 +583,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
psp = p->p_sigacts;
frame = p->p_md.md_tf;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(alpha_pal_rdusp());
fsize = sizeof ksi;
rndfsize = ((fsize + 15) / 16) * 16;
@@ -618,7 +618,7 @@ osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Build the signal context to be used by sigreturn.
*/
- ksi.si_sc.sc_onstack = oonstack;
+ ksi.si_sc.sc_onstack = (oonstack) ? 1 : 0;
bsd_to_osf1_sigset(mask, &ksi.si_sc.sc_mask);
ksi.si_sc.sc_pc = frame->tf_regs[FRAME_PC];
ksi.si_sc.sc_ps = frame->tf_regs[FRAME_PS];
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 2e6416745bb5..5c059291c6b5 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -494,14 +494,16 @@ osendsig(catcher, sig, mask, code)
p = curproc;
psp = p->p_sigacts;
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Allocate and validate space for the signal handler context. */
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct osigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
fp = (struct osigframe *)regs->tf_esp - 1;
@@ -560,7 +562,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
/* Build the signal context to be used by osigreturn(). */
- sf.sf_siginfo.si_sc.sc_onstack = oonstack;
+ sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
@@ -633,13 +635,15 @@ sendsig(catcher, sig, mask, code)
return;
}
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Save user context. */
bzero(&sf, sizeof(sf));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = p->p_sigstk;
- sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
@@ -648,7 +652,9 @@ sendsig(catcher, sig, mask, code)
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct sigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
sfp = (struct sigframe *)regs->tf_esp - 1;
@@ -849,10 +855,13 @@ osigreturn(p, uap)
regs->tf_ss = scp->sc_ss;
regs->tf_isp = scp->sc_isp;
- if (scp->sc_onstack & 01)
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ if (scp->sc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
+
SIGSETOLD(p->p_sigmask, scp->sc_mask);
SIG_CANTMASK(p->p_sigmask);
regs->tf_ebp = scp->sc_fp;
@@ -958,10 +967,13 @@ sigreturn(p, uap)
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
}
+
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h
index 669af64c1b47..9293ba29b741 100644
--- a/sys/amd64/include/cpu.h
+++ b/sys/amd64/include/cpu.h
@@ -58,7 +58,8 @@
#define cpu_exec(p) /* nothing */
#define cpu_swapin(p) /* nothing */
-#define cpu_setstack(p, ap) ((p)->p_md.md_regs[SP] = (ap))
+#define cpu_getstack(p) ((p)->p_md.md_regs->tf_esp)
+#define cpu_setstack(p, ap) ((p)->p_md.md_regs->tf_esp = (ap))
#define CLKF_USERMODE(framep) \
((ISPL((framep)->cf_cs) == SEL_UPL) || (framep->cf_eflags & PSL_VM))
diff --git a/sys/compat/svr4/svr4_signal.c b/sys/compat/svr4/svr4_signal.c
index c80538edb42a..84f8ce07725f 100644
--- a/sys/compat/svr4/svr4_signal.c
+++ b/sys/compat/svr4/svr4_signal.c
@@ -628,7 +628,7 @@ svr4_sys_context(p, uap)
case 0:
DPRINTF(("getcontext(%p)\n", uap->uc));
svr4_getcontext(p, &uc, &p->p_sigmask,
- p->p_sigstk.ss_flags & SS_ONSTACK);
+ sigonstack(cpu_getstack(p)));
return copyout(&uc, uap->uc, sizeof(uc));
case 1:
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 2e6416745bb5..5c059291c6b5 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -494,14 +494,16 @@ osendsig(catcher, sig, mask, code)
p = curproc;
psp = p->p_sigacts;
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Allocate and validate space for the signal handler context. */
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct osigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
fp = (struct osigframe *)regs->tf_esp - 1;
@@ -560,7 +562,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
/* Build the signal context to be used by osigreturn(). */
- sf.sf_siginfo.si_sc.sc_onstack = oonstack;
+ sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
@@ -633,13 +635,15 @@ sendsig(catcher, sig, mask, code)
return;
}
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Save user context. */
bzero(&sf, sizeof(sf));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = p->p_sigstk;
- sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
@@ -648,7 +652,9 @@ sendsig(catcher, sig, mask, code)
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct sigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
sfp = (struct sigframe *)regs->tf_esp - 1;
@@ -849,10 +855,13 @@ osigreturn(p, uap)
regs->tf_ss = scp->sc_ss;
regs->tf_isp = scp->sc_isp;
- if (scp->sc_onstack & 01)
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ if (scp->sc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
+
SIGSETOLD(p->p_sigmask, scp->sc_mask);
SIG_CANTMASK(p->p_sigmask);
regs->tf_ebp = scp->sc_fp;
@@ -958,10 +967,13 @@ sigreturn(p, uap)
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
}
+
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/i386/include/cpu.h b/sys/i386/include/cpu.h
index 669af64c1b47..9293ba29b741 100644
--- a/sys/i386/include/cpu.h
+++ b/sys/i386/include/cpu.h
@@ -58,7 +58,8 @@
#define cpu_exec(p) /* nothing */
#define cpu_swapin(p) /* nothing */
-#define cpu_setstack(p, ap) ((p)->p_md.md_regs[SP] = (ap))
+#define cpu_getstack(p) ((p)->p_md.md_regs->tf_esp)
+#define cpu_setstack(p, ap) ((p)->p_md.md_regs->tf_esp = (ap))
#define CLKF_USERMODE(framep) \
((ISPL((framep)->cf_cs) == SEL_UPL) || (framep->cf_eflags & PSL_VM))
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index d253897cd941..8aff68a2ec98 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -163,7 +163,6 @@ struct linux_new_utsname {
/* sigaltstack */
#define LINUX_MINSIGSTKSZ 2048
-#define LINUX_SS_ONSTACK_BC 0 /* backwards compat SS_ONSTACK */
#define LINUX_SS_ONSTACK 1
#define LINUX_SS_DISABLE 2
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index c152a108d2bf..7e4b37e4b320 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -82,8 +82,6 @@ linux_to_bsd_sigaltstack(int lsa)
bsa |= SS_DISABLE;
if (lsa & LINUX_SS_ONSTACK)
bsa |= SS_ONSTACK;
- if (lsa == LINUX_SS_ONSTACK_BC)
- bsa = SS_ONSTACK;
return (bsa);
}
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 7d7fccbdfc2f..cd944a2a4880 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -205,7 +205,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
int oonstack;
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
#ifdef DEBUG
printf("Linux-emul(%ld): linux_rt_sendsig(%p, %d, %p, %lu)\n",
@@ -218,10 +218,8 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
fp = (struct linux_rt_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct linux_rt_sigframe));
- p->p_sigstk.ss_flags |= SS_ONSTACK;
- } else {
+ } else
fp = (struct linux_rt_sigframe *)regs->tf_esp - 1;
- }
/*
* grow() will return FALSE if the fp will not fit inside the stack
@@ -240,8 +238,8 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
SIGDELSET(p->p_sigcatch, SIGILL);
SIGDELSET(p->p_sigmask, SIGILL);
#ifdef DEBUG
- printf("Linux-emul(%ld): linux_rt_sendsig -- bad stack %p, SS_ONSTACK: 0x%x ",
- (long)p->p_pid, fp, p->p_sigstk.ss_flags & SS_ONSTACK);
+ printf("Linux-emul(%ld): linux_rt_sendsig -- bad stack %p, "
+ "oonstack=%x\n", (long)p->p_pid, fp, oonstack);
#endif
psignal(p, SIGILL);
return;
@@ -271,9 +269,9 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_sc.uc_link = NULL; /* XXX ??? */
frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp;
- frame.sf_sc.uc_stack.ss_flags =
- bsd_to_linux_sigaltstack(p->p_sigstk.ss_flags);
frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size;
+ frame.sf_sc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
@@ -298,9 +296,10 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame.sf_sc.uc_mcontext.sc_trapno = code; /* XXX ???? */
#ifdef DEBUG
- printf("Linux-emul(%ld): rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x\n",
- (long)p->p_pid, frame.sf_sc.uc_stack.ss_flags, p->p_sigstk.ss_sp,
- p->p_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
+ printf("Linux-emul(%ld): rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, "
+ "mask: 0x%x\n", (long)p->p_pid, frame.sf_sc.uc_stack.ss_flags,
+ p->p_sigstk.ss_sp, p->p_sigstk.ss_size,
+ frame.sf_sc.uc_mcontext.sc_mask);
#endif
if (copyout(&frame, fp, sizeof(frame)) != 0) {
@@ -355,7 +354,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
}
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
#ifdef DEBUG
printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n",
@@ -369,10 +368,8 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) {
fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct linux_sigframe));
- p->p_sigstk.ss_flags |= SS_ONSTACK;
- } else {
+ } else
fp = (struct linux_sigframe *)regs->tf_esp - 1;
- }
/*
* grow() will return FALSE if the fp will not fit inside the stack
@@ -521,7 +518,6 @@ linux_sigreturn(p, args)
return(EINVAL);
}
- p->p_sigstk.ss_flags &= ~SS_ONSTACK;
lmask.__bits[0] = frame.sf_sc.sc_mask;
for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
lmask.__bits[i+1] = frame.sf_extramask[i];
@@ -621,7 +617,6 @@ linux_rt_sigreturn(p, args)
return(EINVAL);
}
- p->p_sigstk.ss_flags &= ~SS_ONSTACK;
linux_to_bsd_sigset(&uc.uc_sigmask, &p->p_sigmask);
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/i386/svr4/svr4_machdep.c b/sys/i386/svr4/svr4_machdep.c
index 38c5cc8fb500..018fb74d3b0f 100644
--- a/sys/i386/svr4/svr4_machdep.c
+++ b/sys/i386/svr4/svr4_machdep.c
@@ -404,7 +404,7 @@ svr4_sendsig(catcher, sig, mask, code)
#endif
tf = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(tf->tf_esp);
/*
* Allocate space for the signal handler context.
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index bed49d53010f..bc0ae1becb41 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -785,7 +785,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
int oonstack, rndfsize;
frame = p->p_md.md_tf;
- oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
+ oonstack = sigonstack(frame->tf_r[FRAME_SP]);
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
/*
@@ -798,7 +798,10 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
bzero(&sf, sizeof(struct sigframe));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = p->p_sigstk;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
sf.sf_uc.uc_mcontext.mc_flags = IA64_MC_FLAG_ONSTACK;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_nat = 0; /* XXX */
sf.sf_uc.uc_mcontext.mc_sp = frame->tf_r[FRAME_SP];
@@ -837,8 +840,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
sbs = (u_int64_t) p->p_sigstk.ss_sp;
sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - rndfsize);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
- sf.sf_uc.uc_mcontext.mc_onstack |= 1;
+#endif
} else
sfp = (struct sigframe *)(frame->tf_r[FRAME_SP] - rndfsize);
@@ -1009,10 +1013,12 @@ sigreturn(struct proc *p,
frame->tf_r[FRAME_SP] = mcp->mc_sp;
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
if (uc.uc_mcontext.mc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
p->p_sigmask = uc.uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/ia64/include/cpu.h b/sys/ia64/include/cpu.h
index c6ebd1c61451..d581447357ad 100644
--- a/sys/ia64/include/cpu.h
+++ b/sys/ia64/include/cpu.h
@@ -52,6 +52,8 @@
#include <machine/frame.h>
+#define cpu_getstack(p) ((p)->p_md.md_tf->tf_r[FRAME_SP])
+
/*
* Arguments to hardclock and gatherstats encapsulate the previous
* machine state in an opaque clockframe. One the Alpha, we use
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 345bc31e49d9..434420beab2e 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -782,20 +782,25 @@ osigstack(p, uap)
register struct osigstack_args *uap;
{
struct sigstack ss;
- int error = 0;
+ int error;
- ss.ss_sp = p->p_sigstk.ss_sp;
- ss.ss_onstack = p->p_sigstk.ss_flags & SS_ONSTACK;
- if (uap->oss && (error = copyout(&ss, uap->oss,
- sizeof(struct sigstack))))
- return (error);
- if (uap->nss && (error = copyin(uap->nss, &ss, sizeof(ss))) == 0) {
+ if (uap->oss != NULL) {
+ ss.ss_sp = p->p_sigstk.ss_sp;
+ ss.ss_onstack = sigonstack(cpu_getstack(p));
+ error = copyout(&ss, uap->oss, sizeof(struct sigstack));
+ if (error)
+ return (error);
+ }
+
+ if (uap->nss != NULL) {
+ if ((error = copyin(uap->nss, &ss, sizeof(ss))) != 0)
+ return (error);
p->p_sigstk.ss_sp = ss.ss_sp;
p->p_sigstk.ss_size = 0;
p->p_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK;
p->p_flag |= P_ALTSTACK;
}
- return (error);
+ return (0);
}
#endif /* COMPAT_43 || COMPAT_SUNOS */
@@ -812,28 +817,33 @@ sigaltstack(p, uap)
register struct sigaltstack_args *uap;
{
stack_t ss;
- int error;
+ int error, oonstack;
- if ((p->p_flag & P_ALTSTACK) == 0)
- p->p_sigstk.ss_flags |= SS_DISABLE;
- if (uap->oss && (error = copyout(&p->p_sigstk, uap->oss,
- sizeof(stack_t))))
- return (error);
- if (uap->ss == 0)
- return (0);
- if ((error = copyin(uap->ss, &ss, sizeof(ss))))
- return (error);
- if (ss.ss_flags & SS_DISABLE) {
- if (p->p_sigstk.ss_flags & SS_ONSTACK)
+ oonstack = sigonstack(cpu_getstack(p));
+
+ if (uap->oss != NULL) {
+ ss = p->p_sigstk;
+ ss.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ if ((error = copyout(&ss, uap->oss, sizeof(stack_t))) != 0)
+ return (error);
+ }
+
+ if (uap->ss != NULL) {
+ if (oonstack)
+ return (EPERM);
+ if ((error = copyin(uap->ss, &ss, sizeof(ss))) != 0)
+ return (error);
+ if ((ss.ss_flags & ~SS_DISABLE) != 0)
return (EINVAL);
- p->p_flag &= ~P_ALTSTACK;
- p->p_sigstk.ss_flags = ss.ss_flags;
- return (0);
+ if (!(ss.ss_flags & SS_DISABLE)) {
+ if (ss.ss_size < p->p_sysent->sv_minsigstksz)
+ return (ENOMEM);
+ p->p_sigstk = ss;
+ p->p_flag |= P_ALTSTACK;
+ } else
+ p->p_flag &= ~P_ALTSTACK;
}
- if (ss.ss_size < p->p_sysent->sv_minsigstksz)
- return (ENOMEM);
- p->p_flag |= P_ALTSTACK;
- p->p_sigstk = ss;
return (0);
}
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 0320ad0fa073..a7567492aab1 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -495,14 +495,16 @@ osendsig(catcher, sig, mask, code)
p = curproc;
psp = p->p_sigacts;
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Allocate and validate space for the signal handler context. */
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct osigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
fp = (struct osigframe *)regs->tf_esp - 1;
@@ -561,7 +563,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
/* Build the signal context to be used by osigreturn(). */
- sf.sf_siginfo.si_sc.sc_onstack = oonstack;
+ sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
@@ -634,13 +636,15 @@ sendsig(catcher, sig, mask, code)
return;
}
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Save user context. */
bzero(&sf, sizeof(sf));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = p->p_sigstk;
- sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
@@ -649,7 +653,9 @@ sendsig(catcher, sig, mask, code)
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct sigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
sfp = (struct sigframe *)regs->tf_esp - 1;
@@ -850,10 +856,13 @@ osigreturn(p, uap)
regs->tf_ss = scp->sc_ss;
regs->tf_isp = scp->sc_isp;
- if (scp->sc_onstack & 01)
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ if (scp->sc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
+
SIGSETOLD(p->p_sigmask, scp->sc_mask);
SIG_CANTMASK(p->p_sigmask);
regs->tf_ebp = scp->sc_fp;
@@ -959,10 +968,13 @@ sigreturn(p, uap)
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
}
+
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 0320ad0fa073..a7567492aab1 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -495,14 +495,16 @@ osendsig(catcher, sig, mask, code)
p = curproc;
psp = p->p_sigacts;
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Allocate and validate space for the signal handler context. */
if ((p->p_flag & P_ALTSTACK) && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
fp = (struct osigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct osigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
fp = (struct osigframe *)regs->tf_esp - 1;
@@ -561,7 +563,7 @@ osendsig(catcher, sig, mask, code)
sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
/* Build the signal context to be used by osigreturn(). */
- sf.sf_siginfo.si_sc.sc_onstack = oonstack;
+ sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0;
SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
@@ -634,13 +636,15 @@ sendsig(catcher, sig, mask, code)
return;
}
regs = p->p_md.md_regs;
- oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ oonstack = sigonstack(regs->tf_esp);
/* Save user context. */
bzero(&sf, sizeof(sf));
sf.sf_uc.uc_sigmask = *mask;
sf.sf_uc.uc_stack = p->p_sigstk;
- sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
sf.sf_uc.uc_mcontext.mc_gs = rgs();
bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
@@ -649,7 +653,9 @@ sendsig(catcher, sig, mask, code)
SIGISMEMBER(psp->ps_sigonstack, sig)) {
sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
p->p_sigstk.ss_size - sizeof(struct sigframe));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
} else
sfp = (struct sigframe *)regs->tf_esp - 1;
@@ -850,10 +856,13 @@ osigreturn(p, uap)
regs->tf_ss = scp->sc_ss;
regs->tf_isp = scp->sc_isp;
- if (scp->sc_onstack & 01)
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ if (scp->sc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
+
SIGSETOLD(p->p_sigmask, scp->sc_mask);
SIG_CANTMASK(p->p_sigmask);
regs->tf_ebp = scp->sc_fp;
@@ -959,10 +968,13 @@ sigreturn(p, uap)
bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
}
+
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
if (ucp->uc_mcontext.mc_onstack & 1)
p->p_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
p->p_sigmask = ucp->uc_sigmask;
SIG_CANTMASK(p->p_sigmask);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 67d525ca0fbb..f52b2d2e653b 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -395,6 +395,20 @@ MALLOC_DECLARE(M_ZOMBIE);
MALLOC_DECLARE(M_PARGS);
#endif
+static __inline int
+sigonstack(size_t sp)
+{
+ register struct proc *p = curproc;
+
+ return ((p->p_flag & P_ALTSTACK) ?
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ ((p->p_sigstk.ss_size == 0) ? (p->p_sigstk.ss_flags & SS_ONSTACK) :
+ ((sp - (size_t)p->p_sigstk.ss_sp) < p->p_sigstk.ss_size))
+#else
+ ((sp - (size_t)p->p_sigstk.ss_sp) < p->p_sigstk.ss_size)
+#endif
+ : 0);
+}
/* Handy macro to determine of p1 can mangle p2 */