summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>1999-10-04 19:33:58 +0000
committermarcel <marcel@FreeBSD.org>1999-10-04 19:33:58 +0000
commit05e89da65f3f17ac5d45847a1070dff333d05e7a (patch)
tree5374ca102220e75048c919ed852c428f9646cddf /sys/alpha
parent77802960193ff746b91be4aae32ed2a9ed8b5090 (diff)
downloadFreeBSD-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.c44
-rw-r--r--sys/alpha/include/reg.h9
-rw-r--r--sys/alpha/include/signal.h26
-rw-r--r--sys/alpha/include/ucontext.h26
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_ */
OpenPOWER on IntegriCloud