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 = &sc;
 
-	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 = &sc;
-
-	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 = &sc;
+
+	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 = &sc;
+
+	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();
+}

Reply via email to