mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:45:50 +00:00
- 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. svn path=/trunk/; revision=23632
This commit is contained in:
parent
c43ef4fb30
commit
4bb966cd9a
3 changed files with 152 additions and 36 deletions
|
@ -120,6 +120,7 @@ Author:
|
||||||
#define KPROCESS_INT21_DESCRIPTOR1 0x2C
|
#define KPROCESS_INT21_DESCRIPTOR1 0x2C
|
||||||
#define KPROCESS_IOPM_OFFSET 0x30
|
#define KPROCESS_IOPM_OFFSET 0x30
|
||||||
#define KPROCESS_ACTIVE_PROCESSORS 0x34
|
#define KPROCESS_ACTIVE_PROCESSORS 0x34
|
||||||
|
#define EPROCESS_VDM_OBJECTS 0x144
|
||||||
|
|
||||||
//
|
//
|
||||||
// KPCR Offsets
|
// KPCR Offsets
|
||||||
|
@ -272,6 +273,7 @@ Author:
|
||||||
#define EXCEPTION_RECORD_EXCEPTION_ADDRESS 0xC
|
#define EXCEPTION_RECORD_EXCEPTION_ADDRESS 0xC
|
||||||
#define EXCEPTION_RECORD_NUMBER_PARAMETERS 0x10
|
#define EXCEPTION_RECORD_NUMBER_PARAMETERS 0x10
|
||||||
#define SIZEOF_EXCEPTION_RECORD 0x14
|
#define SIZEOF_EXCEPTION_RECORD 0x14
|
||||||
|
#define EXCEPTION_RECORD_LENGTH 0x50
|
||||||
|
|
||||||
//
|
//
|
||||||
// TEB Offsets
|
// TEB Offsets
|
||||||
|
@ -381,6 +383,9 @@ Author:
|
||||||
#define STATUS_ACCESS_VIOLATION 0xC0000005
|
#define STATUS_ACCESS_VIOLATION 0xC0000005
|
||||||
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
|
#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
|
||||||
#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
|
#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 APC_INDEX_MISMATCH 0x01
|
||||||
#define TRAP_CAUSE_UNKNOWN 0x12
|
#define TRAP_CAUSE_UNKNOWN 0x12
|
||||||
#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
|
#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
|
||||||
|
|
|
@ -499,6 +499,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||||
/*
|
/*
|
||||||
* Check for stack underflow, this may be obsolete
|
* Check for stack underflow, this may be obsolete
|
||||||
*/
|
*/
|
||||||
|
DPRINT1("Exception: %x\n", ExceptionNr);
|
||||||
if (PsGetCurrentThread() != NULL &&
|
if (PsGetCurrentThread() != NULL &&
|
||||||
Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
|
Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -679,6 +679,84 @@ Error:
|
||||||
jmp _KiServiceExit
|
jmp _KiServiceExit
|
||||||
.endfunc
|
.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:
|
_KiTrap0:
|
||||||
/* Push error code */
|
/* Push error code */
|
||||||
push 0
|
push 0
|
||||||
|
@ -686,19 +764,38 @@ _KiTrap0:
|
||||||
/* Enter trap */
|
/* Enter trap */
|
||||||
TRAP_PROLOG(0)
|
TRAP_PROLOG(0)
|
||||||
|
|
||||||
/* Call the C exception handler */
|
/* Check for V86 */
|
||||||
push 0
|
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
|
||||||
push ebp
|
jnz V86Int0
|
||||||
call _KiTrapHandler
|
|
||||||
add esp, 8
|
|
||||||
|
|
||||||
/* Check for v86 recovery */
|
/* Check if the frame was from kernelmode */
|
||||||
cmp eax, 1
|
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
|
||||||
|
jz EnableInterrupts
|
||||||
|
|
||||||
/* Return to caller */
|
/* Check the old mode */
|
||||||
jne _Kei386EoiHelper@0
|
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
|
||||||
jmp _KiV86Complete
|
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:
|
_KiTrap1:
|
||||||
/* Push error code */
|
/* Push error code */
|
||||||
push 0
|
push 0
|
||||||
|
@ -706,38 +803,51 @@ _KiTrap1:
|
||||||
/* Enter trap */
|
/* Enter trap */
|
||||||
TRAP_PROLOG(1)
|
TRAP_PROLOG(1)
|
||||||
|
|
||||||
/* Call the C exception handler */
|
/* Check for V86 */
|
||||||
push 1
|
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
|
||||||
push ebp
|
jnz V86Int1
|
||||||
call _KiTrapHandler
|
|
||||||
add esp, 8
|
|
||||||
|
|
||||||
/* Check for v86 recovery */
|
/* Check if the frame was from kernelmode */
|
||||||
cmp eax, 1
|
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
|
||||||
|
jz PrepInt1
|
||||||
|
|
||||||
/* Return to caller */
|
/* Check the old mode */
|
||||||
jne _Kei386EoiHelper@0
|
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
|
||||||
jmp _KiV86Complete
|
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:
|
_KiTrap2:
|
||||||
/* Push error code */
|
|
||||||
|
/* FIXME: This is an NMI, nothing like a normal exception */
|
||||||
|
push 0
|
||||||
|
push 0
|
||||||
push 0
|
push 0
|
||||||
|
|
||||||
/* Enter trap */
|
|
||||||
TRAP_PROLOG(2)
|
|
||||||
|
|
||||||
/* Call the C exception handler */
|
|
||||||
push 2
|
push 2
|
||||||
push ebp
|
push UNEXPECTED_KERNEL_MODE_TRAP
|
||||||
call _KiTrapHandler
|
call _KeBugCheckEx@20
|
||||||
add esp, 8
|
.endfunc
|
||||||
|
|
||||||
/* Check for v86 recovery */
|
|
||||||
cmp eax, 1
|
|
||||||
|
|
||||||
/* Return to caller */
|
|
||||||
jne _Kei386EoiHelper@0
|
|
||||||
jmp _KiV86Complete
|
|
||||||
|
|
||||||
_KiTrap3:
|
_KiTrap3:
|
||||||
/* Push error code */
|
/* Push error code */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue