Trap Handlers in C Patch 2 of X (Patch by Sir_Richard <ros.arm@reactos.org>):

[NTOS]: Convert Trap 0, 1, 3, 4, 5, 8, 10, 11, 12, 15, 17, 2C (Assertion) and 2D (Debug) to C. Tested INT3 and still works as expected, and obviously DbgPrint is still functionning (0x2D). The other traps are mainly programming errors such as bound overflow or integer overflow, so we need some test cases, but they should work. Note the 3-4 lines of C for what used to be dozens of ASM lines.
    [NTOS]: Fix infinite loop in KiCheckForApcDelivery.

Stefan Ginsberg: Could you please implement the relevant Extended GCC ASM into MSVC?
   

svn path=/trunk/; revision=45002
This commit is contained in:
ReactOS Portable Systems Group 2010-01-08 15:16:00 +00:00
parent 34ad648d58
commit 0940d6e34a
3 changed files with 257 additions and 384 deletions

View file

@ -194,19 +194,18 @@ KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
Thread->Alerted[KernelMode] = FALSE;
/* Are there pending user APCs? */
if (Thread->ApcState.UserApcPending)
{
/* Raise to APC level and enable interrupts */
OldIrql = KfRaiseIrql(APC_LEVEL);
_enable();
if (!Thread->ApcState.UserApcPending) break;
/* Deliver APCs */
KiDeliverApc(UserMode, NULL, TrapFrame);
/* Raise to APC level and enable interrupts */
OldIrql = KfRaiseIrql(APC_LEVEL);
_enable();
/* Restore IRQL and disable interrupts once again */
KfLowerIrql(OldIrql);
_disable();
}
/* Deliver APCs */
KiDeliverApc(UserMode, NULL, TrapFrame);
/* Restore IRQL and disable interrupts once again */
KfLowerIrql(OldIrql);
_disable();
}
}
}

View file

