[NTOS:KD] Use a PCONTEXT instead of a PKTRAP_FRAME in KDBG

This commit is contained in:
Hervé Poussineau 2020-04-08 23:08:57 +02:00
parent ba37323a62
commit baa47fa5e0
7 changed files with 170 additions and 284 deletions

View file

@ -29,12 +29,17 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
{
KD_CONTINUE_TYPE Return = kdHandleException;
#ifdef KDBG
EXCEPTION_RECORD64 ExceptionRecord64;
/* Check if this is an assertion failure */
if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE)
{
/* Bump EIP to the instruction following the int 2C */
ContextRecord->Eip += 2;
}
ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord,
&ExceptionRecord64);
#endif
/* Get out of here if the Debugger isn't connected */
@ -42,10 +47,9 @@ KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
#ifdef KDBG
/* Call KDBG if available */
Return = KdbEnterDebuggerException(ExceptionRecord,
Return = KdbEnterDebuggerException(&ExceptionRecord64,
PreviousMode,
ContextRecord,
TrapFrame,
!SecondChanceException);
#else /* not KDBG */
/* We'll manually dump the stack for the user... */

View file

@ -2,7 +2,7 @@
#include <asm.inc>
#include <ks386.inc>
EXTERN _KdbEnterDebuggerException:PROC
EXTERN _KdbEnterDebuggerFirstChanceException:PROC
.code
@ -61,12 +61,8 @@ _KdbEnter:
* Call KDB
*/
mov eax, esp
push 1 /* FirstChance */
push eax /* Push a pointer to the trap frame */
push 0 /* Context */
push 0 /* PreviousMode (KernelMode) */
push 0 /* ExceptionRecord */
call _KdbEnterDebuggerException
call _KdbEnterDebuggerFirstChanceException
/*
* Pop the arguments and unused portions of the trap frame:

View file

@ -49,8 +49,8 @@ PEPROCESS KdbOriginalProcess = NULL; /* The process in whichs context KDB was in
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;
@ -108,68 +108,8 @@ static const CHAR *ExceptionNrToString[] =
"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(
PKTRAP_FRAME TrapFrame,
PKDB_KTRAP_FRAME KdbTrapFrame)
{
/* Copy the TrapFrame only up to Eflags and zero the rest*/
RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
RtlZeroMemory((PVOID)((ULONG_PTR)&KdbTrapFrame->Tf + FIELD_OFFSET(KTRAP_FRAME, HardwareEsp)),
sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
KdbTrapFrame->Cr0 = __readcr0();
KdbTrapFrame->Cr2 = __readcr2();
KdbTrapFrame->Cr3 = __readcr3();
KdbTrapFrame->Cr4 = __readcr4();
KdbTrapFrame->Tf.HardwareEsp = KiEspFromTrapFrame(TrapFrame);
KdbTrapFrame->Tf.HardwareSegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) & 0xFFFF);
/* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
}
static VOID
KdbpKdbTrapFrameToTrapFrame(
PKDB_KTRAP_FRAME KdbTrapFrame,
PKTRAP_FRAME TrapFrame)
{
/* Copy the TrapFrame only up to Eflags and zero the rest*/
RtlCopyMemory(TrapFrame, &KdbTrapFrame->Tf, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
/* FIXME: write cr0, cr2, cr3 and cr4 (not needed atm) */
KiSsToTrapFrame(TrapFrame, KdbTrapFrame->Tf.HardwareSegSs);
KiEspToTrapFrame(TrapFrame, KdbTrapFrame->Tf.HardwareEsp);
/* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */
}
static VOID
KdbpKdbTrapFrameFromKernelStack(
PVOID KernelStack,
@ -180,17 +120,17 @@ KdbpKdbTrapFrameFromKernelStack(
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.HardwareEsp = (ULONG) (StackPtr + 8);
KdbTrapFrame->Tf.HardwareSegSs = 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??? */
@ -374,7 +314,7 @@ KdbpStepIntoInstruction(
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;
@ -703,14 +643,14 @@ KdbpDeleteBreakPoint(
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 BpEip = (ULONG_PTR)Context->Eip - 1; /* Get EIP of INT3 instruction */
for (i = 0; i < KdbSwBreakPointCount; i++)
{
ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
@ -733,7 +673,7 @@ KdbpIsBreakPointOurs(
KdbHwBreakPoints[i]->Enabled);
DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
if ((TrapFrame->Dr6 & (1 << DebugReg)) != 0)
if ((Context->Dr6 & (1 << DebugReg)) != 0)
{
return KdbHwBreakPoints[i] - KdbBreakPoints;
}
@ -832,7 +772,7 @@ KdbpEnableBreakPoint(
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;
}
@ -842,27 +782,27 @@ KdbpEnableBreakPoint(
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)
@ -883,20 +823,20 @@ KdbpEnableBreakPoint(
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;
@ -988,11 +928,11 @@ KdbpDisableBreakPoint(
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++)
@ -1316,10 +1256,9 @@ KdbpGetExceptionNumberFromStatus(
*/
KD_CONTINUE_TYPE
KdbEnterDebuggerException(
IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
IN PEXCEPTION_RECORD64 ExceptionRecord,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT Context,
IN OUT PKTRAP_FRAME TrapFrame,
IN BOOLEAN FirstChance)
{
KDB_ENTER_CONDITION EnterCondition;
@ -1361,7 +1300,7 @@ KdbEnterDebuggerException(
KdbEnteredOnSingleStep = FALSE;
if (FirstChance && (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) &&
(KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExceptionCode, TrapFrame)) >= 0)
(KdbLastBreakPointNr = KdbpIsBreakPointOurs(ExceptionCode, Context)) >= 0)
{
BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
@ -1382,7 +1321,7 @@ KdbEnterDebuggerException(
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--;
Context->Eip--;
}
if ((BreakPoint->Type == KdbBreakPointHardware) &&
@ -1399,15 +1338,15 @@ KdbEnterDebuggerException(
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 */
KdbpDeleteBreakPoint(-1, BreakPoint);
if (--KdbNumSingleSteps > 0)
{
if ((KdbSingleStepOver && !KdbpStepOverInstruction(TrapFrame->Eip)) ||
(!KdbSingleStepOver && !KdbpStepIntoInstruction(TrapFrame->Eip)))
if ((KdbSingleStepOver && !KdbpStepOverInstruction(Context->Eip)) ||
(!KdbSingleStepOver && !KdbpStepIntoInstruction(Context->Eip)))
{
Context->EFlags |= EFLAGS_TF;
}
@ -1440,7 +1379,7 @@ KdbEnterDebuggerException(
if (BreakPoint->Condition)
{
/* Setup the KDB trap frame */
KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
KdbTrapFrame = *Context;
ull = 0;
if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
@ -1456,7 +1395,7 @@ KdbEnterDebuggerException(
if (BreakPoint->Type == KdbBreakPointSoftware)
{
KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
KdbLastBreakPointNr, TrapFrame->SegCs & 0xffff, TrapFrame->Eip);
KdbLastBreakPointNr, Context->SegCs & 0xffff, Context->Eip);
}
else if (BreakPoint->Type == KdbBreakPointHardware)
{
@ -1471,7 +1410,7 @@ KdbEnterDebuggerException(
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;
@ -1504,13 +1443,13 @@ KdbEnterDebuggerException(
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(Context->Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(Context->Eip)))
{
Context->EFlags &= ~EFLAGS_TF;
}
@ -1550,7 +1489,7 @@ KdbEnterDebuggerException(
}
KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
TrapFrame->SegCs & 0xffff, TrapFrame->Eip - 1);
Context->SegCs & 0xffff, Context->Eip - 1);
}
else
{
@ -1569,26 +1508,11 @@ KdbEnterDebuggerException(
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");
}
KdbpPrint("Memory at 0x%p could not be accessed\n", TrapCr2);
}
}
@ -1601,7 +1525,7 @@ KdbEnterDebuggerException(
KdbCurrentTrapFrame = &KdbTrapFrame;
/* Setup the KDB trap frame */
KdbpTrapFrameToKdbTrapFrame(TrapFrame, &KdbTrapFrame);
KdbTrapFrame = *Context;
/* Enter critical section */
OldEflags = __readeflags();
@ -1628,15 +1552,15 @@ KdbEnterDebuggerException(
/* Variable explains itself! */
KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Tf.Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Tf.Eip)))
if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Eip)))
{
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;
}
}
@ -1648,8 +1572,8 @@ KdbEnterDebuggerException(
KeUnstackDetachProcess(&KdbApcState);
}
/* Update the exception TrapFrame */
KdbpKdbTrapFrameToTrapFrame(&KdbTrapFrame, TrapFrame);
/* Update the exception Context */
*Context = KdbTrapFrame;
/* Decrement the entry count */
InterlockedDecrement(&KdbEntryCount);
@ -1675,11 +1599,11 @@ continue_execution:
/* 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))
{
@ -1691,6 +1615,35 @@ continue_execution:
return ContinueType;
}
KD_CONTINUE_TYPE
KdbEnterDebuggerFirstChanceException(
IN OUT PKTRAP_FRAME TrapFrame)
{
EXCEPTION_RECORD64 ExceptionRecord;
KD_CONTINUE_TYPE Return;
CONTEXT Context;
/* Copy TrapFrame to Context */
RtlZeroMemory(&Context, sizeof(CONTEXT));
Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_EXTENDED_REGISTERS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
KeTrapFrameToContext(TrapFrame, NULL, &Context);
/* Create ExceptionRecord (assume breakpoint) */
RtlZeroMemory(&ExceptionRecord, sizeof(EXCEPTION_RECORD64));
ExceptionRecord.ExceptionCode = STATUS_BREAKPOINT;
/* Call real function */
Return = KdbEnterDebuggerException(&ExceptionRecord,
KernelMode,
&Context,
TRUE);
/* Copy back Context to TrapFrame */
KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
return Return;
}
VOID
NTAPI
KdbpGetCommandLineSettings(

View file

@ -10,15 +10,7 @@
/* TYPES *********************************************************************/
/* from kdb.c */
typedef struct _KDB_KTRAP_FRAME
{
KTRAP_FRAME Tf;
ULONG Cr0;
ULONG Cr1; /* reserved/unused */
ULONG Cr2;
ULONG Cr3;
ULONG Cr4;
} KDB_KTRAP_FRAME, *PKDB_KTRAP_FRAME;
typedef CONTEXT KDB_KTRAP_FRAME, *PKDB_KTRAP_FRAME;
typedef enum _KDB_BREAKPOINT_TYPE
{
@ -163,7 +155,7 @@ KdbpSymFindModule(
BOOLEAN
KdbSymPrintAddress(
IN PVOID Address,
IN PKTRAP_FRAME Context
IN PCONTEXT Context
);
VOID
@ -247,11 +239,15 @@ NTAPI
KdbpGetCommandLineSettings(PCHAR p1);
KD_CONTINUE_TYPE
KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
KPROCESSOR_MODE PreviousMode,
PCONTEXT Context,
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance);
KdbEnterDebuggerException(IN PEXCEPTION_RECORD64 ExceptionRecord,
IN KPROCESSOR_MODE PreviousMode,
IN OUT PCONTEXT Context,
IN BOOLEAN FirstChance);
KD_CONTINUE_TYPE
KdbEnterDebuggerFirstChanceException(
IN OUT PKTRAP_FRAME TrapFrame);
/* other functions */
NTSTATUS

View file

@ -345,7 +345,6 @@ static const struct
{ "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
{ "x", "x [address] [L count]", "Display count dwords, starting at address.", KdbpCmdDisassembleX },
{ "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
{ "cregs", "cregs", "Display control, descriptor table and task segment registers.", KdbpCmdRegs },
{ "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
{ "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
{ "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame address.", KdbpCmdBackTrace },
@ -794,7 +793,7 @@ KdbpCmdDisassembleX(
ULONG ul;
INT i;
ULONGLONG Result = 0;
ULONG_PTR Address = KdbCurrentTrapFrame->Tf.Eip;
ULONG_PTR Address = KdbCurrentTrapFrame->Eip;
LONG InstLen;
if (Argv[0][0] == 'x') /* display memory */
@ -911,7 +910,7 @@ KdbpCmdRegs(
ULONG Argc,
PCHAR Argv[])
{
PKTRAP_FRAME Tf = &KdbCurrentTrapFrame->Tf;
PCONTEXT Context = KdbCurrentTrapFrame;
INT i;
static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
" ZF", " SF", " TF", " IF", " DF", " OF",
@ -929,109 +928,51 @@ KdbpCmdRegs(
" ECX 0x%08x EDX 0x%08x\n"
" ESI 0x%08x EDI 0x%08x\n"
" EBP 0x%08x\n",
Tf->SegCs & 0xFFFF, Tf->Eip,
Tf->HardwareSegSs, Tf->HardwareEsp,
Tf->Eax, Tf->Ebx,
Tf->Ecx, Tf->Edx,
Tf->Esi, Tf->Edi,
Tf->Ebp);
Context->SegCs & 0xFFFF, Context->Eip,
Context->SegSs, Context->Esp,
Context->Eax, Context->Ebx,
Context->Ecx, Context->Edx,
Context->Esi, Context->Edi,
Context->Ebp);
/* Display the EFlags */
KdbpPrint("EFLAGS 0x%08x ", Tf->EFlags);
KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
for (i = 0; i < 32; i++)
{
if (i == 1)
{
if ((Tf->EFlags & (1 << 1)) == 0)
if ((Context->EFlags & (1 << 1)) == 0)
KdbpPrint(" !BIT1");
}
else if (i == 12)
{
KdbpPrint(" IOPL%d", (Tf->EFlags >> 12) & 3);
KdbpPrint(" IOPL%d", (Context->EFlags >> 12) & 3);
}
else if (i == 13)
{
}
else if ((Tf->EFlags & (1 << i)) != 0)
else if ((Context->EFlags & (1 << i)) != 0)
{
KdbpPrint(EflagsBits[i]);
}
}
KdbpPrint("\n");
}
else if (Argv[0][0] == 'c') /* cregs */
{
ULONG Cr0, Cr2, Cr3, Cr4;
KDESCRIPTOR Gdtr = {0, 0, 0}, Idtr = {0, 0, 0};
USHORT Ldtr, Tr;
static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
" WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
" PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
/* Retrieve the control registers */
Cr0 = KdbCurrentTrapFrame->Cr0;
Cr2 = KdbCurrentTrapFrame->Cr2;
Cr3 = KdbCurrentTrapFrame->Cr3;
Cr4 = KdbCurrentTrapFrame->Cr4;
/* Retrieve the descriptor table and task segment registers */
Ke386GetGlobalDescriptorTable(&Gdtr.Limit);
Ldtr = Ke386GetLocalDescriptorTable();
__sidt(&Idtr.Limit);
Tr = Ke386GetTr();
/* Display the control registers */
KdbpPrint("CR0 0x%08x ", Cr0);
for (i = 0; i < 32; i++)
{
if (!Cr0Bits[i])
continue;
if ((Cr0 & (1 << i)) != 0)
KdbpPrint(Cr0Bits[i]);
}
KdbpPrint("\n");
KdbpPrint("CR2 0x%08x\n", Cr2);
KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
(Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
KdbpPrint("CR4 0x%08x ", Cr4);
for (i = 0; i < 32; i++)
{
if (!Cr4Bits[i])
continue;
if ((Cr4 & (1 << i)) != 0)
KdbpPrint(Cr4Bits[i]);
}
KdbpPrint("\n");
/* Display the descriptor table and task segment registers */
KdbpPrint("GDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
KdbpPrint("LDTR 0x%04x\n", Ldtr);
KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit);
KdbpPrint("TR 0x%04x\n", Tr);
}
else if (Argv[0][0] == 's') /* sregs */
{
KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
Tf->SegCs & 0xffff, (Tf->SegCs & 0xffff) >> 3,
(Tf->SegCs & (1 << 2)) ? 'L' : 'G', Tf->SegCs & 3);
Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
(Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
Tf->SegDs, Tf->SegDs >> 3, (Tf->SegDs & (1 << 2)) ? 'L' : 'G', Tf->SegDs & 3);
Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
Tf->SegEs, Tf->SegEs >> 3, (Tf->SegEs & (1 << 2)) ? 'L' : 'G', Tf->SegEs & 3);
Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
Tf->SegFs, Tf->SegFs >> 3, (Tf->SegFs & (1 << 2)) ? 'L' : 'G', Tf->SegFs & 3);
Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
Tf->SegGs, Tf->SegGs >> 3, (Tf->SegGs & (1 << 2)) ? 'L' : 'G', Tf->SegGs & 3);
Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
Tf->HardwareSegSs, Tf->HardwareSegSs >> 3, (Tf->HardwareSegSs & (1 << 2)) ? 'L' : 'G', Tf->HardwareSegSs & 3);
Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
}
else /* dregs */
{
@ -1042,8 +983,8 @@ KdbpCmdRegs(
"DR3 0x%08x\n"
"DR6 0x%08x\n"
"DR7 0x%08x\n",
Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3,
Tf->Dr6, Tf->Dr7);
Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
Context->Dr6, Context->Dr7);
}
return TRUE;
@ -1117,8 +1058,8 @@ KdbpIsNestedTss(
}
static BOOLEAN
KdbpTrapFrameFromPrevTss(
IN OUT PKTRAP_FRAME TrapFrame,
KdbpContextFromPrevTss(
IN OUT PCONTEXT Context,
OUT PUSHORT TssSelector,
IN OUT PKTSS* pTss,
IN PKDESCRIPTOR pGdtr)
@ -1157,8 +1098,8 @@ KdbpTrapFrameFromPrevTss(
/* Return the parent TSS and its trap frame */
*TssSelector = Backlink;
*pTss = Tss;
TrapFrame->Eip = Eip;
TrapFrame->Ebp = Ebp;
Context->Eip = Eip;
Context->Ebp = Ebp;
return TRUE;
}
@ -1171,8 +1112,8 @@ KdbpCmdBackTrace(
{
ULONG ul;
ULONGLONG Result = 0;
KTRAP_FRAME TrapFrame = KdbCurrentTrapFrame->Tf;
ULONG_PTR Frame = TrapFrame.Ebp;
CONTEXT Context = *KdbCurrentTrapFrame;
ULONG_PTR Frame = Context.Ebp;
ULONG_PTR Address;
KDESCRIPTOR Gdtr;
USHORT TssSelector;
@ -1247,8 +1188,8 @@ KdbpCmdBackTrace(
if (Argc <= 1)
{
KdbpPrint("Eip:\n");
if (!KdbSymPrintAddress((PVOID)TrapFrame.Eip, &TrapFrame))
KdbpPrint("<%08x>\n", TrapFrame.Eip);
if (!KdbSymPrintAddress((PVOID)Context.Eip, &Context))
KdbpPrint("<%08x>\n", Context.Eip);
else
KdbpPrint("\n");
}
@ -1274,12 +1215,12 @@ KdbpCmdBackTrace(
GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
if (GotNextFrame)
TrapFrame.Ebp = Frame;
Context.Ebp = Frame;
// else
// Frame = 0;
/* Print the location of the call instruction (assumed 5 bytes length) */
if (!KdbSymPrintAddress((PVOID)(Address - 5), &TrapFrame))
if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
KdbpPrint("<%08x>\n", Address);
else
KdbpPrint("\n");
@ -1304,18 +1245,18 @@ CheckForParentTSS:
if (!KdbpIsNestedTss(TssSelector, Tss))
break; // The TSS is not nested, we stop there.
GotNextFrame = KdbpTrapFrameFromPrevTss(&TrapFrame, &TssSelector, &Tss, &Gdtr);
GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
if (!GotNextFrame)
{
KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
break; // Cannot retrieve the parent TSS, we stop there.
}
Address = TrapFrame.Eip;
Frame = TrapFrame.Ebp;
Address = Context.Eip;
Frame = Context.Ebp;
KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
if (!KdbSymPrintAddress((PVOID)Address, &TrapFrame))
if (!KdbSymPrintAddress((PVOID)Address, &Context))
KdbpPrint("<%08x>\n", Address);
else
KdbpPrint("\n");
@ -3672,13 +3613,13 @@ KdbpCliMainLoop(
if (EnteredOnSingleStep)
{
if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip, &KdbCurrentTrapFrame->Tf))
if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Eip, KdbCurrentTrapFrame))
{
KdbpPrint("<%08x>", KdbCurrentTrapFrame->Tf.Eip);
KdbpPrint("<%08x>", KdbCurrentTrapFrame->Eip);
}
KdbpPrint(": ");
if (KdbpDisassemble(KdbCurrentTrapFrame->Tf.Eip, KdbUseIntelSyntax) < 0)
if (KdbpDisassemble(KdbCurrentTrapFrame->Eip, KdbUseIntelSyntax) < 0)
{
KdbpPrint("<INVALID>");
}
@ -3862,7 +3803,7 @@ KdbpCliInit(VOID)
/* Interpret the init file... */
KdbInitFileBuffer = FileBuffer;
KdbEnter();
//KdbEnter(); // FIXME
KdbInitFileBuffer = NULL;
/* Leave critical section */

View file

@ -111,32 +111,28 @@ static const struct
}
RegisterToTrapFrame[] =
{
{"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)},
{"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.EFlags)},
{"eax", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eax), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eax)},
{"ebx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebx)},
{"ecx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ecx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ecx)},
{"edx", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edx)},
{"esi", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Esi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Esi)},
{"edi", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edi)},
{"esp", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareEsp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareEsp)},
{"ebp", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebp)},
{"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegCs), 2 }, /* Use only the lower 2 bytes */
{"ds", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegDs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegDs)},
{"es", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegEs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegEs)},
{"fs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegFs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegFs)},
{"gs", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegGs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegGs)},
{"ss", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareSegSs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareSegSs)},
{"dr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr0)},
{"dr1", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr1), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr1)},
{"dr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr2)},
{"dr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr3)},
{"dr6", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr6), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr6)},
{"dr7", FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr7), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr7)},
{"cr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr0)},
{"cr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr2)},
{"cr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)},
{"cr4", FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)}
{"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Eip)},
{"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, EFlags)},
{"eax", FIELD_OFFSET(KDB_KTRAP_FRAME, Eax), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Eax)},
{"ebx", FIELD_OFFSET(KDB_KTRAP_FRAME, Ebx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Ebx)},
{"ecx", FIELD_OFFSET(KDB_KTRAP_FRAME, Ecx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Ecx)},
{"edx", FIELD_OFFSET(KDB_KTRAP_FRAME, Edx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Edx)},
{"esi", FIELD_OFFSET(KDB_KTRAP_FRAME, Esi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Esi)},
{"edi", FIELD_OFFSET(KDB_KTRAP_FRAME, Edi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Edi)},
{"esp", FIELD_OFFSET(KDB_KTRAP_FRAME, Esp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Esp)},
{"ebp", FIELD_OFFSET(KDB_KTRAP_FRAME, Ebp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Ebp)},
{"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, SegCs), 2 }, /* Use only the lower 2 bytes */
{"ds", FIELD_OFFSET(KDB_KTRAP_FRAME, SegDs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, SegDs)},
{"es", FIELD_OFFSET(KDB_KTRAP_FRAME, SegEs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, SegEs)},
{"fs", FIELD_OFFSET(KDB_KTRAP_FRAME, SegFs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, SegFs)},
{"gs", FIELD_OFFSET(KDB_KTRAP_FRAME, SegGs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, SegGs)},
{"ss", FIELD_OFFSET(KDB_KTRAP_FRAME, SegSs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, SegSs)},
{"dr0", FIELD_OFFSET(KDB_KTRAP_FRAME, Dr0), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Dr0)},
{"dr1", FIELD_OFFSET(KDB_KTRAP_FRAME, Dr1), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Dr1)},
{"dr2", FIELD_OFFSET(KDB_KTRAP_FRAME, Dr2), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Dr2)},
{"dr3", FIELD_OFFSET(KDB_KTRAP_FRAME, Dr3), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Dr3)},
{"dr6", FIELD_OFFSET(KDB_KTRAP_FRAME, Dr6), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Dr6)},
{"dr7", FIELD_OFFSET(KDB_KTRAP_FRAME, Dr7), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Dr7)}
};
static const INT RegisterToTrapFrameCount = sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]);

View file

@ -155,7 +155,7 @@ KdbpSymUnicodeToAnsi(IN PUNICODE_STRING Unicode,
BOOLEAN
KdbSymPrintAddress(
IN PVOID Address,
IN PKTRAP_FRAME Context)
IN PCONTEXT Context)
{
PLDR_DATA_TABLE_ENTRY LdrEntry;
ULONG_PTR RelativeAddress;