/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
+#include "kdb.h"
/* TYPES *********************************************************************/
/* DEFINES *******************************************************************/
#define KDB_STACK_SIZE (4096*3)
+#ifdef _M_AMD64
+#define KDB_STACK_ALIGN 16
+#define KDB_STACK_RESERVE (5 * sizeof(PVOID)) /* Home space + return address */
+#else
+#define KDB_STACK_ALIGN 4
+#define KDB_STACK_RESERVE sizeof(ULONG) /* Return address */
+#endif
#define KDB_MAXIMUM_BREAKPOINT_COUNT 256
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT 4
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT 256
/* GLOBALS *******************************************************************/
static LONG KdbEntryCount = 0;
-static CHAR KdbStack[KDB_STACK_SIZE];
+static DECLSPEC_ALIGN(KDB_STACK_ALIGN) CHAR KdbStack[KDB_STACK_SIZE];
static ULONG KdbBreakPointCount = 0; /* Number of used breakpoints in the array */
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT] = {{0}}; /* Breakpoint array */
LONG KdbLastBreakPointNr = -1; /* Index of the breakpoint which cause KDB to be entered */
ULONG KdbNumSingleSteps = 0; /* How many single steps to do */
BOOLEAN KdbSingleStepOver = FALSE; /* Whether to step over calls/reps. */
-ULONG KdbDebugState = 0; /* KDBG Settings (NOECHO, KDSERIAL) */
static BOOLEAN KdbEnteredOnSingleStep = FALSE; /* Set to true when KDB was entered because of single step */
PEPROCESS KdbCurrentProcess = NULL; /* The current process context in which KDB runs */
PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context KDB was intered */
PETHREAD KdbCurrentThread = NULL; /* The current thread context in which KDB runs */
PETHREAD KdbOriginalThread = NULL; /* The thread in whichs context KDB was entered */
PKDB_KTRAP_FRAME KdbCurrentTrapFrame = NULL; /* Pointer to the current trapframe */
-static KDB_KTRAP_FRAME KdbTrapFrame = { { 0 } }; /* The trapframe which was passed to KdbEnterDebuggerException */
-static KDB_KTRAP_FRAME KdbThreadTrapFrame = { { 0 } }; /* The trapframe of the current thread (KdbCurrentThread) */
+static KDB_KTRAP_FRAME KdbTrapFrame = { 0 }; /* The trapframe which was passed to KdbEnterDebuggerException */
+static KDB_KTRAP_FRAME KdbThreadTrapFrame = { 0 }; /* The trapframe of the current thread (KdbCurrentThread) */
static KAPC_STATE KdbApcState;
extern BOOLEAN KdbpBugCheckRequested;
"Assertion Failure"
};
-ULONG
-NTAPI
-KiSsFromTrapFrame(
- IN PKTRAP_FRAME TrapFrame);
-
-ULONG
-NTAPI
-KiEspFromTrapFrame(
- IN PKTRAP_FRAME TrapFrame);
-
-VOID
-NTAPI
-KiSsToTrapFrame(
- IN PKTRAP_FRAME TrapFrame,
- IN ULONG Ss);
-
-VOID
-NTAPI
-KiEspToTrapFrame(
- IN PKTRAP_FRAME TrapFrame,
- IN ULONG Esp);
-
/* FUNCTIONS *****************************************************************/
-static VOID
-KdbpTrapFrameToKdbTrapFrame(
- PCONTEXT Context,
- PKTRAP_FRAME TrapFrame,
- PKDB_KTRAP_FRAME KdbTrapFrame)
-{
- if (Context)
- {
- KdbTrapFrame->Tf = *Context;
- }
- else
- {
- ASSERT(TrapFrame);
-
- RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME));
- KdbTrapFrame->Tf.Dr0 = TrapFrame->Dr0;
- KdbTrapFrame->Tf.Dr1 = TrapFrame->Dr1;
- KdbTrapFrame->Tf.Dr2 = TrapFrame->Dr2;
- KdbTrapFrame->Tf.Dr3 = TrapFrame->Dr3;
- KdbTrapFrame->Tf.Dr6 = TrapFrame->Dr6;
- KdbTrapFrame->Tf.Dr7 = TrapFrame->Dr7;
- KdbTrapFrame->Tf.SegGs = TrapFrame->SegGs;
- KdbTrapFrame->Tf.SegEs = TrapFrame->SegEs;
- KdbTrapFrame->Tf.SegDs = TrapFrame->SegDs;
- KdbTrapFrame->Tf.Edx = TrapFrame->Edx;
- KdbTrapFrame->Tf.Ecx = TrapFrame->Ecx;
- KdbTrapFrame->Tf.Eax = TrapFrame->Eax;
- KdbTrapFrame->Tf.SegFs = TrapFrame->SegFs;
- KdbTrapFrame->Tf.Edi = TrapFrame->Edi;
- KdbTrapFrame->Tf.Esi = TrapFrame->Esi;
- KdbTrapFrame->Tf.Ebx = TrapFrame->Ebx;
- KdbTrapFrame->Tf.Ebp = TrapFrame->Ebp;
- KdbTrapFrame->Tf.Eip = TrapFrame->Eip;
- KdbTrapFrame->Tf.SegCs = TrapFrame->SegCs;
- KdbTrapFrame->Tf.EFlags = TrapFrame->EFlags;
- KdbTrapFrame->Tf.Esp = KiEspFromTrapFrame(TrapFrame);
- KdbTrapFrame->Tf.SegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
-
- KdbTrapFrame->Cr0 = __readcr0();
- KdbTrapFrame->Cr2 = __readcr2();
- KdbTrapFrame->Cr3 = __readcr3();
- KdbTrapFrame->Cr4 = __readcr4();
-
- /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
- }
-}
-
-static VOID
-KdbpKdbTrapFrameToTrapFrame(
- PKDB_KTRAP_FRAME KdbTrapFrame,
- PCONTEXT Context,
- PKTRAP_FRAME TrapFrame)
-{
- if (Context)
- {
- /* Update context */
- *Context = KdbTrapFrame->Tf;
- }
-
- if (TrapFrame)
- {
- TrapFrame->Dr0 = KdbTrapFrame->Tf.Dr0;
- TrapFrame->Dr1 = KdbTrapFrame->Tf.Dr1;
- TrapFrame->Dr2 = KdbTrapFrame->Tf.Dr2;
- TrapFrame->Dr3 = KdbTrapFrame->Tf.Dr3;
- TrapFrame->Dr6 = KdbTrapFrame->Tf.Dr6;
- TrapFrame->Dr7 = KdbTrapFrame->Tf.Dr7;
- TrapFrame->SegGs = KdbTrapFrame->Tf.SegGs;
- TrapFrame->SegEs = KdbTrapFrame->Tf.SegEs;
- TrapFrame->SegDs = KdbTrapFrame->Tf.SegDs;
- TrapFrame->Edx = KdbTrapFrame->Tf.Edx;
- TrapFrame->Ecx = KdbTrapFrame->Tf.Ecx;
- TrapFrame->Eax = KdbTrapFrame->Tf.Eax;
- TrapFrame->SegFs = KdbTrapFrame->Tf.SegFs;
- TrapFrame->Edi = KdbTrapFrame->Tf.Edi;
- TrapFrame->Esi = KdbTrapFrame->Tf.Esi;
- TrapFrame->Ebx = KdbTrapFrame->Tf.Ebx;
- TrapFrame->Ebp = KdbTrapFrame->Tf.Ebp;
- TrapFrame->Eip = KdbTrapFrame->Tf.Eip;
- TrapFrame->SegCs = KdbTrapFrame->Tf.SegCs;
- TrapFrame->EFlags = KdbTrapFrame->Tf.EFlags;
- KiSsToTrapFrame(TrapFrame, KdbTrapFrame->Tf.SegSs);
- KiEspToTrapFrame(TrapFrame, KdbTrapFrame->Tf.Esp);
-
- /* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
-
- /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
- }
-}
-
static VOID
KdbpKdbTrapFrameFromKernelStack(
PVOID KernelStack,
RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME));
StackPtr = (ULONG_PTR *) KernelStack;
#ifdef _M_IX86
- KdbTrapFrame->Tf.Ebp = StackPtr[3];
- KdbTrapFrame->Tf.Edi = StackPtr[4];
- KdbTrapFrame->Tf.Esi = StackPtr[5];
- KdbTrapFrame->Tf.Ebx = StackPtr[6];
- KdbTrapFrame->Tf.Eip = StackPtr[7];
- KdbTrapFrame->Tf.Esp = (ULONG) (StackPtr + 8);
- KdbTrapFrame->Tf.SegSs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegCs = KGDT_R0_CODE;
- KdbTrapFrame->Tf.SegDs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegEs = KGDT_R0_DATA;
- KdbTrapFrame->Tf.SegGs = KGDT_R0_DATA;
+ KdbTrapFrame->Ebp = StackPtr[3];
+ KdbTrapFrame->Edi = StackPtr[4];
+ KdbTrapFrame->Esi = StackPtr[5];
+ KdbTrapFrame->Ebx = StackPtr[6];
+ KdbTrapFrame->Eip = StackPtr[7];
+ KdbTrapFrame->Esp = (ULONG) (StackPtr + 8);
+ KdbTrapFrame->SegSs = KGDT_R0_DATA;
+ KdbTrapFrame->SegCs = KGDT_R0_CODE;
+ KdbTrapFrame->SegDs = KGDT_R0_DATA;
+ KdbTrapFrame->SegEs = KGDT_R0_DATA;
+ KdbTrapFrame->SegGs = KGDT_R0_DATA;
#endif
/* FIXME: what about the other registers??? */
/* Detach from process */
if (CurrentProcess != Process)
{
- KeDetachProcess();
+ KeUnstackDetachProcess(&ApcState);
}
return Status;
if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
{
- KdbpPrint("Couldn't access memory at 0x%p\n", Eip);
+ KdbPrintf("Couldn't access memory at 0x%p\n", Eip);
return FALSE;
}
/* Read memory */
if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
{
- /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
+ // KdbPrintf("Couldn't access memory at 0x%p\n", Eip);
return FALSE;
}
IntVect = 3;
else if (Mem[0] == 0xcd)
IntVect = Mem[1];
- else if (Mem[0] == 0xce && KdbCurrentTrapFrame->Tf.EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
+ else if (Mem[0] == 0xce && KdbCurrentTrapFrame->EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
IntVect = 4;
else
return FALSE;
__sidt(&Idtr.Limit);
if (IntVect >= (Idtr.Limit + 1) / 8)
{
- /*KdbpPrint("IDT does not contain interrupt vector %d\n.", IntVect);*/
+ // KdbPrintf("IDT does not contain interrupt vector %d.\n", IntVect);
return TRUE;
}
/* Get the interrupt descriptor */
- if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(ULONG_PTR)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
+ if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)((ULONG_PTR)Idtr.Base + (IntVect * 8)), sizeof(IntDesc))))
{
- /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
+ // KdbPrintf("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));
return FALSE;
}
IN BOOLEAN Global,
OUT PLONG BreakPointNr OPTIONAL)
{
- LONG i;
+ LONG_PTR i;
PVOID Condition;
PCHAR ConditionExpressionDup;
LONG ErrOffset;
{
if ((Address % Size) != 0)
{
- KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
+ KdbPrintf("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
return STATUS_UNSUCCESSFUL;
}
if (AccessType == KdbAccessExec && Size != 1)
{
- KdbpPrint("Size must be 1 for execution breakpoints.\n");
+ KdbPuts("Size must be 1 for execution breakpoints.\n");
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_UNSUCCESSFUL;
}
- /* Parse conditon expression string and duplicate it */
+ /* Parse condition expression string and duplicate it */
if (ConditionExpression)
{
Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
if (!Condition)
{
if (ErrOffset >= 0)
- KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
+ KdbPrintf("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
else
- KdbpPrint("Couldn't parse expression: %s", ErrMsg);
+ KdbPrintf("Couldn't parse expression: %s", ErrMsg);
return STATUS_UNSUCCESSFUL;
}
KdbBreakPointCount++;
if (Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d inserted.\n", i);
+ KdbPrintf("Breakpoint %d inserted.\n", i);
/* Try to enable the breakpoint */
KdbpEnableBreakPoint(i, NULL);
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
{
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ KdbPrintf("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
if (BreakPoint->Type == KdbBreakPointNone)
{
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ KdbPrintf("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
return FALSE;
if (BreakPoint->Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
+ KdbPrintf("Breakpoint %d deleted.\n", BreakPointNr);
BreakPoint->Type = KdbBreakPointNone;
KdbBreakPointCount--;
static LONG
KdbpIsBreakPointOurs(
IN NTSTATUS ExceptionCode,
- IN PKTRAP_FRAME TrapFrame)
+ IN PCONTEXT Context)
{
ULONG i;
ASSERT(ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT);
if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
{
- ULONG_PTR BpEip = (ULONG_PTR)TrapFrame->Eip - 1; /* Get EIP of INT3 instruction */
+ ULONG_PTR BpPc = KeGetContextPc(Context) - 1; /* Get EIP of INT3 instruction */
for (i = 0; i < KdbSwBreakPointCount; i++)
{
ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
ASSERT(KdbSwBreakPoints[i]->Enabled);
- if (KdbSwBreakPoints[i]->Address == BpEip)
+ if (KdbSwBreakPoints[i]->Address == BpPc)
{
return KdbSwBreakPoints[i] - KdbBreakPoints;
}
KdbHwBreakPoints[i]->Enabled);
DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
- if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
+ if ((Context->Dr6 & ((ULONG_PTR)1 << DebugReg)) != 0)
{
return KdbHwBreakPoints[i] - KdbBreakPoints;
}
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
{
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ KdbPrintf("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
if (BreakPoint->Type == KdbBreakPointNone)
{
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ KdbPrintf("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
if (BreakPoint->Enabled)
{
- KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
+ KdbPrintf("Breakpoint %d is already enabled.\n", BreakPointNr);
return TRUE;
}
{
if (KdbSwBreakPointCount >= KDB_MAXIMUM_SW_BREAKPOINT_COUNT)
{
- KdbpPrint("Maximum number of SW breakpoints (%d) used. "
+ KdbPrintf("Maximum number of SW breakpoints (%d) used. "
"Disable another breakpoint in order to enable this one.\n",
KDB_MAXIMUM_SW_BREAKPOINT_COUNT);
return FALSE;
0xCC, &BreakPoint->Data.SavedInstruction);
if (!NT_SUCCESS(Status))
{
- KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
+ KdbPrintf("Couldn't access memory at 0x%p\n", BreakPoint->Address);
return FALSE;
}
if (KdbHwBreakPointCount >= KDB_MAXIMUM_HW_BREAKPOINT_COUNT)
{
- KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
+ KdbPrintf("Maximum number of HW breakpoints (%d) already used. "
"Disable another breakpoint in order to enable this one.\n",
KDB_MAXIMUM_HW_BREAKPOINT_COUNT);
-
return FALSE;
}
ASSERT(KDB_MAXIMUM_HW_BREAKPOINT_COUNT == 4);
for (i = 0; i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT; i++)
{
- if ((KdbTrapFrame.Tf.Dr7 & (0x3 << (i * 2))) == 0)
+ if ((KdbTrapFrame.Dr7 & (0x3 << (i * 2))) == 0)
break;
}
switch (i)
{
case 0:
- KdbTrapFrame.Tf.Dr0 = BreakPoint->Address;
+ KdbTrapFrame.Dr0 = BreakPoint->Address;
break;
case 1:
- KdbTrapFrame.Tf.Dr1 = BreakPoint->Address;
+ KdbTrapFrame.Dr1 = BreakPoint->Address;
break;
case 2:
- KdbTrapFrame.Tf.Dr2 = BreakPoint->Address;
+ KdbTrapFrame.Dr2 = BreakPoint->Address;
break;
case 3:
- KdbTrapFrame.Tf.Dr3 = BreakPoint->Address;
+ KdbTrapFrame.Dr3 = BreakPoint->Address;
break;
}
/* Enable the global breakpoint */
- KdbTrapFrame.Tf.Dr7 |= (0x2 << (i * 2));
+ KdbTrapFrame.Dr7 |= (0x2 << (i * 2));
/* Enable the exact match bits. */
- KdbTrapFrame.Tf.Dr7 |= 0x00000300;
+ KdbTrapFrame.Dr7 |= 0x00000300;
/* Clear existing state. */
- KdbTrapFrame.Tf.Dr7 &= ~(0xF << (16 + (i * 4)));
+ KdbTrapFrame.Dr7 &= ~(0xF << (16 + (i * 4)));
/* Set the breakpoint type. */
switch (BreakPoint->Data.Hw.AccessType)
break;
}
- KdbTrapFrame.Tf.Dr7 |= (ul << (16 + (i * 4)));
+ KdbTrapFrame.Dr7 |= (ul << (16 + (i * 4)));
/* Set the breakpoint length. */
- KdbTrapFrame.Tf.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
+ KdbTrapFrame.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
/* Update KdbCurrentTrapFrame - values are taken from there by the CLI */
if (&KdbTrapFrame != KdbCurrentTrapFrame)
{
- KdbCurrentTrapFrame->Tf.Dr0 = KdbTrapFrame.Tf.Dr0;
- KdbCurrentTrapFrame->Tf.Dr1 = KdbTrapFrame.Tf.Dr1;
- KdbCurrentTrapFrame->Tf.Dr2 = KdbTrapFrame.Tf.Dr2;
- KdbCurrentTrapFrame->Tf.Dr3 = KdbTrapFrame.Tf.Dr3;
- KdbCurrentTrapFrame->Tf.Dr6 = KdbTrapFrame.Tf.Dr6;
- KdbCurrentTrapFrame->Tf.Dr7 = KdbTrapFrame.Tf.Dr7;
+ KdbCurrentTrapFrame->Dr0 = KdbTrapFrame.Dr0;
+ KdbCurrentTrapFrame->Dr1 = KdbTrapFrame.Dr1;
+ KdbCurrentTrapFrame->Dr2 = KdbTrapFrame.Dr2;
+ KdbCurrentTrapFrame->Dr3 = KdbTrapFrame.Dr3;
+ KdbCurrentTrapFrame->Dr6 = KdbTrapFrame.Dr6;
+ KdbCurrentTrapFrame->Dr7 = KdbTrapFrame.Dr7;
}
BreakPoint->Data.Hw.DebugReg = i;
BreakPoint->Enabled = TRUE;
if (BreakPoint->Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
+ KdbPrintf("Breakpoint %d enabled.\n", BreakPointNr);
return TRUE;
}
if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
{
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ KdbPrintf("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
if (BreakPoint->Type == KdbBreakPointNone)
{
- KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
+ KdbPrintf("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
if (BreakPoint->Enabled == FALSE)
{
- KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr);
+ KdbPrintf("Breakpoint %d is not enabled.\n", BreakPointNr);
return TRUE;
}
if (!NT_SUCCESS(Status))
{
- KdbpPrint("Couldn't restore original instruction.\n");
+ KdbPuts("Couldn't restore original instruction.\n");
return FALSE;
}
ASSERT(BreakPoint->Type == KdbBreakPointHardware);
/* Clear the breakpoint. */
- KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
- if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
+ KdbTrapFrame.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
+ if ((KdbTrapFrame.Dr7 & 0xFF) == 0)
{
/* If no breakpoints are enabled then clear the exact match flags. */
- KdbTrapFrame.Tf.Dr7 &= 0xFFFFFCFF;
+ KdbTrapFrame.Dr7 &= 0xFFFFFCFF;
}
for (i = 0; i < KdbHwBreakPointCount; i++)
BreakPoint->Enabled = FALSE;
if (BreakPoint->Type != KdbBreakPointTemporary)
- KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
+ KdbPrintf("Breakpoint %d disabled.\n", BreakPointNr);
return TRUE;
}
KbdDisableMouse();
- if (KdpDebugMode.Screen &&
- InbvIsBootDriverInstalled() &&
- !InbvCheckDisplayOwnership())
- {
- /* Acquire ownership and reset the display */
- InbvAcquireDisplayOwnership();
- InbvResetDisplay();
-
- /* Display debugger prompt */
- InbvSolidColorFill(0, 0, 639, 479, 0);
- InbvSetTextColor(15);
- InbvInstallDisplayStringFilter(NULL);
- InbvEnableDisplayString(TRUE);
- InbvSetScrollRegion(0, 0, 639, 479);
- }
+ /* Take control of the display */
+ if (KdpDebugMode.Screen)
+ KdpScreenAcquire();
/* Call the interface's main loop on a different stack */
Thread = PsGetCurrentThread();
Thread->Tcb.StackLimit = (ULONG_PTR)KdbStack;
Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
- /*KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);*/
+ // KdbPrintf("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);
- KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
+ KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - KDB_STACK_RESERVE, KdbpCallMainLoop);
Thread->Tcb.InitialStack = SavedInitialStack;
Thread->Tcb.StackBase = SavedStackBase;
Thread->Tcb.StackLimit = SavedStackLimit;
Thread->Tcb.KernelStack = SavedKernelStack;
+
+ /* Release the display */
+ if (KdpDebugMode.Screen)
+ KdpScreenRelease();
+
KbdEnableMouse();
}
*/
KD_CONTINUE_TYPE
KdbEnterDebuggerException(
- IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
+ IN PEXCEPTION_RECORD64 ExceptionRecord,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT Context,
- IN OUT PKTRAP_FRAME InitialTrapFrame,
IN BOOLEAN FirstChance)
{
- PKTRAP_FRAME TrapFrame = InitialTrapFrame;
KDB_ENTER_CONDITION EnterCondition;
KD_CONTINUE_TYPE ContinueType = kdHandleException;
PKDB_BREAKPOINT BreakPoint;
EnterConditionMet = FALSE;
}
- /* If we stopped on one of our breakpoints then let the user know. */
+ /* If we stopped on one of our breakpoints then let the user know */
KdbLastBreakPointNr = -1;
KdbEnteredOnSingleStep = FALSE;
if (FirstChance && (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) &&
- (KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExceptionCode, TrapFrame)) >= 0)
+ (KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExceptionCode, Context)) >= 0)
{
BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
if (ExceptionCode == STATUS_BREAKPOINT)
{
- /* ... and restore the original instruction. */
+ /* ... and restore the original instruction */
if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address,
BreakPoint->Data.SavedInstruction, NULL)))
{
- KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
+ KdbPuts("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
KeBugCheck(0); // FIXME: Proper bugcode!
}
KiDispatchException accounts for that. Whatever we do here with
the TrapFrame does not matter anyway, since KiDispatchException
will overwrite it with the values from the Context! */
- TrapFrame->Eip--;
+ KeSetContextPc(Context, KeGetContextPc(Context) - 1);
}
if ((BreakPoint->Type == KdbBreakPointHardware) &&
else if (BreakPoint->Type == KdbBreakPointTemporary &&
BreakPoint->Process == KdbCurrentProcess)
{
- ASSERT((TrapFrame->EFlags & EFLAGS_TF) == 0);
+ ASSERT((Context->EFlags & EFLAGS_TF) == 0);
- /* Delete the temporary breakpoint which was used to step over or into the instruction. */
+ /* Delete the temporary breakpoint which was used to step over or into the instruction */
KdbpDeleteBreakPoint(-1, BreakPoint);
if (--KdbNumSingleSteps > 0)
{
- if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
- (!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
+ if ((KdbSingleStepOver && !KdbpStepOverInstruction(KeGetContextPc(Context))) ||
+ (!KdbSingleStepOver && !KdbpStepIntoInstruction(KeGetContextPc(Context))))
{
Context->EFlags |= EFLAGS_TF;
}
if (BreakPoint->Condition)
{
/* Setup the KDB trap frame */
- KdbpTrapFrameToKdbTrapFrame(Context, InitialTrapFrame, &KdbTrapFrame);
+ KdbTrapFrame = *Context;
ull = 0;
if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
if (BreakPoint->Type == KdbBreakPointSoftware)
{
- KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
- KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
+ KdbPrintf("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%p\n",
+ KdbLastBreakPointNr, Context->SegCs & 0xffff, KeGetContextPc(Context));
}
else if (BreakPoint->Type == KdbBreakPointHardware)
{
- KdbpPrint("\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
+ KdbPrintf("\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
KdbLastBreakPointNr,
- (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
- ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
- ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")),
- BreakPoint->Address);
+ (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
+ ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
+ ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")),
+ BreakPoint->Address);
}
}
else if (ExceptionCode == STATUS_SINGLE_STEP)
{
/* Silently ignore a debugger initiated single step. */
- if ((TrapFrame->Dr6 & 0xf) == 0 && KdbBreakPointToReenable)
+ if ((Context->Dr6 & 0xf) == 0 && KdbBreakPointToReenable)
{
/* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
BreakPoint = KdbBreakPointToReenable;
if (!NT_SUCCESS(KdbpOverwriteInstruction(KdbCurrentProcess, BreakPoint->Address, 0xCC,
&BreakPoint->Data.SavedInstruction)))
{
- KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
+ KdbPrintf("Warning: Couldn't reenable breakpoint %d\n",
BreakPoint - KdbBreakPoints);
}
KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = FALSE;
/* Check if we expect a single step */
- if ((TrapFrame->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
+ if ((Context->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
{
/*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
if (--KdbNumSingleSteps > 0)
{
- if ((KdbSingleStepOver && KdbpStepOverInstruction(TrapFrame->Eip)) ||
- (!KdbSingleStepOver && KdbpStepIntoInstruction(TrapFrame->Eip)))
+ if ((KdbSingleStepOver && KdbpStepOverInstruction(KeGetContextPc(Context))) ||
+ (!KdbSingleStepOver && KdbpStepIntoInstruction(KeGetContextPc(Context))))
{
Context->EFlags &= ~EFLAGS_TF;
}
return kdHandleException;
}
- KdbpPrint("\nEntered debugger on unexpected debug trap!\n");
+ KdbPuts("\nEntered debugger on unexpected debug trap!\n");
}
}
else if (ExceptionCode == STATUS_BREAKPOINT)
return kdHandleException;
}
- KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
- TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
+ KdbPrintf("\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
+ Context->SegCs & 0xffff, KeGetContextPc(Context));
}
else
{
const CHAR *ExceptionString = (ExpNr < RTL_NUMBER_OF(ExceptionNrToString)) ?
- (ExceptionNrToString[ExpNr]) :
- ("Unknown/User defined exception");
+ ExceptionNrToString[ExpNr] :
+ "Unknown/User defined exception";
if (!EnterConditionMet)
{
return ContinueType;
}
- KdbpPrint("\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
+ KdbPrintf("\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
if (ExceptionCode == STATUS_ACCESS_VIOLATION &&
ExceptionRecord && ExceptionRecord->NumberParameters != 0)
{
- /* FIXME: Add noexec memory stuff */
- ULONG_PTR TrapCr2;
- ULONG Err;
-
- TrapCr2 = __readcr2();
-
- Err = TrapFrame->ErrCode;
- KdbpPrint("Memory at 0x%p could not be %s: ", TrapCr2, (Err & (1 << 1)) ? "written" : "read");
-
- if ((Err & (1 << 0)) == 0)
- {
- KdbpPrint("Page not present.\n");
- }
- else
- {
- if ((Err & (1 << 3)) != 0)
- KdbpPrint("Reserved bits in page directory set.\n");
- else
- KdbpPrint("Page protection violation.\n");
- }
+ ULONG_PTR TrapCr2 = __readcr2();
+ KdbPrintf("Memory at 0x%p could not be accessed\n", TrapCr2);
}
}
KdbCurrentTrapFrame = &KdbTrapFrame;
/* Setup the KDB trap frame */
- KdbpTrapFrameToKdbTrapFrame(Context, InitialTrapFrame, &KdbTrapFrame);
+ KdbTrapFrame = *Context;
/* Enter critical section */
OldEflags = __readeflags();
_disable();
- /* HACK: Save the current IRQL and pretend we are at passive level,
- * although interrupts are off. Needed because KDBG calls pageable code. */
+ /* HACK: Save the current IRQL and pretend we are at dispatch level */
OldIrql = KeGetCurrentIrql();
- KeLowerIrql(PASSIVE_LEVEL);
+ if (OldIrql > DISPATCH_LEVEL)
+ KeLowerIrql(DISPATCH_LEVEL);
/* Exception inside the debugger? Game over. */
if (InterlockedIncrement(&KdbEntryCount) > 1)
return kdHandleException;
}
- /* Call the main loop. */
+ /* Call the main loop */
KdbpInternalEnter();
/* Check if we should single step */
/* Variable explains itself! */
KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
- if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
- (!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
+ if ((KdbSingleStepOver && KdbpStepOverInstruction(KeGetContextPc(KdbCurrentTrapFrame))) ||
+ (!KdbSingleStepOver && KdbpStepIntoInstruction(KeGetContextPc(KdbCurrentTrapFrame))))
{
- ASSERT((KdbCurrentTrapFrame->Tf.EFlags & EFLAGS_TF) == 0);
- /*KdbCurrentTrapFrame->Tf.EFlags &= ~EFLAGS_TF;*/
+ ASSERT((KdbCurrentTrapFrame->EFlags & EFLAGS_TF) == 0);
+ /*KdbCurrentTrapFrame->EFlags &= ~EFLAGS_TF;*/
}
else
{
- Context->EFlags |= EFLAGS_TF;
+ KdbTrapFrame.EFlags |= EFLAGS_TF;
}
}
KeUnstackDetachProcess(&KdbApcState);
}
- /* Update the exception Context/TrapFrame */
- KdbpKdbTrapFrameToTrapFrame(&KdbTrapFrame, Context, InitialTrapFrame);
+ /* Update the exception Context */
+ *Context = KdbTrapFrame;
/* Decrement the entry count */
InterlockedDecrement(&KdbEntryCount);
/* HACK: Raise back to old IRQL */
- KeRaiseIrql(OldIrql, &OldIrql);
+ if (OldIrql > DISPATCH_LEVEL)
+ KeRaiseIrql(OldIrql, &OldIrql);
/* Leave critical section */
__writeeflags(OldEflags);
/* Set the RF flag so we don't trigger the same breakpoint again. */
if (Resume)
{
- TrapFrame->EFlags |= EFLAGS_RF;
+ Context->EFlags |= EFLAGS_RF;
}
/* Clear dr6 status flags. */
- TrapFrame->Dr6 &= ~0x0000e00f;
+ Context->Dr6 &= ~0x0000e00f;
if (!(KdbEnteredOnSingleStep && KdbSingleStepOver))
{
/* Skip the current instruction */
- Context->Eip++;
+ KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
}
}
}
VOID
-NTAPI
-INIT_FUNCTION
KdbpGetCommandLineSettings(
- PCHAR p1)
+ _In_ PCSTR p1)
{
#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
- while (p1 && (p1 = strchr(p1, ' ')))
+ while (p1 && *p1)
{
- /* Skip other spaces */
+ /* Skip leading whitespace */
while (*p1 == ' ') ++p1;
- if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
- {
- p1 += CONST_STR_LEN("KDSERIAL");
- KdbDebugState |= KD_DEBUG_KDSERIAL;
- KdpDebugMode.Serial = TRUE;
- }
- else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
- {
- p1 += CONST_STR_LEN("KDNOECHO");
- KdbDebugState |= KD_DEBUG_KDNOECHO;
- }
- else if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
+ if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
{
p1 += CONST_STR_LEN("FIRSTCHANCE");
KdbpSetEnterCondition(-1, TRUE, KdbEnterAlways);
}
+
+ /* Move on to the next option */
+ p1 = strchr(p1, ' ');
}
}
IN PVOID Src,
IN ULONG Bytes)
{
- BOOLEAN Result = TRUE;
-
- switch (Bytes)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- Result = KdpSafeReadMemory((ULONG_PTR)Src, Bytes, Dest);
- break;
-
- default:
- {
- ULONG_PTR Start, End, Write;
-
- for (Start = (ULONG_PTR)Src,
- End = Start + Bytes,
- Write = (ULONG_PTR)Dest;
- Result && (Start < End);
- Start++, Write++)
- if (!KdpSafeReadMemory(Start, 1, (PVOID)Write))
- Result = FALSE;
-
- break;
- }
- }
-
- return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
+ return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Src,
+ Dest,
+ Bytes,
+ 0,
+ MMDBG_COPY_UNSAFE,
+ NULL);
}
NTSTATUS
IN PVOID Src,
IN ULONG Bytes)
{
- BOOLEAN Result = TRUE;
- ULONG_PTR Start, End, Write;
-
- for (Start = (ULONG_PTR)Src,
- End = Start + Bytes,
- Write = (ULONG_PTR)Dest;
- Result && (Start < End);
- Start++, Write++)
- if (!KdpSafeWriteMemory(Write, 1, *((PCHAR)Start)))
- Result = FALSE;
-
- return Result ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
+ return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Dest,
+ Src,
+ Bytes,
+ 0,
+ MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+ NULL);
}