static void trapmemref(int signo, siginfo_t *si, void *a) { USED(a); /* ucontext_t*, could fetch pc in machine-dependent way */ if(isnilref(si)) disfault(nil, exNilref); else if(signo == SIGBUS) sysfault("bad address addr=", si->si_addr); /* eg, misaligned */ else sysfault("segmentation violation addr=", si->si_addr); }
static void faultarm(Ureg *ureg) { char buf[ERRMAX]; sprint(buf, "sys: trap: fault pc=%8.8lux", (ulong)ureg->pc); if(0){ iprint("%s\n", buf); dumpregs(ureg); } disfault(ureg, buf); }
static void trapUSR1(int signo) { int intwait; USED(signo); intwait = up->intwait; up->intwait = 0; /* clear it to let proc continue in osleave */ if(up->type != Interp) /* Used to unblock pending I/O */ return; if(intwait == 0) /* Not posted so its a sync error */ disfault(nil, Eintr); /* Should never happen */ }
LONG TrapHandler(LPEXCEPTION_POINTERS ureg) { int i; char *name; DWORD code; // WORD pc; char buf[ERRMAX]; code = ureg->ExceptionRecord->ExceptionCode; // pc = ureg->ContextRecord->Eip; name = nil; for(i = 0; i < nelem(ecodes); i++) { if(ecodes[i].code == code) { name = ecodes[i].name; break; } } if(name == nil) { snprint(buf, sizeof(buf), "unknown trap type (%#.8lux)\n", code); name = buf; } /* if(pc != 0) { snprint(buf, sizeof(buf), "%s: pc=0x%lux", name, pc); name = buf; } */ switch (code) { case EXCEPTION_FLT_DENORMAL_OPERAND: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_INEXACT_RESULT: case EXCEPTION_FLT_INVALID_OPERATION: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_STACK_CHECK: case EXCEPTION_FLT_UNDERFLOW: /* clear exception flags and ensure safe empty state */ _asm { fnclex }; _asm { fninit }; } disfault(nil, name); /* not reached */ return EXCEPTION_CONTINUE_EXECUTION; }
void trap(Ureg *ureg) { int rem, itype, t; if(up != nil) rem = ((char*)ureg)-up->kstack; else rem = ((char*)ureg)-(char*)m->stack; if(ureg->type != PsrMfiq && rem < 256) { dumpregs(ureg); panic("trap %d stack bytes remaining (%s), " "up=#%8.8lux ureg=#%8.8lux pc=#%8.8ux" ,rem, up?up->text:"", up, ureg, ureg->pc); for(;;); } itype = ureg->type; /* All interrupts/exceptions should be resumed at ureg->pc-4, except for Data Abort which resumes at ureg->pc-8. */ if(itype == PsrMabt+1) ureg->pc -= 8; else ureg->pc -= 4; if(up){ up->pc = ureg->pc; up->dbgreg = ureg; } switch(itype) { case PsrMirq: t = m->ticks; /* CPU time per proc */ up = nil; /* no process at interrupt level */ irq(ureg); up = m->proc; preemption(m->ticks - t); m->intr++; break; case PsrMund: if(*(ulong*)ureg->pc == BREAK && breakhandler) { int s; Proc *p; p = up; s = breakhandler(ureg, p); if(s == BrkSched) { p->preempted = 0; sched(); } else if(s == BrkNoSched) { /* stop it being preempted until next instruction */ p->preempted = 1; if(up) up->dbgreg = 0; return; } break; } if(up == nil) goto faultpanic; spllo(); if(waserror()) { if(waslo(ureg->psr) && up->type == Interp) disfault(ureg, up->env->errstr); setpanic(); dumpregs(ureg); panic("%s", up->env->errstr); } if(!fpiarm(ureg)) { dumpregs(ureg); sys_trap_error(ureg->type); } poperror(); break; case PsrMsvc: /* Jump through 0 or SWI */ if(waslo(ureg->psr) && up && up->type == Interp) { spllo(); dumpregs(ureg); sys_trap_error(ureg->type); } setpanic(); dumpregs(ureg); panic("SVC/SWI exception"); break; case PsrMabt: /* Prefetch abort */ if(catchdbg && catchdbg(ureg, 0)) break; /* FALL THROUGH */ case PsrMabt+1: /* Data abort */ if(waslo(ureg->psr) && up && up->type == Interp) { spllo(); faultarm(ureg); } print("Data Abort\n"); /* FALL THROUGH */ default: faultpanic: setpanic(); dumpregs(ureg); panic("exception %uX %s\n", ureg->type, trapname(ureg->type)); break; } splhi(); if(up) up->dbgreg = 0; /* becomes invalid after return from trap */ }
static void trapSEGV(int signo) { disfault(nil, "Segmentation violation"); }
static void trapILL(int signo) { disfault(nil, "Illegal instruction"); }
void dodisfault(void) { disfault(nil, up->env->errstr); }
static void trapBUS(int signo) { USED(signo); disfault(nil, "Bus error"); }