@ -53,6 +53,11 @@ idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */
idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */
GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */
/* Trap handlers referenced from C code */
.globl _KiTrap2
.globl _KiTrap8
.globl _KiTrap19
/* System call entrypoints: */
.globl _KiFastCallEntry
.globl _KiSystemService
@ -464,50 +469,8 @@ AbiosExit:
/* FIXME: TODO */
UNHANDLED_PATH "ABIOS Exit"
.func KiRaiseAssertion
TRAP_FIXUPS kira_a, kira_t, DoFixupV86, DoFixupAbios
_KiRaiseAssertion:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kira_a, kira_t
/*
* Modify EIP so it points to the faulting instruction and set it as the
* exception address. Note that the 'int 2C' instruction used for this call
* is 2 bytes long as opposed to 1 byte 'int 3'.
*/
sub dword ptr [ebp+KTRAP_FRAME_EIP], 2
mov ebx, [ebp+KTRAP_FRAME_EIP]
/* Raise an assertion failure */
mov eax, STATUS_ASSERTION_FAILURE
jmp _DispatchNoParam
.endfunc
.func KiDebugService
TRAP_FIXUPS kids_a, kids_t, DoFixupV86, DoFixupAbios
_KiDebugService:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kids_a, kids_t
/* Increase EIP so we skip the INT3 */
inc dword ptr [ebp+KTRAP_FRAME_EIP]
/* Call debug service dispatcher */
mov eax, [ebp+KTRAP_FRAME_EAX]
mov ecx, [ebp+KTRAP_FRAME_ECX]
mov edx, [ebp+KTRAP_FRAME_EDX]
/* Jump to INT3 handler */
jmp PrepareInt3
.endfunc
GENERATE_TRAP_HANDLER KiRaiseAssertion, 1
GENERATE_TRAP_HANDLER KiDebugService, 1
.func NtRaiseException@12
_NtRaiseException@12:
@ -704,91 +667,9 @@ _KiFixupFrame:
UNHANDLED_PATH "Trap Frame Fixup"
.endfunc
.func KiTrap0
TRAP_FIXUPS kit0_a, kit0_t, DoFixupV86, DoNotFixupAbios
_KiTrap0:
/* Push error code */
push 0
GENERATE_TRAP_HANDLER KiTrap0, 1
GENERATE_TRAP_HANDLER KiTrap1, 1
/* Enter trap */
TRAP_PROLOG kit0_a, kit0_t
/* 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 SendException
/* 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, PCR[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:
/* FIXME: TODO */
UNHANDLED_V86_PATH
.endfunc
.func KiTrap1
TRAP_FIXUPS kit1_a, kit1_t, DoFixupV86, DoNotFixupAbios
_KiTrap1:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit1_a, kit1_t
/* 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, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz EnableInterrupts
/* We don't support VDM! */
UNHANDLED_V86_PATH
.endfunc
.globl _KiTrap2
.func KiTrap2
_KiTrap2:
//
@ -811,148 +692,9 @@ _KiTrap2:
jmp _KiSystemFatalException // Bugcheck helper
.endfunc
.func KiTrap3
TRAP_FIXUPS kit3_a, kit3_t, DoFixupV86, DoNotFixupAbios
_KiTrap3:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit3_a, kit3_t
/*
* Set the special code to indicate that this is a software breakpoint
* and not a debug service call
*/
mov eax, BREAKPOINT_BREAK
/* Check for V86 */
PrepareInt3:
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int3
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz PrepInt3
/* Check the old mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne V86Int3
EnableInterrupts3:
/* Enable interrupts for user-mode */
sti
PrepInt3:
/* Prepare the exception */
mov esi, ecx
mov edi, edx
mov edx, eax
/* Setup EIP, NTSTATUS and parameter count, then dispatch */
mov ebx, [ebp+KTRAP_FRAME_EIP]
dec ebx
mov ecx, 3
mov eax, STATUS_BREAKPOINT
call _CommonDispatchException
V86Int3:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz EnableInterrupts3
/* We don't support VDM! */
UNHANDLED_V86_PATH
.endfunc
.func KiTrap4
TRAP_FIXUPS kit4_a, kit4_t, DoFixupV86, DoNotFixupAbios
_KiTrap4:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit4_a, kit4_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int4
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz SendException4
/* Check the old mode */
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne VdmCheck4
SendException4:
/* Re-enable interrupts for user-mode and send the exception */
sti
mov eax, STATUS_INTEGER_OVERFLOW
mov ebx, [ebp+KTRAP_FRAME_EIP]
dec ebx
jmp _DispatchNoParam
VdmCheck4:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException4
/* We don't support this yet! */
V86Int4:
UNHANDLED_V86_PATH
.endfunc
.func KiTrap5
TRAP_FIXUPS kit5_a, kit5_t, DoFixupV86, DoNotFixupAbios
_KiTrap5:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit5_a, kit5_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86Int5
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz CheckMode
/* It did, and this should never happen */
mov eax, 5
jmp _KiSystemFatalException
/* Check the old mode */
CheckMode:
cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
jne VdmCheck5
/* Re-enable interrupts for user-mode and send the exception */
SendException5:
sti
mov eax, STATUS_ARRAY_BOUNDS_EXCEEDED
mov ebx, [ebp+KTRAP_FRAME_EIP]
jmp _DispatchNoParam
VdmCheck5:
/* Check if this is a VDM process */
mov ebx, PCR[KPCR_CURRENT_THREAD]
mov ebx, [ebx+KTHREAD_APCSTATE_PROCESS]
cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0
jz SendException5
/* We don't support this yet! */
V86Int5:
UNHANDLED_V86_PATH
.endfunc
GENERATE_TRAP_HANDLER KiTrap3, 1
GENERATE_TRAP_HANDLER KiTrap4, 1
GENERATE_TRAP_HANDLER KiTrap5, 1
.func KiTrap6
TRAP_FIXUPS kit6_a, kit6_t, DoFixupV86, DoNotFixupAbios
@ -1380,80 +1122,11 @@ BogusTrap:
call _KeBugCheckEx@20
.endfunc
.globl _KiTrap8
.func KiTrap8
_KiTrap8:
/* Can't really do too much */
mov eax, 8
jmp _KiSystemFatalException
.endfunc
.func KiTrap9
TRAP_FIXUPS kit9_a, kit9_t, DoFixupV86, DoNotFixupAbios
_KiTrap9:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kit9_a, kit9_t
/* Enable interrupts and bugcheck */
sti
mov eax, 9
jmp _KiSystemFatalException
.endfunc
.func KiTrap10
TRAP_FIXUPS kita_a, kita_t, DoFixupV86, DoNotFixupAbios
_KiTrap10:
/* Enter trap */
TRAP_PROLOG kita_a, kita_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86IntA
/* Check if the frame was from kernelmode */
test word ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jz Fatal
V86IntA:
/* Check if OF was set during iretd */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAG_ZERO
sti
jz Fatal
/* It was, just mask it out */
and dword ptr [ebp+KTRAP_FRAME_EFLAGS], ~EFLAG_ZERO
jmp _Kei386EoiHelper@0
Fatal:
/* TSS failure for some other reason: crash */
mov eax, 10
jmp _KiSystemFatalException
.endfunc
.func KiTrap11
TRAP_FIXUPS kitb_a, kitb_t, DoFixupV86, DoNotFixupAbios
_KiTrap11:
/* Enter trap */
TRAP_PROLOG kitb_a, kitb_t
/* FIXME: ROS Doesn't handle segment faults yet */
mov eax, 11
jmp _KiSystemFatalException
.endfunc
.func KiTrap12
TRAP_FIXUPS kitc_a, kitc_t, DoFixupV86, DoNotFixupAbios
_KiTrap12:
/* Enter trap */
TRAP_PROLOG kitc_a, kitc_t
/* FIXME: ROS Doesn't handle stack faults yet */
mov eax, 12
jmp _KiSystemFatalException
.endfunc
GENERATE_TRAP_HANDLER KiTrap8, 0
GENERATE_TRAP_HANDLER KiTrap9, 1
GENERATE_TRAP_HANDLER KiTrap10, 0
GENERATE_TRAP_HANDLER KiTrap11, 0
GENERATE_TRAP_HANDLER KiTrap12, 0
.func KiTrapExceptHandler
_KiTrapExceptHandler:
@ -2131,20 +1804,7 @@ HandleLockErrata:
jmp DispatchLockErrata
.endfunc
.func KiTrap0F
TRAP_FIXUPS kitf_a, kitf_t, DoFixupV86, DoNotFixupAbios
_KiTrap0F:
/* Push error code */
push 0
/* Enter trap */
TRAP_PROLOG kitf_a, kitf_t
sti
/* Raise a fatal exception */
mov eax, 15
jmp _KiSystemFatalException
.endfunc
GENERATE_TRAP_HANDLER KiTrap0F, 1
.func KiTrap16
TRAP_FIXUPS kit10_a, kit10_t, DoFixupV86, DoNotFixupAbios
@ -2172,21 +1832,8 @@ _KiTrap16:
jmp _Kei386EoiHelper@0
.endfunc
.func KiTrap17
TRAP_FIXUPS kit11_a, kit11_t, DoFixupV86, DoNotFixupAbios
_KiTrap17:
/* Push error code */
push 0
GENERATE_TRAP_HANDLER KiTrap17, 1
/* Enter trap */
TRAP_PROLOG kit11_a, kit11_t
/* FIXME: ROS Doesn't handle alignment faults yet */
mov eax, 17
jmp _KiSystemFatalException
.endfunc
.globl _KiTrap19
.func KiTrap19
TRAP_FIXUPS kit19_a, kit19_t, DoFixupV86, DoNotFixupAbios
_KiTrap19:
@ -2359,7 +2006,6 @@ KernelXmmi:
call _KeBugCheckWithTf@24
.endfunc
.func KiSystemFatalException
_KiSystemFatalException:

