Add support for COMPAT_SVR4_32.

This commit is contained in:
eeh 2001-02-11 00:39:37 +00:00
parent 750052a46f
commit d8405328df
5 changed files with 817 additions and 10 deletions

View File

@ -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"

View File

@ -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 <compat/svr4_32/svr4_32_types.h>
#include <machine/svr4_machdep.h>
/*
* 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_ */

View File

@ -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 <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/user.h>
#include <sys/filedesc.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/exec_elf.h>
#include <sys/types.h>
#include <compat/svr4_32/svr4_32_types.h>
#include <compat/svr4_32/svr4_32_lwp.h>
#include <compat/svr4_32/svr4_32_ucontext.h>
#include <compat/svr4_32/svr4_32_syscallargs.h>
#include <compat/svr4_32/svr4_32_util.h>
#include <compat/svr4_32/svr4_32_exec.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <machine/trap.h>
#include <machine/vmparam.h>
#include <machine/svr4_machdep.h>
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 <sparc64/sparc64/sigdebug.h>
#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;
}
}

View File

@ -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

View File

@ -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 <machine/svr4_machdep.h>
#endif
#ifdef COMPAT_SVR4_32
#include <machine/svr4_32_machdep.h>
#endif
#include <sparc/fpu/fpu_extern.h>
#include <sparc64/sparc64/cache.h>
@ -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;