diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index f048bbbc483..9c3ace5ff70 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 a0be38fe0f5..3da213f66d1 100644 --- a/sys/alpha/include/cpu.h +++ b/sys/alpha/include/cpu.h @@ -52,6 +52,8 @@ #include +#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 738b0a45d05..770ccf32d01 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 2e6416745bb..5c059291c6b 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 669af64c1b4..9293ba29b74 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 c80538edb42..84f8ce07725 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 2e6416745bb..5c059291c6b 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 669af64c1b4..9293ba29b74 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 d253897cd94..8aff68a2ec9 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 c152a108d2b..7e4b37e4b32 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 7d7fccbdfc2..cd944a2a488 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 38c5cc8fb50..018fb74d3b0 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 bed49d53010..bc0ae1becb4 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 c6ebd1c6145..d581447357a 100644 --- a/sys/ia64/include/cpu.h +++ b/sys/ia64/include/cpu.h @@ -52,6 +52,8 @@ #include +#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 345bc31e49d..434420beab2 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) - return (EINVAL); - p->p_flag &= ~P_ALTSTACK; - p->p_sigstk.ss_flags = ss.ss_flags; - return (0); + 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); + 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 0320ad0fa07..a7567492aab 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 0320ad0fa07..a7567492aab 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 67d525ca0fb..f52b2d2e653 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 */