2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/hal/x86/exp.c
5 * PURPOSE: Handling exceptions
6 * PROGRAMMER: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/ntoskrnl.h>
15 #include <internal/ke.h>
16 #include <internal/symbol.h>
17 #include <internal/i386/segment.h>
18 #include <internal/mmhal.h>
19 #include <internal/module.h>
22 #include <internal/debug.h>
24 /* GLOBALS *****************************************************************/
26 asmlinkage
int page_fault_handler(unsigned int cs
,
29 static exception_hook
* exception_hooks
[256]={NULL
,};
32 #define STR(x) _STR(x)
34 extern void interrupt_handler2e(void);
36 extern ULONG init_stack
;
37 extern ULONG init_stack_top
;
39 /* FUNCTIONS ****************************************************************/
41 #define EXCEPTION_HANDLER_WITH_ERROR(x,y) \
42 void exception_handler##y (void); \
43 void tmp_exception_handler##y (void) { \
44 __asm__("\n\t_exception_handler"##x":\n\t" \
51 "movw $"STR(KERNEL_DS)",%ax\n\t" \
56 "call _exception_handler\n\t" \
66 #define EXCEPTION_HANDLER_WITHOUT_ERROR(x,y) \
67 asmlinkage void exception_handler##y (void); \
68 void tmp_exception_handler##y (void) { \
69 __asm__("\n\t_exception_handler"##x":\n\t" \
77 "movw $"STR(KERNEL_DS)",%ax\n\t" \
82 "call _exception_handler\n\t" \
92 asmlinkage
void exception_handler_unknown(void);
93 asmlinkage
void tmp_exception_handler_unknown(void)
95 __asm__("\n\t_exception_handler_unknown:\n\t"
104 "movw $"STR(KERNEL_DS
)",%ax\n\t"
109 "call _exception_handler\n\t"
115 EXCEPTION_HANDLER_WITHOUT_ERROR("0",0);
116 EXCEPTION_HANDLER_WITHOUT_ERROR("1",1);
117 EXCEPTION_HANDLER_WITHOUT_ERROR("2",2);
118 EXCEPTION_HANDLER_WITHOUT_ERROR("3",3);
119 EXCEPTION_HANDLER_WITHOUT_ERROR("4",4);
120 EXCEPTION_HANDLER_WITHOUT_ERROR("5",5);
121 EXCEPTION_HANDLER_WITHOUT_ERROR("6",6);
122 EXCEPTION_HANDLER_WITHOUT_ERROR("7",7);
123 EXCEPTION_HANDLER_WITH_ERROR("8",8);
124 EXCEPTION_HANDLER_WITHOUT_ERROR("9",9);
125 EXCEPTION_HANDLER_WITH_ERROR("10",10);
126 EXCEPTION_HANDLER_WITH_ERROR("11",11);
127 EXCEPTION_HANDLER_WITH_ERROR("12",12);
128 EXCEPTION_HANDLER_WITH_ERROR("13",13);
129 EXCEPTION_HANDLER_WITH_ERROR("14",14);
130 EXCEPTION_HANDLER_WITH_ERROR("15",15);
131 EXCEPTION_HANDLER_WITHOUT_ERROR("16",16);
133 extern unsigned int stext
, etext
;
135 static void print_address(PVOID address
)
137 PLIST_ENTRY current_entry
;
138 PMODULE_OBJECT current
;
139 extern LIST_ENTRY ModuleListHead
;
141 current_entry
= ModuleListHead
.Flink
;
143 while (current_entry
!= &ModuleListHead
)
145 current
= CONTAINING_RECORD(current_entry
, MODULE_OBJECT
, ListEntry
);
147 if (address
>= current
->Base
&&
148 address
< (current
->Base
+ current
->Length
))
150 DbgPrint("<%w: %x>\n", current
->Name
,
151 address
- current
->Base
);
155 current_entry
= current_entry
->Flink
;
157 DbgPrint("<%x>\n", address
);
160 asmlinkage
void exception_handler(unsigned int edi
,
161 unsigned int esi
, unsigned int ebp
,
162 unsigned int esp
, unsigned int ebx
,
163 unsigned int edx
, unsigned int ecx
,
170 unsigned int error_code
,
172 unsigned int cs
, unsigned int eflags
,
173 unsigned int esp0
, unsigned int ss0
)
175 * FUNCTION: Called by the lowlevel execption handlers to print an amusing
176 * message and halt the computer
178 * Complete CPU context
181 unsigned int cr2
, cr3
;
183 // unsigned int j, sym;
185 static char *TypeStrings
[] =
192 "BOUND range exceeded",
194 "No Math Coprocessor",
198 "Segment Not Present",
199 "Stack Segment Fault",
200 "General Protection",
211 if (page_fault_handler(cs
&0xffff,eip
))
218 DbgPrint("Trap at CS:EIP %x:%x\n",cs
&0xffff,eip
);
223 * Activate any hook for the exception
225 if (exception_hooks
[type
]!=NULL
)
227 exception_hooks
[type
](NULL
,type
);
231 * Print out the CPU registers
235 DbgPrint("%s Exception: %d(%x)\n",TypeStrings
[type
],type
,
240 DbgPrint("Exception: %d(%x)\n",type
,error_code
&0xffff);
242 DbgPrint("CS:EIP %x:%x\n",cs
&0xffff,eip
);
243 DbgPrint("CS:EIP %x");
245 __asm__("movl %%cr2,%0\n\t"
247 __asm__("movl %%cr3,%0\n\t"
249 DbgPrint("cr2 %x cr3 %x\n",cr2
,cr3
);
251 DbgPrint("Process: %x\n",PsGetCurrentProcess());
252 if (PsGetCurrentProcess() != NULL
)
254 DbgPrint("Process id: %x\n", PsGetCurrentProcess()->UniqueProcessId
);
256 if (PsGetCurrentThread() != NULL
)
258 DbgPrint("Thread: %x Thread id: %x\n",
259 PsGetCurrentThread(),
260 PsGetCurrentThread()->Cid
.UniqueThread
);
262 DbgPrint("DS %x ES %x FS %x GS %x\n",ds
&0xffff,es
&0xffff,fs
&0xffff,
264 DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax
,ebx
,ecx
);
265 DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n",edx
,ebp
,esi
);
266 DbgPrint("EDI: %.8x EFLAGS: %.8x ",edi
,eflags
);
267 if ((cs
&0xffff) == KERNEL_CS
)
269 DbgPrint("kESP %.8x\n",esp
);
270 if (PsGetCurrentThread() != NULL
)
272 DbgPrint("kernel stack base %x\n",
273 PsGetCurrentThread()->Tcb
.Context
.KernelStackBase
);
279 DbgPrint("kernel ESP %.8x\n",esp
);
281 if ((cs
& 0xffff) == KERNEL_CS
)
283 DbgPrint("ESP %x\n",esp
);
284 stack
= (unsigned int *) (esp
+ 24);
286 DbgPrint("Stack:\n");
287 for (i
= 0; i
< 16; i
= i
+ 4)
289 DbgPrint("%.8x %.8x %.8x %.8x\n",
295 DbgPrint("Frames:\n");
296 for (i
= 0; i
< 32; i
++)
298 if (stack
[i
] > ((unsigned int) &stext
) &&
299 !(stack
[i
] >= ((ULONG
)&init_stack
) &&
300 stack
[i
] <= ((ULONG
)&init_stack_top
)))
302 // DbgPrint(" %.8x", stack[i]);
303 print_address(stack
[i
]);
309 DbgPrint("SS:ESP %x:%x\n",ss0
,esp0
);
310 stack
=(unsigned int *)(esp0
);
312 DbgPrint("Stack:\n");
315 if (MmIsPagePresent(NULL
,&stack
[i
]))
317 DbgPrint("%.8x ",stack
[i
]);
326 DPRINT1("Killing current task\n");
328 KeLowerIrql(PASSIVE_LEVEL
);
329 if ((cs
&0xffff) == USER_CS
)
331 ZwTerminateProcess(NtCurrentProcess(),
332 STATUS_NONCONTINUABLE_EXCEPTION
);
338 VOID
KeDumpStackFrames(ULONG DummyArg
, ULONG NrFrames
)
340 PULONG Stack
= &((&DummyArg
)[-1]);
343 Stack
= (PVOID
)(((ULONG
)Stack
) & (~0x3));
345 DbgPrint("Frames:\n");
346 for (i
=0; i
<NrFrames
; i
++)
348 // if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext))
349 if (Stack
[i
] > KERNEL_BASE
)
351 DbgPrint("%.8x ",Stack
[i
]);
353 if (Stack
[i
] == 0xceafbeef)
361 static void set_system_call_gate(unsigned int sel
, unsigned int func
)
363 DPRINT("sel %x %d\n",sel
,sel
);
364 KiIdt
[sel
].a
= (((int)func
)&0xffff) +
366 KiIdt
[sel
].b
= 0xef00 + (((int)func
)&0xffff0000);
367 DPRINT("idt[sel].b %x\n",KiIdt
[sel
].b
);
370 static void set_interrupt_gate(unsigned int sel
, unsigned int func
)
372 DPRINT("set_interrupt_gate(sel %d, func %x)\n",sel
,func
);
373 KiIdt
[sel
].a
= (((int)func
)&0xffff) +
375 KiIdt
[sel
].b
= 0x8f00 + (((int)func
)&0xffff0000);
378 asmlinkage
unsigned int ExHookException(exception_hook fn
, unsigned int exp
)
380 * FUNCTION: Hook an exception
387 exception_hooks
[exp
]=fn
;
391 asmlinkage
void KeInitExceptions(void)
393 * FUNCTION: Initalize CPU exception handling
398 DPRINT("KeInitExceptions()\n",0);
400 set_interrupt_gate(0,(int)exception_handler0
);
401 set_interrupt_gate(1,(int)exception_handler1
);
402 set_interrupt_gate(2,(int)exception_handler2
);
403 set_interrupt_gate(3,(int)exception_handler3
);
404 set_interrupt_gate(4,(int)exception_handler4
);
405 set_interrupt_gate(5,(int)exception_handler5
);
406 set_interrupt_gate(6,(int)exception_handler6
);
407 set_interrupt_gate(7,(int)exception_handler7
);
408 set_interrupt_gate(8,(int)exception_handler8
);
409 set_interrupt_gate(9,(int)exception_handler9
);
410 set_interrupt_gate(10,(int)exception_handler10
);
411 set_interrupt_gate(11,(int)exception_handler11
);
412 set_interrupt_gate(12,(int)exception_handler12
);
413 set_interrupt_gate(13,(int)exception_handler13
);
414 set_interrupt_gate(14,(int)exception_handler14
);
415 set_interrupt_gate(15,(int)exception_handler15
);
416 set_interrupt_gate(16,(int)exception_handler16
);
420 set_interrupt_gate(i
,(int)exception_handler_unknown
);
423 set_system_call_gate(0x2e,(int)interrupt_handler2e
);