aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/locore.s52
-rw-r--r--sys/alpha/alpha/machdep.c217
-rw-r--r--sys/alpha/include/md_var.h6
-rw-r--r--sys/alpha/include/sigframe.h10
-rw-r--r--sys/alpha/include/signal.h4
-rw-r--r--sys/alpha/include/ucontext.h12
-rw-r--r--sys/alpha/osf1/osf1_signal.c11
-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
-rw-r--r--sys/conf/options1
-rw-r--r--sys/i386/i386/genassym.c9
-rw-r--r--sys/i386/i386/locore.s26
-rw-r--r--sys/i386/i386/machdep.c276
-rw-r--r--sys/i386/include/md_var.h8
-rw-r--r--sys/i386/include/sigframe.h18
-rw-r--r--sys/i386/include/signal.h4
-rw-r--r--sys/i386/include/ucontext.h28
-rw-r--r--sys/ia64/ia64/machdep.c21
-rw-r--r--sys/ia64/include/sigframe.h3
-rw-r--r--sys/ia64/include/signal.h7
-rw-r--r--sys/kern/init_sysent.c10
-rw-r--r--sys/kern/kern_sig.c77
-rw-r--r--sys/kern/syscalls.c10
-rw-r--r--sys/kern/syscalls.master11
-rw-r--r--sys/powerpc/aim/machdep.c21
-rw-r--r--sys/powerpc/include/signal.h21
-rw-r--r--sys/powerpc/powerpc/machdep.c21
-rw-r--r--sys/sparc64/include/signal.h8
-rw-r--r--sys/sparc64/sparc64/machdep.c24
-rw-r--r--sys/sys/_sigset.h4
-rw-r--r--sys/sys/signal.h8
-rw-r--r--sys/sys/signalvar.h7
-rw-r--r--sys/sys/syscall.h8
-rw-r--r--sys/sys/syscall.mk7
-rw-r--r--sys/sys/syscallsubr.h6
-rw-r--r--sys/sys/sysproto.h38
-rw-r--r--sys/sys/ucontext.h14
43 files changed, 1182 insertions, 221 deletions
diff --git a/sys/alpha/alpha/locore.s b/sys/alpha/alpha/locore.s
index 5d1cdce312ec..e5a7f654dc2e 100644
--- a/sys/alpha/alpha/locore.s
+++ b/sys/alpha/alpha/locore.s
@@ -53,6 +53,8 @@
* rights to redistribute these changes.
*/
+#include "opt_compat.h"
+
#include <machine/asm.h>
#include <sys/syscall.h>
#include <assym.s>
@@ -190,15 +192,55 @@ NESTED(sigcode,0,0,ra,0,0)
jsr ra, (t12) /* call the signal handler (t12==pv) */
ldq a0, 0(sp) /* get the sigcontext pointer */
lda sp, 16(sp)
- CALLSYS_NOERROR(sigreturn) /* and call sigreturn() with it. */
+ ldiq v0, SYS_sigreturn
+ call_pal PAL_OSF1_callsys /* and call sigreturn() with it. */
mov v0, a0 /* if that failed, get error code */
- CALLSYS_NOERROR(exit) /* and call exit() with it. */
-XNESTED(esigcode,0)
+ ldiq v0, SYS_exit
+ call_pal PAL_OSF1_callsys /* and call exit() with it. */
END(sigcode)
+#ifdef COMPAT_43
+NESTED(osigcode,0,0,ra,0,0)
+ lda sp, -16(sp) /* save the sigcontext pointer */
+ stq a2, 0(sp)
+ jsr ra, (t12) /* call the signal handler (t12==pv) */
+ ldq a0, 0(sp) /* get the sigcontext pointer */
+ lda sp, 16(sp)
+ ldiq v0, 103 /* Old 3.x SYS_sigreturn */
+ call_pal PAL_OSF1_callsys /* and call sigreturn() with it. */
+ mov v0, a0 /* if that failed, get error code */
+ ldiq v0, SYS_exit
+ call_pal PAL_OSF1_callsys /* and call exit() with it. */
+ END(osigcode)
+#endif
+
+#ifdef COMPAT_FREEBSD4
+NESTED(freebsd4_sigcode,0,0,ra,0,0)
+ lda sp, -16(sp) /* save the sigcontext pointer */
+ stq a2, 0(sp)
+ jsr ra, (t12) /* call the signal handler (t12==pv) */
+ ldq a0, 0(sp) /* get the sigcontext pointer */
+ lda sp, 16(sp)
+ ldiq v0, 344 /* Old 4.x SYS_sigreturn */
+ call_pal PAL_OSF1_callsys /* and call sigreturn() with it. */
+ mov v0, a0 /* if that failed, get error code */
+ ldiq v0, SYS_exit
+ call_pal PAL_OSF1_callsys /* and call exit() with it. */
+ END(freebsd4_sigcode)
+#endif
+EXPORT(esigcode) /* end of all sigcode */
+
.data
- EXPORT(szsigcode)
- .quad esigcode-sigcode
+EXPORT(szsigcode)
+ .long esigcode-sigcode
+#ifdef COMPAT_43
+EXPORT(szosigcode)
+ .long esigcode-osigcode
+#endif
+#ifdef COMPAT_FREEBSD4
+EXPORT(szfreebsd4_sigcode)
+ .long esigcode-freebsd4_sigcode
+#endif
.text
/**************************************************************************/
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index db64fd3cf1de..888eb42e0966 100644
--- a/sys/alpha/alpha/machdep.c
+++ b/sys/alpha/alpha/machdep.c
@@ -232,6 +232,10 @@ SYSCTL_ULONG(_hw, OID_AUTO, availpages, CTLFLAG_RD, &physmem, 0, "");
#ifdef COMPAT_43
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 void identifycpu(void);
@@ -1250,7 +1254,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Set up the registers to return to sigcode.
*/
- frame->tf_regs[FRAME_PC] = PS_STRINGS - (esigcode - sigcode);
+ frame->tf_regs[FRAME_PC] = PS_STRINGS - szosigcode;
frame->tf_regs[FRAME_A0] = sig;
frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
PROC_LOCK(p);
@@ -1264,6 +1268,121 @@ 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)
+{
+ struct proc *p;
+ struct thread *td;
+ struct trapframe *frame;
+ struct sigacts *psp;
+ struct sigframe4 sf, *sfp;
+ int oonstack, rndfsize;
+
+ td = curthread;
+ p = td->td_proc;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ psp = p->p_sigacts;
+
+ frame = td->td_frame;
+ oonstack = sigonstack(alpha_pal_rdusp());
+ rndfsize = ((sizeof(sf) + 15) / 16) * 16;
+
+ /* 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;
+
+ fill_regs(td, (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
+ * context. Note that if the stack is in P0 space, the
+ * call to grow() is a nop, and the useracc() check
+ * will fail if the process has not already allocated
+ * the space with a `brk'.
+ */
+ if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
+ SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ sfp = (struct sigframe4 *)((caddr_t)p->p_sigstk.ss_sp +
+ p->p_sigstk.ss_size - rndfsize);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ p->p_sigstk.ss_flags |= SS_ONSTACK;
+#endif
+ } else
+ sfp = (struct sigframe4 *)(alpha_pal_rdusp() - rndfsize);
+ PROC_UNLOCK(p);
+
+ /* save the floating-point state, if necessary, then copy it. */
+ alpha_fpstate_save(td, 1);
+ sf.sf_uc.uc_mcontext.mc_ownedfp = td->td_md.md_flags & MDTD_FPUSED;
+ bcopy(&td->td_pcb->pcb_fp,
+ (struct fpreg *)sf.sf_uc.uc_mcontext.mc_fpregs,
+ sizeof(struct fpreg));
+ sf.sf_uc.uc_mcontext.mc_fp_control = td->td_pcb->pcb_fp_control;
+
+#ifdef COMPAT_OSF1
+ /*
+ * XXX Create an OSF/1-style sigcontext and associated goo.
+ */
+#endif
+
+ /*
+ * copy the frame out to userland.
+ */
+ if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ PROC_LOCK(p);
+ SIGACTION(p, SIGILL) = SIG_DFL;
+ SIGDELSET(p->p_sigignore, SIGILL);
+ SIGDELSET(p->p_sigcatch, SIGILL);
+ SIGDELSET(p->p_sigmask, SIGILL);
+ psignal(p, SIGILL);
+ return;
+ }
+
+ /*
+ * Set up the registers to return to sigcode.
+ */
+ frame->tf_regs[FRAME_PC] = PS_STRINGS - szfreebsd4_sigcode;
+ frame->tf_regs[FRAME_A0] = sig;
+ PROC_LOCK(p);
+ if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
+ frame->tf_regs[FRAME_A1] = (u_int64_t)&(sfp->sf_si);
+
+ /* Fill in POSIX parts */
+ sf.sf_si.si_signo = sig;
+ sf.sf_si.si_code = code;
+ sf.sf_si.si_addr = (void*)frame->tf_regs[FRAME_TRAPARG_A0];
+ sf.sf_si.si_pid = p->p_pid;
+ sf.sf_si.si_uid = p->p_ucred->cr_uid;
+ }
+ else
+ frame->tf_regs[FRAME_A1] = code;
+
+ frame->tf_regs[FRAME_A2] = (u_int64_t)&(sfp->sf_uc);
+ frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */
+ frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
+ alpha_pal_wrusp((unsigned long)sfp);
+}
+#endif /* COMPAT_FREEBSD4 */
+
void
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
{
@@ -1278,6 +1397,12 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
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);
@@ -1377,7 +1502,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/*
* Set up the registers to return to sigcode.
*/
- frame->tf_regs[FRAME_PC] = PS_STRINGS - (esigcode - sigcode);
+ frame->tf_regs[FRAME_PC] = PS_STRINGS - szsigcode;
frame->tf_regs[FRAME_A0] = sig;
PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
@@ -1419,13 +1544,13 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
*
* MPSAFE
*/
+#ifdef COMPAT_43
int
osigreturn(struct thread *td,
struct osigreturn_args /* {
struct osigcontext *sigcntxp;
} */ *uap)
{
-#ifdef COMPAT_43
struct osigcontext *scp, ksc;
struct proc *p = td->td_proc;
@@ -1479,10 +1604,82 @@ osigreturn(struct thread *td,
sizeof(struct fpreg));
td->td_pcb->pcb_fp_control = ksc.sc_fp_control;
return (EJUSTRETURN);
-#else /* !COMPAT_43 */
- return (ENOSYS);
+}
#endif /* COMPAT_43 */
+
+#ifdef COMPAT_FREEBSD4
+/*
+ * MPSAFE
+ */
+int
+freebsd4_sigreturn(struct thread *td,
+ struct freebsd4_sigreturn_args /* {
+ const struct ucontext4 *sigcntxp;
+ } */ *uap)
+{
+ struct ucontext4 uc;
+ const struct ucontext4 *ucp;
+ struct pcb *pcb;
+ unsigned long val;
+ struct proc *p;
+ int error;
+
+ ucp = uap->sigcntxp;
+ pcb = td->td_pcb;
+ p = td->td_proc;
+
+ /*
+ * Fetch the entire context structure at once for speed.
+ * Note that struct osigcontext is smaller than a ucontext_t,
+ * so even if copyin() faults, we may have actually gotten a complete
+ * struct osigcontext.
+ */
+ error = copyin(ucp, &uc, sizeof(ucontext_t));
+ if (error != 0) {
+#ifdef COMPAT_43
+ if (((struct osigcontext*)&uc)->sc_regs[R_ZERO] == 0xACEDBADE)
+ return osigreturn(td, (struct osigreturn_args *)uap);
+#endif
+ return (error);
+ }
+
+#ifdef COMPAT_43
+ if (((struct osigcontext*)&uc)->sc_regs[R_ZERO] == 0xACEDBADE)
+ return osigreturn(td, (struct osigreturn_args *)uap);
+#endif
+
+ /*
+ * Restore the user-supplied information
+ */
+ set_regs(td, (struct reg *)uc.uc_mcontext.mc_regs);
+ val = (uc.uc_mcontext.mc_regs[R_PS] | ALPHA_PSL_USERSET) &
+ ~ALPHA_PSL_USERCLR;
+ td->td_frame->tf_regs[FRAME_PS] = val;
+ td->td_frame->tf_regs[FRAME_PC] = uc.uc_mcontext.mc_regs[R_PC];
+ td->td_frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
+ alpha_pal_wrusp(uc.uc_mcontext.mc_regs[R_SP]);
+
+ PROC_LOCK(p);
+#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
+ if (uc.uc_mcontext.mc_onstack & 1)
+ p->p_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+#endif
+
+ p->p_sigmask = uc.uc_sigmask;
+ SIG_CANTMASK(p->p_sigmask);
+ signotify(p);
+ PROC_UNLOCK(p);
+
+ /* XXX ksc.sc_ownedfp ? */
+ alpha_fpstate_drop(td);
+ bcopy((struct fpreg *)uc.uc_mcontext.mc_fpregs,
+ &td->td_pcb->pcb_fp, sizeof(struct fpreg));
+ td->td_pcb->pcb_fp_control = uc.uc_mcontext.mc_fp_control;
+ return (EJUSTRETURN);
}
+#endif /* COMPAT_FREEBSD4 */
/*
* MPSAFE
@@ -1498,6 +1695,7 @@ sigreturn(struct thread *td,
struct pcb *pcb;
unsigned long val;
struct proc *p;
+ int error;
ucp = uap->sigcntxp;
pcb = td->td_pcb;
@@ -1507,21 +1705,22 @@ sigreturn(struct thread *td,
if (sigdebug & SDB_FOLLOW)
printf("sigreturn: pid %d, scp %p\n", p->p_pid, ucp);
#endif
-
/*
* Fetch the entire context structure at once for speed.
* Note that struct osigcontext is smaller than a ucontext_t,
* so even if copyin() faults, we may have actually gotten a complete
* struct osigcontext.
+ * XXX we'll *still* be getting osigcontext's here due to longjmp(3)
+ * brain damage.
*/
- if (copyin(ucp, &uc, sizeof(ucontext_t))) {
+ error = copyin(ucp, &uc, sizeof(ucontext_t));
+ if (error != 0) {
#ifdef COMPAT_43
if (((struct osigcontext*)&uc)->sc_regs[R_ZERO] == 0xACEDBADE)
return osigreturn(td, (struct osigreturn_args *)uap);
#endif
- return (EFAULT);
+ return (error);
}
-
#ifdef COMPAT_43
if (((struct osigcontext*)&uc)->sc_regs[R_ZERO] == 0xACEDBADE)
return osigreturn(td, (struct osigreturn_args *)uap);
diff --git a/sys/alpha/include/md_var.h b/sys/alpha/include/md_var.h
index b59cb7df5178..12df6141c882 100644
--- a/sys/alpha/include/md_var.h
+++ b/sys/alpha/include/md_var.h
@@ -36,6 +36,12 @@
extern char sigcode[];
extern char esigcode[];
extern int szsigcode;
+#ifdef COMPAT_43
+extern int szosigcode;
+#endif
+#ifdef COMPAT_FREEBSD4
+extern int szfreebsd4_sigcode;
+#endif
extern long Maxmem;
extern int busdma_swi_pending;
diff --git a/sys/alpha/include/sigframe.h b/sys/alpha/include/sigframe.h
index eb8039b8532a..01196e569e83 100644
--- a/sys/alpha/include/sigframe.h
+++ b/sys/alpha/include/sigframe.h
@@ -31,10 +31,12 @@
#ifndef _MACHINE_SIGFRAME_H_
#define _MACHINE_SIGFRAME_H_ 1
-#ifdef _KERNEL
-struct osigframe {
- struct osigcontext sf_sc;
- osiginfo_t sf_si;
+#if defined(_KERNEL) && defined(COMPAT_FREEBSD4)
+/* FreeBSD 4.x */
+struct sigframe4 {
+ unsigned long __spare__;
+ struct ucontext4 sf_uc;
+ siginfo_t sf_si;
};
#endif
diff --git a/sys/alpha/include/signal.h b/sys/alpha/include/signal.h
index da32b41cbcf8..2a1f17b9b2d5 100644
--- a/sys/alpha/include/signal.h
+++ b/sys/alpha/include/signal.h
@@ -47,7 +47,7 @@ typedef long 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
@@ -58,8 +58,6 @@ typedef long sig_atomic_t;
* Note that sc_regs[] and sc_fpregs[]+sc_fpcr are inline
* representations of 'struct reg' and 'struct fpreg', respectively.
*/
-typedef unsigned int osigset_t;
-
struct osigcontext {
long sc_onstack; /* sigstack state to restore */
long sc_mask; /* signal mask to restore */
diff --git a/sys/alpha/include/ucontext.h b/sys/alpha/include/ucontext.h
index 3e8888143853..bfc18df8f42f 100644
--- a/sys/alpha/include/ucontext.h
+++ b/sys/alpha/include/ucontext.h
@@ -50,4 +50,16 @@ typedef struct __mcontext {
long __spare__[6];
} mcontext_t;
+#if defined(_KERNEL) && defined(COMPAT_FREEBSD4)
+struct mcontext4 {
+ 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];
+};
+#endif
+
#endif /* !_MACHINE_UCONTEXT_H_ */
diff --git a/sys/alpha/osf1/osf1_signal.c b/sys/alpha/osf1/osf1_signal.c
index 7ea80fd8a2b6..b16c2c807abe 100644
--- a/sys/alpha/osf1/osf1_signal.c
+++ b/sys/alpha/osf1/osf1_signal.c
@@ -33,6 +33,11 @@
* $FreeBSD$
*/
+#include "opt_compat.h"
+#ifndef COMPAT_43
+#error "COMPAT_OSF1 requires COMPAT_43"
+#endif
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
@@ -101,7 +106,6 @@ static void osf1_to_bsd_sigaction(const struct osf1_sigaction *osa,
#define osf1_sigismember(s, n) (*(s) & sigmask(n))
#define osf1_sigaddset(s, n) (*(s) |= sigmask(n))
-
void
osf1_to_bsd_sigset(oss, bss)
const osf1_sigset_t *oss;
@@ -747,9 +751,6 @@ osf1_sigreturn(struct thread *td,
return (EJUSTRETURN);
}
-extern int
-osigstack(struct thread *td, struct osf1_osigstack_args *uap);
-
int
osf1_osigstack(td, uap)
register struct thread *td;
@@ -761,5 +762,5 @@ osf1_osigstack(td, uap)
/* uprintf("osf1_osigstack: oss = %p, nss = %p",uap->oss, uap->nss);
uprintf(" stack ptr = %p\n",p->p_sigacts->ps_sigstk.ss_sp);*/
- return(osigstack(td, uap));
+ return(osigstack(td, (struct osigstack_args *)uap));
}
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);
diff --git a/sys/conf/options b/sys/conf/options
index 5c67f4972bc2..4433f1b04624 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -77,6 +77,7 @@ ADAPTIVE_MUTEXES
COMPAT_43 opt_compat.h
COMPAT_FREEBSD4 opt_compat.h
COMPAT_SUNOS opt_compat.h
+NO_COMPAT_FREEBSD4 opt_compat.h
COMPILING_LINT opt_global.h
CY_PCI_FASTINTR
CONSPEED opt_comconsole.h
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index d4aa9e3da060..5a8cf704dd22 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/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/i386/i386/locore.s b/sys/i386/i386/locore.s
index 5d5b39ed5fd9..8f1d801268b3 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/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/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 80805a2048c5..ff69b568be79 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/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/i386/include/md_var.h b/sys/i386/include/md_var.h
index f449c045d459..9fa396876854 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/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/i386/include/sigframe.h b/sys/i386/include/sigframe.h
index 947743d2c0c0..98be731d8f10 100644
--- a/sys/i386/include/sigframe.h
+++ b/sys/i386/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/i386/include/signal.h b/sys/i386/include/signal.h
index 9fcca63f1aab..29a97767cc69 100644
--- a/sys/i386/include/signal.h
+++ b/sys/i386/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/i386/include/ucontext.h b/sys/i386/include/ucontext.h
index d02959c232d3..af9b4fd3e732 100644
--- a/sys/i386/include/ucontext.h
+++ b/sys/i386/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);
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 454cf4963834..4f739d2faa59 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -951,18 +951,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
}
/*
- * Stub to satisfy the reference to osigreturn in the syscall table. This
- * is needed even for newer arches that don't support old signals because
- * the syscall table is machine-independent.
- */
-int
-osigreturn(struct thread *td, struct osigreturn_args *uap)
-{
-
- return (nosys(td, (struct nosys_args *)uap));
-}
-
-/*
* System call to cleanup state after a signal
* has been taken. Reset signal mask and
* stack state from context left by sendsig (above).
@@ -1069,6 +1057,15 @@ sigreturn(struct thread *td,
return (EJUSTRETURN);
}
+#ifdef COMPAT_FREEBSD4
+int
+freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
+{
+
+ return sigreturn(td, (struct sigreturn_args *)uap);
+}
+#endif
+
/*
* Machine dependent boot() routine
*/
diff --git a/sys/ia64/include/sigframe.h b/sys/ia64/include/sigframe.h
index b0772d75c494..d0e886e9bc90 100644
--- a/sys/ia64/include/sigframe.h
+++ b/sys/ia64/include/sigframe.h
@@ -31,9 +31,6 @@
#ifndef _MACHINE_SIGFRAME_H_
#define _MACHINE_SIGFRAME_H_ 1
-struct osigframe {
-};
-
struct sigframe {
ucontext_t sf_uc;
siginfo_t sf_si;
diff --git a/sys/ia64/include/signal.h b/sys/ia64/include/signal.h
index 1014d2b2128b..1a20e01050da 100644
--- a/sys/ia64/include/signal.h
+++ b/sys/ia64/include/signal.h
@@ -70,7 +70,6 @@ struct ia64_fpreg {
#endif
#endif
-#ifdef _KERNEL
/*
* Information pushed on stack when a signal is delivered.
@@ -82,12 +81,6 @@ struct ia64_fpreg {
* Note that sc_regs[] and sc_fpregs[]+sc_fpcr are inline
* representations of 'struct reg' and 'struct fpreg', respectively.
*/
-typedef unsigned int osigset_t;
-struct osigcontext {
- int _not_used;
-};
-
-#endif /* !_KERNEL */
#if __BSD_VISIBLE
/*
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index fb28d326493c..601920bb435c 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -131,7 +131,7 @@ struct sysent sysent[] = {
{ SYF_MPSAFE | AS(getpriority_args), (sy_call_t *)getpriority }, /* 100 = getpriority */
{ compat(SYF_MPSAFE | AS(osend_args),send) }, /* 101 = old send */
{ compat(SYF_MPSAFE | AS(orecv_args),recv) }, /* 102 = old recv */
- { SYF_MPSAFE | AS(osigreturn_args), (sy_call_t *)osigreturn }, /* 103 = osigreturn */
+ { compat(SYF_MPSAFE | AS(osigreturn_args),sigreturn) }, /* 103 = old sigreturn */
{ SYF_MPSAFE | AS(bind_args), (sy_call_t *)bind }, /* 104 = bind */
{ SYF_MPSAFE | AS(setsockopt_args), (sy_call_t *)setsockopt }, /* 105 = setsockopt */
{ SYF_MPSAFE | AS(listen_args), (sy_call_t *)listen }, /* 106 = listen */
@@ -370,9 +370,9 @@ struct sysent sysent[] = {
{ 0, (sy_call_t *)nosys }, /* 339 = pioctl */
{ SYF_MPSAFE | AS(sigprocmask_args), (sy_call_t *)sigprocmask }, /* 340 = sigprocmask */
{ SYF_MPSAFE | AS(sigsuspend_args), (sy_call_t *)sigsuspend }, /* 341 = sigsuspend */
- { SYF_MPSAFE | AS(sigaction_args), (sy_call_t *)sigaction }, /* 342 = sigaction */
+ { compat4(SYF_MPSAFE | AS(freebsd4_sigaction_args),sigaction) }, /* 342 = old sigaction */
{ SYF_MPSAFE | AS(sigpending_args), (sy_call_t *)sigpending }, /* 343 = sigpending */
- { SYF_MPSAFE | AS(sigreturn_args), (sy_call_t *)sigreturn }, /* 344 = sigreturn */
+ { compat4(SYF_MPSAFE | AS(freebsd4_sigreturn_args),sigreturn) }, /* 344 = old sigreturn */
{ 0, (sy_call_t *)nosys }, /* 345 = sigtimedwait */
{ 0, (sy_call_t *)nosys }, /* 346 = sigwaitinfo */
{ SYF_MPSAFE | AS(__acl_get_file_args), (sy_call_t *)__acl_get_file }, /* 347 = __acl_get_file */
@@ -444,8 +444,8 @@ struct sysent sysent[] = {
{ AS(extattr_get_link_args), (sy_call_t *)extattr_get_link }, /* 413 = extattr_get_link */
{ AS(extattr_delete_link_args), (sy_call_t *)extattr_delete_link }, /* 414 = extattr_delete_link */
{ 0, (sy_call_t *)nosys }, /* 415 = __execve_mac */
- { 0, (sy_call_t *)nosys }, /* 416 = newsigreturn */
- { 0, (sy_call_t *)nosys }, /* 417 = newsigaction */
+ { SYF_MPSAFE | AS(sigaction_args), (sy_call_t *)sigaction }, /* 416 = sigaction */
+ { SYF_MPSAFE | AS(sigreturn_args), (sy_call_t *)sigreturn }, /* 417 = sigreturn */
{ 0, (sy_call_t *)nosys }, /* 418 = __xstat */
{ 0, (sy_call_t *)nosys }, /* 419 = __xfstat */
{ 0, (sy_call_t *)nosys }, /* 420 = __xlstat */
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 0d5000e18263..35036098819d 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -73,6 +73,13 @@
#include <machine/cpu.h>
+#if !defined(COMPAT_FREEBSD4) && !defined(NO_COMPAT_FREEBSD4)
+#error "You *really* want COMPAT_FREEBSD4 on -current for a while"
+#endif
+#if defined (__alpha__) && !defined(COMPAT_43)
+#error "You *really* need COMPAT_43 on the alpha for longjmp(3)"
+#endif
+
#define ONSIG 32 /* NSIG for osig* syscalls. XXX. */
static int coredump(struct thread *);
@@ -229,14 +236,15 @@ sig_ffs(sigset_t *set)
/*
* kern_sigaction
* sigaction
+ * freebsd4_sigaction
* osigaction
*/
int
-kern_sigaction(td, sig, act, oact, old)
+kern_sigaction(td, sig, act, oact, flags)
struct thread *td;
register int sig;
struct sigaction *act, *oact;
- int old;
+ int flags;
{
register struct sigacts *ps;
struct proc *p = td->td_proc;
@@ -353,9 +361,18 @@ kern_sigaction(td, sig, act, oact, old)
else
SIGADDSET(p->p_sigcatch, sig);
}
+#ifdef COMPAT_FREEBSD4
+ if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
+ ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL ||
+ (flags & KSA_FREEBSD4) == 0)
+ SIGDELSET(ps->ps_freebsd4, sig);
+ else
+ SIGADDSET(ps->ps_freebsd4, sig);
+#endif
#ifdef COMPAT_43
if (ps->ps_sigact[_SIG_IDX(sig)] == SIG_IGN ||
- ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL || !old)
+ ps->ps_sigact[_SIG_IDX(sig)] == SIG_DFL ||
+ (flags & KSA_OSIGSET) == 0)
SIGDELSET(ps->ps_osigset, sig);
else
SIGADDSET(ps->ps_osigset, sig);
@@ -403,6 +420,46 @@ done2:
return (error);
}
+#ifdef COMPAT_FREEBSD4
+#ifndef _SYS_SYSPROTO_H_
+struct freebsd4_sigaction_args {
+ int sig;
+ struct sigaction *act;
+ struct sigaction *oact;
+};
+#endif
+/*
+ * MPSAFE
+ */
+/* ARGSUSED */
+int
+freebsd4_sigaction(td, uap)
+ struct thread *td;
+ register struct freebsd4_sigaction_args *uap;
+{
+ struct sigaction act, oact;
+ register struct sigaction *actp, *oactp;
+ int error;
+
+ mtx_lock(&Giant);
+
+ actp = (uap->act != NULL) ? &act : NULL;
+ oactp = (uap->oact != NULL) ? &oact : NULL;
+ if (actp) {
+ error = copyin(uap->act, actp, sizeof(act));
+ if (error)
+ goto done2;
+ }
+ error = kern_sigaction(td, uap->sig, actp, oactp, KSA_FREEBSD4);
+ if (oactp && !error) {
+ error = copyout(oactp, uap->oact, sizeof(oact));
+ }
+done2:
+ mtx_unlock(&Giant);
+ return (error);
+}
+#endif /* COMAPT_FREEBSD4 */
+
#ifdef COMPAT_43 /* XXX - COMPAT_FBSD3 */
#ifndef _SYS_SYSPROTO_H_
struct osigaction_args {
@@ -441,7 +498,7 @@ osigaction(td, uap)
nsap->sa_flags = sa.sa_flags;
OSIG2SIG(sa.sa_mask, nsap->sa_mask);
}
- error = kern_sigaction(td, uap->signum, nsap, osap, 1);
+ error = kern_sigaction(td, uap->signum, nsap, osap, KSA_OSIGSET);
if (osap && !error) {
sa.sa_handler = osap->sa_handler;
sa.sa_flags = osap->sa_flags;
@@ -452,6 +509,18 @@ done2:
mtx_unlock(&Giant);
return (error);
}
+
+#if !defined(__i386__) && !defined(__alpha__)
+/* Avoid replicating the same stub everywhere */
+int
+osigreturn(td, uap)
+ struct thread *td;
+ struct osigreturn_args *uap;
+{
+
+ return (nosys(td, (struct nosys_args *)uap));
+}
+#endif
#endif /* COMPAT_43 */
/*
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 142e8f2b9156..3215b63b2a9e 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -110,7 +110,7 @@ char *syscallnames[] = {
"getpriority", /* 100 = getpriority */
"old.send", /* 101 = old send */
"old.recv", /* 102 = old recv */
- "osigreturn", /* 103 = osigreturn */
+ "old.sigreturn", /* 103 = old sigreturn */
"bind", /* 104 = bind */
"setsockopt", /* 105 = setsockopt */
"listen", /* 106 = listen */
@@ -349,9 +349,9 @@ char *syscallnames[] = {
"#339", /* 339 = pioctl */
"sigprocmask", /* 340 = sigprocmask */
"sigsuspend", /* 341 = sigsuspend */
- "sigaction", /* 342 = sigaction */
+ "old.sigaction", /* 342 = old sigaction */
"sigpending", /* 343 = sigpending */
- "sigreturn", /* 344 = sigreturn */
+ "old.sigreturn", /* 344 = old sigreturn */
"#345", /* 345 = sigtimedwait */
"#346", /* 346 = sigwaitinfo */
"__acl_get_file", /* 347 = __acl_get_file */
@@ -423,8 +423,8 @@ char *syscallnames[] = {
"extattr_get_link", /* 413 = extattr_get_link */
"extattr_delete_link", /* 414 = extattr_delete_link */
"#415", /* 415 = __execve_mac */
- "#416", /* 416 = newsigreturn */
- "#417", /* 417 = newsigaction */
+ "sigaction", /* 416 = sigaction */
+ "sigreturn", /* 417 = sigreturn */
"#418", /* 418 = __xstat */
"#419", /* 419 = __xfstat */
"#420", /* 420 = __xlstat */
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index a0172b882e7f..482b2a96b20c 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -175,7 +175,7 @@
100 MSTD BSD { int getpriority(int which, int who); }
101 MCOMPAT BSD { int send(int s, caddr_t buf, int len, int flags); }
102 MCOMPAT BSD { int recv(int s, caddr_t buf, int len, int flags); }
-103 MSTD BSD { int osigreturn(struct osigcontext *sigcntxp); }
+103 MCOMPAT BSD { int sigreturn(struct osigcontext *sigcntxp); }
104 MSTD BSD { int bind(int s, caddr_t name, int namelen); }
105 MSTD BSD { int setsockopt(int s, int level, int name, \
caddr_t val, int valsize); }
@@ -490,10 +490,10 @@
340 MSTD POSIX { int sigprocmask(int how, const sigset_t *set, \
sigset_t *oset); }
341 MSTD POSIX { int sigsuspend(const sigset_t *sigmask); }
-342 MSTD POSIX { int sigaction(int sig, const struct sigaction *act, \
+342 MCOMPAT4 POSIX { int sigaction(int sig, const struct sigaction *act, \
struct sigaction *oact); }
343 MSTD POSIX { int sigpending(sigset_t *set); }
-344 MSTD BSD { int sigreturn(const struct __ucontext *sigcntxp); }
+344 MCOMPAT4 BSD { int sigreturn(const struct ucontext4 *sigcntxp); }
345 UNIMPL NOHIDE sigtimedwait
346 UNIMPL NOHIDE sigwaitinfo
347 MSTD BSD { int __acl_get_file(const char *path, \
@@ -601,8 +601,9 @@
414 STD BSD { int extattr_delete_link(const char *path, \
int attrnamespace, const char *attrname); }
415 UNIMPL BSD __execve_mac
-416 UNIMPL BSD newsigreturn
-417 UNIMPL BSD newsigaction
+416 MSTD POSIX { int sigaction(int sig, const struct sigaction *act, \
+ struct sigaction *oact); }
+417 MSTD BSD { int sigreturn(const struct __ucontext *sigcntxp); }
418 UNIMPL BSD __xstat
419 UNIMPL BSD __xfstat
420 UNIMPL BSD __xlstat
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c
index 3c44ba975d5a..cec3dd4250b1 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/machdep.c
@@ -598,18 +598,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
PROC_LOCK(p);
}
-/*
- * Stub to satisfy the reference to osigreturn in the syscall table. This
- * is needed even for newer arches that don't support old signals because
- * the syscall table is machine-independent.
- */
-int
-osigreturn(struct thread *td, struct osigreturn_args *uap)
-{
-
- return (nosys(td, (struct nosys_args *)uap));
-}
-
int
sigreturn(struct thread *td, struct sigreturn_args *uap)
{
@@ -656,6 +644,15 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
return (EJUSTRETURN);
}
+#ifdef COMPAT_FREEBSD4
+int
+freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
+{
+
+ return sigreturn(td, (struct sigreturn_args *)uap);
+}
+#endif
+
void
cpu_boot(int howto)
{
diff --git a/sys/powerpc/include/signal.h b/sys/powerpc/include/signal.h
index 55b16ddd3539..c290bb9bd74e 100644
--- a/sys/powerpc/include/signal.h
+++ b/sys/powerpc/include/signal.h
@@ -44,28 +44,7 @@
typedef int sig_atomic_t;
#ifdef _KERNEL
-typedef unsigned int osigset_t;
-
#include <machine/frame.h>
-
-/*
- * XXX why do we have compatibility structs for a new platform?
- */
-#if defined(__LIBC12_SOURCE__) || defined(_KERNEL)
-struct sigcontext13 {
- int sc_onstack; /* saved onstack flag */
- int sc_mask; /* saved signal mask (old style) */
- struct trapframe sc_frame; /* saved registers */
-};
-#endif /* __LIBC12_SOURCE__ || _KERNEL */
-
-struct osigcontext {
- int sc_onstack; /* saved onstack flag */
- int __sc_mask13; /* saved signal mask (old style) */
- struct trapframe sc_frame; /* saved registers */
- struct __sigset sc_mask; /* saved signal mask (new style) */
-};
-
#endif /* _KERNEL */
#if __BSD_VISIBLE
diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c
index 3c44ba975d5a..cec3dd4250b1 100644
--- a/sys/powerpc/powerpc/machdep.c
+++ b/sys/powerpc/powerpc/machdep.c
@@ -598,18 +598,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
PROC_LOCK(p);
}
-/*
- * Stub to satisfy the reference to osigreturn in the syscall table. This
- * is needed even for newer arches that don't support old signals because
- * the syscall table is machine-independent.
- */
-int
-osigreturn(struct thread *td, struct osigreturn_args *uap)
-{
-
- return (nosys(td, (struct nosys_args *)uap));
-}
-
int
sigreturn(struct thread *td, struct sigreturn_args *uap)
{
@@ -656,6 +644,15 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
return (EJUSTRETURN);
}
+#ifdef COMPAT_FREEBSD4
+int
+freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
+{
+
+ return sigreturn(td, (struct sigreturn_args *)uap);
+}
+#endif
+
void
cpu_boot(int howto)
{
diff --git a/sys/sparc64/include/signal.h b/sys/sparc64/include/signal.h
index c27ad575ff7c..2b834ad69af1 100644
--- a/sys/sparc64/include/signal.h
+++ b/sys/sparc64/include/signal.h
@@ -46,14 +46,6 @@ typedef long sig_atomic_t;
#define MINSIGSTKSZ (1024 * 4)
#endif
-#ifdef _KERNEL
-typedef int osigset_t;
-
-struct osigcontext {
- int dummy;
-};
-#endif
-
#if __BSD_VISIBLE
struct sigcontext {
int _dummy;
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 55ef2a9ade70..820305685b26 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -40,6 +40,7 @@
* $FreeBSD$
*/
+#include "opt_compat.h"
#include "opt_ddb.h"
#include "opt_msgbuf.h"
@@ -449,20 +450,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
PROC_LOCK(p);
}
-/*
- * Stub to satisfy the reference to osigreturn in the syscall table. This
- * is needed even for newer arches that don't support old signals because
- * the syscall table is machine-independent.
- *
- * MPSAFE
- */
-int
-osigreturn(struct thread *td, struct osigreturn_args *uap)
-{
-
- return (nosys(td, (struct nosys_args *)uap));
-}
-
#ifndef _SYS_SYSPROTO_H_
struct sigreturn_args {
ucontext_t *ucp;
@@ -506,6 +493,15 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
return (EJUSTRETURN);
}
+#ifdef COMPAT_FREEBSD4
+int
+freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
+{
+
+ return sigreturn(td, (struct sigreturn_args *)uap);
+}
+#endif
+
/*
* Exit the kernel and execute a firmware call that will not return, as
* specified by the arguments.
diff --git a/sys/sys/_sigset.h b/sys/sys/_sigset.h
index dfb954e5b762..77f2a9acfc97 100644
--- a/sys/sys/_sigset.h
+++ b/sys/sys/_sigset.h
@@ -56,4 +56,8 @@ typedef struct __sigset {
__uint32_t __bits[_SIG_WORDS];
} __sigset_t;
+#if defined(_KERNEL) && defined(COMPAT_43)
+typedef unsigned int osigset_t;
+#endif
+
#endif /* !_SYS__SIGSET_H_ */
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
index edbb46097b28..deae42d69976 100644
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -302,6 +302,14 @@ struct sigvec {
#define sv_onstack sv_flags /* isn't compatibility wonderful! */
#endif
+/* Keep this in one place only */
+#if defined(_KERNEL) && defined(COMPAT_43) && \
+ !defined(__i386__) && !defined(__alpha__)
+struct osigcontext {
+ int _not_used;
+};
+#endif
+
#if __XSI_VISIBLE
/*
* Structure used in sigstack call.
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index d2fbacf95d28..d7d7227e0ab7 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -56,11 +56,12 @@ struct sigacts {
sigset_t ps_sigreset; /* signals that reset when caught */
sigset_t ps_signodefer; /* signals not masked while handled */
sigset_t ps_siginfo; /* signals that want SA_SIGINFO args */
- sigset_t ps_osigset; /* signals that use osigset_t */
+ sigset_t ps_freebsd4; /* signals that use freebsd4 ucontext */
+ sigset_t ps_osigset; /* signals that use <= 3.x osigset_t */
sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */
};
-#ifdef _KERNEL
+#if defined(_KERNEL) && defined(COMPAT_43)
/*
* Compatibility.
*/
@@ -81,7 +82,7 @@ struct osigaction {
};
typedef void __osiginfohandler_t(int, osiginfo_t *, void *);
-#endif /* _KERNEL */
+#endif /* _KERNEL && COMPAT_43 */
/* additional signal action values, used only temporarily/internally */
#define SIG_CATCH ((__sighandler_t *)2)
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index b1da44913dc1..a72b3179b3ed 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -107,7 +107,7 @@
#define SYS_getpriority 100
/* 101 is old send */
/* 102 is old recv */
-#define SYS_osigreturn 103
+ /* 103 is old sigreturn */
#define SYS_bind 104
#define SYS_setsockopt 105
#define SYS_listen 106
@@ -265,9 +265,9 @@
#define SYS_jail 338
#define SYS_sigprocmask 340
#define SYS_sigsuspend 341
-#define SYS_sigaction 342
+ /* 342 is old sigaction */
#define SYS_sigpending 343
-#define SYS_sigreturn 344
+ /* 344 is old sigreturn */
#define SYS___acl_get_file 347
#define SYS___acl_set_file 348
#define SYS___acl_get_fd 349
@@ -323,4 +323,6 @@
#define SYS_extattr_set_link 412
#define SYS_extattr_get_link 413
#define SYS_extattr_delete_link 414
+#define SYS_sigaction 416
+#define SYS_sigreturn 417
#define SYS_MAXSYSCALL 421
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index 4e6f0ea5d536..51fc2f943e17 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -82,7 +82,6 @@ MIASM = \
socket.o \
connect.o \
getpriority.o \
- osigreturn.o \
bind.o \
setsockopt.o \
listen.o \
@@ -214,9 +213,7 @@ MIASM = \
jail.o \
sigprocmask.o \
sigsuspend.o \
- sigaction.o \
sigpending.o \
- sigreturn.o \
__acl_get_file.o \
__acl_set_file.o \
__acl_get_fd.o \
@@ -271,4 +268,6 @@ MIASM = \
__mac_set_link.o \
extattr_set_link.o \
extattr_get_link.o \
- extattr_delete_link.o
+ extattr_delete_link.o \
+ sigaction.o \
+ sigreturn.o
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index aa434c2574ee..25c2f53d4185 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -67,7 +67,7 @@ int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg);
int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
fd_set *fd_ex, struct timeval *tvp);
int kern_sigaction(struct thread *td, int sig, struct sigaction *act,
- struct sigaction *oact, int old);
+ struct sigaction *oact, int flags);
int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);
int kern_sigsuspend(struct thread *td, sigset_t mask);
int kern_symlink(struct thread *td, char *path, char *link,
@@ -78,4 +78,8 @@ int kern_unlink(struct thread *td, char *path, enum uio_seg pathseg);
int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg,
struct timeval *tptr, enum uio_seg tptrseg);
+/* flags for kern_sigaction */
+#define KSA_OSIGSET 0x0001 /* uses osigact_t */
+#define KSA_FREEBSD4 0x0002 /* uses ucontext4 */
+
#endif /* !_SYS_SYSCALLSUBR_H_ */
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 6f1904a8a2a3..683c722d08c4 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -361,9 +361,6 @@ struct getpriority_args {
char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)];
};
-struct osigreturn_args {
- char sigcntxp_l_[PADL_(struct osigcontext *)]; struct osigcontext * sigcntxp; char sigcntxp_r_[PADR_(struct osigcontext *)];
-};
struct bind_args {
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
char name_l_[PADL_(caddr_t)]; caddr_t name; char name_r_[PADR_(caddr_t)];
@@ -923,17 +920,9 @@ struct sigprocmask_args {
struct sigsuspend_args {
char sigmask_l_[PADL_(const sigset_t *)]; const sigset_t * sigmask; char sigmask_r_[PADR_(const sigset_t *)];
};
-struct sigaction_args {
- char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
- char act_l_[PADL_(const struct sigaction *)]; const struct sigaction * act; char act_r_[PADR_(const struct sigaction *)];
- char oact_l_[PADL_(struct sigaction *)]; struct sigaction * oact; char oact_r_[PADR_(struct sigaction *)];
-};
struct sigpending_args {
char set_l_[PADL_(sigset_t *)]; sigset_t * set; char set_r_[PADR_(sigset_t *)];
};
-struct sigreturn_args {
- char sigcntxp_l_[PADL_(const struct __ucontext *)]; const struct __ucontext * sigcntxp; char sigcntxp_r_[PADR_(const struct __ucontext *)];
-};
struct __acl_get_file_args {
char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
char type_l_[PADL_(acl_type_t)]; acl_type_t type; char type_r_[PADR_(acl_type_t)];
@@ -1188,6 +1177,14 @@ struct extattr_delete_link_args {
char attrnamespace_l_[PADL_(int)]; int attrnamespace; char attrnamespace_r_[PADR_(int)];
char attrname_l_[PADL_(const char *)]; const char * attrname; char attrname_r_[PADR_(const char *)];
};
+struct sigaction_args {
+ char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
+ char act_l_[PADL_(const struct sigaction *)]; const struct sigaction * act; char act_r_[PADR_(const struct sigaction *)];
+ char oact_l_[PADL_(struct sigaction *)]; struct sigaction * oact; char oact_r_[PADR_(struct sigaction *)];
+};
+struct sigreturn_args {
+ char sigcntxp_l_[PADL_(const struct __ucontext *)]; const struct __ucontext * sigcntxp; char sigcntxp_r_[PADR_(const struct __ucontext *)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_exit(struct thread *, struct sys_exit_args *);
int fork(struct thread *, struct fork_args *);
@@ -1267,7 +1264,6 @@ int setpriority(struct thread *, struct setpriority_args *);
int socket(struct thread *, struct socket_args *);
int connect(struct thread *, struct connect_args *);
int getpriority(struct thread *, struct getpriority_args *);
-int osigreturn(struct thread *, struct osigreturn_args *);
int bind(struct thread *, struct bind_args *);
int setsockopt(struct thread *, struct setsockopt_args *);
int listen(struct thread *, struct listen_args *);
@@ -1397,9 +1393,7 @@ int kldsym(struct thread *, struct kldsym_args *);
int jail(struct thread *, struct jail_args *);
int sigprocmask(struct thread *, struct sigprocmask_args *);
int sigsuspend(struct thread *, struct sigsuspend_args *);
-int sigaction(struct thread *, struct sigaction_args *);
int sigpending(struct thread *, struct sigpending_args *);
-int sigreturn(struct thread *, struct sigreturn_args *);
int __acl_get_file(struct thread *, struct __acl_get_file_args *);
int __acl_set_file(struct thread *, struct __acl_set_file_args *);
int __acl_get_fd(struct thread *, struct __acl_get_fd_args *);
@@ -1456,6 +1450,8 @@ int __mac_set_link(struct thread *, struct __mac_set_link_args *);
int extattr_set_link(struct thread *, struct extattr_set_link_args *);
int extattr_get_link(struct thread *, struct extattr_get_link_args *);
int extattr_delete_link(struct thread *, struct extattr_delete_link_args *);
+int sigaction(struct thread *, struct sigaction_args *);
+int sigreturn(struct thread *, struct sigreturn_args *);
#ifdef COMPAT_43
@@ -1523,6 +1519,9 @@ struct orecv_args {
char len_l_[PADL_(int)]; int len; char len_r_[PADR_(int)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
+struct osigreturn_args {
+ char sigcntxp_l_[PADL_(struct osigcontext *)]; struct osigcontext * sigcntxp; char sigcntxp_r_[PADR_(struct osigcontext *)];
+};
struct osigvec_args {
char signum_l_[PADL_(int)]; int signum; char signum_r_[PADR_(int)];
char nsv_l_[PADL_(struct sigvec *)]; struct sigvec * nsv; char nsv_r_[PADR_(struct sigvec *)];
@@ -1602,6 +1601,7 @@ int osethostname(struct thread *, struct sethostname_args *);
int oaccept(struct thread *, struct accept_args *);
int osend(struct thread *, struct osend_args *);
int orecv(struct thread *, struct orecv_args *);
+int osigreturn(struct thread *, struct osigreturn_args *);
int osigvec(struct thread *, struct osigvec_args *);
int osigblock(struct thread *, struct osigblock_args *);
int osigsetmask(struct thread *, struct osigsetmask_args *);
@@ -1636,7 +1636,17 @@ struct freebsd4_sendfile_args {
char sbytes_l_[PADL_(off_t *)]; off_t * sbytes; char sbytes_r_[PADR_(off_t *)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
+struct freebsd4_sigaction_args {
+ char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
+ char act_l_[PADL_(const struct sigaction *)]; const struct sigaction * act; char act_r_[PADR_(const struct sigaction *)];
+ char oact_l_[PADL_(struct sigaction *)]; struct sigaction * oact; char oact_r_[PADR_(struct sigaction *)];
+};
+struct freebsd4_sigreturn_args {
+ char sigcntxp_l_[PADL_(const struct ucontext4 *)]; const struct ucontext4 * sigcntxp; char sigcntxp_r_[PADR_(const struct ucontext4 *)];
+};
int freebsd4_sendfile(struct thread *, struct freebsd4_sendfile_args *);
+int freebsd4_sigaction(struct thread *, struct freebsd4_sigaction_args *);
+int freebsd4_sigreturn(struct thread *, struct freebsd4_sigreturn_args *);
#endif /* COMPAT_FREEBSD4 */
diff --git a/sys/sys/ucontext.h b/sys/sys/ucontext.h
index 194b63a73595..dcce16e1a6fb 100644
--- a/sys/sys/ucontext.h
+++ b/sys/sys/ucontext.h
@@ -53,6 +53,20 @@ typedef struct __ucontext {
int __spare__[4];
} ucontext_t;
+#if defined(_KERNEL) && defined(COMPAT_FREEBSD4)
+#if defined(__i386__) || defined(__alpha__)
+struct ucontext4 {
+ sigset_t uc_sigmask;
+ struct mcontext4 uc_mcontext;
+ struct ucontext4 *uc_link;
+ stack_t uc_stack;
+ int __spare__[8];
+};
+#else /* __i386__ || __alpha__ */
+#define ucontext4 ucontext
+#endif /* __i386__ || __alpha__ */
+#endif /* _KERNEL */
+
#ifndef _KERNEL
__BEGIN_DECLS