- Gutted out KiTrapHandler. Now it is only a gateway for GPF/UD for V86 mode.

- Removed all the code in userptrap.c and removed KiKernelTrapHandler.
- Set Traps 11, 12, 16 and 17 as unhandled for now(Segment fault, stack fault, fpu fault and alignment fault). We weren't really "handling" them in the past either.
- I probably need to implement GPF handler for non-V86 mode to support Lazy segment loading and fix the vmware syscall bug that has been haunting me for two years.

svn path=/trunk/; revision=23636
This commit is contained in:
Alex Ionescu 2006-08-21 03:31:53 +00:00
parent 775b443831
commit f038f4a895
4 changed files with 47 additions and 290 deletions

View file

@ -144,43 +144,6 @@ KiRosPrintAddress(PVOID address)
return(FALSE);
}
ULONG
KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
{
EXCEPTION_RECORD Er;
Er.ExceptionFlags = 0;
Er.ExceptionRecord = NULL;
Er.ExceptionAddress = (PVOID)Tf->Eip;
if (ExceptionNr == 14)
{
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
Er.NumberParameters = 2;
Er.ExceptionInformation[0] = Tf->ErrCode & 0x1;
Er.ExceptionInformation[1] = (ULONG)Cr2;
}
else
{
if (ExceptionNr < ARRAY_SIZE(ExceptionToNtStatus))
{
Er.ExceptionCode = ExceptionToNtStatus[ExceptionNr];
}
else
{
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
}
Er.NumberParameters = 0;
}
/* FIXME: Which exceptions are noncontinuable? */
Er.ExceptionFlags = 0;
KiDispatchException(&Er, NULL, Tf, KernelMode, TRUE);
return(0);
}
VOID
NTAPI
KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG Parameter1, ULONG Parameter2)
@ -266,13 +229,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
*/
{
ULONG_PTR cr2;
ULONG Esp0;
ASSERT(ExceptionNr != 14);
ASSERT((ExceptionNr != 7 && ExceptionNr != 16 && ExceptionNr != 19));
/* Use the address of the trap frame as approximation to the ring0 esp */
Esp0 = (ULONG)&Tf->Eip;
ASSERT(ExceptionNr == 13 || ExceptionNr == 6);
/* Get CR2 */
cr2 = Ke386GetCr2();
@ -286,56 +243,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
DPRINT("Tf->Eflags, %x, Tf->Eip %x, ExceptionNr: %d\n", Tf->EFlags, Tf->Eip, ExceptionNr);
return(KeV86Exception(ExceptionNr, Tf, cr2));
}
/*
* Check for stack underflow, this may be obsolete
*/
DPRINT1("Exception: %x\n", ExceptionNr);
if (PsGetCurrentThread() != NULL &&
Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
{
DPRINT1("Stack underflow (tf->esp %x Limit %x Eip %x)\n",
Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit, Tf->Eip);
ExceptionNr = 12;
}
if (ExceptionNr == 15)
{
/*
* FIXME:
* This exception should never occur. The P6 has a bug, which does sometimes deliver
* the apic spurious interrupt as exception 15. On an athlon64, I get one exception
* in the early boot phase in apic mode (using the smp build). I've looked to the linux
* sources. Linux does ignore this exception.
*
*/
DPRINT1("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
return(0);
}
/*
* Check for a breakpoint that was only for the attention of the debugger.
*/
if (ExceptionNr == 3 && Tf->Eip == ((ULONG)DbgBreakPointNoBugCheck) + 1)
{
/*
EIP is already adjusted by the processor to point to the instruction
after the breakpoint.
*/
return(0);
}
/*
* Handle user exceptions differently
*/
if ((Tf->SegCs & 0xFFFF) == (KGDT_R3_CODE | RPL_MASK))
{
return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
}
else
{
return(KiKernelTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
}
return 0;
}
ULONG

View file

@ -14,8 +14,10 @@
/*
* FIXMEs:
* - Implement kernel-mode GPF handler, possibly fixing below:
* - Figure out why ES/DS gets messed up in VMWare, when doing KiServiceExit only,
* and only when called from user-mode, and returning to user-mode.
* - Implement Invalid Opcode handler.
* - Figure out what the DEBUGEIP hack is for and how it can be moved away.
* - Add DR macro/save and VM macro/save.
* - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
@ -977,6 +979,7 @@ V86Int5:
int 3
.endfunc
.func KiTrap6
_KiTrap6:
/* Push error code */
push 0
@ -996,6 +999,7 @@ _KiTrap6:
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
.endfunc
.func KiTrap7
_KiTrap7:
@ -1186,40 +1190,27 @@ Fatal:
jmp _KiSystemFatalException
.endfunc
.func KiTrap11
_KiTrap11:
/* Enter trap */
TRAP_PROLOG(11)
/* Call the C exception handler */
push 11
push ebp
call _KiTrapHandler
add esp, 8
/* Check for v86 recovery */
cmp eax, 1
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
/* FIXME: ROS Doesn't handle segment faults yet */
mov eax, 11
jmp _KiSystemFatalException
.endfunc
.func KiTrap12
_KiTrap12:
/* Enter trap */
TRAP_PROLOG(12)
/* Call the C exception handler */
push 12
push ebp
call _KiTrapHandler
add esp, 8
/* Check for v86 recovery */
cmp eax, 1
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
/* FIXME: ROS Doesn't handle stack faults yet */
mov eax, 12
jmp _KiSystemFatalException
.endfunc
.func KiTrap13
_KiTrap13:
/* Enter trap */
TRAP_PROLOG(13)
@ -1236,7 +1227,9 @@ _KiTrap13:
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
.endfunc
.func KiTrap14
_KiTrap14:
/* Enter trap */
TRAP_PROLOG(14)
@ -1247,13 +1240,11 @@ _KiTrap14:
call _KiPageFaultHandler
add esp, 8
/* Check for v86 recovery */
cmp eax, 1
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
jmp _Kei386EoiHelper@0
.endfunc
.func KiTrap0F
_KiTrap0F:
/* Push error code */
push 0
@ -1265,7 +1256,9 @@ _KiTrap0F:
/* Raise a fatal exception */
mov eax, 15
jmp _KiSystemFatalException
.endfunc
.func KiTrap16
_KiTrap16:
/* Push error code */
push 0
@ -1273,19 +1266,12 @@ _KiTrap16:
/* Enter trap */
TRAP_PROLOG(16)
/* Call the C exception handler */
push 16
push ebp
call _KiTrapHandler
add esp, 8
/* Check for v86 recovery */
cmp eax, 1
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
/* FIXME: ROS Doesn't handle FPU faults yet */
mov eax, 16
jmp _KiSystemFatalException
.endfunc
.func KiTrap17
_KiTrap17:
/* Push error code */
push 0
@ -1293,18 +1279,10 @@ _KiTrap17:
/* Enter trap */
TRAP_PROLOG(17)
/* Call the C exception handler */
push 17
push ebp
call _KiTrapHandler
add esp, 8
/* Check for v86 recovery */
cmp eax, 1
/* Return to caller */
jne _Kei386EoiHelper@0
jmp _KiV86Complete
/* FIXME: ROS Doesn't handle alignment faults yet */
mov eax, 17
jmp _KiSystemFatalException
.endfunc
.func KiSystemFatalException
_KiSystemFatalException:

View file

@ -1,133 +1 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/usertrap.c
* PURPOSE: Handling usermode exceptions.
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
BOOLEAN
print_user_address(PVOID address)
{
PLIST_ENTRY current_entry;
PLDR_DATA_TABLE_ENTRY current;
PEPROCESS CurrentProcess;
PPEB Peb = NULL;
ULONG_PTR RelativeAddress;
PPEB_LDR_DATA Ldr;
NTSTATUS Status = STATUS_SUCCESS;
CurrentProcess = PsGetCurrentProcess();
if (NULL != CurrentProcess)
{
Peb = CurrentProcess->Peb;
}
if (NULL == Peb)
{
DbgPrint("<%x>", address);
return(TRUE);
}
_SEH_TRY
{
RtlCopyMemory(&Ldr,
&Peb->Ldr,
sizeof(PPEB_LDR_DATA));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
DbgPrint("<%x>", address);
return(TRUE);
}
current_entry = Ldr->InLoadOrderModuleList.Flink;
while (current_entry != &Ldr->InLoadOrderModuleList &&
current_entry != NULL)
{
current =
CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (address >= (PVOID)current->DllBase &&
address < (PVOID)((char*)current->DllBase + current->SizeOfImage))
{
RelativeAddress =
(ULONG_PTR) address - (ULONG_PTR)current->DllBase;
DbgPrint("<%wZ: %x>", &current->BaseDllName, RelativeAddress);
return(TRUE);
}
current_entry = current_entry->Flink;
}
return(FALSE);
}
ULONG
NTAPI
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
{
EXCEPTION_RECORD Er;
if (ExceptionNr == 0)
{
Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
}
else if (ExceptionNr == 1)
{
Er.ExceptionCode = STATUS_SINGLE_STEP;
}
else if (ExceptionNr == 3)
{
Er.ExceptionCode = STATUS_BREAKPOINT;
}
else if (ExceptionNr == 4)
{
Er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
}
else if (ExceptionNr == 5)
{
Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED;
}
else if (ExceptionNr == 6)
{
Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
}
else
{
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
}
Er.ExceptionFlags = 0;
Er.ExceptionRecord = NULL;
Er.ExceptionAddress = (PVOID)Tf->Eip;
if (ExceptionNr == 14)
{
Er.NumberParameters = 2;
Er.ExceptionInformation[0] = Tf->ErrCode & 0x1;
Er.ExceptionInformation[1] = (ULONG)Cr2;
}
else
{
Er.NumberParameters = 0;
}
/* FIXME: Which exceptions are noncontinuable? */
Er.ExceptionFlags = 0;
KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
return(0);
}

View file

@ -32,6 +32,7 @@ ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
ULONG_PTR cr2;
NTSTATUS Status;
KPROCESSOR_MODE Mode;
EXCEPTION_RECORD Er;
ASSERT(ExceptionNr == 14);
@ -120,16 +121,18 @@ ULONG KiPageFaultHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
return 0;
}
/*
* Handle user exceptions differently
*/
if (Mode == KernelMode)
{
return(KiKernelTrapHandler(Tf, 14, (PVOID)cr2));
}
else
{
return(KiUserTrapHandler(Tf, 14, (PVOID)cr2));
}
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
Er.ExceptionFlags = 0;
Er.ExceptionRecord = NULL;
Er.ExceptionAddress = (PVOID)Tf->Eip;
Er.NumberParameters = 2;
Er.ExceptionInformation[0] = Tf->ErrCode & 0x1;
Er.ExceptionInformation[1] = (ULONG)cr2;
/* FIXME: Which exceptions are noncontinuable? */
Er.ExceptionFlags = 0;
KiDispatchException(&Er, 0, Tf, Mode, TRUE);
return 0;
}