summaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2002-10-25 19:10:58 +0000
committerPeter Wemm <peter@FreeBSD.org>2002-10-25 19:10:58 +0000
commit23eeeff7bee66bd81fa2d7ec9d648339bd0d041f (patch)
tree96a1089f558875f808b1fd36f885179cd78f55de /sys/amd64
parentfb3a308a4ac3ca2c6fcd097a2990d7ea52ab230f (diff)
Notes
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/genassym.c9
-rw-r--r--sys/amd64/amd64/locore.S26
-rw-r--r--sys/amd64/amd64/locore.s26
-rw-r--r--sys/amd64/amd64/machdep.c276
-rw-r--r--sys/amd64/include/md_var.h8
-rw-r--r--sys/amd64/include/sigframe.h18
-rw-r--r--sys/amd64/include/signal.h4
-rw-r--r--sys/amd64/include/ucontext.h28
8 files changed, 363 insertions, 32 deletions
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index d4aa9e3da060..5a8cf704dd22 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -37,6 +37,7 @@
* $FreeBSD$
*/
+#include "opt_compat.h"
#include "opt_kstack_pages.h"
#include <sys/param.h>
@@ -151,12 +152,20 @@ ASSYM(TF_ERR, offsetof(struct trapframe, tf_err));
ASSYM(TF_CS, offsetof(struct trapframe, tf_cs));
ASSYM(TF_EFLAGS, offsetof(struct trapframe, tf_eflags));
ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler));
+#ifdef COMPAT_43
ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc));
+#endif
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
+#ifdef COMPAT_43
ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps));
ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs));
ASSYM(SC_GS, offsetof(struct osigcontext, sc_gs));
ASSYM(SC_TRAPNO, offsetof(struct osigcontext, sc_trapno));
+#endif
+#ifdef COMPAT_FREEBSD4
+ASSYM(UC4_EFLAGS, offsetof(struct ucontext4, uc_mcontext.mc_eflags));
+ASSYM(UC4_GS, offsetof(struct ucontext4, uc_mcontext.mc_gs));
+#endif
ASSYM(UC_EFLAGS, offsetof(ucontext_t, uc_mcontext.mc_eflags));
ASSYM(UC_GS, offsetof(ucontext_t, uc_mcontext.mc_gs));
ASSYM(ENOENT, ENOENT);
diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S
index 5d5b39ed5fd9..8f1d801268b3 100644
--- a/sys/amd64/amd64/locore.S
+++ b/sys/amd64/amd64/locore.S
@@ -406,6 +406,22 @@ NON_GPROF_ENTRY(sigcode)
int $0x80 /* enter kernel with args */
0: jmp 0b
+#ifdef COMPAT_FREEBSD4
+ ALIGN_TEXT
+freebsd4_sigcode:
+ call *SIGF_HANDLER(%esp) /* call signal handler */
+ lea SIGF_UC(%esp),%eax /* get ucontext_t */
+ pushl %eax
+ testl $PSL_VM,UC4_EFLAGS(%eax)
+ jne 9f
+ movl UC4_GS(%eax),%gs /* restore %gs */
+9:
+ movl $344,%eax /* 4.x SYS_sigreturn */
+ pushl %eax /* junk to fake return addr. */
+ int $0x80 /* enter kernel with args */
+0: jmp 0b
+#endif
+
#ifdef COMPAT_43
ALIGN_TEXT
osigcode:
@@ -416,7 +432,7 @@ osigcode:
jne 9f
movl SC_GS(%eax),%gs /* restore %gs */
9:
- movl $SYS_osigreturn,%eax
+ movl $103,%eax /* 3.x SYS_sigreturn */
pushl %eax /* junk to fake return addr. */
int $0x80 /* enter kernel with args */
0: jmp 0b
@@ -426,10 +442,16 @@ osigcode:
esigcode:
.data
- .globl szsigcode, szosigcode
+ .globl szsigcode
szsigcode:
.long esigcode-sigcode
+#ifdef COMPAT_FREEBSD4
+ .globl szfreebsd4_sigcode
+szfreebsd4_sigcode:
+ .long esigcode-freebsd4_sigcode
+#endif
#ifdef COMPAT_43
+ .globl szosigcode
szosigcode:
.long esigcode-osigcode
#endif
diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s
index 5d5b39ed5fd9..8f1d801268b3 100644
--- a/sys/amd64/amd64/locore.s
+++ b/sys/amd64/amd64/locore.s
@@ -406,6 +406,22 @@ NON_GPROF_ENTRY(sigcode)
int $0x80 /* enter kernel with args */
0: jmp 0b
+#ifdef COMPAT_FREEBSD4
+ ALIGN_TEXT
+freebsd4_sigcode:
+ call *SIGF_HANDLER(%esp) /* call signal handler */
+ lea SIGF_UC(%esp),%eax /* get ucontext_t */
+ pushl %eax
+ testl $PSL_VM,UC4_EFLAGS(%eax)
+ jne 9f
+ movl UC4_GS(%eax),%gs /* restore %gs */
+9:
+ movl $344,%eax /* 4.x SYS_sigreturn */
+ pushl %eax /* junk to fake return addr. */
+ int $0x80 /* enter kernel with args */
+0: jmp 0b
+#endif
+
#ifdef COMPAT_43
ALIGN_TEXT
osigcode:
@@ -416,7 +432,7 @@ osigcode:
jne 9f
movl SC_GS(%eax),%gs /* restore %gs */
9:
- movl $SYS_osigreturn,%eax
+ movl $103,%eax /* 3.x SYS_sigreturn */
pushl %eax /* junk to fake return addr. */
int $0x80 /* enter kernel with args */
0: jmp 0b
@@ -426,10 +442,16 @@ osigcode:
esigcode:
.data
- .globl szsigcode, szosigcode
+ .globl szsigcode
szsigcode:
.long esigcode-sigcode
+#ifdef COMPAT_FREEBSD4
+ .globl szfreebsd4_sigcode
+szfreebsd4_sigcode:
+ .long esigcode-freebsd4_sigcode
+#endif
#ifdef COMPAT_43
+ .globl szosigcode
szosigcode:
.long esigcode-osigcode
#endif
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 80805a2048c5..ff69b568be79 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -165,6 +165,10 @@ int cold = 1;
#ifdef COMPAT_43
static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code);
#endif
+#ifdef COMPAT_FREEBSD4
+static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
+ u_long code);
+#endif
static int
sysctl_hw_physmem(SYSCTL_HANDLER_ARGS)
@@ -286,8 +290,7 @@ osendsig(catcher, sig, mask, code)
sigset_t *mask;
u_long code;
{
- struct osigframe sf;
- struct osigframe *fp;
+ struct osigframe sf, *fp;
struct proc *p;
struct thread *td;
struct sigacts *psp;
@@ -408,6 +411,129 @@ osendsig(catcher, sig, mask, code)
}
#endif /* COMPAT_43 */
+#ifdef COMPAT_FREEBSD4
+static void
+freebsd4_sendsig(catcher, sig, mask, code)
+ sig_t catcher;
+ int sig;
+ sigset_t *mask;
+ u_long code;
+{
+ struct sigframe4 sf, *sfp;
+ struct proc *p;
+ struct thread *td;
+ struct sigacts *psp;
+ struct trapframe *regs;
+ int oonstack;
+
+ td = curthread;
+ p = td->td_proc;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ psp = p->p_sigacts;
+ regs = td->td_frame;
+ oonstack = sigonstack(regs->tf_esp);
+
+ /* Save user context. */
+ bzero(&sf, sizeof(sf));
+ sf.sf_uc.uc_sigmask = *mask;
+ sf.sf_uc.uc_stack = p->p_sigstk;
+ sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
+ ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
+ sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
+ sf.sf_uc.uc_mcontext.mc_gs = rgs();
+ bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
+
+ /* Allocate space for the signal handler context. */
+ if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
+ SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ sfp = (struct sigframe4 *)(p->p_sigstk.ss_sp +
+ p->p_sigstk.ss_size - sizeof(struct sigframe4));
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
+ } else
+ sfp = (struct sigframe4 *)regs->tf_esp - 1;
+ PROC_UNLOCK(p);
+
+ /* Translate the signal if appropriate. */
+ if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
+ sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+
+ /* Build the argument list for the signal handler. */
+ sf.sf_signum = sig;
+ sf.sf_ucontext = (register_t)&sfp->sf_uc;
+ PROC_LOCK(p);
+ if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
+ /* Signal handler installed with SA_SIGINFO. */
+ sf.sf_siginfo = (register_t)&sfp->sf_si;
+ sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
+
+ /* Fill in POSIX parts */
+ sf.sf_si.si_signo = sig;
+ sf.sf_si.si_code = code;
+ sf.sf_si.si_addr = (void *)regs->tf_err;
+ sf.sf_si.si_pid = p->p_pid;
+ sf.sf_si.si_uid = p->p_ucred->cr_uid;
+ } else {
+ /* Old FreeBSD-style arguments. */
+ sf.sf_siginfo = code;
+ sf.sf_addr = regs->tf_err;
+ sf.sf_ahu.sf_handler = catcher;
+ }
+ PROC_UNLOCK(p);
+
+ /*
+ * If we're a vm86 process, we want to save the segment registers.
+ * We also change eflags to be our emulated eflags, not the actual
+ * eflags.
+ */
+ if (regs->tf_eflags & PSL_VM) {
+ struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
+ struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
+
+ sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
+ sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
+ sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
+ sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
+
+ if (vm86->vm86_has_vme == 0)
+ sf.sf_uc.uc_mcontext.mc_eflags =
+ (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
+ (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
+
+ /*
+ * Clear PSL_NT to inhibit T_TSSFLT faults on return from
+ * syscalls made by the signal handler. This just avoids
+ * wasting time for our lazy fixup of such faults. PSL_NT
+ * does nothing in vm86 mode, but vm86 programs can set it
+ * almost legitimately in probes for old cpu types.
+ */
+ tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
+ }
+
+ /*
+ * Copy the sigframe out to the user's stack.
+ */
+ if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
+#ifdef DEBUG
+ printf("process %ld has trashed its stack\n", (long)p->p_pid);
+#endif
+ PROC_LOCK(p);
+ sigexit(td, SIGILL);
+ }
+
+ regs->tf_esp = (int)sfp;
+ regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode;
+ regs->tf_eflags &= ~PSL_T;
+ regs->tf_cs = _ucodesel;
+ regs->tf_ds = _udatasel;
+ regs->tf_es = _udatasel;
+ regs->tf_fs = _udatasel;
+ regs->tf_ss = _udatasel;
+ PROC_LOCK(p);
+}
+#endif /* COMPAT_FREEBSD4 */
+
void
sendsig(catcher, sig, mask, code)
sig_t catcher;
@@ -415,18 +541,23 @@ sendsig(catcher, sig, mask, code)
sigset_t *mask;
u_long code;
{
- struct sigframe sf;
+ struct sigframe sf, *sfp;
struct proc *p;
struct thread *td;
struct sigacts *psp;
struct trapframe *regs;
- struct sigframe *sfp;
int oonstack;
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
+#ifdef COMPAT_FREEBSD4
+ if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
+ freebsd4_sendsig(catcher, sig, mask, code);
+ return;
+ }
+#endif
#ifdef COMPAT_43
if (SIGISMEMBER(psp->ps_osigset, sig)) {
osendsig(catcher, sig, mask, code);
@@ -550,6 +681,7 @@ sendsig(catcher, sig, mask, code)
*
* MPSAFE
*/
+#ifdef COMPAT_43
int
osigreturn(td, uap)
struct thread *td;
@@ -557,7 +689,6 @@ osigreturn(td, uap)
struct osigcontext *sigcntxp;
} */ *uap;
{
-#ifdef COMPAT_43
struct osigcontext sc;
struct trapframe *regs;
struct osigcontext *scp;
@@ -662,10 +793,116 @@ osigreturn(td, uap)
signotify(p);
PROC_UNLOCK(p);
return (EJUSTRETURN);
-#else /* !COMPAT_43 */
- return (ENOSYS);
+}
#endif /* COMPAT_43 */
+
+#ifdef COMPAT_FREEBSD4
+/*
+ * MPSAFE
+ */
+int
+freebsd4_sigreturn(td, uap)
+ struct thread *td;
+ struct freebsd4_sigreturn_args /* {
+ const ucontext4 *sigcntxp;
+ } */ *uap;
+{
+ struct ucontext4 uc;
+ struct proc *p = td->td_proc;
+ struct trapframe *regs;
+ const struct ucontext4 *ucp;
+ int cs, eflags, error;
+
+ error = copyin(uap->sigcntxp, &uc, sizeof(uc));
+ if (error != 0)
+ return (error);
+ ucp = &uc;
+ regs = td->td_frame;
+ eflags = ucp->uc_mcontext.mc_eflags;
+ if (eflags & PSL_VM) {
+ struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
+ struct vm86_kernel *vm86;
+
+ /*
+ * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
+ * set up the vm86 area, and we can't enter vm86 mode.
+ */
+ if (td->td_pcb->pcb_ext == 0)
+ return (EINVAL);
+ vm86 = &td->td_pcb->pcb_ext->ext_vm86;
+ if (vm86->vm86_inited == 0)
+ return (EINVAL);
+
+ /* Go back to user mode if both flags are set. */
+ if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
+ trapsignal(p, SIGBUS, 0);
+
+ if (vm86->vm86_has_vme) {
+ eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
+ (eflags & VME_USERCHANGE) | PSL_VM;
+ } else {
+ vm86->vm86_eflags = eflags; /* save VIF, VIP */
+ eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
+ (eflags & VM_USERCHANGE) | PSL_VM;
+ }
+ bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
+ tf->tf_eflags = eflags;
+ tf->tf_vm86_ds = tf->tf_ds;
+ tf->tf_vm86_es = tf->tf_es;
+ tf->tf_vm86_fs = tf->tf_fs;
+ tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
+ tf->tf_ds = _udatasel;
+ tf->tf_es = _udatasel;
+ tf->tf_fs = _udatasel;
+ } else {
+ /*
+ * Don't allow users to change privileged or reserved flags.
+ */
+ /*
+ * XXX do allow users to change the privileged flag PSL_RF.
+ * The cpu sets PSL_RF in tf_eflags for faults. Debuggers
+ * should sometimes set it there too. tf_eflags is kept in
+ * the signal context during signal handling and there is no
+ * other place to remember it, so the PSL_RF bit may be
+ * corrupted by the signal handler without us knowing.
+ * Corruption of the PSL_RF bit at worst causes one more or
+ * one less debugger trap, so allowing it is fairly harmless.
+ */
+ if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
+ printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags);
+ return (EINVAL);
+ }
+
+ /*
+ * Don't allow users to load a valid privileged %cs. Let the
+ * hardware check for invalid selectors, excess privilege in
+ * other selectors, invalid %eip's and invalid %esp's.
+ */
+ cs = ucp->uc_mcontext.mc_cs;
+ if (!CS_SECURE(cs)) {
+ printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
+ trapsignal(p, SIGBUS, T_PROTFLT);
+ return (EINVAL);
+ }
+
+ bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
+ }
+
+ PROC_LOCK(p);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ if (ucp->uc_mcontext.mc_onstack & 1)
+ p->p_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
+
+ p->p_sigmask = ucp->uc_sigmask;
+ SIG_CANTMASK(p->p_sigmask);
+ signotify(p);
+ PROC_UNLOCK(p);
+ return (EJUSTRETURN);
}
+#endif /* COMPAT_FREEBSD4 */
/*
* MPSAFE
@@ -2162,7 +2399,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp)
#ifndef DEV_NPX
mcp->mc_fpformat = _MC_FPFMT_NODEV;
mcp->mc_ownedfp = _MC_FPOWNED_NONE;
-#else /* DEV_NPX */
+#else
union savefpu *addr;
/*
@@ -2192,9 +2429,8 @@ get_fpcontext(struct thread *td, mcontext_t *mcp)
bcopy(addr, &mcp->mc_fpstate, sizeof(mcp->mc_fpstate));
bzero(&mcp->mc_spare2, sizeof(mcp->mc_spare2));
}
- bcopy(&mcp->mc_fpstate, &td->td_pcb->pcb_save, sizeof(mcp->mc_fpstate));
mcp->mc_fpformat = npxformat();
-#endif /* !DEV_NPX */
+#endif
}
static int
@@ -2204,7 +2440,10 @@ set_fpcontext(struct thread *td, const mcontext_t *mcp)
if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
return (0);
- if (mcp->mc_ownedfp == _MC_FPOWNED_NONE)
+ else if (mcp->mc_fpformat != _MC_FPFMT_387 &&
+ mcp->mc_fpformat != _MC_FPFMT_XMM)
+ return (EINVAL);
+ else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE)
/* We don't care what state is left in the FPU or PCB. */
fpstate_drop(td);
else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU ||
@@ -2227,25 +2466,14 @@ set_fpcontext(struct thread *td, const mcontext_t *mcp)
* be called with interrupts disabled.
*/
npxsetregs(td, addr);
+#endif
/*
* Don't bother putting things back where they were in the
* misaligned case, since we know that the caller won't use
* them again.
*/
- } else {
- /*
- * There is no valid FPU state in *mcp, so use the saved
- * state in the PCB if there is one. XXX the test for
- * whether there is one seems to be quite broken. We
- * forcibly drop the state in sendsig().
- */
- if ((td->td_pcb->pcb_flags & PCB_NPXINITDONE) != 0)
- npxsetregs(td, &td->td_pcb->pcb_save);
-#endif
-#if !defined(COMPAT_FREEBSD4) && !defined(COMPAT_43)
+ } else
return (EINVAL);
-#endif
- }
return (0);
}
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index f449c045d459..9fa396876854 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -56,7 +56,13 @@ extern int need_post_dma_flush;
#endif
extern void (*ovbcopy_vector)(const void *from, void *to, size_t len);
extern char sigcode[];
-extern int szsigcode, szosigcode;
+extern int szsigcode;
+#ifdef COMPAT_FREEBSD4
+extern int szfreebsd4_sigcode;
+#endif
+#ifdef COMPAT_43
+extern int szosigcode;
+#endif
typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
struct thread;
diff --git a/sys/amd64/include/sigframe.h b/sys/amd64/include/sigframe.h
index 947743d2c0c0..98be731d8f10 100644
--- a/sys/amd64/include/sigframe.h
+++ b/sys/amd64/include/sigframe.h
@@ -35,6 +35,7 @@
* Signal frames, arguments passed to application signal handlers.
*/
#ifdef _KERNEL
+#ifdef COMPAT_43
struct osigframe {
/*
* The first four members may be used by applications.
@@ -70,6 +71,23 @@ struct osigframe {
osiginfo_t sf_siginfo;
};
#endif
+#ifdef COMPAT_FREEBSD4
+/* FreeBSD 4.x */
+struct sigframe4 {
+ register_t sf_signum;
+ register_t sf_siginfo; /* code or pointer to sf_si */
+ register_t sf_ucontext; /* points to sf_uc */
+ register_t sf_addr; /* undocumented 4th arg */
+
+ union {
+ __siginfohandler_t *sf_action;
+ __sighandler_t *sf_handler;
+ } sf_ahu;
+ struct ucontext4 sf_uc; /* = *sf_ucontext */
+ siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case) */
+};
+#endif
+#endif
struct sigframe {
/*
diff --git a/sys/amd64/include/signal.h b/sys/amd64/include/signal.h
index 9fcca63f1aab..29a97767cc69 100644
--- a/sys/amd64/include/signal.h
+++ b/sys/amd64/include/signal.h
@@ -60,7 +60,7 @@ typedef int sig_atomic_t;
/*
* Only the kernel should need these old type definitions.
*/
-#ifdef _KERNEL
+#if defined(_KERNEL) && defined(COMPAT_43)
/*
* Information pushed on stack when a signal is delivered.
* This is used by the kernel to restore state following
@@ -68,8 +68,6 @@ typedef int sig_atomic_t;
* to the handler to allow it to restore state properly if
* a non-standard exit is performed.
*/
-typedef unsigned int osigset_t;
-
struct osigcontext {
int sc_onstack; /* sigstack state to restore */
osigset_t sc_mask; /* signal mask to restore */
diff --git a/sys/amd64/include/ucontext.h b/sys/amd64/include/ucontext.h
index d02959c232d3..af9b4fd3e732 100644
--- a/sys/amd64/include/ucontext.h
+++ b/sys/amd64/include/ucontext.h
@@ -73,6 +73,34 @@ typedef struct __mcontext {
} mcontext_t;
#ifdef _KERNEL
+#ifdef COMPAT_FREEBSD4
+/* For 4.x binaries */
+struct mcontext4 {
+ int mc_onstack; /* XXX - sigcontext compat. */
+ int mc_gs;
+ int mc_fs;
+ int mc_es;
+ int mc_ds;
+ int mc_edi;
+ int mc_esi;
+ int mc_ebp;
+ int mc_isp;
+ int mc_ebx;
+ int mc_edx;
+ int mc_ecx;
+ int mc_eax;
+ int mc_trapno;
+ int mc_err;
+ int mc_eip;
+ int mc_cs;
+ int mc_eflags;
+ int mc_esp; /* machine state */
+ int mc_ss;
+ int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
+ int __spare__[17];
+};
+#endif
+
struct thread;
void get_mcontext(struct thread *td, mcontext_t *mcp);