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/amd64 | |
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/amd64')
-rw-r--r-- | sys/amd64/amd64/genassym.c | 6 | ||||
-rw-r--r-- | sys/amd64/amd64/machdep.c | 17 | ||||
-rw-r--r-- | sys/amd64/include/signal.h | 73 | ||||
-rw-r--r-- | sys/amd64/include/ucontext.h | 21 |
4 files changed, 78 insertions, 39 deletions
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 <machine/apic.h> #endif #include <machine/segments.h> +#include <machine/sigframe.h> #include <machine/globaldata.h> #include <machine/vm86.h> -#include <machine/sigframe.h> - #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 <machine/frame.h> -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_ */ |