Module Name: src
Committed By: pgoyette
Date: Sun Sep 30 00:17:55 UTC 2018
Modified Files:
src/sys/arch/sparc64/conf [pgoyette-compat]: files.sparc64
src/sys/arch/sparc64/sparc64 [pgoyette-compat]: netbsd32_machdep.c
Added Files:
src/sys/arch/sparc64/sparc64 [pgoyette-compat]: netbsd32_machdep_13.c
netbsd32_machdep_16.c
Log Message:
Split sparc64/netbsd32_machdep.c into pieces specific to versions _13
and _16
XXX Somehow this has broken compat_sunos - must investigate further
To generate a diff of this commit:
cvs rdiff -u -r1.154 -r1.154.2.1 src/sys/arch/sparc64/conf/files.sparc64
cvs rdiff -u -r1.110 -r1.110.14.1 \
src/sys/arch/sparc64/sparc64/netbsd32_machdep.c
cvs rdiff -u -r0 -r1.1.2.1 src/sys/arch/sparc64/sparc64/netbsd32_machdep_13.c \
src/sys/arch/sparc64/sparc64/netbsd32_machdep_16.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sparc64/conf/files.sparc64
diff -u src/sys/arch/sparc64/conf/files.sparc64:1.154 src/sys/arch/sparc64/conf/files.sparc64:1.154.2.1
--- src/sys/arch/sparc64/conf/files.sparc64:1.154 Tue Dec 19 14:34:08 2017
+++ src/sys/arch/sparc64/conf/files.sparc64 Sun Sep 30 00:17:54 2018
@@ -1,4 +1,4 @@
-# $NetBSD: files.sparc64,v 1.154 2017/12/19 14:34:08 nakayama Exp $
+# $NetBSD: files.sparc64,v 1.154.2.1 2018/09/30 00:17:54 pgoyette Exp $
# @(#)files.sparc64 8.1 (Berkeley) 7/19/93
# sparc64-specific configuration info
@@ -288,8 +288,12 @@ file arch/sparc64/sparc64/compat_16_mach
# NetBSD/sparc 32-bit Binary compatibility (COMPAT_NETBSD32)
include "compat/netbsd32/files.netbsd32"
-file arch/sparc64/sparc64/netbsd32_machdep.c compat_netbsd32
-file arch/sparc64/sparc64/netbsd32_sigcode.s compat_netbsd32
+file arch/sparc64/sparc64/netbsd32_machdep.c compat_netbsd32
+file arch/sparc64/sparc64/netbsd32_machdep_13.c compat_netbsd32 &
+ compat_13
+file arch/sparc64/sparc64/netbsd32_machdep_16.c compat_netbsd32 &
+ compat_16
+file arch/sparc64/sparc64/netbsd32_sigcode.s compat_netbsd32
# SVR4 Binary Compatibility (COMPAT_SVR4)
include "compat/svr4/files.svr4"
Index: src/sys/arch/sparc64/sparc64/netbsd32_machdep.c
diff -u src/sys/arch/sparc64/sparc64/netbsd32_machdep.c:1.110 src/sys/arch/sparc64/sparc64/netbsd32_machdep.c:1.110.14.1
--- src/sys/arch/sparc64/sparc64/netbsd32_machdep.c:1.110 Wed Oct 19 09:44:01 2016
+++ src/sys/arch/sparc64/sparc64/netbsd32_machdep.c Sun Sep 30 00:17:55 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.c,v 1.110 2016/10/19 09:44:01 skrll Exp $ */
+/* $NetBSD: netbsd32_machdep.c,v 1.110.14.1 2018/09/30 00:17:55 pgoyette Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,13 +27,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.110 2016/10/19 09:44:01 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.110.14.1 2018/09/30 00:17:55 pgoyette Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
#include "opt_compat_sunos.h"
#include "opt_modular.h"
#include "opt_execfmt.h"
+#include "opt_coredump.h"
#include "firm_events.h"
#endif
@@ -88,6 +89,8 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_mac
const char machine32[] = "sparc";
const char machine_arch32[] = "sparc";
+int netbsd32_sendsig_siginfo(const ksiginfo_t *, const sigset_t *);
+
#if NFIRM_EVENTS > 0
static int ev_out32(struct firm_event *, int, struct uio *);
#endif
@@ -150,166 +153,12 @@ netbsd32_setregs(struct lwp *l, struct e
tf->tf_out[7] = 0;
}
-#ifdef COMPAT_16
-/*
- * NB: since this is a 32-bit address world, sf_scp and sf_sc
- * can't be a pointer since those are 64-bits wide.
- */
-struct sparc32_sigframe {
- int sf_signo; /* signal number */
- int sf_code; /* code */
- u_int sf_scp; /* SunOS user addr of sigcontext */
- int sf_addr; /* SunOS compat, always 0 for now */
- struct netbsd32_sigcontext sf_sc; /* actual sigcontext */
-};
-
-#undef DEBUG
-#ifdef DEBUG
-extern int sigdebug;
-#endif
-
-static void
-netbsd32_sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
-{
- int sig = ksi->ksi_signo;
- struct lwp *l = curlwp;
- struct proc *p = l->l_proc;
- struct sparc32_sigframe *fp;
- struct trapframe64 *tf;
- int addr, onstack, error;
- struct rwindow32 *oldsp, *newsp;
- register32_t sp;
- sig_t catcher = SIGACTION(p, sig).sa_handler;
- struct sparc32_sigframe sf;
- extern char netbsd32_sigcode[], netbsd32_esigcode[];
-#define szsigcode (netbsd32_esigcode - netbsd32_sigcode)
-
- tf = l->l_md.md_tf;
- /* Need to attempt to zero extend this 32-bit pointer */
- oldsp = (struct rwindow32 *)(u_long)(u_int)tf->tf_out[6];
- /* Do we need to jump onto the signal stack? */
- onstack =
- (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
- (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
- if (onstack) {
- fp = (struct sparc32_sigframe *)((char *)l->l_sigstk.ss_sp +
- l->l_sigstk.ss_size);
- l->l_sigstk.ss_flags |= SS_ONSTACK;
- } else
- fp = (struct sparc32_sigframe *)oldsp;
- fp = (struct sparc32_sigframe *)((u_long)(fp - 1) & ~7);
-
-#ifdef DEBUG
- sigpid = p->p_pid;
- if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
- printf("sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n",
- p->p_comm, p->p_pid, sig, fp, &fp->sf_sc, oldsp);
- if (sigdebug & SDB_DDB) Debugger();
- }
-#endif
- /*
- * Now set up the signal frame. We build it in kernel space
- * and then copy it out. We probably ought to just build it
- * directly in user space....
- */
- sf.sf_signo = sig;
- sf.sf_code = (u_int)ksi->ksi_trap;
-#if defined(COMPAT_SUNOS) || defined(MODULAR)
- sf.sf_scp = (u_long)&fp->sf_sc;
-#endif
- sf.sf_addr = 0; /* XXX */
-
- /*
- * Build the signal context to be used by sigreturn.
- */
- sf.sf_sc.sc_onstack = onstack;
- sf.sf_sc.sc_mask = *mask;
- sf.sf_sc.sc_sp = (u_long)oldsp;
- sf.sf_sc.sc_pc = tf->tf_pc;
- sf.sf_sc.sc_npc = tf->tf_npc;
- sf.sf_sc.sc_psr = TSTATECCR_TO_PSR(tf->tf_tstate); /* XXX */
- sf.sf_sc.sc_g1 = tf->tf_global[1];
- sf.sf_sc.sc_o0 = tf->tf_out[0];
-
- /*
- * Put the stack in a consistent state before we whack away
- * at it. Note that write_user_windows may just dump the
- * registers into the pcb; we need them in the process's memory.
- * We also need to make sure that when we start the signal handler,
- * its %i6 (%fp), which is loaded from the newly allocated stack area,
- * joins seamlessly with the frame it was in when the signal occurred,
- * so that the debugger and _longjmp code can back up through it.
- */
- sendsig_reset(l, sig);
- mutex_exit(p->p_lock);
- newsp = (struct rwindow32 *)((long)fp - sizeof(struct rwindow32));
- write_user_windows();
-#ifdef DEBUG
- if ((sigdebug & SDB_KSTACK))
- printf("sendsig: saving sf to %p, setting stack pointer %p to %p\n",
- fp, &(((struct rwindow32 *)newsp)->rw_in[6]), oldsp);
-#endif
- sp = NETBSD32PTR32I(oldsp);
- error = (rwindow_save(l) ||
- copyout(&sf, fp, sizeof sf) ||
- copyout(&sp, &(((struct rwindow32 *)newsp)->rw_in[6]),
- sizeof(sp)));
- mutex_enter(p->p_lock);
- if (error) {
- /*
- * Process has trashed its stack; give it an illegal
- * instruction to halt it in its tracks.
- */
-#ifdef DEBUG
- mutex_exit(p->p_lock);
- if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
- printf("sendsig: window save or copyout error\n");
- printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
- if (sigdebug & SDB_DDB) Debugger();
- mutex_enter(p->p_lock);
-#endif
- sigexit(l, SIGILL);
- /* NOTREACHED */
- }
-
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW) {
- printf("sendsig: %s[%d] sig %d scp %p\n",
- p->p_comm, p->p_pid, sig, &fp->sf_sc);
- }
-#endif
- /*
- * Arrange to continue execution at the code copied out in exec().
- * It needs the function to call in %g1, and a new stack pointer.
- */
- addr = p->p_psstrp - szsigcode;
- tf->tf_global[1] = (long)catcher;
- tf->tf_pc = addr;
- tf->tf_npc = addr + 4;
- tf->tf_out[6] = (uint64_t)(u_int)(u_long)newsp;
-
- /* Remember that we're now on the signal stack. */
- if (onstack)
- l->l_sigstk.ss_flags |= SS_ONSTACK;
-
-#ifdef DEBUG
- if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
- mutex_exit(p->p_lock);
- printf("sendsig: about to return to catcher %p thru %p\n",
- catcher, addr);
- if (sigdebug & SDB_DDB) Debugger();
- mutex_enter(p->p_lock);
- }
-#endif
-}
-#endif
-
struct sparc32_sigframe_siginfo {
siginfo32_t sf_si;
ucontext32_t sf_uc;
};
-static void
+int
netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
{
struct lwp *l = curlwp;
@@ -407,197 +256,26 @@ netbsd32_sendsig_siginfo(const ksiginfo_
/* Remember that we're now on the signal stack. */
if (onstack)
l->l_sigstk.ss_flags |= SS_ONSTACK;
-}
-void
-netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
-{
-#ifdef COMPAT_16
- if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
- netbsd32_sendsig_sigcontext(ksi, mask);
- else
-#endif
- netbsd32_sendsig_siginfo(ksi, mask);
+ return 0;
}
-#undef DEBUG
+struct netbsd32_sendsig_hook_t netbsd32_sendsig_hook;
+
+MODULE_CALL_HOOK_DECL(netbsd32_sendsig_hook, f,
+ (const ksiginfo_t *ksi, const sigset_t *mask));
+MODULE_CALL_HOOK(netbsd32_sendsig_hook, f,
+ (const ksiginfo_t *ksi, const sigset_t *mask), (ksi, mask),
+ netbsd32_sendsig_siginfo(ksi, mask));
-#ifdef COMPAT_13
-int
-compat_13_netbsd32_sigreturn(struct lwp *l, const struct compat_13_netbsd32_sigreturn_args *uap, register_t *retval)
+void
+netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
{
- /* {
- syscallarg(struct netbsd32_sigcontext13 *) sigcntxp;
- } */
- struct netbsd32_sigcontext13 *scp;
- struct netbsd32_sigcontext13 sc;
- struct trapframe64 *tf;
- struct proc *p = l->l_proc;
- sigset_t mask;
-
- /* First ensure consistent stack state (see sendsig). */
- write_user_windows();
- if (rwindow_save(l)) {
-#ifdef DEBUG
- printf("compat_13_netbsd32_sigreturn: rwindow_save(%p) failed, sending SIGILL\n", p);
- Debugger();
-#endif
- mutex_enter(p->p_lock);
- sigexit(l, SIGILL);
- }
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW) {
- printf("compat_13_netbsd32_sigreturn: %s[%d], sigcntxp %p\n",
- p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
- if (sigdebug & SDB_DDB) Debugger();
- }
-#endif
- scp = (struct netbsd32_sigcontext13 *)(u_long)SCARG(uap, sigcntxp);
- if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
- {
-#ifdef DEBUG
- printf("compat_13_netbsd32_sigreturn: copyin failed\n");
- Debugger();
-#endif
- return (EINVAL);
- }
- scp = ≻
- tf = l->l_md.md_tf;
- /*
- * Only the icc bits in the psr are used, so it need not be
- * verified. pc and npc must be multiples of 4. This is all
- * that is required; if it holds, just do it.
- */
- if (((sc.sc_pc | sc.sc_npc) & 3) != 0)
-#ifdef DEBUG
- {
- printf("compat_13_netbsd32_sigreturn: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
- Debugger();
- return (EINVAL);
- }
-#else
- return (EINVAL);
-#endif
- /* take only psr ICC field */
- tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
- tf->tf_pc = (int64_t)sc.sc_pc;
- tf->tf_npc = (int64_t)sc.sc_npc;
- tf->tf_global[1] = (int64_t)sc.sc_g1;
- tf->tf_out[0] = (int64_t)sc.sc_o0;
- tf->tf_out[6] = (int64_t)sc.sc_sp;
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW) {
- printf("compat_13_netbsd32_sys_sigreturn: return trapframe pc=%p sp=%p tstate=%x\n",
- (int)tf->tf_pc, (int)tf->tf_out[6], (int)tf->tf_tstate);
- if (sigdebug & SDB_DDB) Debugger();
- }
-#endif
- mutex_enter(p->p_lock);
- if (scp->sc_onstack & SS_ONSTACK)
- l->l_sigstk.ss_flags |= SS_ONSTACK;
- else
- l->l_sigstk.ss_flags &= ~SS_ONSTACK;
- /* Restore signal mask */
- native_sigset13_to_sigset((sigset13_t *)&scp->sc_mask, &mask);
- (void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
- mutex_exit(p->p_lock);
-
- return (EJUSTRETURN);
+ netbsd32_sendsig_hook_f_call(ksi, mask);
}
-#endif
-
-/*
- * System call to cleanup state after a signal
- * has been taken. Reset signal mask and
- * stack state from context left by sendsig (above),
- * and return to the given trap frame (if there is one).
- * Check carefully to make sure that the user has not
- * modified the state to gain improper privileges or to cause
- * a machine fault.
- */
-/* ARGSUSED */
-int
-compat_16_netbsd32___sigreturn14(struct lwp *l, const struct compat_16_netbsd32___sigreturn14_args *uap, register_t *retval)
-{
- /* {
- syscallarg(struct sigcontext *) sigcntxp;
- } */
- struct netbsd32_sigcontext sc, *scp;
- struct trapframe64 *tf;
- struct proc *p = l->l_proc;
-
- /* First ensure consistent stack state (see sendsig). */
- write_user_windows();
- if (rwindow_save(l)) {
-#ifdef DEBUG
- printf("netbsd32_sigreturn14: rwindow_save(%p) failed, sending SIGILL\n", p);
- Debugger();
-#endif
- mutex_enter(p->p_lock);
- sigexit(l, SIGILL);
- }
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW) {
- printf("netbsd32_sigreturn14: %s[%d], sigcntxp %p\n",
- p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
- if (sigdebug & SDB_DDB) Debugger();
- }
-#endif
- scp = (struct netbsd32_sigcontext *)(u_long)SCARG(uap, sigcntxp);
- if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
- {
-#ifdef DEBUG
- printf("netbsd32_sigreturn14: copyin failed: scp=%p\n", scp);
- Debugger();
-#endif
- return (EINVAL);
- }
- scp = ≻
-
- tf = l->l_md.md_tf;
- /*
- * Only the icc bits in the psr are used, so it need not be
- * verified. pc and npc must be multiples of 4. This is all
- * that is required; if it holds, just do it.
- */
- if (((sc.sc_pc | sc.sc_npc) & 3) != 0 || (sc.sc_pc == 0) || (sc.sc_npc == 0))
-#ifdef DEBUG
- {
- printf("netbsd32_sigreturn14: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
- Debugger();
- return (EINVAL);
- }
-#else
- return (EINVAL);
-#endif
- /* take only psr ICC field */
- tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
- tf->tf_pc = (int64_t)sc.sc_pc;
- tf->tf_npc = (int64_t)sc.sc_npc;
- tf->tf_global[1] = (int64_t)sc.sc_g1;
- tf->tf_out[0] = (int64_t)sc.sc_o0;
- tf->tf_out[6] = (int64_t)sc.sc_sp;
-#ifdef DEBUG
- if (sigdebug & SDB_FOLLOW) {
- printf("netbsd32_sigreturn14: return trapframe pc=%p sp=%p tstate=%llx\n",
- (vaddr_t)tf->tf_pc, (vaddr_t)tf->tf_out[6], tf->tf_tstate);
- if (sigdebug & SDB_DDB) Debugger();
- }
-#endif
- /* Restore signal stack. */
- mutex_enter(p->p_lock);
- if (sc.sc_onstack & SS_ONSTACK)
- l->l_sigstk.ss_flags |= SS_ONSTACK;
- else
- l->l_sigstk.ss_flags &= ~SS_ONSTACK;
- /* Restore signal mask. */
- (void) sigprocmask1(l, SIG_SETMASK, &sc.sc_mask, 0);
- mutex_exit(p->p_lock);
-
- return (EJUSTRETURN);
-}
+#undef DEBUG
/* Unfortunately we need to convert v9 trapframe to v8 regs */
int
@@ -680,6 +358,7 @@ netbsd32_process_write_fpregs(struct lwp
/*
* 32-bit version of cpu_coredump.
*/
+#ifdef COREDUMP
int
cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
struct core32 *chdr)
@@ -735,6 +414,7 @@ cpu_coredump32(struct lwp *l, struct cor
return coredump_write(iocookie, UIO_SYSSPACE, &md_core,
sizeof(md_core));
}
+#endif
void netbsd32_cpu_getmcontext(struct lwp *, mcontext_t *, unsigned int *);
@@ -1340,3 +1020,18 @@ netbsd32_vm_default_addr(struct proc *p,
{
return round_page((vaddr_t)(base) + (vsize_t)MAXDSIZ32);
}
+
+void
+netbsd32_machdep_md_init(void)
+{
+
+ /* nothing to do */
+}
+
+void
+netbsd32_machdep_md_fini(void)
+{
+
+ /* nothing to do */
+}
+
Added files:
Index: src/sys/arch/sparc64/sparc64/netbsd32_machdep_13.c
diff -u /dev/null src/sys/arch/sparc64/sparc64/netbsd32_machdep_13.c:1.1.2.1
--- /dev/null Sun Sep 30 00:17:55 2018
+++ src/sys/arch/sparc64/sparc64/netbsd32_machdep_13.c Sun Sep 30 00:17:55 2018
@@ -0,0 +1,184 @@
+/* $NetBSD: netbsd32_machdep_13.c,v 1.1.2.1 2018/09/30 00:17:55 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 1998, 2001 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep_13.c,v 1.1.2.1 2018/09/30 00:17:55 pgoyette Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_compat_netbsd.h"
+#include "opt_compat_sunos.h"
+#include "opt_modular.h"
+#include "opt_execfmt.h"
+#include "firm_events.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/exec_aout.h>
+#include <sys/filedesc.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+#include <sys/core.h>
+#include <sys/mount.h>
+#include <sys/buf.h>
+#include <sys/vnode.h>
+#include <sys/select.h>
+#include <sys/socketvar.h>
+#include <sys/ucontext.h>
+#include <sys/ioctl.h>
+#include <sys/kmem.h>
+
+#include <dev/sun/event_var.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/igmp.h>
+#include <netinet/igmp_var.h>
+#include <netinet/ip_mroute.h>
+
+#include <compat/netbsd32/netbsd32.h>
+#include <compat/netbsd32/netbsd32_ioctl.h>
+#include <compat/netbsd32/netbsd32_syscallargs.h>
+#include <compat/netbsd32/netbsd32_exec.h>
+
+#include <compat/sys/signal.h>
+#include <compat/sys/signalvar.h>
+#include <compat/sys/siginfo.h>
+#include <compat/sys/ucontext.h>
+
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/reg.h>
+#include <machine/vmparam.h>
+#include <machine/vuid_event.h>
+#include <machine/netbsd32_machdep.h>
+#include <machine/userret.h>
+
+int
+compat_13_netbsd32_sigreturn(struct lwp *l, const struct compat_13_netbsd32_sigreturn_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(struct netbsd32_sigcontext13 *) sigcntxp;
+ } */
+ struct netbsd32_sigcontext13 *scp;
+ struct netbsd32_sigcontext13 sc;
+ struct trapframe64 *tf;
+ struct proc *p = l->l_proc;
+ sigset_t mask;
+
+ /* First ensure consistent stack state (see sendsig). */
+ write_user_windows();
+ if (rwindow_save(l)) {
+#ifdef DEBUG
+ printf("%s: rwindow_save(%p) failed, sending SIGILL\n",
+ __func__, p);
+ Debugger();
+#endif
+ mutex_enter(p->p_lock);
+ sigexit(l, SIGILL);
+ }
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("%s: %s[%d], sigcntxp %p\n", __func__,
+ p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
+ if (sigdebug & SDB_DDB) Debugger();
+ }
+#endif
+ scp = (struct netbsd32_sigcontext13 *)(u_long)SCARG(uap, sigcntxp);
+ if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
+ {
+#ifdef DEBUG
+ printf("%s: copyin failed\n", __func__);
+ Debugger();
+#endif
+ return (EINVAL);
+ }
+ scp = ≻
+
+ tf = l->l_md.md_tf;
+ /*
+ * Only the icc bits in the psr are used, so it need not be
+ * verified. pc and npc must be multiples of 4. This is all
+ * that is required; if it holds, just do it.
+ */
+ if (((sc.sc_pc | sc.sc_npc) & 3) != 0)
+#ifdef DEBUG
+ {
+ printf("%s: pc %p or npc %p invalid\n",
+ __func__, sc.sc_pc, sc.sc_npc);
+ Debugger();
+ return (EINVAL);
+ }
+#else
+ return (EINVAL);
+#endif
+ /* take only psr ICC field */
+ tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
+ tf->tf_pc = (int64_t)sc.sc_pc;
+ tf->tf_npc = (int64_t)sc.sc_npc;
+ tf->tf_global[1] = (int64_t)sc.sc_g1;
+ tf->tf_out[0] = (int64_t)sc.sc_o0;
+ tf->tf_out[6] = (int64_t)sc.sc_sp;
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("%s: return trapframe pc=%p sp=%p tstate=%x\n", __func__,
+ (int)tf->tf_pc, (int)tf->tf_out[6], (int)tf->tf_tstate);
+ if (sigdebug & SDB_DDB) Debugger();
+ }
+#endif
+ mutex_enter(p->p_lock);
+ if (scp->sc_onstack & SS_ONSTACK)
+ l->l_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ l->l_sigstk.ss_flags &= ~SS_ONSTACK;
+ /* Restore signal mask */
+ native_sigset13_to_sigset((sigset13_t *)&scp->sc_mask, &mask);
+ (void) sigprocmask1(l, SIG_SETMASK, &mask, 0);
+ mutex_exit(p->p_lock);
+
+ return (EJUSTRETURN);
+}
+
+void
+netbsd32_machdep_md_13_init(void)
+{
+
+ /* Nothing to do */
+}
+
+void
+netbsd32_machdep_md_13_fini(void)
+{
+
+ /* Nothing to do */
+}
Index: src/sys/arch/sparc64/sparc64/netbsd32_machdep_16.c
diff -u /dev/null src/sys/arch/sparc64/sparc64/netbsd32_machdep_16.c:1.1.2.1
--- /dev/null Sun Sep 30 00:17:55 2018
+++ src/sys/arch/sparc64/sparc64/netbsd32_machdep_16.c Sun Sep 30 00:17:55 2018
@@ -0,0 +1,370 @@
+/* $NetBSD: netbsd32_machdep_16.c,v 1.1.2.1 2018/09/30 00:17:55 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 1998, 2001 Matthew R. Green
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep_16.c,v 1.1.2.1 2018/09/30 00:17:55 pgoyette Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_compat_netbsd.h"
+#include "opt_compat_sunos.h"
+#include "opt_modular.h"
+#include "opt_execfmt.h"
+#include "firm_events.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/exec_aout.h>
+#include <sys/filedesc.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+#include <sys/core.h>
+#include <sys/mount.h>
+#include <sys/buf.h>
+#include <sys/vnode.h>
+#include <sys/select.h>
+#include <sys/socketvar.h>
+#include <sys/ucontext.h>
+#include <sys/ioctl.h>
+#include <sys/kmem.h>
+
+#include <dev/sun/event_var.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/igmp.h>
+#include <netinet/igmp_var.h>
+#include <netinet/ip_mroute.h>
+
+#include <compat/netbsd32/netbsd32.h>
+#include <compat/netbsd32/netbsd32_ioctl.h>
+#include <compat/netbsd32/netbsd32_syscallargs.h>
+#include <compat/netbsd32/netbsd32_exec.h>
+
+#include <compat/sys/signal.h>
+#include <compat/sys/signalvar.h>
+#include <compat/sys/siginfo.h>
+#include <compat/sys/ucontext.h>
+
+#include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/reg.h>
+#include <machine/vmparam.h>
+#include <machine/vuid_event.h>
+#include <machine/netbsd32_machdep.h>
+#include <machine/userret.h>
+
+void netbsd32_sendsig_siginfo(const ksiginfo_t *, const sigset_t *);
+
+int netbsd32_sendsig_16(const ksiginfo_t *, const sigset_t *);
+
+/*
+ * NB: since this is a 32-bit address world, sf_scp and sf_sc
+ * can't be a pointer since those are 64-bits wide.
+ */
+struct sparc32_sigframe {
+ int sf_signo; /* signal number */
+ int sf_code; /* code */
+ u_int sf_scp; /* SunOS user addr of sigcontext */
+ int sf_addr; /* SunOS compat, always 0 for now */
+ struct netbsd32_sigcontext sf_sc; /* actual sigcontext */
+};
+
+extern struct netbsd32_sendsig_hook_t netbsd32_sendsig_hook;
+
+#undef DEBUG
+#ifdef DEBUG
+extern int sigdebug;
+#endif
+
+static void
+netbsd32_sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+ int sig = ksi->ksi_signo;
+ struct lwp *l = curlwp;
+ struct proc *p = l->l_proc;
+ struct sparc32_sigframe *fp;
+ struct trapframe64 *tf;
+ int addr, onstack, error;
+ struct rwindow32 *oldsp, *newsp;
+ register32_t sp;
+ sig_t catcher = SIGACTION(p, sig).sa_handler;
+ struct sparc32_sigframe sf;
+ extern char netbsd32_sigcode[], netbsd32_esigcode[];
+#define szsigcode (netbsd32_esigcode - netbsd32_sigcode)
+
+ tf = l->l_md.md_tf;
+ /* Need to attempt to zero extend this 32-bit pointer */
+ oldsp = (struct rwindow32 *)(u_long)(u_int)tf->tf_out[6];
+ /* Do we need to jump onto the signal stack? */
+ onstack =
+ (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
+ (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
+ if (onstack) {
+ fp = (struct sparc32_sigframe *)((char *)l->l_sigstk.ss_sp +
+ l->l_sigstk.ss_size);
+ l->l_sigstk.ss_flags |= SS_ONSTACK;
+ } else
+ fp = (struct sparc32_sigframe *)oldsp;
+ fp = (struct sparc32_sigframe *)((u_long)(fp - 1) & ~7);
+
+#ifdef DEBUG
+ sigpid = p->p_pid;
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
+ printf("sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n",
+ p->p_comm, p->p_pid, sig, fp, &fp->sf_sc, oldsp);
+ if (sigdebug & SDB_DDB) Debugger();
+ }
+#endif
+ /*
+ * Now set up the signal frame. We build it in kernel space
+ * and then copy it out. We probably ought to just build it
+ * directly in user space....
+ */
+ sf.sf_signo = sig;
+ sf.sf_code = (u_int)ksi->ksi_trap;
+#if defined(COMPAT_SUNOS) || defined(MODULAR)
+ sf.sf_scp = (u_long)&fp->sf_sc;
+#endif
+ sf.sf_addr = 0; /* XXX */
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ sf.sf_sc.sc_onstack = onstack;
+ sf.sf_sc.sc_mask = *mask;
+ sf.sf_sc.sc_sp = (u_long)oldsp;
+ sf.sf_sc.sc_pc = tf->tf_pc;
+ sf.sf_sc.sc_npc = tf->tf_npc;
+ sf.sf_sc.sc_psr = TSTATECCR_TO_PSR(tf->tf_tstate); /* XXX */
+ sf.sf_sc.sc_g1 = tf->tf_global[1];
+ sf.sf_sc.sc_o0 = tf->tf_out[0];
+
+ /*
+ * Put the stack in a consistent state before we whack away
+ * at it. Note that write_user_windows may just dump the
+ * registers into the pcb; we need them in the process's memory.
+ * We also need to make sure that when we start the signal handler,
+ * its %i6 (%fp), which is loaded from the newly allocated stack area,
+ * joins seamlessly with the frame it was in when the signal occurred,
+ * so that the debugger and _longjmp code can back up through it.
+ */
+ sendsig_reset(l, sig);
+ mutex_exit(p->p_lock);
+ newsp = (struct rwindow32 *)((long)fp - sizeof(struct rwindow32));
+ write_user_windows();
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK))
+ printf("sendsig: saving sf to %p, setting stack pointer %p to %p\n",
+ fp, &(((struct rwindow32 *)newsp)->rw_in[6]), oldsp);
+#endif
+ sp = NETBSD32PTR32I(oldsp);
+ error = (rwindow_save(l) ||
+ copyout(&sf, fp, sizeof sf) ||
+ copyout(&sp, &(((struct rwindow32 *)newsp)->rw_in[6]),
+ sizeof(sp)));
+ mutex_enter(p->p_lock);
+ if (error) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+#ifdef DEBUG
+ mutex_exit(p->p_lock);
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
+ printf("sendsig: window save or copyout error\n");
+ printf("sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
+ if (sigdebug & SDB_DDB) Debugger();
+ mutex_enter(p->p_lock);
+#endif
+ sigexit(l, SIGILL);
+ /* NOTREACHED */
+ }
+
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("sendsig: %s[%d] sig %d scp %p\n",
+ p->p_comm, p->p_pid, sig, &fp->sf_sc);
+ }
+#endif
+ /*
+ * Arrange to continue execution at the code copied out in exec().
+ * It needs the function to call in %g1, and a new stack pointer.
+ */
+ addr = p->p_psstrp - szsigcode;
+ tf->tf_global[1] = (long)catcher;
+ tf->tf_pc = addr;
+ tf->tf_npc = addr + 4;
+ tf->tf_out[6] = (uint64_t)(u_int)(u_long)newsp;
+
+ /* Remember that we're now on the signal stack. */
+ if (onstack)
+ l->l_sigstk.ss_flags |= SS_ONSTACK;
+
+#ifdef DEBUG
+ if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
+ mutex_exit(p->p_lock);
+ printf("sendsig: about to return to catcher %p thru %p\n",
+ catcher, addr);
+ if (sigdebug & SDB_DDB) Debugger();
+ mutex_enter(p->p_lock);
+ }
+#endif
+}
+
+struct sparc32_sigframe_siginfo {
+ siginfo32_t sf_si;
+ ucontext32_t sf_uc;
+};
+
+int
+netbsd32_sendsig_16(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+ if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
+ netbsd32_sendsig_sigcontext(ksi, mask);
+ else
+ netbsd32_sendsig_siginfo(ksi, mask);
+
+ return 0;
+}
+
+#undef DEBUG
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by sendsig (above),
+ * and return to the given trap frame (if there is one).
+ * Check carefully to make sure that the user has not
+ * modified the state to gain improper privileges or to cause
+ * a machine fault.
+ */
+/* ARGSUSED */
+int
+compat_16_netbsd32___sigreturn14(struct lwp *l, const struct compat_16_netbsd32___sigreturn14_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(struct sigcontext *) sigcntxp;
+ } */
+ struct netbsd32_sigcontext sc, *scp;
+ struct trapframe64 *tf;
+ struct proc *p = l->l_proc;
+
+ /* First ensure consistent stack state (see sendsig). */
+ write_user_windows();
+ if (rwindow_save(l)) {
+#ifdef DEBUG
+ printf("netbsd32_sigreturn14: rwindow_save(%p) failed, sending SIGILL\n", p);
+ Debugger();
+#endif
+ mutex_enter(p->p_lock);
+ sigexit(l, SIGILL);
+ }
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("netbsd32_sigreturn14: %s[%d], sigcntxp %p\n",
+ p->p_comm, p->p_pid, SCARG(uap, sigcntxp));
+ if (sigdebug & SDB_DDB) Debugger();
+ }
+#endif
+ scp = (struct netbsd32_sigcontext *)(u_long)SCARG(uap, sigcntxp);
+ if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0))
+ {
+#ifdef DEBUG
+ printf("netbsd32_sigreturn14: copyin failed: scp=%p\n", scp);
+ Debugger();
+#endif
+ return (EINVAL);
+ }
+ scp = ≻
+
+ tf = l->l_md.md_tf;
+ /*
+ * Only the icc bits in the psr are used, so it need not be
+ * verified. pc and npc must be multiples of 4. This is all
+ * that is required; if it holds, just do it.
+ */
+ if (((sc.sc_pc | sc.sc_npc) & 3) != 0 || (sc.sc_pc == 0) || (sc.sc_npc == 0))
+#ifdef DEBUG
+ {
+ printf("netbsd32_sigreturn14: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc);
+ Debugger();
+ return (EINVAL);
+ }
+#else
+ return (EINVAL);
+#endif
+ /* take only psr ICC field */
+ tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr);
+ tf->tf_pc = (int64_t)sc.sc_pc;
+ tf->tf_npc = (int64_t)sc.sc_npc;
+ tf->tf_global[1] = (int64_t)sc.sc_g1;
+ tf->tf_out[0] = (int64_t)sc.sc_o0;
+ tf->tf_out[6] = (int64_t)sc.sc_sp;
+#ifdef DEBUG
+ if (sigdebug & SDB_FOLLOW) {
+ printf("netbsd32_sigreturn14: return trapframe pc=%p sp=%p tstate=%llx\n",
+ (vaddr_t)tf->tf_pc, (vaddr_t)tf->tf_out[6], tf->tf_tstate);
+ if (sigdebug & SDB_DDB) Debugger();
+ }
+#endif
+
+ /* Restore signal stack. */
+ mutex_enter(p->p_lock);
+ if (sc.sc_onstack & SS_ONSTACK)
+ l->l_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ l->l_sigstk.ss_flags &= ~SS_ONSTACK;
+ /* Restore signal mask. */
+ (void) sigprocmask1(l, SIG_SETMASK, &sc.sc_mask, 0);
+ mutex_exit(p->p_lock);
+
+ return (EJUSTRETURN);
+}
+
+MODULE_SET_HOOK(netbsd32_sendsig_hook, "nb32_16", netbsd32_sendsig_16);
+MODULE_UNSET_HOOK(netbsd32_sendsig_hook);
+
+void
+netbsd32_machdep_md_16_init(void)
+{
+
+ netbsd32_sendsig_hook_set();
+}
+
+void
+netbsd32_machdep_md_16_fini(void)
+{
+
+ netbsd32_sendsig_hook_unset();
+}