From 05e89da65f3f17ac5d45847a1070dff333d05e7a Mon Sep 17 00:00:00 2001 From: marcel Date: Mon, 4 Oct 1999 19:33:58 +0000 Subject: 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 --- sys/alpha/alpha/machdep.c | 44 +++++++++++++----- sys/alpha/include/reg.h | 9 ++++ sys/alpha/include/signal.h | 26 ++++++++++- sys/alpha/include/ucontext.h | 26 +++++++---- sys/amd64/amd64/genassym.c | 6 +-- sys/amd64/amd64/machdep.c | 17 ++++--- sys/amd64/include/signal.h | 73 ++++++++++++++++++++--------- sys/amd64/include/ucontext.h | 21 ++++++--- sys/i386/i386/genassym.c | 6 +-- sys/i386/i386/machdep.c | 17 ++++--- sys/i386/include/signal.h | 73 ++++++++++++++++++++--------- sys/i386/include/ucontext.h | 21 ++++++--- sys/pc98/i386/machdep.c | 17 ++++--- sys/pc98/pc98/machdep.c | 17 ++++--- sys/sys/_sigset.h | 106 +++++++++++++++++++++++-------------------- sys/sys/signal.h | 106 +++++++++++++++++++++++-------------------- sys/sys/ucontext.h | 23 +++++++--- 17 files changed, 390 insertions(+), 218 deletions(-) (limited to 'sys') 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 -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_ */ diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 62dbf53..8299177 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -69,11 +69,10 @@ #include #endif #include +#include #include #include -#include - #define OS(s, m) ((u_int)offsetof(struct s, m)) int main __P((void)); @@ -157,7 +156,8 @@ main() printf("#define\tSC_FS %#x\n", OS(osigcontext, sc_fs)); printf("#define\tSC_GS %#x\n", OS(osigcontext, sc_gs)); - printf("#define\tUC_EFLAGS %#x\n", OS(__ucontext, uc_mcontext.mc_tf.tf_eflags)); + printf("#define\tUC_EFLAGS %#x\n", + OS(__ucontext, uc_mcontext.mc_tf.tf_eflags)); printf("#define\tUC_GS %#x\n", OS(__ucontext, uc_mcontext.mc_gs)); printf("#define\tB_READ %#x\n", B_READ); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 8b6bb84..1ef6fb0 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -613,6 +613,7 @@ sendsig(catcher, sig, mask, code) struct trapframe *regs; struct sigacts *psp; struct sigframe sf, *sfp; + int onstack; p = curproc; @@ -623,17 +624,18 @@ sendsig(catcher, sig, mask, code) regs = p->p_md.md_regs; psp = p->p_sigacts; + onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; /* 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_onstack = onstack; sf.sf_uc.uc_mcontext.mc_tf = *regs; sf.sf_uc.uc_mcontext.mc_gs = rgs(); /* Allocate and validate space for the signal handler context. */ - 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 *)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct sigframe)); @@ -884,16 +886,13 @@ sigreturn(p, uap) { struct trapframe *regs; ucontext_t *ucp; - struct sigframe *sfp; int cs, eflags; regs = p->p_md.md_regs; ucp = uap->sigcntxp; - sfp = (struct sigframe *) - ((caddr_t)ucp - offsetof(struct sigframe, sf_uc)); eflags = ucp->uc_mcontext.mc_tf.tf_eflags; - if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0) + if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0) return(EFAULT); if (eflags & PSL_VM) { @@ -963,7 +962,11 @@ sigreturn(p, uap) *regs = ucp->uc_mcontext.mc_tf; } - p->p_sigacts->ps_sigstk = ucp->uc_stack; + if (ucp->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_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); return(EJUSTRETURN); diff --git a/sys/amd64/include/signal.h b/sys/amd64/include/signal.h index e9f739e..f02539e 100644 --- a/sys/amd64/include/signal.h +++ b/sys/amd64/include/signal.h @@ -57,33 +57,62 @@ typedef int sig_atomic_t; typedef unsigned int osigset_t; struct osigcontext { - int sc_onstack; /* sigstack state to restore */ - osigset_t sc_mask; /* signal mask to restore */ - int sc_esp; /* machine state */ - int sc_ebp; - int sc_isp; - int sc_eip; - int sc_efl; - int sc_es; - int sc_ds; - int sc_cs; - int sc_ss; - int sc_edi; - int sc_esi; - int sc_ebx; - int sc_edx; - int sc_ecx; - int sc_eax; - int sc_gs; - int sc_fs; + int sc_onstack; /* sigstack state to restore */ + osigset_t sc_mask; /* signal mask to restore */ + int sc_esp; /* machine state */ + int sc_ebp; + int sc_isp; + int sc_eip; + int sc_efl; + int sc_es; + int sc_ds; + int sc_cs; + int sc_ss; + int sc_edi; + int sc_esi; + int sc_ebx; + int sc_edx; + int sc_ecx; + int sc_eax; + int sc_gs; + int sc_fs; + int sc_trapno; + int sc_err; +}; + +/* + * The sequence of the fields/registers in sigcontext should match + * those in mcontext_t. + */ +struct sigcontext { + sigset_t sc_mask; /* signal mask to restore */ + int sc_onstack; /* sigstack state to restore */ + int sc_gs; + int sc_fs; + int sc_es; + int sc_ds; + int sc_edi; + int sc_esi; + int sc_ebp; + int sc_isp; + int sc_ebx; + int sc_edx; + int sc_ecx; + int sc_eax; + int sc_trapno; + int sc_err; + int sc_eip; + int sc_cs; + int sc_efl; + int sc_esp; /* machine state */ + int sc_ss; +}; + #define sc_sp sc_esp #define sc_fp sc_ebp #define sc_pc sc_eip #define sc_ps sc_efl #define sc_eflags sc_efl - int sc_trapno; - int sc_err; -}; #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ diff --git a/sys/amd64/include/ucontext.h b/sys/amd64/include/ucontext.h index bdf2e1d..0d72716 100644 --- a/sys/amd64/include/ucontext.h +++ b/sys/amd64/include/ucontext.h @@ -29,15 +29,22 @@ */ #ifndef _MACHINE_UCONTEXT_H_ -#define _MACHINE_UCONTEXT_H_ 1 +#define _MACHINE_UCONTEXT_H_ #include -typedef struct { - int mc_gs; /* %gs */ - struct trapframe mc_tf; /* trapframe */ - int mc_fpregs[28]; /* env87 + fpacc87 + u_long */ - int __spare__[17]; +typedef struct __mcontext { + /* + * The first 3 fields must match the definition of + * sigcontext. So that we can support sigcontext + * and ucontext_t at the same time. + */ + int mc_onstack; /* XXX - sigcontext compat. */ + int mc_gs; + struct trapframe mc_tf; + + int mc_fpregs[28]; /* env87 + fpacc87 + u_long */ + int __spare__[17]; } mcontext_t; -#endif /* _MACHINE_UCONTEXT_H_ */ +#endif /* !_MACHINE_UCONTEXT_H_ */ diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c index 62dbf53..8299177 100644 --- a/sys/i386/i386/genassym.c +++ b/sys/i386/i386/genassym.c @@ -69,11 +69,10 @@ #include #endif #include +#include #include #include -#include - #define OS(s, m) ((u_int)offsetof(struct s, m)) int main __P((void)); @@ -157,7 +156,8 @@ main() printf("#define\tSC_FS %#x\n", OS(osigcontext, sc_fs)); printf("#define\tSC_GS %#x\n", OS(osigcontext, sc_gs)); - printf("#define\tUC_EFLAGS %#x\n", OS(__ucontext, uc_mcontext.mc_tf.tf_eflags)); + printf("#define\tUC_EFLAGS %#x\n", + OS(__ucontext, uc_mcontext.mc_tf.tf_eflags)); printf("#define\tUC_GS %#x\n", OS(__ucontext, uc_mcontext.mc_gs)); printf("#define\tB_READ %#x\n", B_READ); diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 8b6bb84..1ef6fb0 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -613,6 +613,7 @@ sendsig(catcher, sig, mask, code) struct trapframe *regs; struct sigacts *psp; struct sigframe sf, *sfp; + int onstack; p = curproc; @@ -623,17 +624,18 @@ sendsig(catcher, sig, mask, code) regs = p->p_md.md_regs; psp = p->p_sigacts; + onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; /* 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_onstack = onstack; sf.sf_uc.uc_mcontext.mc_tf = *regs; sf.sf_uc.uc_mcontext.mc_gs = rgs(); /* Allocate and validate space for the signal handler context. */ - 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 *)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct sigframe)); @@ -884,16 +886,13 @@ sigreturn(p, uap) { struct trapframe *regs; ucontext_t *ucp; - struct sigframe *sfp; int cs, eflags; regs = p->p_md.md_regs; ucp = uap->sigcntxp; - sfp = (struct sigframe *) - ((caddr_t)ucp - offsetof(struct sigframe, sf_uc)); eflags = ucp->uc_mcontext.mc_tf.tf_eflags; - if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0) + if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0) return(EFAULT); if (eflags & PSL_VM) { @@ -963,7 +962,11 @@ sigreturn(p, uap) *regs = ucp->uc_mcontext.mc_tf; } - p->p_sigacts->ps_sigstk = ucp->uc_stack; + if (ucp->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_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); return(EJUSTRETURN); diff --git a/sys/i386/include/signal.h b/sys/i386/include/signal.h index e9f739e..f02539e 100644 --- a/sys/i386/include/signal.h +++ b/sys/i386/include/signal.h @@ -57,33 +57,62 @@ typedef int sig_atomic_t; typedef unsigned int osigset_t; struct osigcontext { - int sc_onstack; /* sigstack state to restore */ - osigset_t sc_mask; /* signal mask to restore */ - int sc_esp; /* machine state */ - int sc_ebp; - int sc_isp; - int sc_eip; - int sc_efl; - int sc_es; - int sc_ds; - int sc_cs; - int sc_ss; - int sc_edi; - int sc_esi; - int sc_ebx; - int sc_edx; - int sc_ecx; - int sc_eax; - int sc_gs; - int sc_fs; + int sc_onstack; /* sigstack state to restore */ + osigset_t sc_mask; /* signal mask to restore */ + int sc_esp; /* machine state */ + int sc_ebp; + int sc_isp; + int sc_eip; + int sc_efl; + int sc_es; + int sc_ds; + int sc_cs; + int sc_ss; + int sc_edi; + int sc_esi; + int sc_ebx; + int sc_edx; + int sc_ecx; + int sc_eax; + int sc_gs; + int sc_fs; + int sc_trapno; + int sc_err; +}; + +/* + * The sequence of the fields/registers in sigcontext should match + * those in mcontext_t. + */ +struct sigcontext { + sigset_t sc_mask; /* signal mask to restore */ + int sc_onstack; /* sigstack state to restore */ + int sc_gs; + int sc_fs; + int sc_es; + int sc_ds; + int sc_edi; + int sc_esi; + int sc_ebp; + int sc_isp; + int sc_ebx; + int sc_edx; + int sc_ecx; + int sc_eax; + int sc_trapno; + int sc_err; + int sc_eip; + int sc_cs; + int sc_efl; + int sc_esp; /* machine state */ + int sc_ss; +}; + #define sc_sp sc_esp #define sc_fp sc_ebp #define sc_pc sc_eip #define sc_ps sc_efl #define sc_eflags sc_efl - int sc_trapno; - int sc_err; -}; #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ diff --git a/sys/i386/include/ucontext.h b/sys/i386/include/ucontext.h index bdf2e1d..0d72716 100644 --- a/sys/i386/include/ucontext.h +++ b/sys/i386/include/ucontext.h @@ -29,15 +29,22 @@ */ #ifndef _MACHINE_UCONTEXT_H_ -#define _MACHINE_UCONTEXT_H_ 1 +#define _MACHINE_UCONTEXT_H_ #include -typedef struct { - int mc_gs; /* %gs */ - struct trapframe mc_tf; /* trapframe */ - int mc_fpregs[28]; /* env87 + fpacc87 + u_long */ - int __spare__[17]; +typedef struct __mcontext { + /* + * The first 3 fields must match the definition of + * sigcontext. So that we can support sigcontext + * and ucontext_t at the same time. + */ + int mc_onstack; /* XXX - sigcontext compat. */ + int mc_gs; + struct trapframe mc_tf; + + int mc_fpregs[28]; /* env87 + fpacc87 + u_long */ + int __spare__[17]; } mcontext_t; -#endif /* _MACHINE_UCONTEXT_H_ */ +#endif /* !_MACHINE_UCONTEXT_H_ */ diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 416443c..2eefb15 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -627,6 +627,7 @@ sendsig(catcher, sig, mask, code) struct trapframe *regs; struct sigacts *psp; struct sigframe sf, *sfp; + int onstack; p = curproc; @@ -637,17 +638,18 @@ sendsig(catcher, sig, mask, code) regs = p->p_md.md_regs; psp = p->p_sigacts; + onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; /* 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_onstack = onstack; sf.sf_uc.uc_mcontext.mc_tf = *regs; sf.sf_uc.uc_mcontext.mc_gs = rgs(); /* Allocate and validate space for the signal handler context. */ - 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 *)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct sigframe)); @@ -897,16 +899,13 @@ sigreturn(p, uap) { struct trapframe *regs; ucontext_t *ucp; - struct sigframe *sfp; int cs, eflags; regs = p->p_md.md_regs; ucp = uap->sigcntxp; - sfp = (struct sigframe *) - ((caddr_t)ucp - offsetof(struct sigframe, sf_uc)); eflags = ucp->uc_mcontext.mc_tf.tf_eflags; - if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0) + if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0) return(EFAULT); if (eflags & PSL_VM) { @@ -976,7 +975,11 @@ sigreturn(p, uap) *regs = ucp->uc_mcontext.mc_tf; } - p->p_sigacts->ps_sigstk = ucp->uc_stack; + if (ucp->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_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); return(EJUSTRETURN); diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 416443c..2eefb15 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -627,6 +627,7 @@ sendsig(catcher, sig, mask, code) struct trapframe *regs; struct sigacts *psp; struct sigframe sf, *sfp; + int onstack; p = curproc; @@ -637,17 +638,18 @@ sendsig(catcher, sig, mask, code) regs = p->p_md.md_regs; psp = p->p_sigacts; + onstack = (psp->ps_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0; /* 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_onstack = onstack; sf.sf_uc.uc_mcontext.mc_tf = *regs; sf.sf_uc.uc_mcontext.mc_gs = rgs(); /* Allocate and validate space for the signal handler context. */ - 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 *)(psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size - sizeof(struct sigframe)); @@ -897,16 +899,13 @@ sigreturn(p, uap) { struct trapframe *regs; ucontext_t *ucp; - struct sigframe *sfp; int cs, eflags; regs = p->p_md.md_regs; ucp = uap->sigcntxp; - sfp = (struct sigframe *) - ((caddr_t)ucp - offsetof(struct sigframe, sf_uc)); eflags = ucp->uc_mcontext.mc_tf.tf_eflags; - if (useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == 0) + if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0) return(EFAULT); if (eflags & PSL_VM) { @@ -976,7 +975,11 @@ sigreturn(p, uap) *regs = ucp->uc_mcontext.mc_tf; } - p->p_sigacts->ps_sigstk = ucp->uc_stack; + if (ucp->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_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); return(EJUSTRETURN); diff --git a/sys/sys/_sigset.h b/sys/sys/_sigset.h index 8d1e773..edddbbe 100644 --- a/sys/sys/_sigset.h +++ b/sys/sys/_sigset.h @@ -44,22 +44,20 @@ #include #include -#include -#include /* sig_atomic_t; trap codes; sigcontext */ /* - * sigset_t macros + * sigset_t macros. */ -#define _SIG_WORDS 4 -#define _SIG_MAXSIG 128 -#define _SIG_IDX(sig) ((sig) - 1) -#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5) -#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31)) +#define _SIG_WORDS 4 +#define _SIG_MAXSIG 128 +#define _SIG_IDX(sig) ((sig) - 1) +#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5) +#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31)) /* - * system defined signals + * System defined signals. */ -#define SIGHUP 1 /* hangup */ +#define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instr. (not reset when caught) */ @@ -98,11 +96,11 @@ #define SIGXFSZ 25 /* exceeded file size limit */ #define SIGVTALRM 26 /* virtual time alarm */ #define SIGPROF 27 /* profiling time alarm */ -#define SIGWINCH 28 /* window size changes */ -#define SIGINFO 29 /* information request */ +#define SIGWINCH 28 /* window size changes */ +#define SIGINFO 29 /* information request */ #endif -#define SIGUSR1 30 /* user defined signal 1 */ -#define SIGUSR2 31 /* user defined signal 2 */ +#define SIGUSR1 30 /* user defined signal 1 */ +#define SIGUSR2 31 /* user defined signal 2 */ /*- * Type of a signal handling function. @@ -124,50 +122,62 @@ typedef void __sighandler_t __P((int)); #define SIG_DFL ((__sighandler_t *)0) #define SIG_IGN ((__sighandler_t *)1) -#define SIG_HOLD ((__sighandler_t *)2) +#define SIG_HOLD ((__sighandler_t *)2) #define SIG_ERR ((__sighandler_t *)-1) +#ifndef _POSIX_SOURCE union sigval { /* Members as suggested by Annex C of POSIX 1003.1b. */ - int sigval_int; - void *sigval_ptr; + int sigval_int; + void *sigval_ptr; }; -typedef struct { - int si_signo; /* signal number */ - int si_errno; /* errno association */ +typedef struct __siginfo { + int si_signo; /* signal number */ + int si_errno; /* errno association */ /* * Cause of signal, one of the SI_ macros or signal-specific * values, i.e. one of the FPE_... values for SIGFPE. This * value is equivalent to the second argument to an old-style * FreeBSD signal handler. */ - int si_code; /* signal code */ - pid_t si_pid; /* sending process */ - uid_t si_uid; /* sender's ruid */ - int si_status; /* exit value */ - void *si_addr; /* faulting instruction */ - union sigval si_value; /* signal value */ - long si_band; /* band event for SIGPOLL */ - int __spare__[7]; /* gimme some slack */ + int si_code; /* signal code */ + int si_pid; /* sending process */ + unsigned int si_uid; /* sender's ruid */ + int si_status; /* exit value */ + void *si_addr; /* faulting instruction */ + union sigval si_value; /* signal value */ + long si_band; /* band event for SIGPOLL */ + int __spare__[7]; /* gimme some slack */ } siginfo_t; +#endif -typedef struct { +typedef struct __sigset { unsigned int __bits[_SIG_WORDS]; } sigset_t; +/* + * XXX - there are some nasty dependencies. + * Now that sigset_t has been defined we can + * include the MD structures. + */ +#include /* sig_atomic_t; trap codes; sigcontext */ + #if !defined(_ANSI_SOURCE) +struct __siginfo; + /* * Signal vector "template" used in sigaction call. */ struct sigaction { union { void (*__sa_handler) __P((int)); - void (*__sa_sigaction) __P((int, siginfo_t *, void *)); + void (*__sa_sigaction) __P((int, struct __siginfo *, + void *)); } __sigaction_u; /* signal handler */ - int sa_flags; /* see signal options below */ - sigset_t sa_mask; /* signal mask to apply */ + int sa_flags; /* see signal options below */ + sigset_t sa_mask; /* signal mask to apply */ }; /* if SA_SIGINFO is set, sa_sigaction is to be used instead of sa_handler. */ @@ -189,7 +199,7 @@ struct sigaction { #define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ #endif -#define NSIG 32 +#define NSIG 32 /* number of old signals (counting 0) */ /* POSIX 1003.1b required values. */ #define SI_USER 0x10001 @@ -211,12 +221,12 @@ typedef _BSD_SIZE_T_ size_t; #endif /* - * sigaltstack + * Structure used in sigaltstack call. */ typedef struct sigaltstack { - char *ss_sp; /* signal stack base */ - unsigned int ss_size; /* signal stack length */ - int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ + char *ss_sp; /* signal stack base */ + size_t ss_size; /* signal stack length */ + int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ } stack_t; #define SS_ONSTACK 0x0001 /* take signal on alternate stack */ @@ -224,9 +234,7 @@ typedef struct sigaltstack { #define MINSIGSTKSZ 8192 /* minimum allowable stack */ #define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */ -/* - * Suck in definition of ucontext_t - */ +/* Have enough typedefs for this now. XXX */ #include /* @@ -234,9 +242,9 @@ typedef struct sigaltstack { * Signal vector "template" used in sigvec call. */ struct sigvec { - __sighandler_t *sv_handler; /* signal handler */ - int sv_mask; /* signal mask to apply */ - int sv_flags; /* see signal options below */ + __sighandler_t *sv_handler; /* signal handler */ + int sv_mask; /* signal mask to apply */ + int sv_flags; /* see signal options below */ }; #define SV_ONSTACK SA_ONSTACK @@ -251,8 +259,8 @@ struct sigvec { * Structure used in sigstack call. */ struct sigstack { - char *ss_sp; /* signal stack pointer */ - int ss_onstack; /* current status */ + char *ss_sp; /* signal stack pointer */ + int ss_onstack; /* current status */ }; /* @@ -272,14 +280,16 @@ struct sigstack { #define SIG_UNBLOCK 2 /* unblock specified signal set */ #define SIG_SETMASK 3 /* set specified signal set */ +#ifndef _POSIX_SOURCE struct sigevent { - int sigev_notify; /* Notification type */ - int sigev_signo; /* Signal number */ - union sigval sigev_value; /* Signal value */ + int sigev_notify; /* Notification type */ + int sigev_signo; /* Signal number */ + union sigval sigev_value; /* Signal value */ }; #define SIGEV_NONE 0 /* No async notification */ #define SIGEV_SIGNAL 1 /* Generate a queued signal */ +#endif #endif /* !_ANSI_SOURCE */ diff --git a/sys/sys/signal.h b/sys/sys/signal.h index 8d1e773..edddbbe 100644 --- a/sys/sys/signal.h +++ b/sys/sys/signal.h @@ -44,22 +44,20 @@ #include #include -#include -#include /* sig_atomic_t; trap codes; sigcontext */ /* - * sigset_t macros + * sigset_t macros. */ -#define _SIG_WORDS 4 -#define _SIG_MAXSIG 128 -#define _SIG_IDX(sig) ((sig) - 1) -#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5) -#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31)) +#define _SIG_WORDS 4 +#define _SIG_MAXSIG 128 +#define _SIG_IDX(sig) ((sig) - 1) +#define _SIG_WORD(sig) (_SIG_IDX(sig) >> 5) +#define _SIG_BIT(sig) (1 << (_SIG_IDX(sig) & 31)) /* - * system defined signals + * System defined signals. */ -#define SIGHUP 1 /* hangup */ +#define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instr. (not reset when caught) */ @@ -98,11 +96,11 @@ #define SIGXFSZ 25 /* exceeded file size limit */ #define SIGVTALRM 26 /* virtual time alarm */ #define SIGPROF 27 /* profiling time alarm */ -#define SIGWINCH 28 /* window size changes */ -#define SIGINFO 29 /* information request */ +#define SIGWINCH 28 /* window size changes */ +#define SIGINFO 29 /* information request */ #endif -#define SIGUSR1 30 /* user defined signal 1 */ -#define SIGUSR2 31 /* user defined signal 2 */ +#define SIGUSR1 30 /* user defined signal 1 */ +#define SIGUSR2 31 /* user defined signal 2 */ /*- * Type of a signal handling function. @@ -124,50 +122,62 @@ typedef void __sighandler_t __P((int)); #define SIG_DFL ((__sighandler_t *)0) #define SIG_IGN ((__sighandler_t *)1) -#define SIG_HOLD ((__sighandler_t *)2) +#define SIG_HOLD ((__sighandler_t *)2) #define SIG_ERR ((__sighandler_t *)-1) +#ifndef _POSIX_SOURCE union sigval { /* Members as suggested by Annex C of POSIX 1003.1b. */ - int sigval_int; - void *sigval_ptr; + int sigval_int; + void *sigval_ptr; }; -typedef struct { - int si_signo; /* signal number */ - int si_errno; /* errno association */ +typedef struct __siginfo { + int si_signo; /* signal number */ + int si_errno; /* errno association */ /* * Cause of signal, one of the SI_ macros or signal-specific * values, i.e. one of the FPE_... values for SIGFPE. This * value is equivalent to the second argument to an old-style * FreeBSD signal handler. */ - int si_code; /* signal code */ - pid_t si_pid; /* sending process */ - uid_t si_uid; /* sender's ruid */ - int si_status; /* exit value */ - void *si_addr; /* faulting instruction */ - union sigval si_value; /* signal value */ - long si_band; /* band event for SIGPOLL */ - int __spare__[7]; /* gimme some slack */ + int si_code; /* signal code */ + int si_pid; /* sending process */ + unsigned int si_uid; /* sender's ruid */ + int si_status; /* exit value */ + void *si_addr; /* faulting instruction */ + union sigval si_value; /* signal value */ + long si_band; /* band event for SIGPOLL */ + int __spare__[7]; /* gimme some slack */ } siginfo_t; +#endif -typedef struct { +typedef struct __sigset { unsigned int __bits[_SIG_WORDS]; } sigset_t; +/* + * XXX - there are some nasty dependencies. + * Now that sigset_t has been defined we can + * include the MD structures. + */ +#include /* sig_atomic_t; trap codes; sigcontext */ + #if !defined(_ANSI_SOURCE) +struct __siginfo; + /* * Signal vector "template" used in sigaction call. */ struct sigaction { union { void (*__sa_handler) __P((int)); - void (*__sa_sigaction) __P((int, siginfo_t *, void *)); + void (*__sa_sigaction) __P((int, struct __siginfo *, + void *)); } __sigaction_u; /* signal handler */ - int sa_flags; /* see signal options below */ - sigset_t sa_mask; /* signal mask to apply */ + int sa_flags; /* see signal options below */ + sigset_t sa_mask; /* signal mask to apply */ }; /* if SA_SIGINFO is set, sa_sigaction is to be used instead of sa_handler. */ @@ -189,7 +199,7 @@ struct sigaction { #define SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ #endif -#define NSIG 32 +#define NSIG 32 /* number of old signals (counting 0) */ /* POSIX 1003.1b required values. */ #define SI_USER 0x10001 @@ -211,12 +221,12 @@ typedef _BSD_SIZE_T_ size_t; #endif /* - * sigaltstack + * Structure used in sigaltstack call. */ typedef struct sigaltstack { - char *ss_sp; /* signal stack base */ - unsigned int ss_size; /* signal stack length */ - int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ + char *ss_sp; /* signal stack base */ + size_t ss_size; /* signal stack length */ + int ss_flags; /* SS_DISABLE and/or SS_ONSTACK */ } stack_t; #define SS_ONSTACK 0x0001 /* take signal on alternate stack */ @@ -224,9 +234,7 @@ typedef struct sigaltstack { #define MINSIGSTKSZ 8192 /* minimum allowable stack */ #define SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended stack size */ -/* - * Suck in definition of ucontext_t - */ +/* Have enough typedefs for this now. XXX */ #include /* @@ -234,9 +242,9 @@ typedef struct sigaltstack { * Signal vector "template" used in sigvec call. */ struct sigvec { - __sighandler_t *sv_handler; /* signal handler */ - int sv_mask; /* signal mask to apply */ - int sv_flags; /* see signal options below */ + __sighandler_t *sv_handler; /* signal handler */ + int sv_mask; /* signal mask to apply */ + int sv_flags; /* see signal options below */ }; #define SV_ONSTACK SA_ONSTACK @@ -251,8 +259,8 @@ struct sigvec { * Structure used in sigstack call. */ struct sigstack { - char *ss_sp; /* signal stack pointer */ - int ss_onstack; /* current status */ + char *ss_sp; /* signal stack pointer */ + int ss_onstack; /* current status */ }; /* @@ -272,14 +280,16 @@ struct sigstack { #define SIG_UNBLOCK 2 /* unblock specified signal set */ #define SIG_SETMASK 3 /* set specified signal set */ +#ifndef _POSIX_SOURCE struct sigevent { - int sigev_notify; /* Notification type */ - int sigev_signo; /* Signal number */ - union sigval sigev_value; /* Signal value */ + int sigev_notify; /* Notification type */ + int sigev_signo; /* Signal number */ + union sigval sigev_value; /* Signal value */ }; #define SIGEV_NONE 0 /* No async notification */ #define SIGEV_SIGNAL 1 /* Generate a queued signal */ +#endif #endif /* !_ANSI_SOURCE */ diff --git a/sys/sys/ucontext.h b/sys/sys/ucontext.h index fda8bcd..b28c685 100644 --- a/sys/sys/ucontext.h +++ b/sys/sys/ucontext.h @@ -29,16 +29,25 @@ */ #ifndef _SYS_UCONTEXT_H_ -#define _SYS_UCONTEXT_H_ 1 +#define _SYS_UCONTEXT_H_ #include typedef struct __ucontext { - struct __ucontext *uc_link; - stack_t uc_stack; - sigset_t uc_sigmask; - mcontext_t uc_mcontext; - int __spare__[8]; + /* + * Keep the order of the first three fields. Also, + * keep them the first to fields in the structure. + * This way we can have a union with struct + * sigcontext and ucontext_t. This allows us to + * support them both at the same time. + * note: the union is not defined, though. + */ + sigset_t uc_sigmask; + stack_t uc_stack; + mcontext_t uc_mcontext; + + struct __ucontext_t *uc_link; + int __spare__[8]; } ucontext_t; -#endif /* _SYS_UCONTEXT_H_ */ +#endif /* !_SYS_UCONTEXT_H_ */ -- cgit v1.1