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