From f05f720ae192799902006ae32d1a04d230778c6b Mon Sep 17 00:00:00 2001 From: chs Date: Sat, 24 Jul 2004 19:04:53 +0000 Subject: [PATCH] real siginfo support. --- sys/arch/hppa/hppa/fpu.c | 44 ++++++++++--- sys/arch/hppa/hppa/sig_machdep.c | 5 +- sys/arch/hppa/hppa/trap.c | 103 +++++++++++++++++++++---------- 3 files changed, 107 insertions(+), 45 deletions(-) diff --git a/sys/arch/hppa/hppa/fpu.c b/sys/arch/hppa/hppa/fpu.c index 2649c5d8a672..f4eb9b0942e6 100644 --- a/sys/arch/hppa/hppa/fpu.c +++ b/sys/arch/hppa/hppa/fpu.c @@ -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 -__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 #include @@ -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 */ diff --git a/sys/arch/hppa/hppa/sig_machdep.c b/sys/arch/hppa/hppa/sig_machdep.c index ee85d13f5cb6..ae3e4bc7e653 100644 --- a/sys/arch/hppa/hppa/sig_machdep.c +++ b/sys/arch/hppa/hppa/sig_machdep.c @@ -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 -__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); diff --git a/sys/arch/hppa/hppa/trap.c b/sys/arch/hppa/hppa/trap.c index ab4ccca2bb98..aae2386321e6 100644 --- a/sys/arch/hppa/hppa/trap.c +++ b/sys/arch/hppa/hppa/trap.c @@ -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 -__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); -}