2 * Acess2 - x86 Architecture
10 #define MAX_BACKTRACE 8 //!< Maximum distance to trace the stack backwards
13 extern void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs);
14 extern void VM8086_GPF(tRegs *Regs);
15 extern void Threads_Dump(void);
16 extern void Threads_Fault(int Num);
19 void Error_Backtrace(Uint eip, Uint ebp);
22 const char *csaERROR_NAMES[] = {
23 "Divide By Zero", "Debug", "NMI Exception", "INT3",
24 "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable",
25 "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present",
26 "Stack Fault Exception", "GPF", "#PF", "Reserved",
27 "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception", "Reserved",
28 "Reserved", "Reserved", "Reserved", "Reserved",
29 "Reserved", "Reserved", "Reserved", "Reserved",
30 "Reserved", "Reserved", "Reserved", "Reserved"
34 void __stack_chk_fail(void)
36 Panic("FATAL ERROR: Stack Check Failed\n");
41 * \fn void ErrorHandler(tRegs *Regs)
42 * \brief General Error Handler
44 void ErrorHandler(tRegs *Regs)
48 //if( Regs && !(Regs->int_num == 13 && Regs->eflags & 0x20000) )
49 // __asm__ __volatile__ ("xchg %bx, %bx");
50 //Log_Debug("X86", "Regs = %p", Regs);
51 //Log_Debug("X86", "Error %i at 0x%08x", Regs->int_num, Regs->eip);
53 __asm__ __volatile__ ("cli");
56 if(Regs->int_num == 14)
58 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
59 MM_PageFault( cr, Regs->err_code, Regs );
64 if(Regs->int_num == 13 && Regs->eflags & 0x20000)
70 // Check if it's a user mode fault
71 if( Regs->eip < KERNEL_BASE || (Regs->cs & 3) == 3 ) {
72 Log_Warning("Arch", "User Fault - %s, Code: 0x%x",
73 csaERROR_NAMES[Regs->int_num], Regs->err_code);
74 Log_Warning("Arch", "at CS:EIP %04x:%08x",
76 switch( Regs->int_num )
79 case 0: Threads_Fault(FAULT_DIV0); break;
81 case 6: Threads_Fault(FAULT_OPCODE); break;
83 case 13: Threads_Fault(FAULT_ACCESS); break;
84 // Floating Point Exception
85 case 16: Threads_Fault(FAULT_FLOAT); break;
87 default: Threads_Fault(FAULT_MISC); break;
93 Warning("CPU Error %i - %s, Code: 0x%x",
94 Regs->int_num, csaERROR_NAMES[Regs->int_num], Regs->err_code);
95 Warning(" CS:EIP = 0x%04x:%08x", Regs->cs, Regs->eip);
97 Warning(" SS:ESP = 0x0010:%08x", (Uint)Regs+sizeof(tRegs));
99 Warning(" SS:ESP = 0x%04x:%08x", Regs->ss, Regs->esp);
100 Warning(" EFLAGS = 0x%08x", Regs->eflags);
101 Warning(" EAX %08x ECX %08x EDX %08x EBX %08x",
102 Regs->eax, Regs->ecx, Regs->edx, Regs->ebx);
103 Warning(" ESP %08x EBP %08x ESI %08x EDI %08x",
104 Regs->esp, Regs->ebp, Regs->esi, Regs->edi);
105 Warning(" DS %04x ES %04x FS %04x GS %04x",
106 Regs->ds, Regs->es, Regs->fs, Regs->gs);
109 __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr));
110 Warning(" CR0 0x%08x", cr);
111 __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr));
112 Warning(" CR2 0x%08x", cr);
113 __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
114 Warning(" CR3 0x%08x", cr);
116 switch( Regs->int_num )
119 Warning(" Offending bytes: %02x %02x %02x %02x",
120 *(Uint8*)Regs->eip+0, *(Uint8*)Regs->eip+1,
121 *(Uint8*)Regs->eip+2, *(Uint8*)Regs->eip+3);
125 // Print Stack Backtrace
126 Error_Backtrace(Regs->eip, Regs->ebp);
128 // Dump running threads
131 for(;;) __asm__ __volatile__ ("hlt");
134 * \fn void Error_Backtrace(Uint eip, Uint ebp)
135 * \brief Unrolls the stack to trace execution
137 void Error_Backtrace(Uint eip, Uint ebp)
143 //if(eip < 0xC0000000 && eip > 0x1000)
145 // LogF("Backtrace: User - 0x%x\n", eip);
151 LogF("Backtrace: Data Area - 0x%x\n", eip);
157 LogF("Backtrace: Kernel Module - 0x%x\n", eip);
161 //str = Debug_GetSymbol(eip, &delta);
163 LogF("Backtrace: 0x%x", eip);
165 LogF("Backtrace: %s+0x%x", str, delta);
166 if(!MM_GetPhysAddr(ebp))
168 LogF("\nBacktrace: Invalid EBP, stopping\n");
173 while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
175 //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
177 LogF(" >> 0x%x", *(Uint*)(ebp+4));
179 LogF(" >> %s+0x%x", str, delta);
187 * \fn void StartupPrint(char *Str)
189 void StartupPrint(char *Str)
191 Uint16 *buf = (void*)0xC00B8000;
196 buf[line*80 + i++] = *Str | 0x0700;
200 while(i < 80) buf[line*80 + i++] = 0x0720;
206 memcpy(buf, &buf[80], 80*24*2);
207 memset(&buf[80*24], 0, 80*2);
212 EXPORT(__stack_chk_fail);