summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkstailey <kstailey@openbsd.org>1999-09-26 11:07:32 +0000
committerkstailey <kstailey@openbsd.org>1999-09-26 11:07:32 +0000
commitacef8e5dd3ee74dc78f560c6aa41885bc5b84d80 (patch)
tree227c67127cc75c4cb3c3bf06a269f669181a29d8
parentstring.h (diff)
downloadwireguard-openbsd-acef8e5dd3ee74dc78f560c6aa41885bc5b84d80.tar.xz
wireguard-openbsd-acef8e5dd3ee74dc78f560c6aa41885bc5b84d80.zip
netbsd_sendsig() + supporting code
-rw-r--r--sys/arch/alpha/alpha/genassym.c10
-rw-r--r--sys/arch/alpha/alpha/locore.s23
-rw-r--r--sys/arch/alpha/alpha/netbsd_machdep.c153
-rw-r--r--sys/arch/alpha/include/asm.h9
-rw-r--r--sys/compat/netbsd/netbsd_exec.c30
5 files changed, 205 insertions, 20 deletions
diff --git a/sys/arch/alpha/alpha/genassym.c b/sys/arch/alpha/alpha/genassym.c
index cfe3ddabf00..f1d15a97ecc 100644
--- a/sys/arch/alpha/alpha/genassym.c
+++ b/sys/arch/alpha/alpha/genassym.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: genassym.c,v 1.5 1996/10/30 22:38:10 niklas Exp $ */
+/* $OpenBSD: genassym.c,v 1.6 1999/09/26 11:07:32 kstailey Exp $ */
/* $NetBSD: genassym.c,v 1.9 1996/08/20 23:00:24 cgd Exp $ */
/*
@@ -55,6 +55,10 @@
#include <stdio.h>
#include <err.h>
+#ifdef COMPAT_NETBSD
+# include <compat/netbsd/netbsd_syscall.h>
+#endif
+
void def __P((char *, long));
int main __P((int argc, char **argv));
@@ -182,6 +186,10 @@ main(argc, argv)
/* Syscalls called from sigreturn. */
def("SYS_sigreturn", SYS_sigreturn);
def("SYS_exit", SYS_exit);
+#ifdef COMPAT_NETBSD
+ def("NETBSD_SYS___sigreturn14", NETBSD_SYS___sigreturn14);
+ def("NETBSD_SYS_exit", NETBSD_SYS_exit);
+#endif
exit(0);
}
diff --git a/sys/arch/alpha/alpha/locore.s b/sys/arch/alpha/alpha/locore.s
index d4af7fbf64e..e7ed78d46bb 100644
--- a/sys/arch/alpha/alpha/locore.s
+++ b/sys/arch/alpha/alpha/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.9 1997/07/08 10:55:53 niklas Exp $ */
+/* $OpenBSD: locore.s,v 1.10 1999/09/26 11:07:32 kstailey Exp $ */
/* $NetBSD: locore.s,v 1.27 1996/12/03 19:54:16 cgd Exp $ */
/*
@@ -168,6 +168,27 @@ XNESTED(esigcode,0)
/**************************************************************************/
+#ifdef COMPAT_NETBSD
+/*
+ * NetBSD signal trampoline code. Almost identical to the normal one.
+ */
+
+NESTED(netbsd_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)
+ NETBSD_CALLSYS_NOERROR(__sigreturn14)/* and call sigreturn() with it. */
+ mov v0, a0 /* if that failed, get error code */
+ NETBSD_CALLSYS_NOERROR(exit) /* and call exit() with it. */
+XNESTED(netbsd_esigcode,0)
+ END(netbsd_sigcode)
+
+#endif /* COMPAT_NETBSD */
+
+/**************************************************************************/
+
/*
* exception_return: return from trap, exception, or syscall
*/
diff --git a/sys/arch/alpha/alpha/netbsd_machdep.c b/sys/arch/alpha/alpha/netbsd_machdep.c
index 128571d3c49..af735a477e3 100644
--- a/sys/arch/alpha/alpha/netbsd_machdep.c
+++ b/sys/arch/alpha/alpha/netbsd_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_machdep.c,v 1.2 1999/09/16 13:20:06 kstailey Exp $ */
+/* $OpenBSD: netbsd_machdep.c,v 1.3 1999/09/26 11:07:32 kstailey Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -31,6 +31,7 @@
#include <sys/systm.h>
#include <sys/signalvar.h>
#include <sys/kernel.h>
+#include <sys/exec.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/mount.h>
@@ -56,6 +57,9 @@ extern int sigpid;
static void netbsd_to_openbsd_sigcontext __P ((struct netbsd_sigcontext *,
struct sigcontext *));
+static void openbsd_to_netbsd_sigcontext __P ((struct sigcontext *,
+ struct netbsd_sigcontext *));
+
static void
netbsd_to_openbsd_sigcontext(nbsc, obsc)
struct netbsd_sigcontext *nbsc;
@@ -73,6 +77,146 @@ netbsd_to_openbsd_sigcontext(nbsc, obsc)
obsc->sc_fp_control = nbsc->sc_fp_control;
}
+static void
+openbsd_to_netbsd_sigcontext(obsc, nbsc)
+ struct sigcontext *obsc;
+ struct netbsd_sigcontext *nbsc;
+{
+ bzero(nbsc, sizeof(nbsc));
+ nbsc->sc_onstack = obsc->sc_onstack;
+ nbsc->__sc_mask13 = obsc->sc_mask;
+ bcopy(&obsc->sc_mask, &nbsc->sc_mask.__bits[0], sizeof(sigset_t));
+ nbsc->sc_pc = obsc->sc_pc;
+ nbsc->sc_ps = obsc->sc_ps;
+ bcopy(obsc->sc_regs, nbsc->sc_regs, sizeof(obsc->sc_regs));
+ nbsc->sc_ownedfp = obsc->sc_ownedfp;
+ bcopy(obsc->sc_fpregs, nbsc->sc_fpregs, sizeof(obsc->sc_fpregs));
+ nbsc->sc_fpcr = obsc->sc_fpcr;
+ nbsc->sc_fp_control = obsc->sc_fp_control;
+}
+
+/*
+ * Send an interrupt to process.
+ */
+void
+netbsd_sendsig(catcher, sig, mask, code, type, val)
+ sig_t catcher;
+ int sig, mask;
+ u_long code;
+ int type;
+ union sigval val;
+{
+ struct proc *p = curproc;
+ struct sigcontext *scp, ksc;
+ struct trapframe *frame;
+ struct sigacts *psp = p->p_sigacts;
+ int oonstack, fsize, rndfsize;
+ extern char netbsd_sigcode[], netbsd_esigcode[];
+ extern struct proc *fpcurproc;
+ struct netbsd_sigcontext nbsc;
+
+ frame = p->p_md.md_tf;
+ oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+ fsize = sizeof(nbsc);
+ rndfsize = ((fsize + 15) / 16) * 16;
+ /*
+ * 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 ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
+ (psp->ps_sigonstack & sigmask(sig))) {
+ scp = (struct sigcontext *)(psp->ps_sigstk.ss_sp +
+ psp->ps_sigstk.ss_size - rndfsize);
+ psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+ } else
+ scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize);
+ if ((u_long)scp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
+ (void)grow(p, (u_long)scp);
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
+ printf("netbsd_sendsig(%d): sig %d ssp %p usp %p scp %p\n",
+ p->p_pid, sig, &oonstack, alpha_pal_rdusp(), scp);
+#endif
+ if (useracc((caddr_t)scp, fsize, B_WRITE) == 0) {
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
+ printf("netbsd_sendsig(%d): useracc failed on sig %d\n",
+ p->p_pid, sig);
+#endif
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ SIGACTION(p, SIGILL) = SIG_DFL;
+ sig = sigmask(SIGILL);
+ p->p_sigignore &= ~sig;
+ p->p_sigcatch &= ~sig;
+ p->p_sigmask &= ~sig;
+ psignal(p, SIGILL);
+ return;
+ }
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ ksc.sc_onstack = oonstack;
+ ksc.sc_mask = mask;
+ ksc.sc_pc = frame->tf_regs[FRAME_PC];
+ ksc.sc_ps = frame->tf_regs[FRAME_PS];
+
+ /* copy the registers. */
+ frametoreg(frame, (struct reg *)ksc.sc_regs);
+ ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */
+ ksc.sc_regs[R_SP] = alpha_pal_rdusp();
+
+ /* save the floating-point state, if necessary, then copy it. */
+ if (p == fpcurproc) {
+ alpha_pal_wrfen(1);
+ savefpstate(&p->p_addr->u_pcb.pcb_fp);
+ alpha_pal_wrfen(0);
+ fpcurproc = NULL;
+ }
+ ksc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED;
+ bcopy(&p->p_addr->u_pcb.pcb_fp, (struct fpreg *)ksc.sc_fpregs,
+ sizeof(struct fpreg));
+ ksc.sc_fp_control = 0; /* XXX ? */
+ bzero(ksc.sc_reserved, sizeof ksc.sc_reserved); /* XXX */
+ bzero(ksc.sc_xxx, sizeof ksc.sc_xxx); /* XXX */
+
+ /*
+ * copy the frame out to userland.
+ */
+ openbsd_to_netbsd_sigcontext(&ksc, &nbsc);
+ (void) copyout((caddr_t)&nbsc, (caddr_t)scp, sizeof(nbsc));
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW)
+ printf("netbsd_sendsig(%d): sig %d scp %p code %lx\n",
+ p->p_pid, sig, scp, code);
+#endif
+
+ /*
+ * Set up the registers to return to netbsd_sigcode.
+ */
+ frame->tf_regs[FRAME_PC] =
+ (u_int64_t)PS_STRINGS - (netbsd_esigcode - netbsd_sigcode);
+ frame->tf_regs[FRAME_A0] = sig;
+ frame->tf_regs[FRAME_A1] = code;
+ frame->tf_regs[FRAME_A2] = (u_int64_t)scp;
+ frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */
+ alpha_pal_wrusp((unsigned long)scp);
+
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW)
+ printf("netbsd_sendsig(%d): pc %lx, catcher %lx\n", p->p_pid,
+ frame->tf_regs[FRAME_PC], frame->tf_regs[FRAME_T12]);
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
+ printf("netbsd_sendsig(%d): sig %d returns\n", p->p_pid, sig);
+#endif
+}
+
/* ARGSUSED */
int
netbsd_sys___sigreturn14(p, v, retval)
@@ -83,16 +227,15 @@ netbsd_sys___sigreturn14(p, v, retval)
struct netbsd_sys___sigreturn14_args /* {
syscallarg(struct netbsd_sigcontext *) sigcntxp;
} */ *uap = v;
- struct sigcontext *scp, ksc;
+ struct sigcontext ksc;
extern struct proc *fpcurproc;
struct netbsd_sigcontext *nbscp, nbsc;
nbscp = SCARG(uap, sigcntxp);
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
- printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
+ printf("sigreturn: pid %d, nbscp %p\n", p->p_pid, nbscp);
#endif
-
if (ALIGN(nbscp) != (u_int64_t)nbscp)
return (EINVAL);
@@ -102,7 +245,7 @@ netbsd_sys___sigreturn14(p, v, retval)
*/
if (useracc((caddr_t)nbscp, sizeof (*nbscp), B_WRITE) == 0 ||
copyin((caddr_t)nbscp, (caddr_t)&nbsc, sizeof (nbsc)))
- return (EINVAL);
+ return (EFAULT);
netbsd_to_openbsd_sigcontext(&nbsc, &ksc);
diff --git a/sys/arch/alpha/include/asm.h b/sys/arch/alpha/include/asm.h
index 7783b3b963e..5ec88decbca 100644
--- a/sys/arch/alpha/include/asm.h
+++ b/sys/arch/alpha/include/asm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: asm.h,v 1.6 1997/01/24 19:57:07 niklas Exp $ */
+/* $OpenBSD: asm.h,v 1.7 1999/09/26 11:07:32 kstailey Exp $ */
/* $NetBSD: asm.h,v 1.11 1996/11/30 02:48:57 jtc Exp $ */
/*
@@ -615,6 +615,13 @@ label: ASCIZ msg; \
ldiq v0, SYSCALLNUM(name); \
call_pal PAL_OSF1_callsys
+#define NETBSD_SYSCALLNUM(name) \
+ ___CONCAT(NETBSD_SYS_,name)
+
+#define NETBSD_CALLSYS_NOERROR(name) \
+ ldiq v0, NETBSD_SYSCALLNUM(name); \
+ call_pal PAL_OSF1_callsys
+
/*
* Load the global pointer.
*/
diff --git a/sys/compat/netbsd/netbsd_exec.c b/sys/compat/netbsd/netbsd_exec.c
index 899d3eb57c7..56233a823b7 100644
--- a/sys/compat/netbsd/netbsd_exec.c
+++ b/sys/compat/netbsd/netbsd_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_exec.c,v 1.4 1999/09/19 16:16:49 kstailey Exp $ */
+/* $OpenBSD: netbsd_exec.c,v 1.5 1999/09/26 11:07:32 kstailey Exp $ */
/* $NetBSD: svr4_exec.c,v 1.16 1995/10/14 20:24:20 christos Exp $ */
/*
@@ -44,39 +44,42 @@
#include <machine/cpu.h>
#include <machine/reg.h>
-#if 0
-#include <machine/netbsd_machdep.h>
-#endif
#include <compat/netbsd/netbsd_util.h>
#include <compat/netbsd/netbsd_syscall.h>
#include <compat/netbsd/netbsd_exec.h>
+#include <compat/netbsd/netbsd_signal.h>
+
+#include <machine/netbsd_machdep.h>
+
+#ifdef _KERN_DO_ELF64
-static void *netbsd_copyargs __P((struct exec_package *, struct ps_strings *,
- void *, void *));
+static void *netbsd_elf64_copyargs __P((struct exec_package *,
+ struct ps_strings *, void *, void *));
-extern char sigcode[], esigcode[];
+extern char netbsd_sigcode[], netbsd_esigcode[];
extern struct sysent netbsd_sysent[];
extern char *netbsd_syscallnames[];
+
struct emul emul_elf64_netbsd = {
"netbsd",
NULL,
- sendsig,
+ netbsd_sendsig,
NETBSD_SYS_syscall,
NETBSD_SYS_MAXSYSCALL,
netbsd_sysent,
netbsd_syscallnames,
0,
- netbsd_copyargs,
+ netbsd_elf64_copyargs,
setregs,
exec_elf64_fixup,
- sigcode,
- esigcode,
+ netbsd_sigcode,
+ netbsd_esigcode,
};
static void *
-netbsd_copyargs(pack, arginfo, stack, argp)
+netbsd_elf64_copyargs(pack, arginfo, stack, argp)
struct exec_package *pack;
struct ps_strings *arginfo;
void *stack;
@@ -86,6 +89,7 @@ netbsd_copyargs(pack, arginfo, stack, argp)
if (!(a = (AuxInfo *)elf64_copyargs(pack, arginfo, stack, argp)))
return (NULL);
+
return (a);
}
@@ -118,3 +122,5 @@ netbsd_elf64_probe(p, epp, itp, pos, os)
*os = OOS_NETBSD;
return (0);
}
+
+#endif /* _KERN_DO_ELF64 */