#include #include #include #include "exc.h" #include "uasm.h" #define MAX_EX 17 #define HOOK_BREAK_POINT 1 /* * Prototypes */ static void HookExcHandler (char i, unsigned int cs); static char errCodeExc (char i); static char *errCodeStr (char i,short x); static void LocalHook (void); /* * Public data */ FARPTR oldExcHandlers [MAX_EX+1]; /* * Local data */ static void (* excHookUser)(excReg *r); static char uasmAtExc; static char privLevel; /* * Application interface to exception handler system * Called once during main start. Add/remove handlers as * required. Can be invoked multiple times */ void InstallExcHandler (void (*userHook)(excReg *r), char debugDump) { int i; unsigned int cseg; CONFIG_INF cnf; _dx_config_inf(&cnf,(char*)&cnf); /* get config block */ cseg = cnf.c_cs_sel; privLevel = cseg & ~3; /* Save vectors for all exception handlers */ for (i=0; i=10 && i<=14)); } /*-----------------------------------------------------------------*/ static char * errCodeStr(char i,short x) { static char buf[23]; if (errCodeExc(i)) { sprintf(buf,"Error code %Xh. ",x); return buf; } else return ""; } /*--------------------------------------------------------------*/ void HookExcHandler (char i, unsigned int cs) { FARPTR newExcHandler; #if HOOK_BREAK_POINT == 0 if (i == 3) return; #endif if (errCodeExc(i)) { FP_SET(newExcHandler,&ExcGlue_1,cs); } else { FP_SET(newExcHandler,&ExcGlue_0,cs); } _dx_excep_set(i,newExcHandler); } /*-----------------------------------------------------------------*/ static void LocalHook(void) { int i; static excReg *r = &except; static void *adr; static char *excName[] = { "Divide Exception", // 0 "Debug Exception", "NMI !!??", // 2 "Breakpoint", "Overflow", // 4 "Array Bound Check", "Invalid Opcode", // 6 "FPU not present", "Double Fault", // 8 "FPU Segment Overrun", "Invalid TSS", // 10 "Segment not present", "Stack Fault", // 12 "General Protection", "Page Fault", // 14 "FPU Error", "Alignment Check" }; // 16 RemoveExcHandler(); if (r->number==3 || r->number==4) /* point to INT 3, INTO */ r->EIP -= 1; /* INT 3 = CC, INTO = CE */ printf ("%s (exc %d) occured at (CS:EIP) %04X:%08X\n\n"\ "%sRegisters:\n" \ "EAX %08X EBX %08X ECX %08X EDX %08X\n" \ "ESI %08X EDI %08X EBP %08X ESP %08X\n" \ "DS %04X FS %04X SS %04X\n" \ "ES %04X GS %04X FLG %08X\n", excName[r->number],r->number,r->CS,r->EIP, errCodeStr(r->number,r->code), r->EAX,r->EBX,r->ECX,r->EDX, r->ESI,r->EDI,r->EBP,r->ESP, r->DS,r->FS,r->SS,r->ES,r->GS,r->EFL); if (uasmAtExc) { printf("\nInstruction trace:\n"); adr = (void*) r->EIP; for (i=0; i<8; i++) { printf("%02X:%08X %s\n",r->CS,adr,disassemble(adr)); adr = disasm_outAdr; } // printf("\nCall Stack:\n"); // whouldn't this be nice :-) } if (excHookUser != NULL) (*excHookUser)(r); exit((char)r->number); }