Prepare for move to SIGINFO framework.
This commit is contained in:
parent
5f8a58e4d6
commit
22813649af
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: trap.c,v 1.93 2003/09/16 14:00:27 cl Exp $ */
|
/* $NetBSD: trap.c,v 1.94 2003/10/12 19:08:17 pk Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
|
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
|
||||||
@ -50,7 +50,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.93 2003/09/16 14:00:27 cl Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.94 2003/10/12 19:08:17 pk Exp $");
|
||||||
|
|
||||||
#define NEW_FPSTATE
|
#define NEW_FPSTATE
|
||||||
|
|
||||||
@ -518,7 +518,9 @@ trap(tf, type, pc, tstate)
|
|||||||
int64_t n;
|
int64_t n;
|
||||||
u_quad_t sticks;
|
u_quad_t sticks;
|
||||||
int pstate = tstate >> TSTATE_PSTATE_SHIFT;
|
int pstate = tstate >> TSTATE_PSTATE_SHIFT;
|
||||||
|
ksiginfo_t ksi;
|
||||||
int error;
|
int error;
|
||||||
|
int sig;
|
||||||
|
|
||||||
/* This steps the PC over the trap. */
|
/* This steps the PC over the trap. */
|
||||||
#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
|
#define ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
|
||||||
@ -640,6 +642,8 @@ extern void db_printf(const char * , ...);
|
|||||||
pcb = &l->l_addr->u_pcb;
|
pcb = &l->l_addr->u_pcb;
|
||||||
l->l_md.md_tf = tf; /* for ptrace/signals */
|
l->l_md.md_tf = tf; /* for ptrace/signals */
|
||||||
|
|
||||||
|
sig = 0;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -669,7 +673,12 @@ badtrap:
|
|||||||
/* ... but leave it in until we find anything */
|
/* ... but leave it in until we find anything */
|
||||||
printf("%s[%d]: unimplemented software trap 0x%x\n",
|
printf("%s[%d]: unimplemented software trap 0x%x\n",
|
||||||
p->p_comm, p->p_pid, type);
|
p->p_comm, p->p_pid, type);
|
||||||
trapsignal(l, SIGILL, type);
|
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
sig = SIGILL;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = ILL_ILLTRP;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(COMPAT_SVR4) || defined(COMPAT_SVR4_32)
|
#if defined(COMPAT_SVR4) || defined(COMPAT_SVR4_32)
|
||||||
@ -713,7 +722,11 @@ badtrap:
|
|||||||
if (trapdebug & TDB_STOPSIG)
|
if (trapdebug & TDB_STOPSIG)
|
||||||
Debugger();
|
Debugger();
|
||||||
#endif
|
#endif
|
||||||
trapsignal(l, SIGILL, 0); /* XXX code?? */
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
sig = SIGILL;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = ILL_ILLOPC;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_PRIVINST:
|
case T_PRIVINST:
|
||||||
@ -723,11 +736,19 @@ badtrap:
|
|||||||
if (trapdebug & TDB_STOPSIG)
|
if (trapdebug & TDB_STOPSIG)
|
||||||
Debugger();
|
Debugger();
|
||||||
#endif
|
#endif
|
||||||
trapsignal(l, SIGILL, 0); /* XXX code?? */
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
sig = SIGILL;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = ILL_PRVOPC;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_PRIVACT:
|
case T_PRIVACT:
|
||||||
trapsignal(l, SIGILL, 0);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
sig = SIGILL;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = ILL_PRVOPC;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_FPDISABLED: {
|
case T_FPDISABLED: {
|
||||||
@ -765,7 +786,7 @@ badtrap:
|
|||||||
case T_ALIGN:
|
case T_ALIGN:
|
||||||
case T_LDDF_ALIGN:
|
case T_LDDF_ALIGN:
|
||||||
case T_STDF_ALIGN:
|
case T_STDF_ALIGN:
|
||||||
{
|
{
|
||||||
int64_t dsfsr, dsfar=0, isfsr;
|
int64_t dsfsr, dsfar=0, isfsr;
|
||||||
|
|
||||||
dsfsr = ldxa(SFSR, ASI_DMMU);
|
dsfsr = ldxa(SFSR, ASI_DMMU);
|
||||||
@ -788,20 +809,24 @@ badtrap:
|
|||||||
l->l_proc->p_pid, l->l_lid, l->l_proc->p_comm, fmt64(dsfsr), fmt64(dsfar),
|
l->l_proc->p_pid, l->l_lid, l->l_proc->p_comm, fmt64(dsfsr), fmt64(dsfar),
|
||||||
fmt64(isfsr), pc);
|
fmt64(isfsr), pc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DDB) && defined(DEBUG)
|
#if defined(DDB) && defined(DEBUG)
|
||||||
if (trapdebug & TDB_STOPSIG) {
|
if (trapdebug & TDB_STOPSIG) {
|
||||||
write_all_windows();
|
write_all_windows();
|
||||||
kdb_trap(type, tf);
|
kdb_trap(type, tf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((l->l_md.md_flags & MDP_FIXALIGN) != 0 &&
|
if ((l->l_md.md_flags & MDP_FIXALIGN) != 0 &&
|
||||||
fixalign(l, tf) == 0) {
|
fixalign(l, tf) == 0) {
|
||||||
ADVANCE;
|
ADVANCE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trapsignal(l, SIGBUS, 0); /* XXX code?? */
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
sig = SIGBUS;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = BUS_ADRALN;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_FP_IEEE_754:
|
case T_FP_IEEE_754:
|
||||||
@ -824,7 +849,11 @@ badtrap:
|
|||||||
&l->l_md.md_fpstate->fs_queue[0].fq_instr,
|
&l->l_md.md_fpstate->fs_queue[0].fq_instr,
|
||||||
sizeof(int));
|
sizeof(int));
|
||||||
if (error) {
|
if (error) {
|
||||||
trapsignal(l, SIGBUS, 0); /* XXX code */
|
sig = SIGBUS;
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = BUS_OBJERR;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
l->l_md.md_fpstate->fs_qsize = 1;
|
l->l_md.md_fpstate->fs_qsize = 1;
|
||||||
@ -839,17 +868,29 @@ badtrap:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_TAGOF:
|
case T_TAGOF:
|
||||||
trapsignal(l, SIGEMT, 0); /* XXX code?? */
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
sig = SIGEMT;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = 0;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_BREAKPOINT:
|
case T_BREAKPOINT:
|
||||||
trapsignal(l, SIGTRAP, 0);
|
sig = SIGTRAP;
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = TRAP_BRKPT;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_IDIV0:
|
case T_IDIV0:
|
||||||
case T_DIV0:
|
case T_DIV0:
|
||||||
ADVANCE;
|
ADVANCE;
|
||||||
trapsignal(l, SIGFPE, FPE_INTDIV_TRAP);
|
sig = SIGFPE;
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = FPE_INTDIV;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_CLEANWIN:
|
case T_CLEANWIN:
|
||||||
@ -866,7 +907,11 @@ badtrap:
|
|||||||
case T_RANGECHECK:
|
case T_RANGECHECK:
|
||||||
printf("T_RANGECHECK\n"); /* XXX */
|
printf("T_RANGECHECK\n"); /* XXX */
|
||||||
ADVANCE;
|
ADVANCE;
|
||||||
trapsignal(l, SIGILL, 0); /* XXX code?? */
|
sig = SIGILL;
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = ILL_ILLADR;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_FIXALIGN:
|
case T_FIXALIGN:
|
||||||
@ -881,9 +926,23 @@ badtrap:
|
|||||||
case T_INTOF:
|
case T_INTOF:
|
||||||
uprintf("T_INTOF\n"); /* XXX */
|
uprintf("T_INTOF\n"); /* XXX */
|
||||||
ADVANCE;
|
ADVANCE;
|
||||||
trapsignal(l, SIGFPE, FPE_INTOVF_TRAP);
|
sig = SIGFPE;
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_code = FPE_INTOVF;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (sig != 0) {
|
||||||
|
KERNEL_PROC_LOCK(l);
|
||||||
|
ksi.ksi_signo = sig;
|
||||||
|
#ifdef __HAVE_SIGINFO
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
#else
|
||||||
|
trapsignal(l, sig, ksi.ksi_code);
|
||||||
|
#endif
|
||||||
|
KERNEL_PROC_UNLOCK(l);
|
||||||
|
}
|
||||||
userret(l, pc, sticks);
|
userret(l, pc, sticks);
|
||||||
share_fpu(l, tf);
|
share_fpu(l, tf);
|
||||||
#undef ADVANCE
|
#undef ADVANCE
|
||||||
@ -1035,6 +1094,7 @@ data_access_fault(tf, type, pc, addr, sfva, sfsr)
|
|||||||
vm_prot_t access_type;
|
vm_prot_t access_type;
|
||||||
vaddr_t onfault;
|
vaddr_t onfault;
|
||||||
u_quad_t sticks;
|
u_quad_t sticks;
|
||||||
|
ksiginfo_t ksi;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int lastdouble;
|
static int lastdouble;
|
||||||
extern struct pcb* cpcb;
|
extern struct pcb* cpcb;
|
||||||
@ -1233,15 +1293,26 @@ kfault:
|
|||||||
Debugger();
|
Debugger();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
KSI_INIT_TRAP(&ksi);
|
||||||
if (rv == ENOMEM) {
|
if (rv == ENOMEM) {
|
||||||
printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
|
printf("UVM: pid %d (%s), uid %d killed: out of swap\n",
|
||||||
p->p_pid, p->p_comm,
|
p->p_pid, p->p_comm,
|
||||||
p->p_cred && p->p_ucred ?
|
p->p_cred && p->p_ucred ?
|
||||||
p->p_ucred->cr_uid : -1);
|
p->p_ucred->cr_uid : -1);
|
||||||
trapsignal(l, SIGKILL, (u_long)addr);
|
ksi.ksi_signo = SIGKILL;
|
||||||
|
ksi.ksi_code = 0;
|
||||||
} else {
|
} else {
|
||||||
trapsignal(l, SIGSEGV, (u_long)addr);
|
ksi.ksi_signo = SIGSEGV;
|
||||||
|
ksi.ksi_code = (rv == EACCES
|
||||||
|
? SEGV_ACCERR : SEGV_MAPERR);
|
||||||
}
|
}
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_addr = (void *)addr;
|
||||||
|
#ifdef __HAVE_SIGINFO
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
#else
|
||||||
|
trapsignal(l, ksi.ksi_signo, (u_long)ksi.ksi_addr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if ((tstate & TSTATE_PRIV) == 0) {
|
if ((tstate & TSTATE_PRIV) == 0) {
|
||||||
l->l_flag &= ~L_SA_PAGEFAULT;
|
l->l_flag &= ~L_SA_PAGEFAULT;
|
||||||
@ -1285,6 +1356,7 @@ data_access_error(tf, type, afva, afsr, sfva, sfsr)
|
|||||||
struct lwp *l;
|
struct lwp *l;
|
||||||
vaddr_t onfault;
|
vaddr_t onfault;
|
||||||
u_quad_t sticks;
|
u_quad_t sticks;
|
||||||
|
ksiginfo_t ksi;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int lastdouble;
|
static int lastdouble;
|
||||||
#endif
|
#endif
|
||||||
@ -1409,7 +1481,16 @@ data_access_error(tf, type, afva, afsr, sfva, sfsr)
|
|||||||
Debugger();
|
Debugger();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
trapsignal(l, SIGSEGV, (u_long)sfva);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_signo = SIGSEGV;
|
||||||
|
ksi.ksi_code = SEGV_MAPERR;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_addr = (void *)sfva;
|
||||||
|
#ifdef __HAVE_SIGINFO
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
#else
|
||||||
|
trapsignal(l, ksi.ksi_signo, (u_long)ksi.ksi_addr);
|
||||||
|
#endif
|
||||||
out:
|
out:
|
||||||
if ((tstate & TSTATE_PRIV) == 0) {
|
if ((tstate & TSTATE_PRIV) == 0) {
|
||||||
userret(l, pc, sticks);
|
userret(l, pc, sticks);
|
||||||
@ -1443,6 +1524,7 @@ text_access_fault(tf, type, pc, sfsr)
|
|||||||
int rv;
|
int rv;
|
||||||
vm_prot_t access_type;
|
vm_prot_t access_type;
|
||||||
u_quad_t sticks;
|
u_quad_t sticks;
|
||||||
|
ksiginfo_t ksi;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (tf->tf_pc == tf->tf_npc) {
|
if (tf->tf_pc == tf->tf_npc) {
|
||||||
@ -1538,7 +1620,16 @@ text_access_fault(tf, type, pc, sfsr)
|
|||||||
Debugger();
|
Debugger();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
trapsignal(l, SIGSEGV, (u_long)pc);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_signo = SIGSEGV;
|
||||||
|
ksi.ksi_code = (rv == EACCES ? SEGV_ACCERR : SEGV_MAPERR);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
|
#ifdef __HAVE_SIGINFO
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
#else
|
||||||
|
trapsignal(l, ksi.ksi_signo, (u_long)ksi.ksi_addr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if ((tstate & TSTATE_PRIV) == 0) {
|
if ((tstate & TSTATE_PRIV) == 0) {
|
||||||
userret(l, pc, sticks);
|
userret(l, pc, sticks);
|
||||||
@ -1580,6 +1671,7 @@ text_access_error(tf, type, pc, sfsr, afva, afsr)
|
|||||||
int rv;
|
int rv;
|
||||||
vm_prot_t access_type;
|
vm_prot_t access_type;
|
||||||
u_quad_t sticks;
|
u_quad_t sticks;
|
||||||
|
ksiginfo_t ksi;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int lastdouble;
|
static int lastdouble;
|
||||||
#endif
|
#endif
|
||||||
@ -1636,7 +1728,16 @@ text_access_error(tf, type, pc, sfsr, afva, afsr)
|
|||||||
panic("text_access_error: kernel memory error");
|
panic("text_access_error: kernel memory error");
|
||||||
|
|
||||||
/* User fault -- Berr */
|
/* User fault -- Berr */
|
||||||
trapsignal(l, SIGBUS, (u_long)pc);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_signo = SIGBUS;
|
||||||
|
ksi.ksi_code = BUS_OBJERR;
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
|
#ifdef __HAVE_SIGINFO
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
#else
|
||||||
|
trapsignal(l, ksi.ksi_signo, (u_long)ksi.ksi_addr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sfsr & SFSR_FV) == 0 || (sfsr & SFSR_FT) == 0)
|
if ((sfsr & SFSR_FV) == 0 || (sfsr & SFSR_FT) == 0)
|
||||||
@ -1716,7 +1817,16 @@ text_access_error(tf, type, pc, sfsr, afva, afsr)
|
|||||||
Debugger();
|
Debugger();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
trapsignal(l, SIGSEGV, (u_long)pc);
|
KSI_INIT_TRAP(&ksi);
|
||||||
|
ksi.ksi_signo = SIGSEGV;
|
||||||
|
ksi.ksi_code = (rv == EACCES ? SEGV_ACCERR : SEGV_MAPERR);
|
||||||
|
ksi.ksi_trap = type;
|
||||||
|
ksi.ksi_addr = (void *)pc;
|
||||||
|
#ifdef __HAVE_SIGINFO
|
||||||
|
trapsignal(l, &ksi);
|
||||||
|
#else
|
||||||
|
trapsignal(l, ksi.ksi_signo, (u_long)ksi.ksi_addr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if ((tstate & TSTATE_PRIV) == 0) {
|
if ((tstate & TSTATE_PRIV) == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user