Add SA_SIGINFO support for VAX.
This commit is contained in:
parent
5c09d20130
commit
050d126a03
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.vax,v 1.99 2003/07/27 01:19:34 thorpej Exp $
|
||||
# $NetBSD: files.vax,v 1.100 2003/09/29 21:04:53 matt Exp $
|
||||
#
|
||||
# new style config file for vax architecture
|
||||
#
|
||||
@ -332,6 +332,7 @@ file arch/vax/vax/bus_dma.c
|
||||
file arch/vax/vax/bus_mem.c
|
||||
file arch/vax/vax/procfs_machdep.c procfs
|
||||
file arch/vax/vax/sgmap.c
|
||||
file arch/vax/vax/sig_machdep.c
|
||||
file arch/vax/vax/vm_machdep.c
|
||||
file arch/vax/vax/findcpu.c
|
||||
file arch/vax/vax/autoconf.c
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ibcs2_machdep.h,v 1.6 2003/09/26 12:02:57 simonb Exp $ */
|
||||
/* $NetBSD: ibcs2_machdep.h,v 1.7 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -47,9 +47,9 @@
|
||||
struct exec_package;
|
||||
struct exec_vmcmd;
|
||||
|
||||
void ibcs2_setregs __P((struct lwp *, struct exec_package *, u_long));
|
||||
void ibcs2_sendsig __P((int, const sigset_t *, u_long));
|
||||
int ibcs2_sys_sysmachine __P((struct proc *, void *, register_t *));
|
||||
void ibcs2_setregs (struct lwp *, struct exec_package *, u_long);
|
||||
void ibcs2_sendsig (const ksiginfo_t *, const sigset_t *);
|
||||
int ibcs2_sys_sysmachine (struct proc *, void *, register_t *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: signal.h,v 1.10 2003/08/07 16:30:12 agc Exp $ */
|
||||
/* $NetBSD: signal.h,v 1.11 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
|
||||
@ -40,6 +40,8 @@
|
||||
|
||||
typedef int sig_atomic_t;
|
||||
|
||||
#define __HAVE_SIGINFO
|
||||
|
||||
#if defined(_NETBSD_SOURCE)
|
||||
/*
|
||||
* Information pushed on stack when a signal is delivered.
|
||||
@ -71,29 +73,16 @@ struct sigcontext {
|
||||
sigset_t sc_mask; /* signal mask to restore (new style) */
|
||||
};
|
||||
|
||||
/*
|
||||
* The following macros are used to convert from a ucontext to sigcontext,
|
||||
* and vice-versa. This is for building a sigcontext to deliver to old-style
|
||||
* signal handlers, and converting back (in the event the handler modifies
|
||||
* the context).
|
||||
*/
|
||||
#define _MCONTEXT_TO_SIGCONTEXT(uc, sc) \
|
||||
do { \
|
||||
(sc)->sc_sp = (uc)->uc_mcontext.__gregs[_REG_SP]; \
|
||||
(sc)->sc_fp = (uc)->uc_mcontext.__gregs[_REG_FP]; \
|
||||
(sc)->sc_ap = (uc)->uc_mcontext.__gregs[_REG_AP]; \
|
||||
(sc)->sc_pc = (uc)->uc_mcontext.__gregs[_REG_PC]; \
|
||||
(sc)->sc_ps = (uc)->uc_mcontext.__gregs[_REG_PSL]; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#ifdef _KERNEL
|
||||
void sendsig_context(int, const sigset_t *, u_long);
|
||||
|
||||
#define _SIGCONTEXT_TO_MCONTEXT(sc, uc) \
|
||||
do { \
|
||||
(uc)->uc_mcontext.__gregs[_REG_SP] = (sc)->sc_sp; \
|
||||
(uc)->uc_mcontext.__gregs[_REG_FP] = (sc)->sc_fp; \
|
||||
(uc)->uc_mcontext.__gregs[_REG_AP] = (sc)->sc_ap; \
|
||||
(uc)->uc_mcontext.__gregs[_REG_PC] = (sc)->sc_pc; \
|
||||
(uc)->uc_mcontext.__gregs[_REG_PSL] = (sc)->sc_ps; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#ifdef COMPAT_16
|
||||
#define SIGTRAMP_VALID(vers) ((vers) <= 3 && (vers) != 1)
|
||||
#else
|
||||
#define SIGTRAMP_VALID(vers) ((vers) == 3)
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETBSD_SOURCE */
|
||||
#endif /* !_VAX_SIGNAL_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: genassym.cf,v 1.26 2003/01/19 22:29:23 ragge Exp $
|
||||
# $NetBSD: genassym.cf,v 1.27 2003/09/29 21:04:53 matt Exp $
|
||||
#
|
||||
# Copyright (c) 1997 Ludd, University of Lule}, Sweden.
|
||||
# All rights reserved.
|
||||
@ -40,11 +40,12 @@ include <sys/device.h>
|
||||
|
||||
include <uvm/uvm.h>
|
||||
|
||||
include <machine/cpu.h>
|
||||
include <machine/mtpr.h>
|
||||
include <machine/pcb.h>
|
||||
include <machine/sid.h>
|
||||
include <machine/signal.h>
|
||||
include <machine/trap.h>
|
||||
include <machine/cpu.h>
|
||||
include <machine/uvax.h>
|
||||
|
||||
define L_PRIORITY offsetof(struct lwp, l_priority)
|
||||
@ -125,7 +126,7 @@ define EFAULT EFAULT
|
||||
|
||||
define EV_COUNT offsetof(struct evcnt, ev_count)
|
||||
|
||||
define SYS___sigreturn14 SYS___sigreturn14
|
||||
define SYS_compat_16___sigreturn14 SYS_compat_16___sigreturn14
|
||||
define SYS_exit SYS_exit
|
||||
|
||||
define VAX_TYP_UV2 VAX_TYP_UV2
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ibcs2_machdep.c,v 1.6 2003/09/26 12:02:57 simonb Exp $ */
|
||||
/* $NetBSD: ibcs2_machdep.c,v 1.7 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ibcs2_machdep.c,v 1.6 2003/09/26 12:02:57 simonb Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ibcs2_machdep.c,v 1.7 2003/09/29 21:04:53 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -57,10 +57,7 @@ __KERNEL_RCSID(0, "$NetBSD: ibcs2_machdep.c,v 1.6 2003/09/26 12:02:57 simonb Exp
|
||||
#include <compat/ibcs2/ibcs2_signal.h>
|
||||
|
||||
void
|
||||
ibcs2_setregs(l, epp, stack)
|
||||
struct lwp *l;
|
||||
struct exec_package *epp;
|
||||
u_long stack;
|
||||
ibcs2_setregs(struct lwp *l, struct exec_package *epp, u_long stack)
|
||||
{
|
||||
/* Don't need to anything special */
|
||||
setregs(l, epp, stack);
|
||||
@ -77,19 +74,19 @@ ibcs2_setregs(l, epp, stack)
|
||||
* specified pc, psl.
|
||||
*/
|
||||
void
|
||||
ibcs2_sendsig(sig, mask, code)
|
||||
int sig;
|
||||
const sigset_t *mask;
|
||||
u_long code;
|
||||
ibcs2_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
|
||||
{
|
||||
sendsig(native_to_ibcs2_signo[sig], mask, code);
|
||||
ksiginfo_t nksi;
|
||||
if (ksi->ksi_signo != native_to_ibcs2_signo[ksi->ksi_signo]) {
|
||||
nksi = *ksi;
|
||||
nksi.ksi_signo = native_to_ibcs2_signo[ksi->ksi_signo];
|
||||
ksi = &nksi;
|
||||
}
|
||||
sendsig(ksi, mask);
|
||||
}
|
||||
|
||||
int
|
||||
ibcs2_sys_sysmachine(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
ibcs2_sys_sysmachine(struct proc *l, void *v, register_t *retval)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.139 2003/09/26 12:02:57 simonb Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.140 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
||||
@ -83,7 +83,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.139 2003/09/26 12:02:57 simonb Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.140 2003/09/29 21:04:53 matt Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
@ -412,268 +412,6 @@ consinit()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(COMPAT_13) || defined(COMPAT_ULTRIX)
|
||||
int
|
||||
compat_13_sys_sigreturn(l, v, retval)
|
||||
struct lwp *l;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
struct compat_13_sys_sigreturn_args /* {
|
||||
syscallarg(struct sigcontext13 *) sigcntxp;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct trapframe *scf;
|
||||
struct sigcontext13 *ucntx;
|
||||
struct sigcontext13 ksc;
|
||||
sigset_t mask;
|
||||
|
||||
scf = l->l_addr->u_pcb.framep;
|
||||
ucntx = SCARG(uap, sigcntxp);
|
||||
if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext)))
|
||||
return EINVAL;
|
||||
|
||||
/* Compatibility mode? */
|
||||
if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) ||
|
||||
((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) ||
|
||||
(ksc.sc_ps & PSL_CM)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (ksc.sc_onstack & SS_ONSTACK)
|
||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
native_sigset13_to_sigset(&ksc.sc_mask, &mask);
|
||||
(void) sigprocmask1(p, SIG_SETMASK, &mask, 0);
|
||||
|
||||
scf->fp = ksc.sc_fp;
|
||||
scf->ap = ksc.sc_ap;
|
||||
scf->pc = ksc.sc_pc;
|
||||
scf->sp = ksc.sc_sp;
|
||||
scf->psl = ksc.sc_ps;
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sys___sigreturn14(l, v, retval)
|
||||
struct lwp *l;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
struct sys___sigreturn14_args /* {
|
||||
syscallarg(struct sigcontext *) sigcntxp;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct trapframe *scf;
|
||||
struct sigcontext *ucntx;
|
||||
struct sigcontext ksc;
|
||||
|
||||
scf = l->l_addr->u_pcb.framep;
|
||||
ucntx = SCARG(uap, sigcntxp);
|
||||
|
||||
if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext)))
|
||||
return EINVAL;
|
||||
/* Compatibility mode? */
|
||||
if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) ||
|
||||
((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) ||
|
||||
(ksc.sc_ps & PSL_CM)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (ksc.sc_onstack & SS_ONSTACK)
|
||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
/* Restore signal mask. */
|
||||
(void) sigprocmask1(p, SIG_SETMASK, &ksc.sc_mask, 0);
|
||||
|
||||
scf->fp = ksc.sc_fp;
|
||||
scf->ap = ksc.sc_ap;
|
||||
scf->pc = ksc.sc_pc;
|
||||
scf->sp = ksc.sc_sp;
|
||||
scf->psl = ksc.sc_ps;
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
#if defined(COMPAT_16) || defined(COMPAT_ULTRIX) || defined(COMPAT_IBCS2)
|
||||
|
||||
struct otrampframe {
|
||||
unsigned sig; /* Signal number */
|
||||
unsigned code; /* Info code */
|
||||
unsigned scp; /* Pointer to struct sigcontext */
|
||||
unsigned r0, r1, r2, r3, r4, r5; /* Registers saved when
|
||||
* interrupt */
|
||||
unsigned pc; /* Address of signal handler */
|
||||
unsigned arg; /* Pointer to first (and only) sigreturn
|
||||
* argument */
|
||||
};
|
||||
|
||||
static void
|
||||
oldsendsig(int sig, const sigset_t *mask, u_long code)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
struct sigacts *ps = p->p_sigacts;
|
||||
struct trapframe *syscf;
|
||||
struct sigcontext *sigctx, gsigctx;
|
||||
struct otrampframe *trampf, gtrampf;
|
||||
unsigned cursp;
|
||||
int onstack;
|
||||
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
||||
|
||||
syscf = l->l_addr->u_pcb.framep;
|
||||
|
||||
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)
|
||||
cursp = ((int)p->p_sigctx.ps_sigstk.ss_sp + p->p_sigctx.ps_sigstk.ss_size);
|
||||
else
|
||||
cursp = syscf->sp;
|
||||
|
||||
/* Set up positions for structs on stack */
|
||||
sigctx = (struct sigcontext *) (cursp - sizeof(struct sigcontext));
|
||||
trampf = (struct otrampframe *) ((unsigned)sigctx -
|
||||
sizeof(struct otrampframe));
|
||||
|
||||
/* Place for pointer to arg list in sigreturn */
|
||||
cursp = (unsigned)sigctx - 8;
|
||||
|
||||
gtrampf.arg = (int) sigctx;
|
||||
gtrampf.pc = (unsigned) catcher;
|
||||
/* r0..r5 are saved by the popr in the sigcode snippet */
|
||||
gtrampf.scp = (int) sigctx;
|
||||
gtrampf.code = code;
|
||||
gtrampf.sig = sig;
|
||||
|
||||
gsigctx.sc_pc = syscf->pc;
|
||||
gsigctx.sc_ps = syscf->psl;
|
||||
gsigctx.sc_ap = syscf->ap;
|
||||
gsigctx.sc_fp = syscf->fp;
|
||||
gsigctx.sc_sp = syscf->sp;
|
||||
gsigctx.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
gsigctx.sc_mask = *mask;
|
||||
|
||||
#if defined(COMPAT_13) || defined(COMPAT_ULTRIX)
|
||||
native_sigset_to_sigset13(mask, &gsigctx.__sc_mask13);
|
||||
#endif
|
||||
|
||||
if (copyout(>rampf, trampf, sizeof(gtrampf)) ||
|
||||
copyout(&gsigctx, sigctx, sizeof(gsigctx)))
|
||||
sigexit(l, SIGILL);
|
||||
|
||||
/*
|
||||
* Note the trampoline version numbers are coordinated with
|
||||
* machine-dependent code in libc.
|
||||
*/
|
||||
switch (ps->sa_sigdesc[sig].sd_vers) {
|
||||
case 0:
|
||||
syscf->pc = (int)p->p_sigctx.ps_sigcode;
|
||||
break;
|
||||
case 1:
|
||||
syscf->pc = (int)ps->sa_sigdesc[sig].sd_tramp;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* ``cannot happen'' */
|
||||
sigexit(l, SIGILL);
|
||||
}
|
||||
syscf->psl = PSL_U | PSL_PREVU;
|
||||
syscf->ap = cursp;
|
||||
syscf->sp = cursp;
|
||||
|
||||
if (onstack)
|
||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct trampoline {
|
||||
unsigned int narg; /* Argument count (== 3) */
|
||||
unsigned int sig; /* Signal number */
|
||||
unsigned int code; /* Info code */
|
||||
unsigned int scp; /* Pointer to struct sigcontext */
|
||||
};
|
||||
|
||||
/*
|
||||
* Brief description of how sendsig() works:
|
||||
* A struct sigcontext is allocated on the user stack. The relevant
|
||||
* registers are saved in it. Below it is a struct trampframe constructed, it
|
||||
* is actually an argument list for callg. The user
|
||||
* stack pointer is put below all structs.
|
||||
*
|
||||
* The registers will contain when the signal handler is called:
|
||||
* pc, psl - Obvious
|
||||
* sp - An address below all structs
|
||||
* fp - The address of the signal handler
|
||||
* ap - The address to the callg frame
|
||||
*
|
||||
* The trampoline code will save r0-r5 before doing anything else.
|
||||
*/
|
||||
void
|
||||
sendsig(int sig, const sigset_t *mask, u_long code)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = curproc;
|
||||
struct sigacts *ps = p->p_sigacts;
|
||||
struct trampoline tramp;
|
||||
struct sigcontext sigctx;
|
||||
struct trapframe *tf = l->l_addr->u_pcb.framep;
|
||||
sig_t catcher = SIGACTION(p, sig).sa_handler;
|
||||
int onstack =
|
||||
(p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
|
||||
(SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
|
||||
int cursp = onstack == 0 ? tf->sp :
|
||||
((int)p->p_sigctx.ps_sigstk.ss_sp + p->p_sigctx.ps_sigstk.ss_size);
|
||||
|
||||
#if defined(COMPAT_16) || defined(COMPAT_ULTRIX) || defined(COMPAT_IBCS2)
|
||||
if (ps->sa_sigdesc[sig].sd_vers < 2)
|
||||
return oldsendsig(sig, mask, code);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The sigcontext struct will be passed back to sigreturn().
|
||||
*/
|
||||
sigctx.sc_pc = tf->pc;
|
||||
sigctx.sc_ps = tf->psl;
|
||||
sigctx.sc_ap = tf->ap;
|
||||
sigctx.sc_fp = tf->fp;
|
||||
sigctx.sc_sp = tf->sp;
|
||||
sigctx.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK;
|
||||
sigctx.sc_mask = *mask;
|
||||
|
||||
/*
|
||||
* Arguments given to the signal handler.
|
||||
*/
|
||||
tramp.narg = 3;
|
||||
tramp.sig = sig;
|
||||
tramp.code = code;
|
||||
tramp.scp = cursp - sizeof(struct sigcontext);
|
||||
|
||||
if (copyout(&sigctx, (char *)tramp.scp, sizeof(struct sigcontext)) ||
|
||||
copyout(&tramp, (char *)tramp.scp - sizeof(tramp), sizeof(tramp)))
|
||||
sigexit(l, SIGILL);
|
||||
|
||||
switch (ps->sa_sigdesc[sig].sd_vers) {
|
||||
case 2:
|
||||
tf->pc = (int)ps->sa_sigdesc[sig].sd_tramp;
|
||||
break;
|
||||
default:
|
||||
/* Don't know what trampoline version; kill it. */
|
||||
sigexit(l, SIGILL);
|
||||
}
|
||||
tf->psl = PSL_U | PSL_PREVU;
|
||||
tf->ap = tramp.scp - sizeof(tramp);
|
||||
tf->fp = (int)catcher;
|
||||
tf->sp = tf->ap;
|
||||
|
||||
if (onstack)
|
||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
}
|
||||
|
||||
int waittime = -1;
|
||||
static volatile int showto; /* Must be volatile to survive MM on -> MM off */
|
||||
|
||||
|
459
sys/arch/vax/vax/sig_machdep.c
Normal file
459
sys/arch/vax/vax/sig_machdep.c
Normal file
@ -0,0 +1,459 @@
|
||||
/* $NetBSD: sig_machdep.c,v 1.1 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Changed for the VAX port (and for readability) /IC
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by the Systems
|
||||
* Programming Group of the University of Utah Computer Science Department.
|
||||
*
|
||||
* 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* from: Utah Hdr: machdep.c 1.63 91/04/24
|
||||
*
|
||||
* @(#)machdep.c 7.16 (Berkeley) 6/3/91
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, Hugh Graham.
|
||||
* Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
*
|
||||
* Changed for the VAX port (and for readability) /IC
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by the Systems
|
||||
* Programming Group of the University of Utah Computer Science Department.
|
||||
*
|
||||
* 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 University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* from: Utah Hdr: machdep.c 1.63 91/04/24
|
||||
*
|
||||
* @(#)machdep.c 7.16 (Berkeley) 6/3/91
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sig_machdep.c,v 1.1 2003/09/29 21:04:53 matt Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_ultrix.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
#include "opt_lockdebug.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/extent.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/msgbuf.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/sa.h>
|
||||
#include <sys/syscallargs.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/savar.h>
|
||||
#include <sys/ksyms.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/sid.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/mtpr.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/macros.h>
|
||||
#include <machine/nexus.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/scb.h>
|
||||
#include <vax/vax/gencons.h>
|
||||
|
||||
#ifdef DDB
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_extern.h>
|
||||
#endif
|
||||
typedef vaddr_t (*sig_setupstack_t)(const ksiginfo_t *, const sigset_t *,
|
||||
int, struct lwp *, struct trapframe *, vaddr_t, int, vaddr_t);
|
||||
|
||||
#if defined(COMPAT_13) || defined(COMAT_ULTRIX) || defined(COMPAT_IBCS2)
|
||||
static vaddr_t setupstack_oldsigcontext(const ksiginfo_t *, const sigset_t *,
|
||||
int, struct lwp *, struct trapframe *, vaddr_t, int, vaddr_t);
|
||||
#endif
|
||||
#if defined(COMPAT_16) || defined(COMAT_ULTRIX)
|
||||
static vaddr_t setupstack_sigcontext2(const ksiginfo_t *, const sigset_t *,
|
||||
int, struct lwp *, struct trapframe *, vaddr_t, int, vaddr_t);
|
||||
#endif
|
||||
static vaddr_t setupstack_siginfo3(const ksiginfo_t *, const sigset_t *,
|
||||
int, struct lwp *, struct trapframe *, vaddr_t, int, vaddr_t);
|
||||
|
||||
const static sig_setupstack_t sig_setupstacks[] = {
|
||||
#if defined(COMPAT_13) || defined(COMAT_ULTRIX) || defined(COMPAT_IBCS2)
|
||||
setupstack_oldsigcontext, /* 0 */
|
||||
setupstack_oldsigcontext, /* 1 */
|
||||
#else
|
||||
0, /* 0 */
|
||||
0, /* 1 */
|
||||
#endif
|
||||
#if defined(COMPAT_16) || defined(COMPAT_ULTRIX)
|
||||
setupstack_sigcontext2, /* 2 */
|
||||
#else
|
||||
0, /* 2 */
|
||||
#endif
|
||||
setupstack_siginfo3, /* 3 */
|
||||
};
|
||||
|
||||
#if defined(COMPAT_13) || defined(COMAT_ULTRIX) || defined(COMPAT_IBCS2)
|
||||
int
|
||||
compat_13_sys_sigreturn(struct lwp *l, void *v, register_t *retval)
|
||||
{
|
||||
struct compat_13_sys_sigreturn_args /* {
|
||||
syscallarg(struct sigcontext13 *) sigcntxp;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct trapframe *scf;
|
||||
struct sigcontext13 *ucntx;
|
||||
struct sigcontext13 ksc;
|
||||
sigset_t mask;
|
||||
|
||||
scf = l->l_addr->u_pcb.framep;
|
||||
ucntx = SCARG(uap, sigcntxp);
|
||||
if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext)))
|
||||
return EINVAL;
|
||||
|
||||
/* Compatibility mode? */
|
||||
if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) ||
|
||||
((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) ||
|
||||
(ksc.sc_ps & PSL_CM)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (ksc.sc_onstack & SS_ONSTACK)
|
||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
|
||||
native_sigset13_to_sigset(&ksc.sc_mask, &mask);
|
||||
(void) sigprocmask1(p, SIG_SETMASK, &mask, 0);
|
||||
|
||||
scf->fp = ksc.sc_fp;
|
||||
scf->ap = ksc.sc_ap;
|
||||
scf->pc = ksc.sc_pc;
|
||||
scf->sp = ksc.sc_sp;
|
||||
scf->psl = ksc.sc_ps;
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_16
|
||||
int
|
||||
compat_16_sys___sigreturn14(struct lwp *l, void *v, register_t *retval)
|
||||
{
|
||||
struct compat_16_sys___sigreturn14_args /* {
|
||||
syscallarg(struct sigcontext *) sigcntxp;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct trapframe *scf;
|
||||
struct sigcontext *ucntx;
|
||||
struct sigcontext ksc;
|
||||
|
||||
scf = l->l_addr->u_pcb.framep;
|
||||
ucntx = SCARG(uap, sigcntxp);
|
||||
|
||||
if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext)))
|
||||
return EINVAL;
|
||||
/* Compatibility mode? */
|
||||
if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) ||
|
||||
((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) ||
|
||||
(ksc.sc_ps & PSL_CM)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (ksc.sc_onstack & SS_ONSTACK)
|
||||
p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
|
||||
else
|
||||
p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
|
||||
/* Restore signal mask. */
|
||||
(void) sigprocmask1(p, SIG_SETMASK, &ksc.sc_mask, 0);
|
||||
|
||||
scf->fp = ksc.sc_fp;
|
||||
scf->ap = ksc.sc_ap;
|
||||
scf->pc = ksc.sc_pc;
|
||||
scf->sp = ksc.sc_sp;
|
||||
scf->psl = ksc.sc_ps;
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
struct otrampframe {
|
||||
unsigned sig; /* Signal number */
|
||||
unsigned code; /* Info code */
|
||||
vaddr_t scp; /* Pointer to struct sigcontext */
|
||||
unsigned r0, r1, r2, r3, r4, r5; /* Registers saved when interrupt */
|
||||
register_t pc; /* Address of signal handler */
|
||||
vaddr_t arg; /* Pointer to first (and only) sigreturn argument */
|
||||
};
|
||||
|
||||
static vaddr_t
|
||||
setupstack_oldsigcontext(const ksiginfo_t *ksi, const sigset_t *mask, int vers,
|
||||
struct lwp *l, struct trapframe *tf, vaddr_t sp, int onstack,
|
||||
vaddr_t handler)
|
||||
{
|
||||
struct sigcontext sigctx;
|
||||
struct otrampframe tramp;
|
||||
|
||||
sigctx.sc_pc = tf->pc;
|
||||
sigctx.sc_ps = tf->psl;
|
||||
sigctx.sc_ap = tf->ap;
|
||||
sigctx.sc_fp = tf->fp;
|
||||
sigctx.sc_sp = tf->sp;
|
||||
sigctx.sc_onstack = onstack ? SS_ONSTACK : 0;
|
||||
sigctx.sc_mask = *mask;
|
||||
sp -= sizeof(struct sigcontext);
|
||||
|
||||
#if defined(COMPAT_13) || defined(COMPAT_ULTRIX)
|
||||
native_sigset_to_sigset13(mask, &sigctx.__sc_mask13);
|
||||
#endif
|
||||
|
||||
tramp.sig = ksi->ksi_signo;
|
||||
tramp.code = ksi->ksi_trap;
|
||||
/* Set up positions for structs on stack */
|
||||
tramp.scp = sp;
|
||||
/* r0..r5 are saved by the popr in the sigcode snippet but we need
|
||||
to zero them anyway. */
|
||||
tramp.r0 = tramp.r1 = tramp.r2 = tramp.r3 = tramp.r4 = tramp.r5 = 0;
|
||||
tramp.pc = (register_t)handler;
|
||||
tramp.arg = sp;
|
||||
|
||||
/* Point stack pointer at pc in trampoline. */
|
||||
sp =- 8;
|
||||
|
||||
if (copyout(&tramp, (caddr_t)tramp.scp - sizeof(tramp), sizeof(tramp)) != 0 ||
|
||||
copyout(&sigctx, (caddr_t)tramp.scp, sizeof(sigctx)) != 0)
|
||||
return 0;
|
||||
|
||||
return sp;
|
||||
}
|
||||
#endif /* COMPAT_16 */
|
||||
|
||||
/*
|
||||
* Brief description of how sendsig() works:
|
||||
* A struct sigcontext is allocated on the user stack. The relevant
|
||||
* registers are saved in it. Below it is a struct trampframe constructed, it
|
||||
* is actually an argument list for callg. The user
|
||||
* stack pointer is put below all structs.
|
||||
*
|
||||
* The registers will contain when the signal handler is called:
|
||||
* pc, psl - Obvious
|
||||
* sp - An address below all structs
|
||||
* fp - The address of the signal handler
|
||||
* ap - The address to the callg frame
|
||||
*
|
||||
* The trampoline code will save r0-r5 before doing anything else.
|
||||
*/
|
||||
struct trampoline2 {
|
||||
unsigned int narg; /* Argument count (== 3) */
|
||||
unsigned int sig; /* Signal number */
|
||||
unsigned int code; /* Info code */
|
||||
vaddr_t scp; /* Pointer to struct sigcontext */
|
||||
};
|
||||
|
||||
|
||||
static vaddr_t
|
||||
setupstack_sigcontext2(const ksiginfo_t *ksi, const sigset_t *mask, int vers,
|
||||
struct lwp *l, struct trapframe *tf, vaddr_t sp, int onstack,
|
||||
vaddr_t handler)
|
||||
{
|
||||
struct trampoline2 tramp;
|
||||
struct sigcontext sigctx;
|
||||
|
||||
/* The sigcontext struct will be passed back to sigreturn(). */
|
||||
sigctx.sc_pc = tf->pc;
|
||||
sigctx.sc_ps = tf->psl;
|
||||
sigctx.sc_ap = tf->ap;
|
||||
sigctx.sc_fp = tf->fp;
|
||||
sigctx.sc_sp = tf->sp;
|
||||
sigctx.sc_onstack = onstack ? SS_ONSTACK : 0;
|
||||
sigctx.sc_mask = *mask;
|
||||
sp -= sizeof(struct sigcontext);
|
||||
|
||||
/* Arguments given to the signal handler. */
|
||||
tramp.narg = 3;
|
||||
tramp.sig = ksi->ksi_signo;
|
||||
tramp.code = ksi->ksi_trap;
|
||||
tramp.scp = sp;
|
||||
sp -= sizeof(tramp);
|
||||
|
||||
/* Store the handler in the trapframe. */
|
||||
tf->fp = handler;
|
||||
|
||||
/* Copy out the sigcontext and trampoline. */
|
||||
if (copyout(&sigctx, (char *)tramp.scp, sizeof(sigctx)) != 0 ||
|
||||
copyout(&tramp, (char *)sp, sizeof(tramp)) != 0)
|
||||
return 0;
|
||||
|
||||
/* return updated stack pointer */
|
||||
return sp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Brief description of how sendsig() works:
|
||||
* A struct sigcontext is allocated on the user stack. The relevant
|
||||
* registers are saved in it. Below it is a struct trampframe constructed, it
|
||||
* is actually an argument list for callg. The user
|
||||
* stack pointer is put below all structs.
|
||||
*
|
||||
* The registers will contain when the signal handler is called:
|
||||
* pc, psl - Obvious
|
||||
* sp - An address below all structs
|
||||
* fp - The address of the signal handler
|
||||
* ap - The address to the callg frame
|
||||
*
|
||||
* The trampoline code will save r0-r5 before doing anything else.
|
||||
*/
|
||||
struct trampoline3 {
|
||||
unsigned int narg; /* Argument count (== 3) */
|
||||
int sig; /* Signal number */
|
||||
vaddr_t sip; /* Pointer to siginfo_t */
|
||||
vaddr_t ucp; /* Pointer to ucontext_t */
|
||||
};
|
||||
|
||||
static vaddr_t
|
||||
setupstack_siginfo3(const ksiginfo_t *ksi, const sigset_t *mask, int vers,
|
||||
struct lwp *l, struct trapframe *tf, vaddr_t sp, int onstack,
|
||||
vaddr_t handler)
|
||||
{
|
||||
struct trampoline3 tramp;
|
||||
ucontext_t uc;
|
||||
|
||||
/*
|
||||
* Arguments given to the signal handler.
|
||||
*/
|
||||
tramp.narg = 3;
|
||||
tramp.sig = ksi->ksi_signo;
|
||||
sp -= sizeof(uc); tramp.ucp = sp;
|
||||
sp -= sizeof(siginfo_t); tramp.sip = sp;
|
||||
sp -= sizeof(tramp);
|
||||
|
||||
/* Save register context. */
|
||||
uc.uc_flags = _UC_SIGMASK;
|
||||
uc.uc_sigmask = *mask;
|
||||
uc.uc_link = NULL;
|
||||
memset(&uc.uc_stack, 0, sizeof(uc.uc_stack));
|
||||
cpu_getmcontext(l, &uc.uc_mcontext, &uc.uc_flags);
|
||||
|
||||
tf->fp = handler;
|
||||
|
||||
/* Copy the context to the stack. */
|
||||
if (copyout(&uc, (char *)tramp.ucp, sizeof(uc)) != 0 ||
|
||||
copyout(ksi, (char *)tramp.sip, sizeof(*ksi)) != 0 ||
|
||||
copyout(&tramp, (char *)sp, sizeof(tramp)) != 0)
|
||||
sigexit(l, SIGILL);
|
||||
|
||||
return sp;
|
||||
};
|
||||
|
||||
void
|
||||
sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
struct trapframe *tf = l->l_addr->u_pcb.framep;
|
||||
struct sigaltstack *ss = &p->p_sigctx.ps_sigstk;
|
||||
const struct sigact_sigdesc *sd =
|
||||
&p->p_sigacts->sa_sigdesc[ksi->ksi_signo];
|
||||
vaddr_t sp;
|
||||
int onstack;
|
||||
sig_setupstack_t setup;
|
||||
|
||||
/* Figure what stack we are running on. */
|
||||
onstack = (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
|
||||
(sd->sd_sigact.sa_flags & SA_ONSTACK) != 0;
|
||||
sp = onstack ? ((vaddr_t)ss->ss_sp + ss->ss_size) : tf->sp;
|
||||
|
||||
if (sd->sd_vers > 3 || (setup = sig_setupstacks[sd->sd_vers]) == NULL)
|
||||
goto nosupport;
|
||||
|
||||
sp = (*setup)(ksi, mask, sd->sd_vers, l, tf, sp, onstack,
|
||||
(vaddr_t)sd->sd_sigact.sa_handler);
|
||||
if (sp == 0)
|
||||
goto nosupport;
|
||||
|
||||
if (sd->sd_vers == 0)
|
||||
tf->pc = (register_t)p->p_sigctx.ps_sigcode;
|
||||
else
|
||||
tf->pc = (register_t)sd->sd_tramp;
|
||||
|
||||
tf->psl = PSL_U | PSL_PREVU;
|
||||
tf->sp = sp;
|
||||
tf->ap = sp;
|
||||
|
||||
if (onstack)
|
||||
ss->ss_flags |= SS_ONSTACK;
|
||||
return;
|
||||
|
||||
nosupport:
|
||||
/* Don't know what trampoline version; kill it. */
|
||||
printf("sendsig(sig %d): bad version %d\n",
|
||||
ksi->ksi_signo, sd->sd_vers);
|
||||
sigexit(l, SIGILL);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: subr.S,v 1.7 2003/01/20 04:45:57 matt Exp $ */
|
||||
/* $NetBSD: subr.S,v 1.8 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||
@ -169,7 +169,7 @@ _C_LABEL(sigcode):
|
||||
movl 0x24(%sp),%r0
|
||||
calls $3,(%r0)
|
||||
popr $0x3f
|
||||
chmk $SYS___sigreturn14
|
||||
chmk $SYS_compat_16___sigreturn14
|
||||
chmk $SYS_exit
|
||||
halt
|
||||
|
||||
@ -191,7 +191,7 @@ _C_LABEL(ibcs2_sigcode):
|
||||
movl 0x24(%sp),%r0
|
||||
calls $3,(%r0)
|
||||
popr $0x3f
|
||||
chmk $SYS___sigreturn14
|
||||
chmk $SYS_compat_16___sigreturn14
|
||||
chmk $SYS_exit
|
||||
halt
|
||||
_C_LABEL(ibcs2_esigcode):
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: trap.c,v 1.82 2003/09/18 22:38:36 cl Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.83 2003/09/29 21:04:53 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||
@ -33,7 +33,7 @@
|
||||
/* All bugs are subject to removal without further notice */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.82 2003/09/18 22:38:36 cl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.83 2003/09/29 21:04:53 matt Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_ktrace.h"
|
||||
@ -163,7 +163,7 @@ userret(struct lwp *l, struct trapframe *frame, u_quad_t oticks)
|
||||
void
|
||||
trap(struct trapframe *frame)
|
||||
{
|
||||
u_int sig = 0, type = frame->trap, trapsig = 1;
|
||||
u_int sig = 0, type = frame->trap, trapsig = 1, code = 0;
|
||||
u_int rv, addr, umode;
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
@ -223,6 +223,7 @@ fram:
|
||||
case T_ACCFLT|T_USER:
|
||||
if (frame->code < 0) { /* Check for kernel space */
|
||||
sig = SIGSEGV;
|
||||
code = SEGV_ACCERR;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -293,6 +294,7 @@ if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
|
||||
panic("Segv in kernel mode: pc %x addr %x",
|
||||
(u_int)frame->pc, (u_int)frame->code);
|
||||
}
|
||||
code = SEGV_ACCERR;
|
||||
if (rv == ENOMEM) {
|
||||
printf("UVM: pid %d (%s), uid %d killed: "
|
||||
"out of swap\n",
|
||||
@ -302,6 +304,8 @@ if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
|
||||
sig = SIGKILL;
|
||||
} else {
|
||||
sig = SIGSEGV;
|
||||
if (rv != EACCES)
|
||||
code = SEGV_MAPERR;
|
||||
}
|
||||
} else {
|
||||
trapsig = 0;
|
||||
@ -316,15 +320,26 @@ if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
|
||||
break;
|
||||
|
||||
case T_BPTFLT|T_USER:
|
||||
sig = SIGTRAP;
|
||||
code = TRAP_BRKPT;
|
||||
break;
|
||||
case T_TRCTRAP|T_USER:
|
||||
sig = SIGTRAP;
|
||||
code = TRAP_TRACE;
|
||||
frame->psl &= ~PSL_T;
|
||||
break;
|
||||
|
||||
case T_PRIVINFLT|T_USER:
|
||||
sig = SIGILL;
|
||||
code = ILL_PRVOPC;
|
||||
break;
|
||||
case T_RESADFLT|T_USER:
|
||||
sig = SIGILL;
|
||||
code = ILL_ILLADR;
|
||||
break;
|
||||
case T_RESOPFLT|T_USER:
|
||||
sig = SIGILL;
|
||||
code = ILL_ILLOPC;
|
||||
break;
|
||||
|
||||
case T_XFCFLT|T_USER:
|
||||
@ -350,12 +365,17 @@ if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
|
||||
#endif
|
||||
}
|
||||
if (trapsig) {
|
||||
ksiginfo_t ksi;
|
||||
if ((sig == SIGSEGV || sig == SIGILL) && cpu_printfataltraps)
|
||||
printf("pid %d.%d (%s): sig %d: type %lx, code %lx, pc %lx, psl %lx\n",
|
||||
p->p_pid, l->l_lid, p->p_comm, sig, frame->trap,
|
||||
frame->code, frame->pc, frame->psl);
|
||||
KERNEL_PROC_LOCK(l);
|
||||
trapsignal(l, sig, frame->code);
|
||||
memset(&ksi, 0, sizeof(ksi));
|
||||
ksi.ksi_signo = sig;
|
||||
ksi.ksi_trap = frame->code;
|
||||
ksi.ksi_code = code;
|
||||
trapsignal(l, &ksi);
|
||||
KERNEL_PROC_UNLOCK(l);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user