bool SignalInterface::is_uplevel_trap(int code) { return code == ILL_TRAP_FAULT(ST_UpLevel); }
static void ucbsigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp) { struct sigcontext sc; int code; char *addr; #ifdef NEVER int gwinswitch = 0; #endif sc.sc_onstack = ((ucp->uc_stack.ss_flags & SS_ONSTACK) != 0); sc.sc_mask = set2mask(&ucp->uc_sigmask); #if defined(__sparc) if (sig == SIGFPE && sip != NULL && SI_FROMKERNEL(sip) && (sip->si_code == FPE_INTDIV || sip->si_code == FPE_INTOVF)) { /* * Hack to emulate the 4.x kernel behavior of incrementing * the PC on integer divide by zero and integer overflow * on sparc machines. (5.x does not increment the PC.) */ ucp->uc_mcontext.gregs[REG_PC] = ucp->uc_mcontext.gregs[REG_nPC]; ucp->uc_mcontext.gregs[REG_nPC] += 4; } sc.sc_sp = ucp->uc_mcontext.gregs[REG_SP]; sc.sc_pc = ucp->uc_mcontext.gregs[REG_PC]; sc.sc_npc = ucp->uc_mcontext.gregs[REG_nPC]; /* XX64 There is no REG_PSR for sparcv9, we map in REG_CCR for now */ #if defined(__sparcv9) sc.sc_psr = ucp->uc_mcontext.gregs[REG_CCR]; #else sc.sc_psr = ucp->uc_mcontext.gregs[REG_PSR]; #endif sc.sc_g1 = ucp->uc_mcontext.gregs[REG_G1]; sc.sc_o0 = ucp->uc_mcontext.gregs[REG_O0]; /* * XXX - What a kludge! * Store a pointer to the original ucontext_t in the sigcontext * so that it's available to the sigcleanup call that needs to * return from the signal handler. Otherwise, vital information * (e.g., the "out" registers) that's only saved in the * ucontext_t isn't available to sigcleanup. */ sc.sc_wbcnt = (int)(sizeof (*ucp)); sc.sc_spbuf[0] = (char *)(uintptr_t)sig; sc.sc_spbuf[1] = (char *)ucp; #ifdef NEVER /* * XXX - Sorry, we can never pass the saved register windows * on in the sigcontext because we use that space to save the * ucontext_t. */ if (ucp->uc_mcontext.gwins != (gwindows_t *)0) { int i, j; gwinswitch = 1; sc.sc_wbcnt = ucp->uc_mcontext.gwins->wbcnt; /* XXX - should use bcopy to move this in bulk */ for (i = 0; i < ucp->uc_mcontext.gwins; i++) { sc.sc_spbuf[i] = ucp->uc_mcontext.gwins->spbuf[i]; for (j = 0; j < 8; j++) sc.sc_wbuf[i][j] = ucp->uc_mcontext.gwins->wbuf[i].rw_local[j]; for (j = 0; j < 8; j++) sc.sc_wbuf[i][j+8] = ucp->uc_mcontext.gwins->wbuf[i].rw_in[j]; } } #endif #endif /* * Translate signal codes from new to old. * /usr/include/sys/siginfo.h contains new codes. * /usr/ucbinclude/sys/signal.h contains old codes. */ code = 0; addr = SIG_NOADDR; if (sip != NULL && SI_FROMKERNEL(sip)) { addr = sip->si_addr; switch (sig) { case SIGILL: switch (sip->si_code) { case ILL_PRVOPC: code = ILL_PRIVINSTR_FAULT; break; case ILL_BADSTK: code = ILL_STACK; break; case ILL_ILLTRP: code = ILL_TRAP_FAULT(sip->si_trapno); break; default: code = ILL_ILLINSTR_FAULT; break; } break; case SIGEMT: code = EMT_TAG; break; case SIGFPE: switch (sip->si_code) { case FPE_INTDIV: code = FPE_INTDIV_TRAP; break; case FPE_INTOVF: code = FPE_INTOVF_TRAP; break; case FPE_FLTDIV: code = FPE_FLTDIV_TRAP; break; case FPE_FLTOVF: code = FPE_FLTOVF_TRAP; break; case FPE_FLTUND: code = FPE_FLTUND_TRAP; break; case FPE_FLTRES: code = FPE_FLTINEX_TRAP; break; default: code = FPE_FLTOPERR_TRAP; break; } break; case SIGBUS: switch (sip->si_code) { case BUS_ADRALN: code = BUS_ALIGN; break; case BUS_ADRERR: code = BUS_HWERR; break; default: /* BUS_OBJERR */ code = FC_MAKE_ERR(sip->si_errno); break; } break; case SIGSEGV: switch (sip->si_code) { case SEGV_MAPERR: code = SEGV_NOMAP; break; case SEGV_ACCERR: code = SEGV_PROT; break; default: code = FC_MAKE_ERR(sip->si_errno); break; } break; default: addr = SIG_NOADDR; break; } } (*_siguhandler[sig])(sig, code, &sc, addr); if (sc.sc_onstack) ucp->uc_stack.ss_flags |= SS_ONSTACK; else ucp->uc_stack.ss_flags &= ~SS_ONSTACK; mask2set(sc.sc_mask, &ucp->uc_sigmask); #if defined(__sparc) ucp->uc_mcontext.gregs[REG_SP] = sc.sc_sp; ucp->uc_mcontext.gregs[REG_PC] = sc.sc_pc; ucp->uc_mcontext.gregs[REG_nPC] = sc.sc_npc; #if defined(__sparcv9) ucp->uc_mcontext.gregs[REG_CCR] = sc.sc_psr; #else ucp->uc_mcontext.gregs[REG_PSR] = sc.sc_psr; #endif ucp->uc_mcontext.gregs[REG_G1] = sc.sc_g1; ucp->uc_mcontext.gregs[REG_O0] = sc.sc_o0; #ifdef NEVER if (gwinswitch == 1) { int i, j; ucp->uc_mcontext.gwins->wbcnt = sc.sc_wbcnt; /* XXX - should use bcopy to move this in bulk */ for (i = 0; i < sc.sc_wbcnt; i++) { ucp->uc_mcontext.gwins->spbuf[i] = sc.sc_spbuf[i]; for (j = 0; j < 8; j++) ucp->uc_mcontext.gwins->wbuf[i].rw_local[j] = sc.sc_wbuf[i][j]; for (j = 0; j < 8; j++) ucp->uc_mcontext.gwins->wbuf[i].rw_in[j] = sc.sc_wbuf[i][j+8]; } } #endif if (sig == SIGFPE) { if (ucp->uc_mcontext.fpregs.fpu_qcnt > 0) { ucp->uc_mcontext.fpregs.fpu_qcnt--; ucp->uc_mcontext.fpregs.fpu_q++; } } #endif (void) setcontext(ucp); }