#define NDEBUG
#include <debug.h>
-/* GLOBALS *******************************************************************/
-
-/* DR Registers in the CONTEXT structure */
-UCHAR KiDebugRegisterContextOffsets[9] =
-{
- FIELD_OFFSET(CONTEXT, Dr0),
- FIELD_OFFSET(CONTEXT, Dr1),
- FIELD_OFFSET(CONTEXT, Dr2),
- FIELD_OFFSET(CONTEXT, Dr3),
- 0,
- 0,
- FIELD_OFFSET(CONTEXT, Dr6),
- FIELD_OFFSET(CONTEXT, Dr7),
- 0,
-};
-
-/* DR Registers in the KTRAP_FRAME structure */
-UCHAR KiDebugRegisterTrapOffsets[9] =
-{
- FIELD_OFFSET(KTRAP_FRAME, Dr0),
- FIELD_OFFSET(KTRAP_FRAME, Dr1),
- FIELD_OFFSET(KTRAP_FRAME, Dr2),
- FIELD_OFFSET(KTRAP_FRAME, Dr3),
- 0,
- 0,
- FIELD_OFFSET(KTRAP_FRAME, Dr6),
- FIELD_OFFSET(KTRAP_FRAME, Dr7),
- 0,
-};
/* FUNCTIONS *****************************************************************/
FASTCALL
KiUpdateDr7(IN ULONG Dr7)
{
- ULONG DebugMask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
+ ULONG DebugMask = KeGetCurrentThread()->Header.DebugActive;
/* Check if debugging is enabled */
if (DebugMask & DR_MASK(DR7_OVERRIDE_V))
if (!DrMask)
{
/* He didn't, use the one from the thread */
- Mask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
+ Mask = KeGetCurrentThread()->Header.DebugActive;
}
else
{
if (Mask != NewMask)
{
/* Update it */
- KeGetCurrentThread()->DispatcherHeader.DebugActive =
- (BOOLEAN)NewMask;
+ KeGetCurrentThread()->Header.DebugActive = (UCHAR)NewMask;
}
}
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
{
/* Check if this is user-mode or V86 */
- if ((TrapFrame->SegCs & MODE_MASK) ||
+ if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Return it directly */
Previous = KiEspFromTrapFrame(TrapFrame);
/* Check if this is user-mode or V86 */
- if ((TrapFrame->SegCs & MODE_MASK) ||
+ if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Write it directly */
/* Just return it */
return TrapFrame->HardwareSegSs;
}
- else if (TrapFrame->SegCs & MODE_MASK)
+ else if (KiUserTrap(TrapFrame))
{
/* User mode, return the User SS */
return TrapFrame->HardwareSegSs | RPL_MASK;
/* Just write it */
TrapFrame->HardwareSegSs = Ss;
}
- else if (TrapFrame->SegCs & MODE_MASK)
+ else if (KiUserTrap(TrapFrame))
{
/* Usermode, save the User SS */
TrapFrame->HardwareSegSs = Ss | RPL_MASK;
PKTHREAD Thread;
ULONG_PTR Stack;
ULONG EFlags;
-
+
/* Get the current thread's stack */
Thread = KeGetCurrentThread();
Stack = (ULONG_PTR)Thread->InitialStack;
-
+
/* Check if we are in V8086 mode */
if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
Stack -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) -
FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
}
-
+
/* Bias the stack for the FPU area */
Stack -= sizeof(FX_SAVE_AREA);
-
+
/* Disable interrupts */
EFlags = __readeflags();
_disable();
-
+
/* Set new ESP0 value in the TSS */
KeGetPcr()->TSS->Esp0 = Stack;
-
+
/* Restore old interrupt state */
__writeeflags(EFlags);
}
BOOLEAN V86Switch = FALSE;
KIRQL OldIrql;
ULONG DrMask = 0;
- PVOID SafeDr;
/* Do this at APC_LEVEL */
OldIrql = KeGetCurrentIrql();
TrapFrame->V86Fs = Context->SegFs;
TrapFrame->V86Gs = Context->SegGs;
}
- else if (!(TrapFrame->SegCs & MODE_MASK))
+ else if (!KiUserTrap(TrapFrame))
{
/* For kernel mode, write the standard values */
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
/* Handle the extended registers */
if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
- CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK))
+ CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame))
{
/* Get the FX Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
/* Handle the floating point state */
if (((ContextFlags & CONTEXT_FLOATING_POINT) ==
- CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
+ CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
{
/* Get the FX Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
}
/* Handle the Debug Registers */
- if (0 && (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+ if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
- /* Loop DR registers */
- for (i = 0; i < 4; i++)
- {
- /* Sanitize the context DR Address */
- SafeDr = Ke386SanitizeDr(KiDrFromContext(i, Context), PreviousMode);
-
- /* Save it in the trap frame */
- *KiDrFromTrapFrame(i, TrapFrame) = SafeDr;
+ /* Copy Dr0 - Dr4 */
+ TrapFrame->Dr0 = Context->Dr0;
+ TrapFrame->Dr1 = Context->Dr1;
+ TrapFrame->Dr2 = Context->Dr2;
+ TrapFrame->Dr3 = Context->Dr3;
- /* Check if this DR address is active and add it in the DR mask */
- if (SafeDr) DrMask |= DR_MASK(i);
+ /* If we're in user-mode */
+ if (PreviousMode != KernelMode)
+ {
+ /* Make sure, no Dr address is above user space */
+ if (Context->Dr0 > (ULONG)MmHighestUserAddress) TrapFrame->Dr0 = 0;
+ if (Context->Dr1 > (ULONG)MmHighestUserAddress) TrapFrame->Dr1 = 0;
+ if (Context->Dr2 > (ULONG)MmHighestUserAddress) TrapFrame->Dr2 = 0;
+ if (Context->Dr3 > (ULONG)MmHighestUserAddress) TrapFrame->Dr3 = 0;
}
- /* Now save and sanitize DR6 */
+ /* Now sanitize and save DR6 */
TrapFrame->Dr6 = Context->Dr6 & DR6_LEGAL;
+
+ /* Update the Dr active mask */
+ if (TrapFrame->Dr0) DrMask |= DR_MASK(0);
+ if (TrapFrame->Dr1) DrMask |= DR_MASK(1);
+ if (TrapFrame->Dr2) DrMask |= DR_MASK(2);
+ if (TrapFrame->Dr3) DrMask |= DR_MASK(3);
if (TrapFrame->Dr6) DrMask |= DR_MASK(6);
- /* Save and sanitize DR7 */
+ /* Sanitize and save DR7 */
TrapFrame->Dr7 = Context->Dr7 & DR7_LEGAL;
KiRecordDr7(&TrapFrame->Dr7, &DrMask);
if (PreviousMode != KernelMode)
{
/* Save the mask */
- KeGetCurrentThread()->DispatcherHeader.DebugActive = DrMask;
+ KeGetCurrentThread()->Header.DebugActive = (UCHAR)DrMask;
}
}
/* Handle extended registers */
if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
- CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK))
+ CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame))
{
/* Get the FX Save Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
/* Handle Floating Point */
if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
- CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
+ CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
{
/* Get the FX Save Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
/* User mode exception, was it first-chance? */
if (FirstChance)
{
- /*
+ /*
* Break into the kernel debugger unless a user mode debugger
* is present or user mode exceptions are ignored, except if this
* is a debug service which we must always pass to KD
}
}
_SEH2_END;
+
+ DPRINT("First chance exception in %.16s, ExceptionCode: %lx, ExceptionAddress: %p, P0: %lx, P1: %lx\n",
+ PsGetCurrentProcess()->ImageFileName,
+ ExceptionRecord->ExceptionCode,
+ ExceptionRecord->ExceptionAddress,
+ ExceptionRecord->ExceptionInformation[0],
+ ExceptionRecord->ExceptionInformation[1]);
}
/* Try second chance */
}
/* 3rd strike, kill the process */
- DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n",
+ DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p, P0: %lx, P1: %lx\n",
PsGetCurrentProcess()->ImageFileName,
ExceptionRecord->ExceptionCode,
- ExceptionRecord->ExceptionAddress);
+ ExceptionRecord->ExceptionAddress,
+ PsGetCurrentProcess()->SectionBaseAddress,
+ ExceptionRecord->ExceptionInformation[0],
+ ExceptionRecord->ExceptionInformation[1]);
ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
return;
}
+DECLSPEC_NORETURN
VOID
NTAPI
-DECLSPEC_NORETURN
KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
IN ULONG_PTR Address,
IN ULONG ParameterCount,
ExceptionRecord.ExceptionInformation[1] = Parameter2;
ExceptionRecord.ExceptionInformation[2] = Parameter3;
}
-
+
/* Now go dispatch the exception */
KiDispatchException(&ExceptionRecord,
NULL,
KiEoiHelper(TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiSystemFatalException(IN ULONG ExceptionCode,
IN PKTRAP_FRAME TrapFrame)
{