mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:45:50 +00:00
[NTOSKRNL]
- Implement saving / restoring debug registers on traps - Replace the loop in KeContextToTrapFrame with something less ridiculous - fixes a number of ntdd exception winetests svn path=/trunk/; revision=56357
This commit is contained in:
parent
ebccbcb163
commit
038a2fbb39
5 changed files with 191 additions and 120 deletions
|
@ -539,28 +539,6 @@ Ke386SanitizeFlags(IN ULONG Eflags,
|
|||
(EFLAGS_INTERRUPT_MASK | (Eflags & EFLAGS_USER_SANITIZE)));
|
||||
}
|
||||
|
||||
//
|
||||
// Gets a DR register from a CONTEXT structure
|
||||
//
|
||||
FORCEINLINE
|
||||
PVOID
|
||||
KiDrFromContext(IN ULONG Dr,
|
||||
IN PCONTEXT Context)
|
||||
{
|
||||
return *(PVOID*)((ULONG_PTR)Context + KiDebugRegisterContextOffsets[Dr]);
|
||||
}
|
||||
|
||||
//
|
||||
// Gets a DR register from a KTRAP_FRAME structure
|
||||
//
|
||||
FORCEINLINE
|
||||
PVOID*
|
||||
KiDrFromTrapFrame(IN ULONG Dr,
|
||||
IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
return (PVOID*)((ULONG_PTR)TrapFrame + KiDebugRegisterTrapOffsets[Dr]);
|
||||
}
|
||||
|
||||
//
|
||||
// Sanitizes a Debug Register
|
||||
//
|
||||
|
|
|
@ -95,18 +95,37 @@ KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame)
|
|||
TrapFrame->PreviousPreviousMode = -1;
|
||||
}
|
||||
|
||||
#define DR7_RESERVED_READ_AS_1 0x400
|
||||
|
||||
#define CheckDr(DrNumner, ExpectedValue) \
|
||||
{ \
|
||||
ULONG DrValue = __readdr(DrNumner); \
|
||||
if (DrValue != (ExpectedValue)) \
|
||||
{ \
|
||||
DbgPrint("Dr%ld: expected %.8lx, got %.8lx\n", \
|
||||
DrNumner, ExpectedValue, DrValue); \
|
||||
__debugbreak(); \
|
||||
} \
|
||||
}
|
||||
|
||||
extern BOOLEAN StopChecking;
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
|
||||
IN BOOLEAN SkipPreviousMode)
|
||||
{
|
||||
/* Don't check recursively */
|
||||
if (StopChecking) return;
|
||||
StopChecking = TRUE;
|
||||
|
||||
/* Make sure interrupts are disabled */
|
||||
if (__readeflags() & EFLAGS_INTERRUPT_MASK)
|
||||
{
|
||||
DbgPrint("Exiting with interrupts enabled: %lx\n", __readeflags());
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
|
||||
/* Make sure this is a real trap frame */
|
||||
if (TrapFrame->DbgArgMark != 0xBADB0D00)
|
||||
{
|
||||
|
@ -114,34 +133,61 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
|
|||
KiDumpTrapFrame(TrapFrame);
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
|
||||
/* Make sure we're not in user-mode or something */
|
||||
if (Ke386GetFs() != KGDT_R0_PCR)
|
||||
{
|
||||
DbgPrint("Exiting with an invalid FS: %lx\n", Ke386GetFs());
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
|
||||
/* Make sure we have a valid SEH chain */
|
||||
if (KeGetPcr()->NtTib.ExceptionList == 0)
|
||||
{
|
||||
DbgPrint("Exiting with NULL exception chain: %p\n", KeGetPcr()->NtTib.ExceptionList);
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
|
||||
/* Make sure we're restoring a valid SEH chain */
|
||||
if (TrapFrame->ExceptionList == 0)
|
||||
{
|
||||
DbgPrint("Entered a trap with a NULL exception chain: %p\n", TrapFrame->ExceptionList);
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
|
||||
/* If we're ignoring previous mode, make sure caller doesn't actually want it */
|
||||
if (SkipPreviousMode && (TrapFrame->PreviousPreviousMode != -1))
|
||||
{
|
||||
DbgPrint("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx\n", TrapFrame->PreviousPreviousMode);
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
/* Check DR values */
|
||||
if (TrapFrame->SegCs & MODE_MASK)
|
||||
{
|
||||
/* Check for active debugging */
|
||||
if (KeGetCurrentThread()->Header.DebugActive)
|
||||
{
|
||||
if ((TrapFrame->Dr7 & ~DR7_RESERVED_MASK) == 0) __debugbreak();
|
||||
|
||||
CheckDr(0, TrapFrame->Dr0);
|
||||
CheckDr(1, TrapFrame->Dr1);
|
||||
CheckDr(2, TrapFrame->Dr2);
|
||||
CheckDr(3, TrapFrame->Dr3);
|
||||
CheckDr(7, TrapFrame->Dr7 | DR7_RESERVED_READ_AS_1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
CheckDr(0, Prcb->ProcessorState.SpecialRegisters.KernelDr0);
|
||||
CheckDr(1, Prcb->ProcessorState.SpecialRegisters.KernelDr1);
|
||||
CheckDr(2, Prcb->ProcessorState.SpecialRegisters.KernelDr2);
|
||||
CheckDr(3, Prcb->ProcessorState.SpecialRegisters.KernelDr3);
|
||||
//CheckDr(7, Prcb->ProcessorState.SpecialRegisters.KernelDr7);
|
||||
}
|
||||
|
||||
StopChecking = FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -150,7 +196,7 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall,
|
|||
IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
|
||||
|
||||
/* Check if this was a user call */
|
||||
if (KiUserTrap(TrapFrame))
|
||||
{
|
||||
|
@ -161,7 +207,7 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall,
|
|||
/* Forcibly put us in a sane state */
|
||||
KeGetPcr()->Irql = PASSIVE_LEVEL;
|
||||
_disable();
|
||||
|
||||
|
||||
/* Fail */
|
||||
KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE,
|
||||
SystemCall,
|
||||
|
@ -208,6 +254,53 @@ VOID
|
|||
|
||||
extern PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler;
|
||||
|
||||
//
|
||||
// Save user mode debug registers and restore kernel values
|
||||
//
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiHandleDebugRegistersOnTrapEntry(
|
||||
IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
|
||||
/* Save all debug registers in the trap frame */
|
||||
TrapFrame->Dr0 = __readdr(0);
|
||||
TrapFrame->Dr1 = __readdr(1);
|
||||
TrapFrame->Dr2 = __readdr(2);
|
||||
TrapFrame->Dr3 = __readdr(3);
|
||||
TrapFrame->Dr6 = __readdr(6);
|
||||
TrapFrame->Dr7 = __readdr(7);
|
||||
|
||||
/* Disable all active debugging */
|
||||
__writedr(7, 0);
|
||||
|
||||
/* Restore kernel values */
|
||||
__writedr(0, Prcb->ProcessorState.SpecialRegisters.KernelDr0);
|
||||
__writedr(1, Prcb->ProcessorState.SpecialRegisters.KernelDr1);
|
||||
__writedr(2, Prcb->ProcessorState.SpecialRegisters.KernelDr2);
|
||||
__writedr(3, Prcb->ProcessorState.SpecialRegisters.KernelDr3);
|
||||
__writedr(6, Prcb->ProcessorState.SpecialRegisters.KernelDr6);
|
||||
__writedr(7, Prcb->ProcessorState.SpecialRegisters.KernelDr7);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiHandleDebugRegistersOnTrapExit(
|
||||
PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Disable all active debugging */
|
||||
__writedr(7, 0);
|
||||
|
||||
/* Load all debug registers from the trap frame */
|
||||
__writedr(0, TrapFrame->Dr0);
|
||||
__writedr(1, TrapFrame->Dr1);
|
||||
__writedr(2, TrapFrame->Dr2);
|
||||
__writedr(3, TrapFrame->Dr3);
|
||||
__writedr(6, TrapFrame->Dr6);
|
||||
__writedr(7, TrapFrame->Dr7);
|
||||
}
|
||||
|
||||
//
|
||||
// Virtual 8086 Mode Optimized Trap Exit
|
||||
//
|
||||
|
@ -218,7 +311,7 @@ KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
|
|||
{
|
||||
PKTHREAD Thread;
|
||||
KIRQL OldIrql;
|
||||
|
||||
|
||||
/* Get the thread */
|
||||
Thread = KeGetCurrentThread();
|
||||
while (TRUE)
|
||||
|
@ -243,15 +336,14 @@ KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
|
|||
KfLowerIrql(OldIrql);
|
||||
_disable();
|
||||
}
|
||||
|
||||
|
||||
/* If we got here, we're still in a valid V8086 context, so quit it */
|
||||
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
|
||||
{
|
||||
/* Not handled yet */
|
||||
DbgPrint("Need Hardware Breakpoint Support!\n");
|
||||
while (TRUE);
|
||||
/* Restore debug registers from the trap frame */
|
||||
KiHandleDebugRegistersOnTrapExit(TrapFrame);
|
||||
}
|
||||
|
||||
|
||||
/* Return from interrupt */
|
||||
KiTrapReturnNoSegments(TrapFrame);
|
||||
}
|
||||
|
@ -270,8 +362,8 @@ KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
|
|||
TrapFrame->Dr7 = __readdr(7);
|
||||
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
|
||||
{
|
||||
DbgPrint("Need Hardware Breakpoint Support!\n");
|
||||
while (TRUE);
|
||||
/* Handle debug registers */
|
||||
KiHandleDebugRegistersOnTrapEntry(TrapFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,14 +378,21 @@ KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
|
|||
TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
|
||||
KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
|
||||
/* Flush DR7 and check for debugging */
|
||||
/* Default to debugging disabled */
|
||||
TrapFrame->Dr7 = 0;
|
||||
if (__builtin_expect(KeGetCurrentThread()->Header.DebugActive & 0xFF, 0))
|
||||
|
||||
/* Check if the frame was from user mode or v86 mode */
|
||||
if ((TrapFrame->SegCs & MODE_MASK) ||
|
||||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
|
||||
{
|
||||
DbgPrint("Need Hardware Breakpoint Support!\n");
|
||||
while (TRUE);
|
||||
/* Check for active debugging */
|
||||
if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
|
||||
{
|
||||
/* Handle debug registers */
|
||||
KiHandleDebugRegistersOnTrapEntry(TrapFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set debug header */
|
||||
KiFillTrapFrameDebug(TrapFrame);
|
||||
}
|
||||
|
@ -307,15 +406,22 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
|||
{
|
||||
/* Save exception list */
|
||||
TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
|
||||
|
||||
/* Flush DR7 and check for debugging */
|
||||
|
||||
/* Default to debugging disabled */
|
||||
TrapFrame->Dr7 = 0;
|
||||
if (__builtin_expect(KeGetCurrentThread()->Header.DebugActive & 0xFF, 0))
|
||||
|
||||
/* Check if the frame was from user mode or v86 mode */
|
||||
if ((TrapFrame->SegCs & MODE_MASK) ||
|
||||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
|
||||
{
|
||||
DbgPrint("Need Hardware Breakpoint Support!\n");
|
||||
while (TRUE);
|
||||
/* Check for active debugging */
|
||||
if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
|
||||
{
|
||||
/* Handle debug registers */
|
||||
KiHandleDebugRegistersOnTrapEntry(TrapFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set debug header */
|
||||
KiFillTrapFrameDebug(TrapFrame);
|
||||
}
|
||||
|
|
|
@ -14,35 +14,6 @@
|
|||
#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 *****************************************************************/
|
||||
|
||||
|
@ -153,8 +124,7 @@ KiRecordDr7(OUT PULONG Dr7Ptr,
|
|||
if (Mask != NewMask)
|
||||
{
|
||||
/* Update it */
|
||||
KeGetCurrentThread()->Header.DebugActive =
|
||||
(BOOLEAN)NewMask;
|
||||
KeGetCurrentThread()->Header.DebugActive = (UCHAR)NewMask;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,11 +282,11 @@ Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
|
|||
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))
|
||||
{
|
||||
|
@ -324,17 +294,17 @@ Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
|
|||
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);
|
||||
}
|
||||
|
@ -352,7 +322,6 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
BOOLEAN V86Switch = FALSE;
|
||||
KIRQL OldIrql;
|
||||
ULONG DrMask = 0;
|
||||
PVOID SafeDr;
|
||||
|
||||
/* Do this at APC_LEVEL */
|
||||
OldIrql = KeGetCurrentIrql();
|
||||
|
@ -584,26 +553,35 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
}
|
||||
|
||||
/* 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++)
|
||||
/* Copy Dr0 - Dr4 */
|
||||
TrapFrame->Dr0 = Context->Dr0;
|
||||
TrapFrame->Dr1 = Context->Dr1;
|
||||
TrapFrame->Dr2 = Context->Dr2;
|
||||
TrapFrame->Dr3 = Context->Dr3;
|
||||
|
||||
/* If we're in user-mode */
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
/* Sanitize the context DR Address */
|
||||
SafeDr = Ke386SanitizeDr(KiDrFromContext(i, Context), PreviousMode);
|
||||
|
||||
/* Save it in the trap frame */
|
||||
*KiDrFromTrapFrame(i, TrapFrame) = SafeDr;
|
||||
|
||||
/* Check if this DR address is active and add it in the DR mask */
|
||||
if (SafeDr) DrMask |= DR_MASK(i);
|
||||
/* 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);
|
||||
|
||||
|
@ -611,7 +589,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
|
|||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
/* Save the mask */
|
||||
KeGetCurrentThread()->Header.DebugActive = (DrMask != 0);
|
||||
KeGetCurrentThread()->Header.DebugActive = (UCHAR)DrMask;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -962,7 +940,7 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
|
|||
/* 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
|
||||
|
@ -1132,7 +1110,7 @@ KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
|
|||
ExceptionRecord.ExceptionInformation[1] = Parameter2;
|
||||
ExceptionRecord.ExceptionInformation[2] = Parameter3;
|
||||
}
|
||||
|
||||
|
||||
/* Now go dispatch the exception */
|
||||
KiDispatchException(&ExceptionRecord,
|
||||
NULL,
|
||||
|
|
|
@ -50,6 +50,9 @@ PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler;
|
|||
PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
|
||||
PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
|
||||
#endif
|
||||
#if TRAP_DEBUG
|
||||
BOOLEAN StopChecking = FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
/* TRAP EXIT CODE *************************************************************/
|
||||
|
@ -86,12 +89,9 @@ KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
|
|||
{
|
||||
/* Disable interrupts until we return */
|
||||
_disable();
|
||||
|
||||
|
||||
/* Check for APC delivery */
|
||||
KiCheckForApcDelivery(TrapFrame);
|
||||
|
||||
/* Debugging checks */
|
||||
KiExitTrapDebugChecks(TrapFrame, SkipPreviousMode);
|
||||
|
||||
/* Restore the SEH handler chain */
|
||||
KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
|
||||
|
@ -99,11 +99,17 @@ KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
|
|||
/* Check if there are active debug registers */
|
||||
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
|
||||
{
|
||||
/* Not handled yet */
|
||||
DbgPrint("Need Hardware Breakpoint Support!\n");
|
||||
DbgBreakPoint();
|
||||
while (TRUE);
|
||||
/* Check if the frame was from user mode or v86 mode */
|
||||
if ((TrapFrame->SegCs & MODE_MASK) ||
|
||||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
|
||||
{
|
||||
/* Handle debug registers */
|
||||
KiHandleDebugRegistersOnTrapExit(TrapFrame);
|
||||
}
|
||||
}
|
||||
|
||||
/* Debugging checks */
|
||||
KiExitTrapDebugChecks(TrapFrame, SkipPreviousMode);
|
||||
}
|
||||
|
||||
DECLSPEC_NORETURN
|
||||
|
@ -841,7 +847,7 @@ KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
|
||||
/* Check for VDM trap */
|
||||
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
|
||||
|
||||
|
||||
/* Kill the system */
|
||||
KiSystemFatalException(EXCEPTION_INVALID_TSS, TrapFrame);
|
||||
}
|
||||
|
@ -1068,7 +1074,7 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: The ASM trap exit code would restore segment registers by doing
|
||||
* a POP <SEG>, which could cause an invalid segment if someone had messed
|
||||
|
@ -1524,12 +1530,18 @@ KiSystemCall(IN PKTRAP_FRAME TrapFrame,
|
|||
TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
|
||||
KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
|
||||
/* Clear DR7 and check for debugging */
|
||||
/* Default to debugging disabled */
|
||||
TrapFrame->Dr7 = 0;
|
||||
if (__builtin_expect(Thread->Header.DebugActive & 0xFF, 0))
|
||||
|
||||
/* Check if the frame was from user mode */
|
||||
if (TrapFrame->SegCs & MODE_MASK)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
/* Check for active debugging */
|
||||
if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
|
||||
{
|
||||
/* Handle debug registers */
|
||||
KiHandleDebugRegistersOnTrapEntry(TrapFrame);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set thread fields */
|
||||
|
|
|
@ -528,10 +528,7 @@ KiEnterV86Mode(IN PKV8086_STACK_FRAME StackFrame)
|
|||
TrapFrame->Dr7 = 0;
|
||||
|
||||
/* Set some debug fields if trap debugging is enabled */
|
||||
#if TRAP_DEBUG
|
||||
TrapFrame->DbgArgMark = 0xBADB0D00;
|
||||
TrapFrame->PreviousPreviousMode = -1;
|
||||
#endif
|
||||
KiFillTrapFrameDebug(TrapFrame);
|
||||
|
||||
/* Disable interrupts */
|
||||
_disable();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue