Prepare for move to SIGINFO framework.

This commit is contained in:
pk 2003-10-12 19:08:17 +00:00
parent 5f8a58e4d6
commit 22813649af

View File

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