diff options
author | marcel <marcel@FreeBSD.org> | 1999-10-04 19:33:58 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 1999-10-04 19:33:58 +0000 |
commit | 05e89da65f3f17ac5d45847a1070dff333d05e7a (patch) | |
tree | 5374ca102220e75048c919ed852c428f9646cddf /sys/alpha | |
parent | 77802960193ff746b91be4aae32ed2a9ed8b5090 (diff) | |
download | FreeBSD-src-05e89da65f3f17ac5d45847a1070dff333d05e7a.zip FreeBSD-src-05e89da65f3f17ac5d45847a1070dff333d05e7a.tar.gz |
Re-introduction of sigcontext.
struct sigcontext and ucontext_t/mcontext_t are defined in such
a way that both (ie struct sigcontext and ucontext_t) can be
passed on to sigreturn. The signal handler is still given a
ucontext_t for maximum flexibility.
For backward compatibility sigreturn restores the state for the
alternate signal stack from sigcontext.sc_onstack and not from
ucontext_t.uc_stack. A good way to determine which value the
application has set and thus which value to use, is still open
for discussion.
NOTE: This change should only affect those binaries that use
sigcontext and/or ucontext_t. In the source tree itself
this is only doscmd. Recompilation is required for those
applications.
This commit also fixes a lot of style bugs without hopefully
adding new ones.
NOTE: struct sigaltstack.ss_size now has type size_t again. For
some reason I changed that into unsigned int.
Parts submitted by: bde
sigaltstack bug found by: bde
Diffstat (limited to 'sys/alpha')
-rw-r--r-- | sys/alpha/alpha/machdep.c | 44 | ||||
-rw-r--r-- | sys/alpha/include/reg.h | 9 | ||||
-rw-r--r-- | sys/alpha/include/signal.h | 26 | ||||
-rw-r--r-- | sys/alpha/include/ucontext.h | 26 |
4 files changed, 82 insertions, 23 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index 85262fe..ce72dce 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -1269,7 +1269,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) struct trapframe *frame; struct sigacts *psp; struct sigframe sf, *sfp; - int rndfsize; + int onstack, rndfsize; p = curproc; @@ -1280,13 +1280,26 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) frame = p->p_md.md_tf; psp = p->p_sigacts; + onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; 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 = psp->ps_sigstk; - sf.sf_uc.uc_mcontext.mc_tf = *frame; + sf.sf_uc.uc_mcontext.mc_onstack = onstack; + + fill_regs(p, (struct reg *)sf.sf_uc.uc_mcontext.mc_regs); + sf.sf_uc.uc_mcontext.mc_regs[R_SP] = alpha_pal_rdusp(); + sf.sf_uc.uc_mcontext.mc_regs[R_ZERO] = 0xACEDBADE; /* magic number */ + sf.sf_uc.uc_mcontext.mc_regs[R_PS] = frame->tf_regs[FRAME_PS]; + sf.sf_uc.uc_mcontext.mc_regs[R_PC] = frame->tf_regs[FRAME_PC]; + sf.sf_uc.uc_mcontext.mc_regs[R_TRAPARG_A0] = + frame->tf_regs[FRAME_TRAPARG_A0]; + sf.sf_uc.uc_mcontext.mc_regs[R_TRAPARG_A1] = + frame->tf_regs[FRAME_TRAPARG_A1]; + sf.sf_uc.uc_mcontext.mc_regs[R_TRAPARG_A2] = + frame->tf_regs[FRAME_TRAPARG_A2]; /* * Allocate and validate space for the signal handler @@ -1295,8 +1308,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) * will fail if the process has not already allocated * the space with a `brk'. */ - if ((psp->ps_flags & SAS_ALTSTACK) != 0 && - (psp->ps_sigstk.ss_flags & SS_ONSTACK) == 0 && + if ((psp->ps_flags & SAS_ALTSTACK) != 0 && !onstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { sfp = (struct sigframe *)((caddr_t)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - rndfsize); @@ -1328,8 +1340,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) return; } - sf.sf_uc.uc_mcontext.mc_tf.tf_regs[FRAME_SP] = alpha_pal_rdusp(); - /* save the floating-point state, if necessary, then copy it. */ if (p == fpcurproc) { alpha_pal_wrfen(1); @@ -1418,6 +1428,10 @@ osigreturn(struct proc *p, copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)) return (EINVAL); + /* + * XXX - Should we do this. What if we get a "handcrafted" + * but valid sigcontext that hasn't the magic number? + */ if (ksc.sc_regs[R_ZERO] != 0xACEDBADE) /* magic number */ return (EINVAL); /* @@ -1464,6 +1478,7 @@ sigreturn(struct proc *p, { ucontext_t uc, *ucp; struct pcb *pcb; + unsigned long val; ucp = uap->sigcntxp; @@ -1491,13 +1506,18 @@ sigreturn(struct proc *p, /* * Restore the user-supplied information */ - *p->p_md.md_tf = uc.uc_mcontext.mc_tf; - p->p_md.md_tf->tf_regs[FRAME_PS] |= ALPHA_PSL_USERSET; - p->p_md.md_tf->tf_regs[FRAME_PS] &= ~ALPHA_PSL_USERCLR; - pcb->pcb_hw.apcb_usp = p->p_md.md_tf->tf_regs[FRAME_SP]; - alpha_pal_wrusp(pcb->pcb_hw.apcb_usp); + set_regs(p, (struct reg *)uc.uc_mcontext.mc_regs); + val = (uc.uc_mcontext.mc_regs[R_PS] | ALPHA_PSL_USERSET) & + ~ALPHA_PSL_USERCLR; + p->p_md.md_tf->tf_regs[FRAME_PS] = val; + 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 (uc.uc_mcontext.mc_onstack & 1) + p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; + else + p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; - p->p_sigacts->ps_sigstk = uc.uc_stack; p->p_sigmask = uc.uc_sigmask; SIG_CANTMASK(p->p_sigmask); diff --git a/sys/alpha/include/reg.h b/sys/alpha/include/reg.h index 341a396..879aeed 100644 --- a/sys/alpha/include/reg.h +++ b/sys/alpha/include/reg.h @@ -73,6 +73,15 @@ #define R_SP 30 #define R_ZERO 31 +/* + * Register extensions used in mcontext_t + */ +#define R_PS 32 +#define R_PC 33 +#define R_TRAPARG_A0 34 +#define R_TRAPARG_A1 35 +#define R_TRAPARG_A2 36 + struct reg { u_int64_t r_regs[32]; }; diff --git a/sys/alpha/include/signal.h b/sys/alpha/include/signal.h index 90a5a39..2e01864 100644 --- a/sys/alpha/include/signal.h +++ b/sys/alpha/include/signal.h @@ -32,6 +32,7 @@ #define _ALPHA_SIGNAL_H_ typedef long sig_atomic_t; + #ifndef _ANSI_SOURCE /* @@ -52,7 +53,6 @@ struct osigcontext { long sc_pc; /* pc to restore */ long sc_ps; /* ps to restore */ unsigned long sc_regs[32]; /* integer register set (see above) */ -#define sc_sp sc_regs[R_SP] long sc_ownedfp; /* fp has been used */ unsigned long sc_fpregs[32]; /* FP register set (see above) */ unsigned long sc_fpcr; /* FP control register (see above) */ @@ -65,5 +65,29 @@ struct osigcontext { long sc_xxx2[3]; /* sc_fp_trap_pc, sc_fp_trigger_sum, sc_fp_trigger_inst */ }; +/* + * The sequence of the fields should match those in + * mcontext_t. Keep them in sync! + */ +struct sigcontext { + sigset_t sc_mask; /* signal mask to restore */ + long sc_onstack; /* sigstack state to restore */ + unsigned long sc_regs[32]; /* integer register set (see above) */ + long sc_ps; /* ps to restore */ + long sc_pc; /* pc to restore */ + unsigned long sc_traparg_a0; /* a0 argument to trap at exception */ + unsigned long sc_traparg_a1; /* a1 argument to trap at exception */ + unsigned long sc_traparg_a2; /* a2 argument to trap at exception */ + unsigned long sc_fpregs[32]; /* FP register set (see above) */ + unsigned long sc_fpcr; /* FP control register (see above) */ + unsigned long sc_fp_control; /* FP software control word */ + long sc_ownedfp; /* fp has been used */ + long sc_xxx1[2]; /* sc_ssize, sc_sbase on DUX */ + long sc_xxx2[3]; /* sc_fp_trap_pc, sc_fp_trigger_sum, sc_fp_trigger_inst */ + long sc_reserved[2]; /* XXX */ +}; + +#define sc_sp sc_regs[R_SP] + #endif /* !_ANSI_SOURCE */ #endif /* !_ALPHA_SIGNAL_H_*/ diff --git a/sys/alpha/include/ucontext.h b/sys/alpha/include/ucontext.h index 66b9e51..40a9037 100644 --- a/sys/alpha/include/ucontext.h +++ b/sys/alpha/include/ucontext.h @@ -29,18 +29,24 @@ */ #ifndef _MACHINE_UCONTEXT_H_ -#define _MACHINE_UCONTEXT_H_ 1 +#define _MACHINE_UCONTEXT_H_ #include <machine/frame.h> -typedef struct { - struct trapframe mc_tf; - unsigned long mc_fpregs[32]; - unsigned long mc_fpcr; - unsigned long mc_fp_control; - unsigned long mc_apcb_usp; - long mc_ownedfp; - long __spare__[8]; +typedef struct __mcontext { + /* + * These fields must match the definition + * of struct sigcontext. That way we can support + * struct sigcontext and ucontext_t at the same + * time. + */ + long mc_onstack; /* XXX - sigcontext compat. */ + unsigned long mc_regs[37]; + unsigned long mc_fpregs[32]; + unsigned long mc_fpcr; + unsigned long mc_fp_control; + long mc_ownedfp; + long __spare__[7]; } mcontext_t; -#endif /* _MACHINE_UCONTEXT_H_ */ +#endif /* !_MACHINE_UCONTEXT_H_ */ |