]> Joshua Wise's Git repositories - netwatch.git/blobdiff - netwatch/traps.c
Improve correctness of backtrace library.
[netwatch.git] / netwatch / traps.c
index bf5ca803b221ef2968fb9dee73ee0be0a47345d1..25a404c6a5fe58bf24275f8ab40c454ce8c5e6e5 100644 (file)
 
 #include "traps.h"
 
-#define CS_SEGSEL      0x8
+#define CS_SEGSEL      0x10
+
+asm (
+       "fault_wrapper_common:\n"
+       "push %eax\n"
+        "mov %cr2, %eax\n"
+        "push %eax\n"
+        "push %esp\n"
+        "call die\n"
+);
+
+#define FAULT_WRAPPER(func_name, code)        asm (    \
+        ".global " #func_name "_wrapper\n"              \
+        #func_name "_wrapper:\n"                        \
+       "mov $" #code ", %eax\n"                        \
+       "jmp fault_wrapper_common\n"                    \
+); void func_name##_wrapper(void);
 
-#define FAULT_WRAPPER(func_name)        asm (           \
+#define FAULT_WRAPPER1(func_name, code)        asm (           \
         ".global " #func_name "_wrapper\n"              \
         #func_name "_wrapper:\n"                        \
-        "mov %cr2, %eax\n"                              \
+       "mov $0, %eax\n"                                \
         "push %eax\n"                                   \
-        "push %esp\n"                                   \
-        "call " #func_name "\n"                         \
+       "mov $" #code ", %eax\n"                        \
+       "jmp fault_wrapper_common\n"                    \
 ); void func_name##_wrapper(void);
 
 #define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) {      \
 /* The 16 bits at offset 4 from the start of an interrupt gate are a
  * bitfield, according to the Intel spec:
  * 15           P - Segment Present - set to 1
- * 14-13        DPL - Descriptor privilege level - set to 11 for trap/int, 00 for IPI
+ * 14-13        DPL - Descriptor privilege level - set to 00, since we're always in ring 0
  * 12-8         01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
  * 7-0          Set to 0
- * Trap:      binary 11101111 0000000, hex EF00.
- * Interrupt: binary 11101110 0000000, hex EE00.
  */
-#define TRAP           0xEF00
-#define INTERRUPT      0xEE00
+#define TRAP           0x8F00
 
 typedef struct trap_t {
        int cr2;
+       int fault_code;
         int error_code;
         int eip;
         int cs;
         int eflags;
-        int esp;
-        int ss;
 } trap_t;
 
+static const char const * trapcodes[20] = {
+       "Divide by Zero",
+       "Debug Trap",
+       "NMI",
+       "Breakpoint Trap",
+       "Overflow Trap",
+       "Bound Range Fault",
+       "Invalid Opcode",
+       "Device Not Available",
+       "Double Fault",
+       "Coprocessor Overrun",
+       "Invalid TSS",
+       "Segmnet Not Present",
+       "Stack Fault",
+       "GPF",
+       "Page Fault",
+       "Reserved Trap",
+       "x87 FPE Pending",
+       "Alignment Check",
+       "Machine Check",
+       "SIMD FPE Fault"
+};
+
 void die(struct trap_t * trap) {
-       outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
-       outputf("%%esp %08x %%eflags %08x", trap->esp, trap->eflags);
-       while(1) asm("hlt");
-}
 
-void fault_gp(struct trap_t * trap) {
-       outputf("GENERAL PROTECTION FAULT");
-       die(trap);
-}
+       DBG(0x40 + trap->fault_code);
 
-void fault_page(struct trap_t * trap) {
-       outputf("PAGE FAULT: %08x", trap->cr2);
-       die(trap);
-}
-void fault_divide(struct trap_t * trap) {
-       outputf("DIVISION FAULT");
-       die(trap);
-}
-void double_fault(struct trap_t * trap) {
-       outputf("DOUBLE FAULT");
-       die(trap);
+       if (trap->fault_code < 20) {
+               outputf("---\n%s", trapcodes[trap->fault_code]);
+       } else {
+               outputf("---\nUNKNOWN FAULT");
+       }
+
+       outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
+       outputf("%%cr2 %08x %%eflags %08x", trap->cr2, trap->eflags);
+       while(1) asm("hlt");
 }
 
