real siginfo support.

This commit is contained in:
chs 2004-07-24 19:04:53 +00:00
parent a3a9698bfd
commit f05f720ae1
3 changed files with 107 additions and 45 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fpu.c,v 1.7 2004/07/24 18:59:05 chs Exp $ */
/* $NetBSD: fpu.c,v 1.8 2004/07/24 19:04:53 chs Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.7 2004/07/24 18:59:05 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.8 2004/07/24 19:04:53 chs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -89,9 +89,6 @@ paddr_t fpu_cur_uspace;
/* In locore.S, this swaps states in and out of the FPU. */
void hppa_fpu_swap(struct pcb *, struct pcb *);
/* XXX see trap.c */
void hppa_trapsignal_hack(struct lwp *, int, u_long);
#ifdef FPEMUL
/*
* Given a trapframe and a general register number, the
@ -360,6 +357,7 @@ hppa_fpu_emulate(struct trapframe *frame, struct lwp *l, u_int inst)
u_int opcode, class, sub;
u_int *fpregs;
int exception;
ksiginfo_t ksi;
/*
* If the process' state is in any hardware FPU,
@ -402,8 +400,14 @@ hppa_fpu_emulate(struct trapframe *frame, struct lwp *l, u_int inst)
switch (opcode) {
case 0x09:
case 0x0b:
if (hppa_fpu_ls(frame, l) != 0)
hppa_trapsignal_hack(l, SIGSEGV, frame->tf_iioq_head);
if (hppa_fpu_ls(frame, l) != 0) {
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_code = SEGV_MAPERR;
ksi.ksi_trap = T_DTLBMISS;
ksi.ksi_addr = (void *)frame->tf_iioq_head;
trapsignal(l, &ksi);
}
return;
case 0x0c:
exception = decode_0c(inst, class, sub, fpregs);
@ -424,9 +428,29 @@ hppa_fpu_emulate(struct trapframe *frame, struct lwp *l, u_int inst)
fdcache(HPPA_SID_KERNEL, (vaddr_t)fpregs,
sizeof(l->l_addr->u_pcb.pcb_fpregs));
if (exception)
hppa_trapsignal_hack(l, (exception & UNIMPLEMENTEDEXCEPTION) ?
SIGILL : SIGFPE, frame->tf_iioq_head);
if (exception) {
KSI_INIT_TRAP(&ksi);
if (exception & UNIMPLEMENTEDEXCEPTION) {
ksi.ksi_signo = SIGILL;
ksi.ksi_code = ILL_COPROC;
} else {
ksi.ksi_signo = SIGFPE;
if (exception & INVALIDEXCEPTION) {
ksi.ksi_code = FPE_FLTINV;
} else if (exception & DIVISIONBYZEROEXCEPTION) {
ksi.ksi_code = FPE_FLTDIV;
} else if (exception & OVERFLOWEXCEPTION) {
ksi.ksi_code = FPE_FLTOVF;
} else if (exception & UNDERFLOWEXCEPTION) {
ksi.ksi_code = FPE_FLTUND;
} else if (exception & INEXACTEXCEPTION) {
ksi.ksi_code = FPE_FLTRES;
}
}
ksi.ksi_trap = T_EMULATION;
ksi.ksi_addr = (void *)frame->tf_iioq_head;
trapsignal(l, &ksi);
}
}
#endif /* FPEMUL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sig_machdep.c,v 1.10 2004/07/18 23:21:35 chs Exp $ */
/* $NetBSD: sig_machdep.c,v 1.11 2004/07/24 19:04:53 chs Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -111,7 +111,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sig_machdep.c,v 1.10 2004/07/18 23:21:35 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: sig_machdep.c,v 1.11 2004/07/24 19:04:53 chs Exp $");
#include "opt_compat_netbsd.h"
@ -327,6 +327,7 @@ sendsig_siginfo(const struct ksiginfo *ksi, const sigset_t *mask)
break;
}
frame.sf_si._info = ksi->ksi_info;
frame.sf_uc.uc_flags = _UC_SIGMASK |
((p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK) ?
_UC_SETSTACK : _UC_CLRSTACK);

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.21 2004/07/24 18:59:06 chs Exp $ */
/* $NetBSD: trap.c,v 1.22 2004/07/24 19:04:53 chs Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.21 2004/07/24 18:59:06 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.22 2004/07/24 19:04:53 chs Exp $");
/* #define INTRDEBUG */
/* #define TRAPDEBUG */
@ -176,9 +176,6 @@ volatile int astpending;
void pmap_hptdump(void);
void syscall(struct trapframe *, int *);
/* XXX */
void hppa_trapsignal_hack(struct lwp *, int, u_long);
#ifdef USERTRACE
/*
* USERTRACE is a crude facility that traces the PC of
@ -454,6 +451,9 @@ do { \
}
#undef SANITY
if (sanity_frame == tf) {
printf("insanity: tf %p lwp %p line %d sp 0x%x pc 0x%x\n",
sanity_frame, sanity_lwp, sanity_checked,
tf->tf_sp, tf->tf_iioq_head);
(void) trap_kdebug(T_IBREAK, 0, tf);
sanity_frame = NULL;
sanity_lwp = NULL;
@ -473,6 +473,7 @@ trap(int type, struct trapframe *frame)
struct vmspace *vm;
vm_prot_t vftype;
pa_space_t space;
ksiginfo_t ksi;
u_int opcode, onfault;
int ret;
const char *tts;
@ -612,7 +613,13 @@ trap(int type, struct trapframe *frame)
* We don't have FPU emulation, so signal the
* process with a SIGFPE.
*/
hppa_trapsignal_hack(l, SIGFPE, frame->tf_iioq_head);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGFPE;
ksi.ksi_code = SI_NOINFO;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)frame->tf_iioq_head;
trapsignal(l, &ksi);
#endif /* !FPEMUL */
break;
@ -635,7 +642,12 @@ trap(int type, struct trapframe *frame)
#ifdef DEBUG
user_backtrace(frame, l, type);
#endif
hppa_trapsignal_hack(l, SIGILL, frame->tf_iioq_head);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGILL;
ksi.ksi_code = ILL_ILLTRP;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)frame->tf_iioq_head;
trapsignal(l, &ksi);
break;
}
if (trap_kdebug(type, va, frame))
@ -692,7 +704,12 @@ trap(int type, struct trapframe *frame)
break;
case T_OVERFLOW | T_USER:
hppa_trapsignal_hack(l, SIGFPE, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGFPE;
ksi.ksi_code = SI_NOINFO;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
case T_CONDITION | T_USER:
@ -702,32 +719,57 @@ trap(int type, struct trapframe *frame)
#ifdef DEBUG
user_backtrace(frame, l, type);
#endif
hppa_trapsignal_hack(l, SIGILL, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGILL;
ksi.ksi_code = ILL_ILLOPC;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
case T_PRIV_OP | T_USER:
#ifdef DEBUG
user_backtrace(frame, l, type);
#endif
hppa_trapsignal_hack(l, SIGILL, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGILL;
ksi.ksi_code = ILL_PRVOPC;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
case T_PRIV_REG | T_USER:
#ifdef DEBUG
user_backtrace(frame, l, type);
#endif
hppa_trapsignal_hack(l, SIGILL, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGILL;
ksi.ksi_code = ILL_PRVREG;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
/* these should never got here */
case T_HIGHERPL | T_USER:
case T_LOWERPL | T_USER:
hppa_trapsignal_hack(l, SIGSEGV, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_code = SEGV_ACCERR;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
case T_IPROT | T_USER:
case T_DPROT | T_USER:
hppa_trapsignal_hack(l, SIGSEGV, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_code = SEGV_ACCERR;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
case T_DATACC: case T_USER | T_DATACC:
@ -784,6 +826,7 @@ trap(int type, struct trapframe *frame)
if (map != kernel_map)
l->l_flag &= ~L_SA_PAGEFAULT;
/*
* If this was a stack access we keep track of the maximum
* accessed stack size. Also, if uvm_fault gets a protection
@ -805,7 +848,13 @@ trap(int type, struct trapframe *frame)
#ifdef DEBUG
user_backtrace(frame, l, type);
#endif
hppa_trapsignal_hack(l, SIGSEGV, frame->tf_ior);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_code = (ret == EACCES ?
SEGV_ACCERR : SEGV_MAPERR);
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
} else {
if (l->l_addr->u_pcb.pcb_onfault) {
#ifdef TRAPDEBUG
@ -828,18 +877,20 @@ trap(int type, struct trapframe *frame)
#ifdef DEBUG
user_backtrace(frame, l, type);
#endif
hppa_trapsignal_hack(l, SIGBUS, va);
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_ADRALN;
ksi.ksi_trap = type;
ksi.ksi_addr = (void *)va;
trapsignal(l, &ksi);
break;
case T_INTERRUPT:
case T_INTERRUPT|T_USER:
hppa_intr(frame);
mtctl(frame->tf_eiem, CR_EIEM);
#if 0
if (trap_kdebug (type, va, frame))
return;
#endif
break;
case T_LOWERPL:
case T_DPROT:
case T_IPROT:
@ -1189,17 +1240,3 @@ upcallret(struct lwp *l)
{
userret(l, l->l_md.md_regs->tf_iioq_head, 0);
}
/*
* XXX for transition to SIGINFO
*/
void
hppa_trapsignal_hack(struct lwp *l, int signum, u_long code)
{
ksiginfo_t ksi;
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = signum;
ksi.ksi_trap = (int)code;
trapsignal(l, &ksi);
}