From c5c6b7b38e4bca2844dc9f7e10f5791100c72b4c Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar 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/amd64/amd64/genassym.c | 6 ++-- sys/amd64/amd64/machdep.c | 17 ++++++----- sys/amd64/include/signal.h | 73 +++++++++++++++++++++++++++++++------------- sys/amd64/include/ucontext.h | 21 ++++++++----- 4 files changed, 78 insertions(+), 39 deletions(-) (limited to 'sys/amd64') diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 62dbf5369c41..829917721f0a 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 8b6bb842d77a..1ef6fb08aa2d 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 e9f739e3a0b9..f02539e079ec 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 bdf2e1df2307..0d7271621232 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_ */ -- cgit v1.3