From d8405328df254566265409e9dfc9532596d49f8e Mon Sep 17 00:00:00 2001 From: eeh Date: Sun, 11 Feb 2001 00:39:37 +0000 Subject: [PATCH] Add support for COMPAT_SVR4_32. --- sys/arch/sparc64/conf/files.sparc64 | 6 +- sys/arch/sparc64/include/svr4_32_machdep.h | 93 +++ sys/arch/sparc64/sparc64/svr4_32_machdep.c | 696 +++++++++++++++++++++ sys/arch/sparc64/sparc64/svr4_machdep.c | 6 +- sys/arch/sparc64/sparc64/trap.c | 26 +- 5 files changed, 817 insertions(+), 10 deletions(-) create mode 100644 sys/arch/sparc64/include/svr4_32_machdep.h create mode 100644 sys/arch/sparc64/sparc64/svr4_32_machdep.c diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64 index 071b1313ebf4..903708e8c31f 100644 --- a/sys/arch/sparc64/conf/files.sparc64 +++ b/sys/arch/sparc64/conf/files.sparc64 @@ -1,4 +1,4 @@ -# $NetBSD: files.sparc64,v 1.44 2001/02/05 12:47:47 mrg Exp $ +# $NetBSD: files.sparc64,v 1.45 2001/02/11 00:42:08 eeh Exp $ # @(#)files.sparc64 8.1 (Berkeley) 7/19/93 # sparc64-specific configuration info @@ -246,6 +246,10 @@ include "compat/aout/files.aout" include "compat/svr4/files.svr4" file arch/sparc64/sparc64/svr4_machdep.c compat_svr4 +# 32-bit SVR4 Binary Compatibility (COMPAT_SVR4_32) +include "compat/svr4_32/files.svr4_32" +file arch/sparc64/sparc64/svr4_32_machdep.c compat_svr4_32 + # SunOS Binary Compatibility (COMPAT_SUNOS), 32-bit & 64-bit kernel # (64-bit also depends on COMPAT_NETBSD32) include "compat/sunos/files.sunos" diff --git a/sys/arch/sparc64/include/svr4_32_machdep.h b/sys/arch/sparc64/include/svr4_32_machdep.h new file mode 100644 index 000000000000..93b8f8dfd58d --- /dev/null +++ b/sys/arch/sparc64/include/svr4_32_machdep.h @@ -0,0 +1,93 @@ +/* $NetBSD: svr4_32_machdep.h,v 1.1 2001/02/11 00:39:37 eeh Exp $ */ + +/*- + * Copyright (c) 1994 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ + +#ifndef _SPARC_SVR4_32_MACHDEP_H_ +#define _SPARC_SVR4_32_MACHDEP_H_ + +#include +#include + +/* + * Machine dependent portions [SPARC] + */ + +typedef u_int svr4_32_greg_t; + +typedef struct { + svr4_32_greg_t rwin_lo[8]; + svr4_32_greg_t rwin_in[8]; +} svr4_32_rwindow_t; + +typedef struct { + int cnt; + u_int *sp[SVR4_SPARC_MAXWIN]; + svr4_32_rwindow_t win[SVR4_SPARC_MAXWIN]; +} svr4_32_gwindow_t; + +typedef svr4_32_greg_t svr4_32_gregset_t[SVR4_SPARC_MAXREG]; + +typedef struct { + union { + u_int fp_ri[32]; + double fp_rd[16]; + } fpu_regs; + void *fp_q; + unsigned fp_fsr; + u_char fp_nqel; + u_char fp_nqsize; + u_char fp_busy; +} svr4_32_fregset_t; + +typedef struct { + u_int id; + void *ptr; +} svr4_32_xrs_t; + +typedef struct svr4_32_mcontext { + svr4_32_gregset_t greg; + svr4_32_gwindow_t *gwin; + svr4_32_fregset_t freg; + svr4_32_xrs_t xrs; + netbsd32_long pad[19]; +} svr4_32_mcontext_t; + +struct svr4_32_ucontext; + +int svr4_32_trap __P((int, struct proc *)); + +#endif /* !_SPARC_SVR4_32_MACHDEP_H_ */ diff --git a/sys/arch/sparc64/sparc64/svr4_32_machdep.c b/sys/arch/sparc64/sparc64/svr4_32_machdep.c new file mode 100644 index 000000000000..4ad11428ddca --- /dev/null +++ b/sys/arch/sparc64/sparc64/svr4_32_machdep.c @@ -0,0 +1,696 @@ +/* $NetBSD: svr4_32_machdep.c,v 1.1 2001/02/11 00:39:37 eeh Exp $ */ + +/*- + * Copyright (c) 1994 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ + +#ifndef _LKM +#include "opt_ddb.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static void svr4_32_getsiginfo __P((union svr4_32_siginfo *, int, u_long, caddr_t)); + +void +svr4_32_setregs(p, epp, stack) + struct proc *p; + struct exec_package *epp; + u_long stack; +{ + register struct trapframe64 *tf = p->p_md.md_tf; + + netbsd32_setregs(p, epp, stack); + + /* This should be the exit function, not PS_STRINGS. */ + tf->tf_global[1] = (vaddr_t)0; +} + +#ifdef DEBUG +#include +#endif + +#ifdef DEBUG_SVR4 +static void svr4_32_printmcontext __P((const char *, struct svr4_32_mcontext *)); + +static void +svr4_32_printmcontext(fun, mc) + const char *fun; + struct svr4_32_mcontext *mc; +{ + svr4_32_greg_t *r = mc->greg; + + printf("%s at %p\n", fun, mc); + + printf("Regs: "); + printf("TSTATE = 0x%x ", r[SVR4_SPARC_PSR]); + printf("PC = 0x%x ", r[SVR4_SPARC_PC]); + printf("nPC = 0x%x ", r[SVR4_SPARC_nPC]); + printf("Y = 0x%x ", r[SVR4_SPARC_Y]); + printf("G1 = 0x%x ", r[SVR4_SPARC_G1]); + printf("G2 = 0x%x ", r[SVR4_SPARC_G2]); + printf("G3 = 0x%x ", r[SVR4_SPARC_G3]); + printf("G4 = 0x%x ", r[SVR4_SPARC_G4]); + printf("G5 = 0x%x ", r[SVR4_SPARC_G5]); + printf("G6 = 0x%x ", r[SVR4_SPARC_G6]); + printf("G7 = 0x%x ", r[SVR4_SPARC_G7]); + printf("O0 = 0x%x ", r[SVR4_SPARC_O0]); + printf("O1 = 0x%x ", r[SVR4_SPARC_O1]); + printf("O2 = 0x%x ", r[SVR4_SPARC_O2]); + printf("O3 = 0x%x ", r[SVR4_SPARC_O3]); + printf("O4 = 0x%x ", r[SVR4_SPARC_O4]); + printf("O5 = 0x%x ", r[SVR4_SPARC_O5]); + printf("O6 = 0x%x ", r[SVR4_SPARC_O6]); + printf("O7 = 0x%x ", r[SVR4_SPARC_O7]); + printf("\n"); +} +#endif + +void * +svr4_32_getmcontext(p, mc, flags) + struct proc *p; + struct svr4_32_mcontext *mc; + netbsd32_u_long *flags; +{ + struct trapframe64 *tf = (struct trapframe64 *)p->p_md.md_tf; + svr4_32_greg_t *r = mc->greg; +#ifdef FPU_CONTEXT + svr4_32_fregset_t *f = &mc->freg; + struct fpstate *fps = p->p_md.md_fpstate; +#endif + + write_user_windows(); + if (rwindow_save(p)) { +#ifdef DEBUG + printf("svr4_32_getcontext: rwindow_save(%p) failed, sending SIGILL\n", p); +#ifdef DDB + Debugger(); +#endif +#endif + sigexit(p, SIGILL); + } + + /* + * Get the general purpose registers + */ + r[SVR4_SPARC_PSR] = tf->tf_tstate; + r[SVR4_SPARC_PC] = tf->tf_pc; + r[SVR4_SPARC_nPC] = tf->tf_npc; + r[SVR4_SPARC_Y] = tf->tf_y; + r[SVR4_SPARC_G1] = tf->tf_global[1]; + r[SVR4_SPARC_G2] = tf->tf_global[2]; + r[SVR4_SPARC_G3] = tf->tf_global[3]; + r[SVR4_SPARC_G4] = tf->tf_global[4]; + r[SVR4_SPARC_G5] = tf->tf_global[5]; + r[SVR4_SPARC_G6] = tf->tf_global[6]; + r[SVR4_SPARC_G7] = tf->tf_global[7]; + r[SVR4_SPARC_O0] = tf->tf_out[0]; + r[SVR4_SPARC_O1] = tf->tf_out[1]; + r[SVR4_SPARC_O2] = tf->tf_out[2]; + r[SVR4_SPARC_O3] = tf->tf_out[3]; + r[SVR4_SPARC_O4] = tf->tf_out[4]; + r[SVR4_SPARC_O5] = tf->tf_out[5]; + r[SVR4_SPARC_O6] = tf->tf_out[6]; + r[SVR4_SPARC_O7] = tf->tf_out[7]; + + *flags |= SVR4_UC_CPU; + +#ifdef FPU_CONTEXT + /* + * Get the floating point registers + */ + bcopy(fps->fs_regs, f->fpu_regs, sizeof(fps->fs_regs)); + f->fp_nqsize = sizeof(struct fp_qentry); + f->fp_nqel = fps->fs_qsize; + f->fp_fsr = fps->fs_fsr; + if (f->fp_q != NULL) { + size_t sz = f->fp_nqel * f->fp_nqsize; + if (sz > sizeof(fps->fs_queue)) { +#ifdef DIAGNOSTIC + printf("getcontext: fp_queue too large\n"); +#endif + return; + } + if (copyout(fps->fs_queue, f->fp_q, sz) != 0) { +#ifdef DIAGNOSTIC + printf("getcontext: copy of fp_queue failed %d\n", + error); +#endif + return; + } + } + f->fp_busy = 0; /* XXX: How do we determine that? */ + *flags |= SVR4_UC_FPU; +#endif + + +#ifdef DEBUG_SVR4 + svr4_32_printmcontext("getmcontext", mc); +#endif + return (void *)(u_long)tf->tf_out[6]; +} + + +/* + * Set to mcontext specified. + * Return to previous pc and psl as specified by + * context left by sendsig. Check carefully to + * make sure that the user has not modified the + * psl to gain improper privileges or to cause + * a machine fault. + * This is almost like sigreturn() and it shows. + */ +int +svr4_32_setmcontext(p, mc, flags) + struct proc *p; + struct svr4_32_mcontext *mc; + netbsd32_u_long flags; +{ + register struct trapframe64 *tf; + svr4_32_greg_t *r = mc->greg; +#ifdef FPU_CONTEXT + svr4_32_fregset_t *f = &mc->freg; + struct fpstate64 *fps = p->p_md.md_fpstate; +#endif + +#ifdef DEBUG_SVR4 + svr4_32_printmcontext("setmcontext", uc); +#endif + + write_user_windows(); + if (rwindow_save(p)) { +#ifdef DEBUG + printf("svr4_32_setcontext: rwindow_save(%p) failed, sending SIGILL\n", p); +#ifdef DDB + Debugger(); +#endif +#endif + sigexit(p, SIGILL); + } + +#ifdef DEBUG + if (sigdebug & SDB_FOLLOW) + printf("svr4_32_setmcontext: %s[%d], svr4_32_mcontext %p\n", + p->p_comm, p->p_pid, mc); +#endif + + if (flags & SVR4_UC_CPU) { + /* Restore register context. */ + tf = (struct trapframe64 *)p->p_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 (((r[SVR4_SPARC_PC] | r[SVR4_SPARC_nPC]) & 3) != 0) { + printf("pc or npc are not multiples of 4!\n"); + return EINVAL; + } + + /* take only psr ICC field */ + tf->tf_tstate = (tf->tf_tstate & ~PSR_ICC) | + (r[SVR4_SPARC_PSR] & PSR_ICC); + tf->tf_pc = r[SVR4_SPARC_PC]; + tf->tf_npc = r[SVR4_SPARC_nPC]; + tf->tf_y = r[SVR4_SPARC_Y]; + + /* Restore everything */ + tf->tf_global[1] = r[SVR4_SPARC_G1]; + tf->tf_global[2] = r[SVR4_SPARC_G2]; + tf->tf_global[3] = r[SVR4_SPARC_G3]; + tf->tf_global[4] = r[SVR4_SPARC_G4]; + tf->tf_global[5] = r[SVR4_SPARC_G5]; + tf->tf_global[6] = r[SVR4_SPARC_G6]; + tf->tf_global[7] = r[SVR4_SPARC_G7]; + + tf->tf_out[0] = r[SVR4_SPARC_O0]; + tf->tf_out[1] = r[SVR4_SPARC_O1]; + tf->tf_out[2] = r[SVR4_SPARC_O2]; + tf->tf_out[3] = r[SVR4_SPARC_O3]; + tf->tf_out[4] = r[SVR4_SPARC_O4]; + tf->tf_out[5] = r[SVR4_SPARC_O5]; + tf->tf_out[6] = r[SVR4_SPARC_O6]; + tf->tf_out[7] = r[SVR4_SPARC_O7]; + } + + +#ifdef FPU_CONTEXT + if (flags & SVR4_UC_FPU) { + /* + * Set the floating point registers + */ + int error; + size_t sz = f->fp_nqel * f->fp_nqsize; + if (sz > sizeof(fps->fs_queue)) { +#ifdef DIAGNOSTIC + printf("setmcontext: fp_queue too large\n"); +#endif + return EINVAL; + } + bcopy(f->fpu_regs, fps->fs_regs, sizeof(fps->fs_regs)); + fps->fs_qsize = f->fp_nqel; + fps->fs_fsr = f->fp_fsr; + if (f->fp_q != NULL) { + if ((error = copyin(f->fp_q, fps->fs_queue, + f->fp_nqel * f->fp_nqsize)) != 0) { +#ifdef DIAGNOSTIC + printf("setmcontext: fp_queue copy failed\n"); +#endif + return error; + } + } + } +#endif + + return 0; +} + +/* + * map the trap code into the svr4 siginfo as best we can + */ +static void +svr4_32_getsiginfo(si, sig, code, addr) + union svr4_32_siginfo *si; + int sig; + u_long code; + caddr_t addr; +{ + si->si_signo = native_to_svr4_sig[sig]; + si->si_errno = 0; + si->si_addr = (netbsd32_caddr_t)(u_long)addr; + /* + * we can do this direct map as they are the same as all sparc + * architectures. + */ + si->si_trap = code; + switch (code) { + case T_POR: + case T_WDR: + case T_XIR: + case T_SIR: + case T_RED_EXCEPTION: + si->si_code = 0; + break; + + case T_TEXTFAULT: + si->si_code = SVR4_BUS_ADRALN; + break; + + case T_ILLINST: + si->si_code = SVR4_ILL_ILLOPC; + break; + + case T_PRIVINST: + si->si_code = SVR4_ILL_PRVOPC; + break; + + case T_FPDISABLED: + si->si_code = SVR4_FPE_FLTINV; + break; + + case T_ALIGN: + si->si_code = SVR4_BUS_ADRALN; + break; + + case T_FP_IEEE_754: + case T_FP_OTHER: + si->si_code = SVR4_FPE_FLTINV; + break; + + case T_DATAFAULT: + si->si_code = SVR4_BUS_ADRALN; + break; + + case T_TAGOF: + si->si_code = SVR4_EMT_TAGOVF; + break; + + case T_DIV0: + si->si_code = SVR4_FPE_INTDIV; + break; + + case T_INTOF: + si->si_code = SVR4_FPE_INTOVF; + break; + + case T_BREAKPOINT: + si->si_code = SVR4_TRAP_BRKPT; + break; + + /* + * XXX - hardware traps with unknown code + */ + case T_L1INT: + case T_L2INT: + case T_L3INT: + case T_L4INT: + case T_L5INT: + case T_L6INT: + case T_L7INT: + case T_L8INT: + case T_L9INT: + case T_L10INT: + case T_L11INT: + case T_L12INT: + case T_L13INT: + case T_L14INT: + case T_L15INT: + si->si_code = 0; + break; + + /* + * XXX - software traps with unknown code + */ + case T_SUN_SYSCALL: + case T_FLUSHWIN: + case T_CLEANWIN: + case T_RANGECHECK: + case T_FIXALIGN: + case T_SVR4_SYSCALL: + case T_BSD_SYSCALL: + case T_KGDB_EXEC: + si->si_code = 0; + break; + + default: + si->si_code = 0; +#ifdef notyet + /* + * XXX: in trap.c, code gets passed the address + * of the fault! not the trap code on SEGV! + */ +#ifdef DIAGNOSTIC + printf("sig %d code %ld\n", sig, code); + panic("svr4_32_getsiginfo"); +#endif +#endif + break; + } +} + +/* + * Send an interrupt to process. + * + * Stack is set up to allow sigcode stored + * in u. to call routine. After the handler is + * done svr4 will call setcontext for us + * with the user context we just set up, and we + * will return to the user pc, psl. + */ +void +svr4_32_sendsig(catcher, sig, mask, code) + sig_t catcher; + int sig; + sigset_t *mask; + u_long code; +{ + register struct proc *p = curproc; + register struct trapframe64 *tf; + struct svr4_32_sigframe *fp, frame; + int onstack; + vaddr_t oldsp, newsp, addr; + + tf = (struct trapframe64 *)p->p_md.md_tf; + oldsp = tf->tf_out[6]; + + /* Do we need to jump onto the signal stack? */ + onstack = + (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && + (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0; + + /* + * Allocate space for the signal handler context. + */ + if (onstack) + fp = (struct svr4_32_sigframe *)((caddr_t)p->p_sigctx.ps_sigstk.ss_sp + + p->p_sigctx.ps_sigstk.ss_size); + else + fp = (struct svr4_32_sigframe *)oldsp; + fp = (struct svr4_32_sigframe *) ((long) (fp - 1) & ~7); + +#ifdef DEBUG + sigpid = p->p_pid; + if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) { + printf("svr4_32_sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n", + p->p_comm, p->p_pid, sig, fp, &fp->sf_uc, (void *)(u_long)oldsp); +#ifdef DDB + if (sigdebug & SDB_DDB) Debugger(); +#endif + } +#endif + /* + * Build the argument list for the signal handler. + */ + svr4_32_getcontext(p, &frame.sf_uc, mask); + svr4_32_getsiginfo(&frame.sf_si, sig, code, (caddr_t)(u_long)tf->tf_pc); + + /* Build stack frame for signal trampoline. */ + frame.sf_signum = frame.sf_si.si_signo; + frame.sf_sip = (netbsd32_caddr_t)(u_long)&fp->sf_si; + frame.sf_ucp = (netbsd32_caddr_t)(u_long)&fp->sf_uc; + frame.sf_handler = catcher; + + DPRINTF(("svr4_32_sendsig signum=%d si = %p uc = %p handler = %p\n", + frame.sf_signum, frame.sf_sip, + frame.sf_ucp, frame.sf_handler)); + /* + * Modify the signal context to be used by sigreturn. + */ + frame.sf_uc.uc_mcontext.greg[SVR4_SPARC_SP] = oldsp; + + newsp = (u_long)fp - sizeof(struct rwindow32); + write_user_windows(); + +#ifdef DEBUG + if ((sigdebug & SDB_KSTACK)) + printf("svr4_32_sendsig: saving sf to %p, setting stack pointer %p to %p\n", + fp, &(((struct rwindow32 *)newsp)->rw_in[6]), (void *)(u_long)oldsp); +#endif + if (rwindow_save(p) || copyout(&frame, fp, sizeof(frame)) != 0 || + copyout(&oldsp, &((struct rwindow32 *)newsp)->rw_in[6], sizeof(oldsp))) { + /* + * Process has trashed its stack; give it an illegal + * instruction to halt it in its tracks. + */ +#ifdef DEBUG + if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) + printf("svr4_32_sendsig: window save or copyout error\n"); + printf("svr4_32_sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig); +#ifdef DDB + Debugger(); +#endif +#endif + sigexit(p, SIGILL); + /* NOTREACHED */ + } + +#ifdef DEBUG + if (sigdebug & SDB_FOLLOW) { + printf("svr4_32_sendsig: %s[%d] sig %d scp %p\n", + p->p_comm, p->p_pid, sig, &fp->sf_uc); + } +#endif + /* + * Build context to run handler in. + */ + addr = (vaddr_t)p->p_sigctx.ps_sigcode; + tf->tf_pc = addr; + tf->tf_npc = addr + 4; + tf->tf_global[1] = (vaddr_t)catcher; + tf->tf_out[6] = newsp; + + /* Remember that we're now on the signal stack. */ + if (onstack) + p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; +#ifdef DEBUG + if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) { + printf("svr4_32_sendsig: about to return to catcher %p thru %p\n", + catcher, (void *)(u_long)addr); +#ifdef DDB + if (sigdebug & SDB_DDB) Debugger(); +#endif + } +#endif +} + + +#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4) +int +svr4_32_trap(type, p) + int type; + struct proc *p; +{ + int n; + struct trapframe64 *tf = p->p_md.md_tf; + extern struct emul emul_svr4_32; + + if (p->p_emul != &emul_svr4_32) + return 0; + + switch (type) { + case T_SVR4_GETCC: + uprintf("T_SVR4_GETCC\n"); + break; + + case T_SVR4_SETCC: + uprintf("T_SVR4_SETCC\n"); + break; + + case T_SVR4_GETPSR: + tf->tf_out[0] = TSTATECCR_TO_PSR(tf->tf_tstate); + break; + + case T_SVR4_SETPSR: + uprintf("T_SVR4_SETPSR\n"); + break; + + case T_SVR4_GETHRTIME: + /* + * This is like gethrtime(3), returning the time expressed + * in nanoseconds since an arbitrary time in the past and + * guaranteed to be monotonically increasing, which we + * obtain from mono_time(9). + */ + { + struct timeval tv; + quad_t tm; + int s; + + s = splclock(); + tv = mono_time; + splx(s); + + tm = (u_quad_t) tv.tv_sec * 1000000000 + + (u_quad_t) tv.tv_usec * 1000; + tf->tf_out[0] = ((u_int32_t *) &tm)[0]; + tf->tf_out[1] = ((u_int32_t *) &tm)[1]; + } + break; + + case T_SVR4_GETHRVTIME: + /* + * This is like gethrvtime(3). returning the LWP's (now: + * proc's) virtual time expressed in nanoseconds. It is + * supposedly guaranteed to be monotonically increasing, but + * for now using the process's real time augmented with its + * current runtime is the best we can do. + */ + { + struct schedstate_percpu *spc = + &curcpu()->ci_schedstate; + struct timeval tv; + quad_t tm; + + microtime(&tv); + + tm = + (u_quad_t) (p->p_rtime.tv_sec + + tv.tv_sec - + spc->spc_runtime.tv_sec) + * 1000000 + + (u_quad_t) (p->p_rtime.tv_usec + + tv.tv_usec - + spc->spc_runtime.tv_usec) + * 1000; + tf->tf_out[0] = ((u_int32_t *) &tm)[0]; + tf->tf_out[1] = ((u_int32_t *) &tm)[1]; + } + break; + + case T_SVR4_GETHRESTIME: + { + /* I assume this is like gettimeofday(3) */ + struct timeval tv; + + microtime(&tv); + tf->tf_out[0] = tv.tv_sec; + tf->tf_out[1] = tv.tv_usec; + } + break; + + default: + return 0; + } + + ADVANCE; + return 1; +} + +/* + */ +int +svr4_32_sys_sysarch(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct svr4_32_sys_sysarch_args *uap = v; + + switch (SCARG(uap, op)) { + default: + printf("(sparc) svr4_32_sysarch(%d)\n", SCARG(uap, op)); + return EINVAL; + } +} diff --git a/sys/arch/sparc64/sparc64/svr4_machdep.c b/sys/arch/sparc64/sparc64/svr4_machdep.c index 01dcccd00cd9..4a62e51348b6 100644 --- a/sys/arch/sparc64/sparc64/svr4_machdep.c +++ b/sys/arch/sparc64/sparc64/svr4_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: svr4_machdep.c,v 1.16 2000/12/22 22:58:56 jdolecek Exp $ */ +/* $NetBSD: svr4_machdep.c,v 1.17 2001/02/11 00:39:37 eeh Exp $ */ /*- * Copyright (c) 1994 The NetBSD Foundation, Inc. @@ -79,8 +79,12 @@ svr4_setregs(p, epp, stack) struct exec_package *epp; u_long stack; { + register struct trapframe64 *tf = p->p_md.md_tf; setregs(p, epp, stack); + + /* This should be the exit function, not PS_STRINGS. */ + tf->tf_global[1] = (vaddr_t)0; } #ifdef DEBUG diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c index 258a69fbcf08..2d1396141ba9 100644 --- a/sys/arch/sparc64/sparc64/trap.c +++ b/sys/arch/sparc64/sparc64/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.61 2001/02/05 12:45:38 mrg Exp $ */ +/* $NetBSD: trap.c,v 1.62 2001/02/11 00:39:38 eeh Exp $ */ /* * Copyright (c) 1996 @@ -87,6 +87,9 @@ #ifdef COMPAT_SVR4 #include #endif +#ifdef COMPAT_SVR4_32 +#include +#endif #include #include @@ -641,7 +644,7 @@ dopanic: } /* NOTREACHED */ } -#if defined(COMPAT_SVR4) || defined(SUN4M) +#if defined(COMPAT_SVR4) || defined(COMPAT_SVR4_32) badtrap: #endif /* the following message is gratuitous */ @@ -651,7 +654,7 @@ badtrap: trapsignal(p, SIGILL, type); break; -#ifdef COMPAT_SVR4 +#if defined(COMPAT_SVR4) || defined(COMPAT_SVR4_32) case T_SVR4_GETCC: case T_SVR4_SETCC: case T_SVR4_GETPSR: @@ -659,9 +662,15 @@ badtrap: case T_SVR4_GETHRTIME: case T_SVR4_GETHRVTIME: case T_SVR4_GETHRESTIME: - if (!svr4_trap(type, p)) - goto badtrap; - break; +#if defined(COMPAT_SVR4_32) + if (svr4_32_trap(type, p)) + break; +#endif +#if defined(COMPAT_SVR4) + if (svr4_trap(type, p)) + break; +#endif + goto badtrap; #endif case T_AST: @@ -673,8 +682,9 @@ badtrap: /* This is not an MMU issue!!!! */ printf("trap: textfault at %lx!! sending SIGILL due to trap %d: %s\n", pc, type, type < N_TRAP_TYPES ? trap_type[type] : T); -#ifdef DDB - Debugger(); +#if defined(DDB) && defined(DEBUG) + if (trapdebug & TDB_STOPSIG) + Debugger(); #endif trapsignal(p, SIGILL, 0); /* XXX code?? */ break;