#include #include #include #include "dat.h" #include "fns.h" #include "linux.h" #pragma profile off void retuser(void) { Uproc *p; Ureg *u; p = current; u = p->ureg; p->ureg = nil; if(p->innote == 0) jumpureg(u); p->innote = 0; noted(NCONT); } static void handletrap(void *v, char *m) { Uproc *p; Usiginfo si; p = current; p->innote = 1; p->ureg = v; if(strncmp(m, "interrupt", 9) == 0){ if(p->notified){ p->notified = 0; } else { memset(&si, 0, sizeof(si)); si.signo = SIGINT; sendsignal(p, &si, 0); } goto handled; } if(p->traceproc) goto traced; if(strncmp(m, "sys: trap: general protection violation", 39) == 0) if(linuxcall() == 0) goto handled; if(strncmp(m, "sys: write on closed pipe", 25) == 0) goto handled; if(strncmp(m, "sys: trap: invalid opcode", 25) == 0){ memset(&si, 0, sizeof(si)); si.signo = SIGILL; si.code = ILL_ILLOPC; si.fault.addr = (void*)p->ureg->pc; sendsignal(p, &si, 0); goto handled; } if(strncmp(m, "sys: trap: divide error", 23) == 0){ memset(&si, 0, sizeof(si)); si.signo = SIGFPE; si.code = FPE_INTDIV; si.fault.addr = (void*)p->ureg->pc; sendsignal(p, &si, 0); goto handled; } if(strncmp(m, "sys: trap: overflow", 19) == 0){ memset(&si, 0, sizeof(si)); si.signo = SIGFPE; si.code = FPE_INTOVF; si.fault.addr = (void*)p->ureg->pc; sendsignal(p, &si, 0); goto handled; } trace("handletrap: %s", m); if(debug) noted(NDFLT); exitproc(p, SIGKILL, 1); handled: if(p->traceproc) traced: p->traceproc(p->tracearg); handlesignals(); retuser(); } #pragma profile on void inittrap(void) { ulong f; /* disable FPU faults */ f = getfcr(); f &= ~(FPINEX|FPOVFL|FPUNFL|FPZDIV|FPINVAL); setfcr(f); notify(handletrap); }