-FAULT_WRAPPER(fault_gp);
-FAULT_WRAPPER(fault_page);
-FAULT_WRAPPER(fault_divide);
-FAULT_WRAPPER(double_fault);
+FAULT_WRAPPER1(fault_divide, 0);
+FAULT_WRAPPER1(fault_db, 1);
+FAULT_WRAPPER1(fault_nmi, 2);
+FAULT_WRAPPER1(fault_3, 3);
+FAULT_WRAPPER1(fault_overflow, 4);
+FAULT_WRAPPER1(fault_oob, 5);
+FAULT_WRAPPER1(fault_opcode, 6);
+FAULT_WRAPPER1(fault_enofpu, 7);
+FAULT_WRAPPER(double_fault, 8);
+FAULT_WRAPPER1(fault_fpu, 9);
+FAULT_WRAPPER(fault_invalid_tss, 10);
+FAULT_WRAPPER(fault_noseg, 11);
+FAULT_WRAPPER(fault_stack, 12);
+FAULT_WRAPPER(fault_gp, 13);
+FAULT_WRAPPER(fault_page, 14);
+FAULT_WRAPPER1(fault_fpe, 16);
+FAULT_WRAPPER(fault_ac, 17);
+FAULT_WRAPPER1(fault_machine, 18);
+FAULT_WRAPPER1(fault_other, 19);
 
 /* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
 
 struct x86_gate {
-unsigned int filler[2]; //64 bits; or 8 bytes.
+       unsigned int filler[2];         //64 bits, or 8 bytes.
 };
 
 static struct x86_gate idt[64];
@@ -99,17 +140,38 @@ struct pseudo_descriptor {
 } __attribute__((packed));
 
 void traps_install(void) {
+        DBG(0xCA);
+       int i;
 
         struct pseudo_descriptor pdesc;
        pdesc.limit = sizeof(idt) - 1;
-       pdesc.linear_base = v2p(&idt);
+       pdesc.linear_base = (int)&idt; //v2p(&idt);
+
+               DBG(0xCB);
+
+       for (i = 0; i < 32; i++)
+               WRAPPER_INSTALL(idt, TRAP, fault_other, i);
 
        WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
+       WRAPPER_INSTALL(idt, TRAP, fault_db, T_DEBUG);
+       WRAPPER_INSTALL(idt, TRAP, fault_nmi, T_NMI);
+       WRAPPER_INSTALL(idt, TRAP, fault_3, T_INT3);
+       WRAPPER_INSTALL(idt, TRAP, fault_overflow, T_OVERFLOW);
+       WRAPPER_INSTALL(idt, TRAP, fault_oob, T_OUT_OF_BOUNDS);
+       WRAPPER_INSTALL(idt, TRAP, fault_opcode, T_INVALID_OPCODE);
+       WRAPPER_INSTALL(idt, TRAP, fault_enofpu, T_NO_FPU);
+       WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, fault_fpu, T_FPU_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, fault_invalid_tss, T_INVALID_TSS);
+       WRAPPER_INSTALL(idt, TRAP, fault_noseg, T_SEGMENT_NOT_PRESENT);
+       WRAPPER_INSTALL(idt, TRAP, fault_stack, T_STACK_FAULT);
        WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
        WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
-       WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
+       WRAPPER_INSTALL(idt, TRAP, fault_fpe, T_FLOATING_POINT_ERROR);
+       WRAPPER_INSTALL(idt, TRAP, fault_ac, T_ALIGNMENT_CHECK);
+       WRAPPER_INSTALL(idt, TRAP, fault_machine, T_MACHINE_CHECK);
 
-        outb(0x80, 0xCC);
+        DBG(0xCC);
        asm volatile("lidt %0" : : "m" (pdesc.limit));
-        outb(0x80, 0xCD);
+        DBG(0xCE);
 }
This page took 0.032563 seconds and 4 git commands to generate.