View file

@ -228,4 +228,232 @@ KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
KiEoiHelper(TrapFrame);
}
/* TRAP HANDLERS **************************************************************/
VOID
FASTCALL
KiDebugHandler(IN PKTRAP_FRAME TrapFrame,
IN ULONG Parameter1,
IN ULONG Parameter2,
IN ULONG Parameter3)
{
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Enable interrupts if the trap came from user-mode */
if (KiUserTrap(TrapFrame)) _enable();
/* Dispatch the exception */
KiDispatchExceptionFromTrapFrame(STATUS_BREAKPOINT,
TrapFrame->Eip - 1,
3,
Parameter1,
Parameter2,
Parameter3,
TrapFrame);
}
VOID
FASTCALL
KiTrap0Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Enable interrupts */
_enable();
/* Dispatch the exception */
KiDispatchException0Args(STATUS_INTEGER_DIVIDE_BY_ZERO,
TrapFrame->Eip,
TrapFrame);
}
VOID
FASTCALL
KiTrap1Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Enable interrupts if the trap came from user-mode */
if (KiUserTrap(TrapFrame)) _enable();
/* Mask out trap flag and dispatch the exception */
TrapFrame->EFlags &= ~EFLAGS_TF;
KiDispatchException0Args(STATUS_SINGLE_STEP,
TrapFrame->Eip,
TrapFrame);
}
VOID
FASTCALL
KiTrap3Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Continue with the common handler */
KiDebugHandler(TrapFrame, BREAKPOINT_BREAK, 0, 0);
}
VOID
FASTCALL
KiTrap4Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Enable interrupts */
_enable();
/* Dispatch the exception */
KiDispatchException0Args(STATUS_INTEGER_OVERFLOW,
TrapFrame->Eip - 1,
TrapFrame);
}
VOID
FASTCALL
KiTrap5Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Check for kernel-mode fault */
if (!KiUserTrap(TrapFrame)) KiSystemFatalException(EXCEPTION_BOUND_CHECK, TrapFrame);
/* Enable interrupts */
_enable();
/* Dispatch the exception */
KiDispatchException0Args(STATUS_ARRAY_BOUNDS_EXCEEDED,
TrapFrame->Eip,
TrapFrame);
}
VOID
FASTCALL
KiTrap8Handler(IN PKTRAP_FRAME TrapFrame)
{
/* FIXME: Not handled */
KiSystemFatalException(EXCEPTION_DOUBLE_FAULT, TrapFrame);
}
VOID
FASTCALL
KiTrap9Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Enable interrupts and kill the system */
_enable();
KiSystemFatalException(EXCEPTION_NPX_OVERRUN, TrapFrame);
}
VOID
FASTCALL
KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Kill the system */
KiSystemFatalException(EXCEPTION_INVALID_TSS, TrapFrame);
}
VOID
FASTCALL
KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* FIXME: Kill the system */
UNIMPLEMENTED;
KiSystemFatalException(EXCEPTION_SEGMENT_NOT_PRESENT, TrapFrame);
}
VOID
FASTCALL
KiTrap12Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* FIXME: Kill the system */
UNIMPLEMENTED;
KiSystemFatalException(EXCEPTION_STACK_FAULT, TrapFrame);
}
VOID
FASTCALL
KiTrap0FHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* FIXME: Kill the system */
UNIMPLEMENTED;
KiSystemFatalException(EXCEPTION_RESERVED_TRAP, TrapFrame);
}
VOID
FASTCALL
KiTrap17Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Enable interrupts and kill the system */
_enable();
KiSystemFatalException(EXCEPTION_ALIGNMENT_CHECK, TrapFrame);
}
VOID
FASTCALL
KiRaiseAssertionHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Increment EIP to skip the INT2C instruction (2 bytes, not 1 like INT3) */
TrapFrame->Eip += 2;
/* Dispatch the exception */
KiDispatchException0Args(STATUS_ASSERTION_FAILURE,
TrapFrame->Eip,
TrapFrame);
}
VOID
FASTCALL
KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Increment EIP to skip the INT3 instruction */
TrapFrame->Eip++;
/* Continue with the common handler */
KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx);
}
/* EOF */