mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:02:56 +00:00
[NTOS:KDBG] Begin port for amd64.
Not really functional, but it prints debug output. Take this as an opportunity to add consistancy between some i386 & amd64 intrinsics
This commit is contained in:
parent
439aefb31d
commit
3726b992ed
11 changed files with 396 additions and 124 deletions
|
@ -119,25 +119,84 @@ extern ULONG KeI386CpuStep;
|
||||||
#define KD_BREAKPOINT_VALUE 0xCC
|
#define KD_BREAKPOINT_VALUE 0xCC
|
||||||
|
|
||||||
//
|
//
|
||||||
// Macros for getting and setting special purpose registers in portable code
|
// One-liners for getting and setting special purpose registers in portable code
|
||||||
//
|
//
|
||||||
#define KeGetContextPc(Context) \
|
FORCEINLINE
|
||||||
((Context)->Rip)
|
ULONG_PTR
|
||||||
|
KeGetContextPc(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Rip;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeSetContextPc(Context, ProgramCounter) \
|
FORCEINLINE
|
||||||
((Context)->Rip = (ProgramCounter))
|
VOID
|
||||||
|
KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter)
|
||||||
|
{
|
||||||
|
Context->Rip = ProgramCounter;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeGetTrapFramePc(TrapFrame) \
|
FORCEINLINE
|
||||||
((TrapFrame)->Rip)
|
ULONG_PTR
|
||||||
|
KeGetContextReturnRegister(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Rax;
|
||||||
|
}
|
||||||
|
|
||||||
#define KiGetLinkedTrapFrame(x) \
|
FORCEINLINE
|
||||||
(PKTRAP_FRAME)((x)->TrapFrame)
|
VOID
|
||||||
|
KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue)
|
||||||
|
{
|
||||||
|
Context->Rax = ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeGetContextReturnRegister(Context) \
|
FORCEINLINE
|
||||||
((Context)->Rax)
|
ULONG_PTR
|
||||||
|
KeGetContextStackRegister(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Rsp;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeSetContextReturnRegister(Context, ReturnValue) \
|
FORCEINLINE
|
||||||
((Context)->Rax = (ReturnValue))
|
ULONG_PTR
|
||||||
|
KeGetContextFrameRegister(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Rbp;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
|
||||||
|
{
|
||||||
|
Context->Rbp = Frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
KeGetTrapFramePc(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return TrapFrame->Rip;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
PKTRAP_FRAME
|
||||||
|
KiGetLinkedTrapFrame(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return (PKTRAP_FRAME)TrapFrame->TrapFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return TrapFrame->Rsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return TrapFrame->Rbp;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Macro to get trap and exception frame from a thread stack
|
// Macro to get trap and exception frame from a thread stack
|
||||||
|
|
|
@ -2,16 +2,29 @@
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
#define Ke386SetGlobalDescriptorTable(X) \
|
FORCEINLINE
|
||||||
__asm__("lgdt %0\n\t" \
|
VOID
|
||||||
: /* no outputs */ \
|
__lgdt(_Out_ PVOID Descriptor)
|
||||||
: "m" (*X));
|
{
|
||||||
|
PVOID* desc = Descriptor;
|
||||||
#define Ke386GetGlobalDescriptorTable(X) \
|
__asm__ __volatile__(
|
||||||
__asm__("sgdt %0\n\t" \
|
"lgdt %0"
|
||||||
: "=m" (*X) \
|
: "=m" (*desc)
|
||||||
: /* no input */ \
|
: /* no input */
|
||||||
: "memory");
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
__sgdt(_Out_ PVOID Descriptor)
|
||||||
|
{
|
||||||
|
PVOID* desc = Descriptor;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"sgdt %0"
|
||||||
|
: "=m" (*desc)
|
||||||
|
: /* no input */
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
|
@ -51,15 +64,14 @@ Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
USHORT
|
VOID
|
||||||
Ke386GetLocalDescriptorTable(VOID)
|
__sldt(PVOID Descriptor)
|
||||||
{
|
{
|
||||||
USHORT Ldt;
|
__asm__ __volatile__(
|
||||||
__asm__("sldt %0\n\t"
|
"sldt %0"
|
||||||
: "=m" (Ldt)
|
: "=m" (*((short*)Descriptor))
|
||||||
: /* no input */
|
: /* no input */
|
||||||
: "memory");
|
: "memory");
|
||||||
return Ldt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Ke386SetLocalDescriptorTable(X) \
|
#define Ke386SetLocalDescriptorTable(X) \
|
||||||
|
@ -155,8 +167,6 @@ __fnsave(OUT PFLOATING_SAVE_AREA SaveArea)
|
||||||
__asm wait;
|
__asm wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Ke386GetGlobalDescriptorTable __sgdt
|
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
__lgdt(IN PVOID Descriptor)
|
__lgdt(IN PVOID Descriptor)
|
||||||
|
@ -167,13 +177,17 @@ __lgdt(IN PVOID Descriptor)
|
||||||
lgdt [eax]
|
lgdt [eax]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#define Ke386SetGlobalDescriptorTable __lgdt
|
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
USHORT
|
VOID
|
||||||
Ke386GetLocalDescriptorTable(VOID)
|
__sldt(PVOID Descriptor)
|
||||||
{
|
{
|
||||||
__asm sldt ax;
|
__asm
|
||||||
|
{
|
||||||
|
sldt ax
|
||||||
|
mov ecx, Descriptor
|
||||||
|
mov [ecx], ax
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -305,4 +319,8 @@ Ke386SaveFpuState(IN PVOID SaveArea)
|
||||||
#error Unknown compiler for inline assembler
|
#error Unknown compiler for inline assembler
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define Ke386GetGlobalDescriptorTable __sgdt
|
||||||
|
#define Ke386SetGlobalDescriptorTable __lgdt
|
||||||
|
#define Ke386GetLocalDescriptorTable __sldt
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -18,25 +18,80 @@
|
||||||
#define KD_BREAKPOINT_VALUE 0xCC
|
#define KD_BREAKPOINT_VALUE 0xCC
|
||||||
|
|
||||||
//
|
//
|
||||||
// Macros for getting and setting special purpose registers in portable code
|
// One-liners for getting and setting special purpose registers in portable code
|
||||||
//
|
//
|
||||||
#define KeGetContextPc(Context) \
|
FORCEINLINE
|
||||||
((Context)->Eip)
|
ULONG_PTR
|
||||||
|
KeGetContextPc(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Eip;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeSetContextPc(Context, ProgramCounter) \
|
FORCEINLINE
|
||||||
((Context)->Eip = (ProgramCounter))
|
VOID
|
||||||
|
KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter)
|
||||||
|
{
|
||||||
|
Context->Eip = ProgramCounter;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeGetTrapFramePc(TrapFrame) \
|
FORCEINLINE
|
||||||
((TrapFrame)->Eip)
|
ULONG_PTR
|
||||||
|
KeGetContextReturnRegister(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Eax;
|
||||||
|
}
|
||||||
|
|
||||||
#define KiGetLinkedTrapFrame(x) \
|
FORCEINLINE
|
||||||
(PKTRAP_FRAME)((x)->Edx)
|
VOID
|
||||||
|
KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue)
|
||||||
|
{
|
||||||
|
Context->Eax = ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeGetContextReturnRegister(Context) \
|
FORCEINLINE
|
||||||
((Context)->Eax)
|
ULONG_PTR
|
||||||
|
KeGetContextFrameRegister(PCONTEXT Context)
|
||||||
|
{
|
||||||
|
return Context->Ebp;
|
||||||
|
}
|
||||||
|
|
||||||
#define KeSetContextReturnRegister(Context, ReturnValue) \
|
FORCEINLINE
|
||||||
((Context)->Eax = (ReturnValue))
|
VOID
|
||||||
|
KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
|
||||||
|
{
|
||||||
|
Context->Ebp = Frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
KeGetTrapFramePc(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return TrapFrame->Eip;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
PKTRAP_FRAME
|
||||||
|
KiGetLinkedTrapFrame(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return (PKTRAP_FRAME)TrapFrame->Edx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
if (TrapFrame->PreviousPreviousMode == KernelMode)
|
||||||
|
return TrapFrame->TempEsp;
|
||||||
|
return TrapFrame->HardwareEsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
return TrapFrame->Ebp;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Macro to get trap and exception frame from a thread stack
|
// Macro to get trap and exception frame from a thread stack
|
||||||
|
|
|
@ -611,7 +611,7 @@ KdSendPacket(
|
||||||
if (KdbgExceptionRecord.ExceptionCode == STATUS_ASSERTION_FAILURE)
|
if (KdbgExceptionRecord.ExceptionCode == STATUS_ASSERTION_FAILURE)
|
||||||
{
|
{
|
||||||
/* Bump EIP to the instruction following the int 2C */
|
/* Bump EIP to the instruction following the int 2C */
|
||||||
KdbgContext.Eip += 2;
|
KeSetContextPc(&KdbgContext, KeGetContextPc(&KdbgContext) + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = KdbEnterDebuggerException(&KdbgExceptionRecord,
|
Result = KdbEnterDebuggerException(&KdbgExceptionRecord,
|
||||||
|
|
0
ntoskrnl/kdbg/amd64/amd64-dis.c
Normal file
0
ntoskrnl/kdbg/amd64/amd64-dis.c
Normal file
22
ntoskrnl/kdbg/amd64/kdb_help.S
Normal file
22
ntoskrnl/kdbg/amd64/kdb_help.S
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
#include <asm.inc>
|
||||||
|
|
||||||
|
.code64
|
||||||
|
|
||||||
|
PUBLIC KdbpStackSwitchAndCall
|
||||||
|
KdbpStackSwitchAndCall:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp /* Old stack - frame */
|
||||||
|
|
||||||
|
/* Switch stack */
|
||||||
|
mov rsp, rcx
|
||||||
|
|
||||||
|
/* Call function */
|
||||||
|
call rdx
|
||||||
|
|
||||||
|
/* Switch back to old stack */
|
||||||
|
pop rsp
|
||||||
|
|
||||||
|
ret 8
|
||||||
|
|
||||||
|
END
|
|
@ -650,14 +650,14 @@ KdbpIsBreakPointOurs(
|
||||||
|
|
||||||
if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
|
if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
|
||||||
{
|
{
|
||||||
ULONG_PTR BpEip = (ULONG_PTR)Context->Eip - 1; /* Get EIP of INT3 instruction */
|
ULONG_PTR BpPc = KeGetContextPc(Context) - 1; /* Get EIP of INT3 instruction */
|
||||||
for (i = 0; i < KdbSwBreakPointCount; i++)
|
for (i = 0; i < KdbSwBreakPointCount; i++)
|
||||||
{
|
{
|
||||||
ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
|
ASSERT((KdbSwBreakPoints[i]->Type == KdbBreakPointSoftware ||
|
||||||
KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
|
KdbSwBreakPoints[i]->Type == KdbBreakPointTemporary));
|
||||||
ASSERT(KdbSwBreakPoints[i]->Enabled);
|
ASSERT(KdbSwBreakPoints[i]->Enabled);
|
||||||
|
|
||||||
if (KdbSwBreakPoints[i]->Address == BpEip)
|
if (KdbSwBreakPoints[i]->Address == BpPc)
|
||||||
{
|
{
|
||||||
return KdbSwBreakPoints[i] - KdbBreakPoints;
|
return KdbSwBreakPoints[i] - KdbBreakPoints;
|
||||||
}
|
}
|
||||||
|
@ -1321,7 +1321,7 @@ KdbEnterDebuggerException(
|
||||||
KiDispatchException accounts for that. Whatever we do here with
|
KiDispatchException accounts for that. Whatever we do here with
|
||||||
the TrapFrame does not matter anyway, since KiDispatchException
|
the TrapFrame does not matter anyway, since KiDispatchException
|
||||||
will overwrite it with the values from the Context! */
|
will overwrite it with the values from the Context! */
|
||||||
Context->Eip--;
|
KeSetContextPc(Context, KeGetContextPc(Context) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((BreakPoint->Type == KdbBreakPointHardware) &&
|
if ((BreakPoint->Type == KdbBreakPointHardware) &&
|
||||||
|
@ -1345,8 +1345,8 @@ KdbEnterDebuggerException(
|
||||||
|
|
||||||
if (--KdbNumSingleSteps > 0)
|
if (--KdbNumSingleSteps > 0)
|
||||||
{
|
{
|
||||||
if ((KdbSingleStepOver && !KdbpStepOverInstruction(Context->Eip)) ||
|
if ((KdbSingleStepOver && !KdbpStepOverInstruction(KeGetContextPc(Context))) ||
|
||||||
(!KdbSingleStepOver && !KdbpStepIntoInstruction(Context->Eip)))
|
(!KdbSingleStepOver && !KdbpStepIntoInstruction(KeGetContextPc(Context))))
|
||||||
{
|
{
|
||||||
Context->EFlags |= EFLAGS_TF;
|
Context->EFlags |= EFLAGS_TF;
|
||||||
}
|
}
|
||||||
|
@ -1394,8 +1394,8 @@ KdbEnterDebuggerException(
|
||||||
|
|
||||||
if (BreakPoint->Type == KdbBreakPointSoftware)
|
if (BreakPoint->Type == KdbBreakPointSoftware)
|
||||||
{
|
{
|
||||||
KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
|
KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%p\n",
|
||||||
KdbLastBreakPointNr, Context->SegCs & 0xffff, Context->Eip);
|
KdbLastBreakPointNr, Context->SegCs & 0xffff, KeGetContextPc(Context));
|
||||||
}
|
}
|
||||||
else if (BreakPoint->Type == KdbBreakPointHardware)
|
else if (BreakPoint->Type == KdbBreakPointHardware)
|
||||||
{
|
{
|
||||||
|
@ -1448,8 +1448,8 @@ KdbEnterDebuggerException(
|
||||||
/*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
|
/*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
|
||||||
if (--KdbNumSingleSteps > 0)
|
if (--KdbNumSingleSteps > 0)
|
||||||
{
|
{
|
||||||
if ((KdbSingleStepOver && KdbpStepOverInstruction(Context->Eip)) ||
|
if ((KdbSingleStepOver && KdbpStepOverInstruction(KeGetContextPc(Context))) ||
|
||||||
(!KdbSingleStepOver && KdbpStepIntoInstruction(Context->Eip)))
|
(!KdbSingleStepOver && KdbpStepIntoInstruction(KeGetContextPc(Context))))
|
||||||
{
|
{
|
||||||
Context->EFlags &= ~EFLAGS_TF;
|
Context->EFlags &= ~EFLAGS_TF;
|
||||||
}
|
}
|
||||||
|
@ -1488,8 +1488,8 @@ KdbEnterDebuggerException(
|
||||||
return kdHandleException;
|
return kdHandleException;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
|
KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
|
||||||
Context->SegCs & 0xffff, Context->Eip - 1);
|
Context->SegCs & 0xffff, KeGetContextPc(Context) - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1552,8 +1552,8 @@ KdbEnterDebuggerException(
|
||||||
/* Variable explains itself! */
|
/* Variable explains itself! */
|
||||||
KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
|
KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
|
||||||
|
|
||||||
if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Eip)) ||
|
if ((KdbSingleStepOver && KdbpStepOverInstruction(KeGetContextPc(KdbCurrentTrapFrame))) ||
|
||||||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Eip)))
|
(!KdbSingleStepOver && KdbpStepIntoInstruction(KeGetContextPc(KdbCurrentTrapFrame))))
|
||||||
{
|
{
|
||||||
ASSERT((KdbCurrentTrapFrame->EFlags & EFLAGS_TF) == 0);
|
ASSERT((KdbCurrentTrapFrame->EFlags & EFLAGS_TF) == 0);
|
||||||
/*KdbCurrentTrapFrame->EFlags &= ~EFLAGS_TF;*/
|
/*KdbCurrentTrapFrame->EFlags &= ~EFLAGS_TF;*/
|
||||||
|
@ -1608,7 +1608,7 @@ continue_execution:
|
||||||
if (!(KdbEnteredOnSingleStep && KdbSingleStepOver))
|
if (!(KdbEnteredOnSingleStep && KdbSingleStepOver))
|
||||||
{
|
{
|
||||||
/* Skip the current instruction */
|
/* Skip the current instruction */
|
||||||
Context->Eip++;
|
KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1625,7 +1625,10 @@ KdbEnterDebuggerFirstChanceException(
|
||||||
|
|
||||||
/* Copy TrapFrame to Context */
|
/* Copy TrapFrame to Context */
|
||||||
RtlZeroMemory(&Context, sizeof(CONTEXT));
|
RtlZeroMemory(&Context, sizeof(CONTEXT));
|
||||||
Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_EXTENDED_REGISTERS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
|
Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
|
||||||
|
#ifdef CONTEXT_EXTENDED_REGISTERS
|
||||||
|
Context.ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
|
||||||
|
#endif
|
||||||
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
KeTrapFrameToContext(TrapFrame, NULL, &Context);
|
||||||
|
|
||||||
/* Create ExceptionRecord (assume breakpoint) */
|
/* Create ExceptionRecord (assume breakpoint) */
|
||||||
|
|
|
@ -82,7 +82,9 @@ static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
|
||||||
static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
|
||||||
static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
|
||||||
static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
|
||||||
|
#ifdef _M_IX86
|
||||||
static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
|
||||||
|
#endif
|
||||||
|
|
||||||
static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
|
||||||
static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[]);
|
||||||
|
@ -103,6 +105,26 @@ BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[]);
|
||||||
static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Be more descriptive than intrinsics */
|
||||||
|
#ifndef Ke386GetGlobalDescriptorTable
|
||||||
|
# define Ke386GetGlobalDescriptorTable __sgdt
|
||||||
|
#endif
|
||||||
|
#ifndef Ke386GetLocalDescriptorTable
|
||||||
|
# define Ke386GetLocalDescriptorTable __sldt
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Portability */
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
strtoulptr(const char* nptr, char** endptr, int base)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86
|
||||||
|
return strtoul(nptr, endptr, base);
|
||||||
|
#else
|
||||||
|
return strtoull(nptr, endptr, base);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
|
@ -376,7 +398,9 @@ static const struct
|
||||||
{ "ldt", "ldt", "Display the local descriptor table.", KdbpCmdGdtLdtIdt },
|
{ "ldt", "ldt", "Display the local descriptor table.", KdbpCmdGdtLdtIdt },
|
||||||
{ "idt", "idt", "Display the interrupt descriptor table.", KdbpCmdGdtLdtIdt },
|
{ "idt", "idt", "Display the interrupt descriptor table.", KdbpCmdGdtLdtIdt },
|
||||||
{ "pcr", "pcr", "Display the processor control region.", KdbpCmdPcr },
|
{ "pcr", "pcr", "Display the processor control region.", KdbpCmdPcr },
|
||||||
|
#ifdef _M_IX86
|
||||||
{ "tss", "tss [selector|*descaddr]", "Display the current task state segment, or the one specified by its selector number or descriptor address.", KdbpCmdTss },
|
{ "tss", "tss [selector|*descaddr]", "Display the current task state segment, or the one specified by its selector number or descriptor address.", KdbpCmdTss },
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Others */
|
/* Others */
|
||||||
{ NULL, NULL, "Others", NULL },
|
{ NULL, NULL, "Others", NULL },
|
||||||
|
@ -793,7 +817,7 @@ KdbpCmdDisassembleX(
|
||||||
ULONG ul;
|
ULONG ul;
|
||||||
INT i;
|
INT i;
|
||||||
ULONGLONG Result = 0;
|
ULONGLONG Result = 0;
|
||||||
ULONG_PTR Address = KdbCurrentTrapFrame->Eip;
|
ULONG_PTR Address = KeGetContextPc(KdbCurrentTrapFrame);
|
||||||
LONG InstLen;
|
LONG InstLen;
|
||||||
|
|
||||||
if (Argv[0][0] == 'x') /* display memory */
|
if (Argv[0][0] == 'x') /* display memory */
|
||||||
|
@ -922,6 +946,7 @@ KdbpCmdRegs(
|
||||||
|
|
||||||
if (Argv[0][0] == 'r') /* regs */
|
if (Argv[0][0] == 'r') /* regs */
|
||||||
{
|
{
|
||||||
|
#ifdef _M_IX86
|
||||||
KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
|
KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
|
||||||
"SS:ESP 0x%04x:0x%08x\n"
|
"SS:ESP 0x%04x:0x%08x\n"
|
||||||
" EAX 0x%08x EBX 0x%08x\n"
|
" EAX 0x%08x EBX 0x%08x\n"
|
||||||
|
@ -934,7 +959,20 @@ KdbpCmdRegs(
|
||||||
Context->Ecx, Context->Edx,
|
Context->Ecx, Context->Edx,
|
||||||
Context->Esi, Context->Edi,
|
Context->Esi, Context->Edi,
|
||||||
Context->Ebp);
|
Context->Ebp);
|
||||||
|
#else
|
||||||
|
KdbpPrint("CS:RIP 0x%04x:0x%p\n"
|
||||||
|
"SS:RSP 0x%04x:0x%p\n"
|
||||||
|
" RAX 0x%p RBX 0x%p\n"
|
||||||
|
" RCX 0x%p RDX 0x%p\n"
|
||||||
|
" RSI 0x%p RDI 0x%p\n"
|
||||||
|
" RBP 0x%p\n",
|
||||||
|
Context->SegCs & 0xFFFF, Context->Rip,
|
||||||
|
Context->SegSs, Context->Rsp,
|
||||||
|
Context->Rax, Context->Rbx,
|
||||||
|
Context->Rcx, Context->Rdx,
|
||||||
|
Context->Rsi, Context->Rdi,
|
||||||
|
Context->Rbp);
|
||||||
|
#endif
|
||||||
/* Display the EFlags */
|
/* Display the EFlags */
|
||||||
KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
|
KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
|
@ -990,6 +1028,7 @@ KdbpCmdRegs(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
static PKTSS
|
static PKTSS
|
||||||
KdbpRetrieveTss(
|
KdbpRetrieveTss(
|
||||||
IN USHORT TssSelector,
|
IN USHORT TssSelector,
|
||||||
|
@ -1102,6 +1141,7 @@ KdbpContextFromPrevTss(
|
||||||
Context->Ebp = Ebp;
|
Context->Ebp = Ebp;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief Displays a backtrace.
|
/*!\brief Displays a backtrace.
|
||||||
*/
|
*/
|
||||||
|
@ -1113,11 +1153,8 @@ KdbpCmdBackTrace(
|
||||||
ULONG ul;
|
ULONG ul;
|
||||||
ULONGLONG Result = 0;
|
ULONGLONG Result = 0;
|
||||||
CONTEXT Context = *KdbCurrentTrapFrame;
|
CONTEXT Context = *KdbCurrentTrapFrame;
|
||||||
ULONG_PTR Frame = Context.Ebp;
|
ULONG_PTR Frame = KeGetContextFrameRegister(&Context);
|
||||||
ULONG_PTR Address;
|
ULONG_PTR Address;
|
||||||
KDESCRIPTOR Gdtr;
|
|
||||||
USHORT TssSelector;
|
|
||||||
PKTSS Tss;
|
|
||||||
|
|
||||||
if (Argc >= 2)
|
if (Argc >= 2)
|
||||||
{
|
{
|
||||||
|
@ -1172,6 +1209,11 @@ KdbpCmdBackTrace(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
|
KDESCRIPTOR Gdtr;
|
||||||
|
USHORT TssSelector;
|
||||||
|
PKTSS Tss;
|
||||||
|
|
||||||
/* Retrieve the Global Descriptor Table */
|
/* Retrieve the Global Descriptor Table */
|
||||||
Ke386GetGlobalDescriptorTable(&Gdtr.Limit);
|
Ke386GetGlobalDescriptorTable(&Gdtr.Limit);
|
||||||
|
|
||||||
|
@ -1183,13 +1225,14 @@ KdbpCmdBackTrace(
|
||||||
/* Display the active TSS if it is nested */
|
/* Display the active TSS if it is nested */
|
||||||
KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
|
KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If no Frame Address or Thread ID was given, try printing the function at EIP */
|
/* If no Frame Address or Thread ID was given, try printing the function at EIP */
|
||||||
if (Argc <= 1)
|
if (Argc <= 1)
|
||||||
{
|
{
|
||||||
KdbpPrint("Eip:\n");
|
KdbpPrint("Eip:\n");
|
||||||
if (!KdbSymPrintAddress((PVOID)Context.Eip, &Context))
|
if (!KdbSymPrintAddress((PVOID)KeGetContextPc(&Context), &Context))
|
||||||
KdbpPrint("<%08x>\n", Context.Eip);
|
KdbpPrint("<%p>\n", KeGetContextPc(&Context));
|
||||||
else
|
else
|
||||||
KdbpPrint("\n");
|
KdbpPrint("\n");
|
||||||
}
|
}
|
||||||
|
@ -1215,7 +1258,9 @@ KdbpCmdBackTrace(
|
||||||
|
|
||||||
GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
|
GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
|
||||||
if (GotNextFrame)
|
if (GotNextFrame)
|
||||||
Context.Ebp = Frame;
|
{
|
||||||
|
KeSetContextFrameRegister(&Context, Frame);
|
||||||
|
}
|
||||||
// else
|
// else
|
||||||
// Frame = 0;
|
// Frame = 0;
|
||||||
|
|
||||||
|
@ -1237,6 +1282,9 @@ KdbpCmdBackTrace(
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CheckForParentTSS:
|
CheckForParentTSS:
|
||||||
|
#ifndef _M_IX86
|
||||||
|
break;
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* We have ended the stack walking for the current (active) TSS.
|
* We have ended the stack walking for the current (active) TSS.
|
||||||
* Check whether this TSS was nested, and if so switch to its parent
|
* Check whether this TSS was nested, and if so switch to its parent
|
||||||
|
@ -1251,6 +1299,8 @@ CheckForParentTSS:
|
||||||
KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
|
KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
|
||||||
break; // Cannot retrieve the parent TSS, we stop there.
|
break; // Cannot retrieve the parent TSS, we stop there.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Address = Context.Eip;
|
Address = Context.Eip;
|
||||||
Frame = Context.Ebp;
|
Frame = Context.Ebp;
|
||||||
|
|
||||||
|
@ -1260,6 +1310,7 @@ CheckForParentTSS:
|
||||||
KdbpPrint("<%08x>\n", Address);
|
KdbpPrint("<%08x>\n", Address);
|
||||||
else
|
else
|
||||||
KdbpPrint("\n");
|
KdbpPrint("\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1359,8 +1410,8 @@ KdbpCmdBreakPointList(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GlobalOrLocal = Buffer;
|
GlobalOrLocal = Buffer;
|
||||||
sprintf(Buffer, " PID 0x%08lx",
|
sprintf(Buffer, " PID 0x%lx",
|
||||||
(ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
|
(ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
|
if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
|
||||||
|
@ -1579,10 +1630,10 @@ KdbpCmdThread(
|
||||||
PETHREAD Thread = NULL;
|
PETHREAD Thread = NULL;
|
||||||
PEPROCESS Process = NULL;
|
PEPROCESS Process = NULL;
|
||||||
BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
|
BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
|
||||||
PULONG Esp;
|
PULONG_PTR Stack;
|
||||||
PULONG Ebp;
|
PULONG_PTR Frame;
|
||||||
ULONG Eip;
|
ULONG_PTR Pc;
|
||||||
ULONG ul = 0;
|
ULONG_PTR ul = 0;
|
||||||
PCHAR State, pend, str1, str2;
|
PCHAR State, pend, str1, str2;
|
||||||
static const PCHAR ThreadStateToString[DeferredReady+1] =
|
static const PCHAR ThreadStateToString[DeferredReady+1] =
|
||||||
{
|
{
|
||||||
|
@ -1599,7 +1650,7 @@ KdbpCmdThread(
|
||||||
|
|
||||||
if (Argc >= 3)
|
if (Argc >= 3)
|
||||||
{
|
{
|
||||||
ul = strtoul(Argv[2], &pend, 0);
|
ul = strtoulptr(Argv[2], &pend, 0);
|
||||||
if (Argv[2] == pend)
|
if (Argv[2] == pend)
|
||||||
{
|
{
|
||||||
KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
|
KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
|
||||||
|
@ -1620,7 +1671,7 @@ KdbpCmdThread(
|
||||||
if (Entry == &Process->ThreadListHead)
|
if (Entry == &Process->ThreadListHead)
|
||||||
{
|
{
|
||||||
if (Argc >= 3)
|
if (Argc >= 3)
|
||||||
KdbpPrint("No threads in process 0x%08x!\n", ul);
|
KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
|
||||||
else
|
else
|
||||||
KdbpPrint("No threads in current process!\n");
|
KdbpPrint("No threads in current process!\n");
|
||||||
|
|
||||||
|
@ -1649,27 +1700,23 @@ KdbpCmdThread(
|
||||||
if (!Thread->Tcb.InitialStack)
|
if (!Thread->Tcb.InitialStack)
|
||||||
{
|
{
|
||||||
/* Thread has no kernel stack (probably terminated) */
|
/* Thread has no kernel stack (probably terminated) */
|
||||||
Esp = Ebp = NULL;
|
Stack = Frame = NULL;
|
||||||
Eip = 0;
|
Pc = 0;
|
||||||
}
|
}
|
||||||
else if (Thread->Tcb.TrapFrame)
|
else if (Thread->Tcb.TrapFrame)
|
||||||
{
|
{
|
||||||
if (Thread->Tcb.TrapFrame->PreviousPreviousMode == KernelMode)
|
Stack = (PULONG_PTR)KeGetTrapFrameStackRegister(Thread->Tcb.TrapFrame);
|
||||||
Esp = (PULONG)Thread->Tcb.TrapFrame->TempEsp;
|
Frame = (PULONG_PTR)KeGetTrapFrameFrameRegister(Thread->Tcb.TrapFrame);
|
||||||
else
|
Pc = KeGetTrapFramePc(Thread->Tcb.TrapFrame);
|
||||||
Esp = (PULONG)Thread->Tcb.TrapFrame->HardwareEsp;
|
|
||||||
|
|
||||||
Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp;
|
|
||||||
Eip = Thread->Tcb.TrapFrame->Eip;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Esp = (PULONG)Thread->Tcb.KernelStack;
|
Stack = (PULONG_PTR)Thread->Tcb.KernelStack;
|
||||||
Ebp = (PULONG)Esp[4];
|
Frame = (PULONG_PTR)Stack[4];
|
||||||
Eip = 0;
|
Pc = 0;
|
||||||
|
|
||||||
if (Ebp) /* FIXME: Should we attach to the process to read Ebp[1]? */
|
if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
|
||||||
KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof(Eip));
|
KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Thread->Tcb.State < (DeferredReady + 1))
|
if (Thread->Tcb.State < (DeferredReady + 1))
|
||||||
|
@ -1683,8 +1730,8 @@ KdbpCmdThread(
|
||||||
State,
|
State,
|
||||||
Thread->Tcb.Priority,
|
Thread->Tcb.Priority,
|
||||||
Thread->Tcb.Affinity,
|
Thread->Tcb.Affinity,
|
||||||
Ebp,
|
Frame,
|
||||||
Eip,
|
Pc,
|
||||||
str2);
|
str2);
|
||||||
|
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
|
@ -1703,7 +1750,7 @@ KdbpCmdThread(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul = strtoul(Argv[2], &pend, 0);
|
ul = strtoulptr(Argv[2], &pend, 0);
|
||||||
if (Argv[2] == pend)
|
if (Argv[2] == pend)
|
||||||
{
|
{
|
||||||
KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
|
KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
|
||||||
|
@ -1723,7 +1770,7 @@ KdbpCmdThread(
|
||||||
|
|
||||||
if (Argc >= 2)
|
if (Argc >= 2)
|
||||||
{
|
{
|
||||||
ul = strtoul(Argv[1], &pend, 0);
|
ul = strtoulptr(Argv[1], &pend, 0);
|
||||||
if (Argv[1] == pend)
|
if (Argv[1] == pend)
|
||||||
{
|
{
|
||||||
KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
|
KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
|
||||||
|
@ -1765,8 +1812,11 @@ KdbpCmdThread(
|
||||||
Thread->Tcb.StackLimit,
|
Thread->Tcb.StackLimit,
|
||||||
Thread->Tcb.StackBase,
|
Thread->Tcb.StackBase,
|
||||||
Thread->Tcb.KernelStack,
|
Thread->Tcb.KernelStack,
|
||||||
Thread->Tcb.TrapFrame,
|
Thread->Tcb.TrapFrame
|
||||||
NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState);
|
#ifndef _M_AMD64
|
||||||
|
, NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
/* Release our reference if we had one */
|
/* Release our reference if we had one */
|
||||||
if (ReferencedThread)
|
if (ReferencedThread)
|
||||||
|
@ -1787,7 +1837,7 @@ KdbpCmdProc(
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
BOOLEAN ReferencedProcess = FALSE;
|
BOOLEAN ReferencedProcess = FALSE;
|
||||||
PCHAR State, pend, str1, str2;
|
PCHAR State, pend, str1, str2;
|
||||||
ULONG ul;
|
ULONG_PTR ul;
|
||||||
extern LIST_ENTRY PsActiveProcessHead;
|
extern LIST_ENTRY PsActiveProcessHead;
|
||||||
|
|
||||||
if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
|
if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
|
||||||
|
@ -1837,7 +1887,7 @@ KdbpCmdProc(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul = strtoul(Argv[2], &pend, 0);
|
ul = strtoulptr(Argv[2], &pend, 0);
|
||||||
if (Argv[2] == pend)
|
if (Argv[2] == pend)
|
||||||
{
|
{
|
||||||
KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
|
KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
|
||||||
|
@ -1849,8 +1899,8 @@ KdbpCmdProc(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbpPrint("Attached to process 0x%08x, thread 0x%08x.\n", (ULONG)ul,
|
KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
|
||||||
(ULONG)KdbCurrentThread->Cid.UniqueThread);
|
KdbCurrentThread->Cid.UniqueThread);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1858,7 +1908,7 @@ KdbpCmdProc(
|
||||||
|
|
||||||
if (Argc >= 2)
|
if (Argc >= 2)
|
||||||
{
|
{
|
||||||
ul = strtoul(Argv[1], &pend, 0);
|
ul = strtoulptr(Argv[1], &pend, 0);
|
||||||
if (Argv[1] == pend)
|
if (Argv[1] == pend)
|
||||||
{
|
{
|
||||||
KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
|
KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
|
||||||
|
@ -1991,9 +2041,9 @@ KdbpCmdGdtLdtIdt(
|
||||||
|
|
||||||
for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
|
for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
|
||||||
{
|
{
|
||||||
if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
|
if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
|
||||||
{
|
{
|
||||||
KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
|
KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)((ULONG_PTR)Reg.Base + i));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2046,7 +2096,7 @@ KdbpCmdGdtLdtIdt(
|
||||||
ASSERT(Argv[0][0] == 'l');
|
ASSERT(Argv[0][0] == 'l');
|
||||||
|
|
||||||
/* Read LDTR */
|
/* Read LDTR */
|
||||||
Reg.Limit = Ke386GetLocalDescriptorTable();
|
Ke386GetLocalDescriptorTable(&Reg.Limit);
|
||||||
Reg.Base = 0;
|
Reg.Base = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
ul = 1 << 2;
|
ul = 1 << 2;
|
||||||
|
@ -2065,9 +2115,9 @@ KdbpCmdGdtLdtIdt(
|
||||||
|
|
||||||
for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
|
for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
|
||||||
{
|
{
|
||||||
if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)(Reg.Base + i), sizeof(SegDesc))))
|
if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
|
||||||
{
|
{
|
||||||
KdbpPrint("Couldn't access memory at 0x%08x!\n", Reg.Base + i);
|
KdbpPrint("Couldn't access memory at 0x%p!\n", (ULONG_PTR)Reg.Base + i);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2194,36 +2244,80 @@ KdbpCmdPcr(
|
||||||
" Tib.FiberData/Version: 0x%08x\n"
|
" Tib.FiberData/Version: 0x%08x\n"
|
||||||
" Tib.ArbitraryUserPointer: 0x%08x\n"
|
" Tib.ArbitraryUserPointer: 0x%08x\n"
|
||||||
" Tib.Self: 0x%08x\n"
|
" Tib.Self: 0x%08x\n"
|
||||||
|
#ifdef _M_IX86
|
||||||
" SelfPcr: 0x%08x\n"
|
" SelfPcr: 0x%08x\n"
|
||||||
|
#else
|
||||||
|
" Self: 0x%p\n"
|
||||||
|
#endif
|
||||||
" PCRCB: 0x%08x\n"
|
" PCRCB: 0x%08x\n"
|
||||||
" Irql: 0x%02x\n"
|
" Irql: 0x%02x\n"
|
||||||
|
#ifdef _M_IX86
|
||||||
" IRR: 0x%08x\n"
|
" IRR: 0x%08x\n"
|
||||||
" IrrActive: 0x%08x\n"
|
" IrrActive: 0x%08x\n"
|
||||||
" IDR: 0x%08x\n"
|
" IDR: 0x%08x\n"
|
||||||
|
#endif
|
||||||
" KdVersionBlock: 0x%08x\n"
|
" KdVersionBlock: 0x%08x\n"
|
||||||
|
#ifdef _M_IX86
|
||||||
" IDT: 0x%08x\n"
|
" IDT: 0x%08x\n"
|
||||||
" GDT: 0x%08x\n"
|
" GDT: 0x%08x\n"
|
||||||
" TSS: 0x%08x\n"
|
" TSS: 0x%08x\n"
|
||||||
|
#endif
|
||||||
" MajorVersion: 0x%04x\n"
|
" MajorVersion: 0x%04x\n"
|
||||||
" MinorVersion: 0x%04x\n"
|
" MinorVersion: 0x%04x\n"
|
||||||
|
#ifdef _M_IX86
|
||||||
" SetMember: 0x%08x\n"
|
" SetMember: 0x%08x\n"
|
||||||
|
#endif
|
||||||
" StallScaleFactor: 0x%08x\n"
|
" StallScaleFactor: 0x%08x\n"
|
||||||
|
#ifdef _M_IX86
|
||||||
" Number: 0x%02x\n"
|
" Number: 0x%02x\n"
|
||||||
|
#endif
|
||||||
" L2CacheAssociativity: 0x%02x\n"
|
" L2CacheAssociativity: 0x%02x\n"
|
||||||
|
#ifdef _M_IX86
|
||||||
" VdmAlert: 0x%08x\n"
|
" VdmAlert: 0x%08x\n"
|
||||||
|
#endif
|
||||||
" L2CacheSize: 0x%08x\n"
|
" L2CacheSize: 0x%08x\n"
|
||||||
" InterruptMode: 0x%08x\n",
|
#ifdef _M_IX86
|
||||||
Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
|
" InterruptMode: 0x%08x\n"
|
||||||
|
#endif
|
||||||
|
, Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
|
||||||
Pcr->NtTib.SubSystemTib, Pcr->NtTib.FiberData, Pcr->NtTib.ArbitraryUserPointer,
|
Pcr->NtTib.SubSystemTib, Pcr->NtTib.FiberData, Pcr->NtTib.ArbitraryUserPointer,
|
||||||
Pcr->NtTib.Self, Pcr->SelfPcr, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
|
Pcr->NtTib.Self
|
||||||
Pcr->IDR, Pcr->KdVersionBlock, Pcr->IDT, Pcr->GDT, Pcr->TSS,
|
#ifdef _M_IX86
|
||||||
Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
|
, Pcr->SelfPcr
|
||||||
Pcr->Number, Pcr->SecondLevelCacheAssociativity,
|
#else
|
||||||
Pcr->VdmAlert, Pcr->SecondLevelCacheSize, Pcr->InterruptMode);
|
, Pcr->Self
|
||||||
|
#endif
|
||||||
|
, Pcr->Prcb, Pcr->Irql
|
||||||
|
#ifdef _M_IX86
|
||||||
|
, Pcr->IRR, Pcr->IrrActive , Pcr->IDR
|
||||||
|
#endif
|
||||||
|
, Pcr->KdVersionBlock
|
||||||
|
#ifdef _M_IX86
|
||||||
|
, Pcr->IDT, Pcr->GDT, Pcr->TSS
|
||||||
|
#endif
|
||||||
|
, Pcr->MajorVersion, Pcr->MinorVersion
|
||||||
|
#ifdef _M_IX86
|
||||||
|
, Pcr->SetMember
|
||||||
|
#endif
|
||||||
|
, Pcr->StallScaleFactor
|
||||||
|
#ifdef _M_IX86
|
||||||
|
, Pcr->Number
|
||||||
|
#endif
|
||||||
|
, Pcr->SecondLevelCacheAssociativity
|
||||||
|
#ifdef _M_IX86
|
||||||
|
, Pcr->VdmAlert
|
||||||
|
#endif
|
||||||
|
, Pcr->SecondLevelCacheSize
|
||||||
|
#ifdef _M_IX86
|
||||||
|
, Pcr->InterruptMode
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
/*!\brief Displays the TSS
|
/*!\brief Displays the TSS
|
||||||
*/
|
*/
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
|
@ -2321,6 +2415,7 @@ KdbpCmdTss(
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!\brief Bugchecks the system.
|
/*!\brief Bugchecks the system.
|
||||||
*/
|
*/
|
||||||
|
@ -3613,13 +3708,13 @@ KdbpCliMainLoop(
|
||||||
|
|
||||||
if (EnteredOnSingleStep)
|
if (EnteredOnSingleStep)
|
||||||
{
|
{
|
||||||
if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Eip, KdbCurrentTrapFrame))
|
if (!KdbSymPrintAddress((PVOID)KeGetContextPc(KdbCurrentTrapFrame), KdbCurrentTrapFrame))
|
||||||
{
|
{
|
||||||
KdbpPrint("<%08x>", KdbCurrentTrapFrame->Eip);
|
KdbpPrint("<%p>", KeGetContextPc(KdbCurrentTrapFrame));
|
||||||
}
|
}
|
||||||
|
|
||||||
KdbpPrint(": ");
|
KdbpPrint(": ");
|
||||||
if (KdbpDisassemble(KdbCurrentTrapFrame->Eip, KdbUseIntelSyntax) < 0)
|
if (KdbpDisassemble(KeGetContextPc(KdbCurrentTrapFrame), KdbUseIntelSyntax) < 0)
|
||||||
{
|
{
|
||||||
KdbpPrint("<INVALID>");
|
KdbpPrint("<INVALID>");
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,8 +111,14 @@ static const struct
|
||||||
}
|
}
|
||||||
RegisterToTrapFrame[] =
|
RegisterToTrapFrame[] =
|
||||||
{
|
{
|
||||||
|
/* FIXME: X86 only */
|
||||||
|
#ifdef _M_IX86
|
||||||
{"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Eip)},
|
{"eip", FIELD_OFFSET(KDB_KTRAP_FRAME, Eip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Eip)},
|
||||||
|
#else
|
||||||
|
{"rip", FIELD_OFFSET(KDB_KTRAP_FRAME, Rip), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rip)},
|
||||||
|
#endif
|
||||||
{"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, EFlags)},
|
{"eflags", FIELD_OFFSET(KDB_KTRAP_FRAME, EFlags), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, EFlags)},
|
||||||
|
#ifdef _M_IX86
|
||||||
{"eax", FIELD_OFFSET(KDB_KTRAP_FRAME, Eax), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Eax)},
|
{"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)},
|
{"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)},
|
{"ecx", FIELD_OFFSET(KDB_KTRAP_FRAME, Ecx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Ecx)},
|
||||||
|
@ -121,6 +127,16 @@ RegisterToTrapFrame[] =
|
||||||
{"edi", FIELD_OFFSET(KDB_KTRAP_FRAME, Edi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Edi)},
|
{"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)},
|
{"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)},
|
{"ebp", FIELD_OFFSET(KDB_KTRAP_FRAME, Ebp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Ebp)},
|
||||||
|
#else
|
||||||
|
{"rax", FIELD_OFFSET(KDB_KTRAP_FRAME, Rax), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rax)},
|
||||||
|
{"rbx", FIELD_OFFSET(KDB_KTRAP_FRAME, Rbx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rbx)},
|
||||||
|
{"rcx", FIELD_OFFSET(KDB_KTRAP_FRAME, Rcx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rcx)},
|
||||||
|
{"rdx", FIELD_OFFSET(KDB_KTRAP_FRAME, Rdx), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rdx)},
|
||||||
|
{"rsi", FIELD_OFFSET(KDB_KTRAP_FRAME, Rsi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rsi)},
|
||||||
|
{"rdi", FIELD_OFFSET(KDB_KTRAP_FRAME, Rdi), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rdi)},
|
||||||
|
{"rsp", FIELD_OFFSET(KDB_KTRAP_FRAME, Rsp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rsp)},
|
||||||
|
{"rbp", FIELD_OFFSET(KDB_KTRAP_FRAME, Rbp), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Rbp)},
|
||||||
|
#endif
|
||||||
{"cs", FIELD_OFFSET(KDB_KTRAP_FRAME, SegCs), 2 }, /* Use only the lower 2 bytes */
|
{"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)},
|
{"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)},
|
{"es", FIELD_OFFSET(KDB_KTRAP_FRAME, SegEs), RTL_FIELD_SIZE(KDB_KTRAP_FRAME, SegEs)},
|
||||||
|
@ -1009,7 +1025,7 @@ RpnpEvaluateStack(
|
||||||
|
|
||||||
if (!Ok)
|
if (!Ok)
|
||||||
{
|
{
|
||||||
_snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p);
|
_snprintf(ErrMsg, 128, "Couldn't access memory at 0x%p", p);
|
||||||
|
|
||||||
if (ErrOffset)
|
if (ErrOffset)
|
||||||
*ErrOffset = Op->CharacterOffset;
|
*ErrOffset = Op->CharacterOffset;
|
||||||
|
|
|
@ -979,7 +979,7 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
|
||||||
Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
|
Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
|
||||||
__sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
|
__sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
|
||||||
ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
|
ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
|
||||||
ProcessorState->SpecialRegisters.Ldtr = Ke386GetLocalDescriptorTable();
|
Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CODE_SEG("INIT")
|
CODE_SEG("INIT")
|
||||||
|
|
|
@ -395,6 +395,10 @@ if(NOT _WINKD_)
|
||||||
elseif(ARCH STREQUAL "amd64")
|
elseif(ARCH STREQUAL "amd64")
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c)
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kd/i386/kdbg.c)
|
||||||
|
if(KDBG)
|
||||||
|
list(APPEND ASM_SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/amd64/kdb_help.S)
|
||||||
|
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/i386/i386-dis.c)
|
||||||
|
endif()
|
||||||
elseif(ARCH STREQUAL "arm")
|
elseif(ARCH STREQUAL "arm")
|
||||||
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/arm/kdbg.c)
|
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/arm/kdbg.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue