Author: ion
Date: Mon Aug 21 06:01:07 2006
New Revision: 23632
URL:
http://svn.reactos.org/svn/reactos?rev=23632&view=rev
Log:
- Implement generic exception dispatcher for traps (kind-of analogous to
KiKernelTrapHandler/KiUserTrapHandler but in assembly and more generic/compact).
- Switch Traps 0, 1 to it.
- Trap 2 is NMI, bugcheck immediately since we can't handle them yet.
Modified:
trunk/reactos/include/ndk/asm.h
trunk/reactos/ntoskrnl/ke/i386/exp.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=2363…
==============================================================================
--- trunk/reactos/include/ndk/asm.h (original)
+++ trunk/reactos/include/ndk/asm.h Mon Aug 21 06:01:07 2006
@@ -120,6 +120,7 @@
#define KPROCESS_INT21_DESCRIPTOR1 0x2C
#define KPROCESS_IOPM_OFFSET 0x30
#define KPROCESS_ACTIVE_PROCESSORS 0x34
+#define EPROCESS_VDM_OBJECTS 0x144
//
// KPCR Offsets
@@ -272,6 +273,7 @@
#define EXCEPTION_RECORD_EXCEPTION_ADDRESS 0xC
#define EXCEPTION_RECORD_NUMBER_PARAMETERS 0x10
#define SIZEOF_EXCEPTION_RECORD 0x14
+#define EXCEPTION_RECORD_LENGTH 0x50
//
// TEB Offsets
@@ -381,6 +383,9 @@
#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
+#define STATUS_SINGLE_STEP 0x80000004
+#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094
+#define STATUS_INTEGER_OVERFLOW 0xC0000095
#define APC_INDEX_MISMATCH 0x01
#define TRAP_CAUSE_UNKNOWN 0x12
#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/exp.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/exp.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c Mon Aug 21 06:01:07 2006
@@ -499,6 +499,7 @@
/*
* Check for stack underflow, this may be obsolete
*/
+ DPRINT1("Exception: %x\n", ExceptionNr);
if (PsGetCurrentThread() != NULL &&
Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
{
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Mon Aug 21 06:01:07 2006
@@ -679,6 +679,84 @@
jmp _KiServiceExit
.endfunc
+.func CommonDispatchException
+_CommonDispatchException:
+
+ /* Make space for an exception record */
+ sub esp, EXCEPTION_RECORD_LENGTH
+
+ /* Set it up */
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax
+ xor eax, eax
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], eax
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], eax
+ mov [esp+EXCEPTION_RECORD_EXCEPTION_ADDRESS], ebx
+ mov [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], ecx
+
+ /* Check parameter count */
+ cmp eax, 0
+ jz NoParams
+
+ /* Get information */
+ lea ebx, [esp+SIZEOF_EXCEPTION_RECORD]
+ mov [ebx], edx
+ mov [ebx+4], esi
+ mov [ebx+8], edi
+
+NoParams:
+
+ /* Set the record in ECX and check if this was V86 */
+ mov ecx, esp
+ test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ jz SetPreviousMode
+
+ /* Set V86 mode */
+ mov eax, 0xFFFF
+ jmp MaskMode
+
+SetPreviousMode:
+
+ /* Calculate the previous mode */
+ mov eax, [ebp+KTRAP_FRAME_CS]
+MaskMode:
+ and eax, MODE_MASK
+
+ /* Dispatch the exception */
+ push 1
+ push eax
+ push ebp
+ push 0
+ push ecx
+ call _KiDispatchException@20
+
+ /* End the trap */
+ jmp _Kei386EoiHelper@0
+.endfunc
+
+.func DispatchNoParam
+_DispatchNoParam:
+ /* Call the common dispatcher */
+ xor ecx, ecx
+ call _CommonDispatchException
+.endfunc
+
+.func DispatchOneParam
+_DispatchOneParam:
+ /* Call the common dispatcher */
+ xor edx, edx
+ mov ecx, 1
+ call _CommonDispatchException
+.endfunc
+
+.func DispatchTwoParam
+_DispatchTwoParam:
+ /* Call the common dispatcher */
+ xor edx, edx
+ mov ecx, 2
+ call _CommonDispatchException
+.endfunc
+
+.func KiTrap0
_KiTrap0:
/* Push error code */
push 0
@@ -686,19 +764,38 @@
/* Enter trap */
TRAP_PROLOG(0)
- /* Call the C exception handler */
- push 0
- push ebp
- call _KiTrapHandler
- add esp, 8
-
- /* Check for v86 recovery */
- cmp eax, 1
-
- /* Return to caller */
- jne _Kei386EoiHelper@0
- jmp _KiV86Complete
-
+ /* Check for V86 */
+ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ jnz V86Int0
+
+ /* Check if the frame was from kernelmode */
+ test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz EnableInterrupts
+
+ /* Check the old mode */
+ cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
+ jne VdmCheck
+
+SendException:
+ /* Re-enable interrupts for user-mode and send the exception */
+ sti
+ mov eax, STATUS_INTEGER_DIVIDE_BY_ZERO
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+ jmp _DispatchNoParam
+
+VdmCheck:
+ /* Check if this is a VDM process */
+ mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
+ cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
+ jz SendException
+
+ /* We don't support this yet! */
+V86Int0:
+ int 3
+.endfunc
+
+.func KiTrap1
_KiTrap1:
/* Push error code */
push 0
@@ -706,38 +803,51 @@
/* Enter trap */
TRAP_PROLOG(1)
- /* Call the C exception handler */
- push 1
- push ebp
- call _KiTrapHandler
- add esp, 8
-
- /* Check for v86 recovery */
- cmp eax, 1
-
- /* Return to caller */
- jne _Kei386EoiHelper@0
- jmp _KiV86Complete
-
+ /* Check for V86 */
+ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ jnz V86Int1
+
+ /* Check if the frame was from kernelmode */
+ test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz PrepInt1
+
+ /* Check the old mode */
+ cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
+ jne V86Int1
+
+EnableInterrupts:
+ /* Enable interrupts for user-mode */
+ sti
+
+PrepInt1:
+ /* Prepare the exception */
+ and dword ptr [ebp+KTRAP_FRAME_EFLAGS], ~EFLAGS_TF
+ mov ebx, [ebp+KTRAP_FRAME_EIP]
+ mov eax, STATUS_SINGLE_STEP
+ jmp _DispatchNoParam
+
+V86Int1:
+ /* Check if this is a VDM process */
+ mov ebx, [fs:KPCR_CURRENT_THREAD]
+ mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
+ cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
+ jz EnableInterrupts
+
+ /* We don't support VDM! */
+ int 3
+.endfunc
+
+.func KiTrap2
_KiTrap2:
- /* Push error code */
- push 0
-
- /* Enter trap */
- TRAP_PROLOG(2)
-
- /* Call the C exception handler */
+
+ /* FIXME: This is an NMI, nothing like a normal exception */
+ push 0
+ push 0
+ push 0
push 2
- push ebp
- call _KiTrapHandler
- add esp, 8
-
- /* Check for v86 recovery */
- cmp eax, 1
-
- /* Return to caller */
- jne _Kei386EoiHelper@0
- jmp _KiV86Complete
+ push UNEXPECTED_KERNEL_MODE_TRAP
+ call _KeBugCheckEx@20
+.endfunc
_KiTrap3:
/* Push error code */