[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:
Jérôme Gardou 2021-04-27 10:23:37 +02:00 committed by Jérôme Gardou
parent 439aefb31d
commit 3726b992ed
11 changed files with 396 additions and 124 deletions

View file

@ -119,25 +119,84 @@ extern ULONG KeI386CpuStep;
#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) \
((Context)->Rip)
FORCEINLINE
ULONG_PTR
KeGetContextPc(PCONTEXT Context)
{
return Context->Rip;
}
#define KeSetContextPc(Context, ProgramCounter) \
((Context)->Rip = (ProgramCounter))
FORCEINLINE
VOID
KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter)
{
Context->Rip = ProgramCounter;
}
#define KeGetTrapFramePc(TrapFrame) \
((TrapFrame)->Rip)
FORCEINLINE
ULONG_PTR
KeGetContextReturnRegister(PCONTEXT Context)
{
return Context->Rax;
}
#define KiGetLinkedTrapFrame(x) \
(PKTRAP_FRAME)((x)->TrapFrame)
FORCEINLINE
VOID
KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue)
{
Context->Rax = ReturnValue;
}
#define KeGetContextReturnRegister(Context) \
((Context)->Rax)
FORCEINLINE
ULONG_PTR
KeGetContextStackRegister(PCONTEXT Context)
{
return Context->Rsp;
}
#define KeSetContextReturnRegister(Context, ReturnValue) \
((Context)->Rax = (ReturnValue))
FORCEINLINE
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

View file

@ -2,16 +2,29 @@
#if defined(__GNUC__)
#define Ke386SetGlobalDescriptorTable(X) \
__asm__("lgdt %0\n\t" \
: /* no outputs */ \
: "m" (*X));
FORCEINLINE
VOID
__lgdt(_Out_ PVOID Descriptor)
{
PVOID* desc = Descriptor;
__asm__ __volatile__(
"lgdt %0"
: "=m" (*desc)
: /* no input */
: "memory");
}
#define Ke386GetGlobalDescriptorTable(X) \
__asm__("sgdt %0\n\t" \
: "=m" (*X) \
: /* no input */ \
: "memory");
FORCEINLINE
VOID
__sgdt(_Out_ PVOID Descriptor)
{
PVOID* desc = Descriptor;
__asm__ __volatile__(
"sgdt %0"
: "=m" (*desc)
: /* no input */
: "memory");
}
FORCEINLINE
VOID
@ -51,15 +64,14 @@ Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
}
FORCEINLINE
USHORT
Ke386GetLocalDescriptorTable(VOID)
VOID
__sldt(PVOID Descriptor)
{
USHORT Ldt;
__asm__("sldt %0\n\t"
: "=m" (Ldt)
: /* no input */
: "memory");
return Ldt;
__asm__ __volatile__(
"sldt %0"
: "=m" (*((short*)Descriptor))
: /* no input */
: "memory");
}
#define Ke386SetLocalDescriptorTable(X) \
@ -155,8 +167,6 @@ __fnsave(OUT PFLOATING_SAVE_AREA SaveArea)
__asm wait;
}
#define Ke386GetGlobalDescriptorTable __sgdt
FORCEINLINE
VOID
__lgdt(IN PVOID Descriptor)
@ -167,13 +177,17 @@ __lgdt(IN PVOID Descriptor)
lgdt [eax]
}
}
#define Ke386SetGlobalDescriptorTable __lgdt
FORCEINLINE
USHORT
Ke386GetLocalDescriptorTable(VOID)
VOID
__sldt(PVOID Descriptor)
{
__asm sldt ax;
__asm
{
sldt ax
mov ecx, Descriptor
mov [ecx], ax
}
}
FORCEINLINE
@ -305,4 +319,8 @@ Ke386SaveFpuState(IN PVOID SaveArea)
#error Unknown compiler for inline assembler
#endif
#define Ke386GetGlobalDescriptorTable __sgdt
#define Ke386SetGlobalDescriptorTable __lgdt
#define Ke386GetLocalDescriptorTable __sldt
/* EOF */

View file

@ -18,25 +18,80 @@
#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) \
((Context)->Eip)
FORCEINLINE
ULONG_PTR
KeGetContextPc(PCONTEXT Context)
{
return Context->Eip;
}
#define KeSetContextPc(Context, ProgramCounter) \
((Context)->Eip = (ProgramCounter))
FORCEINLINE
VOID
KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter)
{
Context->Eip = ProgramCounter;
}
#define KeGetTrapFramePc(TrapFrame) \
((TrapFrame)->Eip)
FORCEINLINE
ULONG_PTR
KeGetContextReturnRegister(PCONTEXT Context)
{
return Context->Eax;
}
#define KiGetLinkedTrapFrame(x) \
(PKTRAP_FRAME)((x)->Edx)
FORCEINLINE
VOID
KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue)
{
Context->Eax = ReturnValue;
}
#define KeGetContextReturnRegister(Context) \
((Context)->Eax)
FORCEINLINE
ULONG_PTR
KeGetContextFrameRegister(PCONTEXT Context)
{
return Context->Ebp;
}
#define KeSetContextReturnRegister(Context, ReturnValue) \
((Context)->Eax = (ReturnValue))
FORCEINLINE
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

View file

@ -611,7 +611,7 @@ KdSendPacket(
if (KdbgExceptionRecord.ExceptionCode == STATUS_ASSERTION_FAILURE)
{
/* Bump EIP to the instruction following the int 2C */
KdbgContext.Eip += 2;
KeSetContextPc(&KdbgContext, KeGetContextPc(&KdbgContext) + 2);
}
Result = KdbEnterDebuggerException(&KdbgExceptionRecord,

View file

View 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

View file

@ -650,14 +650,14 @@ KdbpIsBreakPointOurs(
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++)
{
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;
}
@ -1321,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! */
Context->Eip--;
KeSetContextPc(Context, KeGetContextPc(Context) - 1);
}
if ((BreakPoint->Type == KdbBreakPointHardware) &&
@ -1345,8 +1345,8 @@ KdbEnterDebuggerException(
if (--KdbNumSingleSteps > 0)
{
if ((KdbSingleStepOver && !KdbpStepOverInstruction(Context->Eip)) ||
(!KdbSingleStepOver && !KdbpStepIntoInstruction(Context->Eip)))
if ((KdbSingleStepOver && !KdbpStepOverInstruction(KeGetContextPc(Context))) ||
(!KdbSingleStepOver && !KdbpStepIntoInstruction(KeGetContextPc(Context))))
{
Context->EFlags |= EFLAGS_TF;
}
@ -1394,8 +1394,8 @@ KdbEnterDebuggerException(
if (BreakPoint->Type == KdbBreakPointSoftware)
{
KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%08x\n",
KdbLastBreakPointNr, Context->SegCs & 0xffff, Context->Eip);
KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%p\n",
KdbLastBreakPointNr, Context->SegCs & 0xffff, KeGetContextPc(Context));
}
else if (BreakPoint->Type == KdbBreakPointHardware)
{
@ -1448,8 +1448,8 @@ KdbEnterDebuggerException(
/*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
if (--KdbNumSingleSteps > 0)
{
if ((KdbSingleStepOver && KdbpStepOverInstruction(Context->Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(Context->Eip)))
if ((KdbSingleStepOver && KdbpStepOverInstruction(KeGetContextPc(Context))) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KeGetContextPc(Context))))
{
Context->EFlags &= ~EFLAGS_TF;
}
@ -1488,8 +1488,8 @@ KdbEnterDebuggerException(
return kdHandleException;
}
KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%08x.\n",
Context->SegCs & 0xffff, Context->Eip - 1);
KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
Context->SegCs & 0xffff, KeGetContextPc(Context) - 1);
}
else
{
@ -1552,8 +1552,8 @@ KdbEnterDebuggerException(
/* Variable explains itself! */
KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep = TRUE;
if ((KdbSingleStepOver && KdbpStepOverInstruction(KdbCurrentTrapFrame->Eip)) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KdbCurrentTrapFrame->Eip)))
if ((KdbSingleStepOver && KdbpStepOverInstruction(KeGetContextPc(KdbCurrentTrapFrame))) ||
(!KdbSingleStepOver && KdbpStepIntoInstruction(KeGetContextPc(KdbCurrentTrapFrame))))
{
ASSERT((KdbCurrentTrapFrame->EFlags & EFLAGS_TF) == 0);
/*KdbCurrentTrapFrame->EFlags &= ~EFLAGS_TF;*/
@ -1608,7 +1608,7 @@ continue_execution:
if (!(KdbEnteredOnSingleStep && KdbSingleStepOver))
{
/* Skip the current instruction */
Context->Eip++;
KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
}
}
@ -1625,7 +1625,10 @@ KdbEnterDebuggerFirstChanceException(
/* 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;
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);
/* Create ExceptionRecord (assume breakpoint) */

View file

@ -82,7 +82,9 @@ static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
#ifdef _M_IX86
static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
#endif
static BOOLEAN KdbpCmdBugCheck(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[]);
#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 *******************************************************************/
typedef
@ -376,7 +398,9 @@ static const struct
{ "ldt", "ldt", "Display the local descriptor table.", KdbpCmdGdtLdtIdt },
{ "idt", "idt", "Display the interrupt descriptor table.", KdbpCmdGdtLdtIdt },
{ "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 },
#endif
/* Others */
{ NULL, NULL, "Others", NULL },
@ -793,7 +817,7 @@ KdbpCmdDisassembleX(
ULONG ul;
INT i;
ULONGLONG Result = 0;
ULONG_PTR Address = KdbCurrentTrapFrame->Eip;
ULONG_PTR Address = KeGetContextPc(KdbCurrentTrapFrame);
LONG InstLen;
if (Argv[0][0] == 'x') /* display memory */
@ -922,6 +946,7 @@ KdbpCmdRegs(
if (Argv[0][0] == 'r') /* regs */
{
#ifdef _M_IX86
KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
"SS:ESP 0x%04x:0x%08x\n"
" EAX 0x%08x EBX 0x%08x\n"
@ -934,7 +959,20 @@ KdbpCmdRegs(
Context->Ecx, Context->Edx,
Context->Esi, Context->Edi,
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 */
KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
for (i = 0; i < 32; i++)
@ -990,6 +1028,7 @@ KdbpCmdRegs(
return TRUE;
}
#ifdef _M_IX86
static PKTSS
KdbpRetrieveTss(
IN USHORT TssSelector,
@ -1102,6 +1141,7 @@ KdbpContextFromPrevTss(
Context->Ebp = Ebp;
return TRUE;
}
#endif
/*!\brief Displays a backtrace.
*/
@ -1113,11 +1153,8 @@ KdbpCmdBackTrace(
ULONG ul;
ULONGLONG Result = 0;
CONTEXT Context = *KdbCurrentTrapFrame;
ULONG_PTR Frame = Context.Ebp;
ULONG_PTR Frame = KeGetContextFrameRegister(&Context);
ULONG_PTR Address;
KDESCRIPTOR Gdtr;
USHORT TssSelector;
PKTSS Tss;
if (Argc >= 2)
{
@ -1172,6 +1209,11 @@ KdbpCmdBackTrace(
}
}
#ifdef _M_IX86
KDESCRIPTOR Gdtr;
USHORT TssSelector;
PKTSS Tss;
/* Retrieve the Global Descriptor Table */
Ke386GetGlobalDescriptorTable(&Gdtr.Limit);
@ -1183,13 +1225,14 @@ KdbpCmdBackTrace(
/* Display the active TSS if it is nested */
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 (Argc <= 1)
{
KdbpPrint("Eip:\n");
if (!KdbSymPrintAddress((PVOID)Context.Eip, &Context))
KdbpPrint("<%08x>\n", Context.Eip);
if (!KdbSymPrintAddress((PVOID)KeGetContextPc(&Context), &Context))
KdbpPrint("<%p>\n", KeGetContextPc(&Context));
else
KdbpPrint("\n");
}
@ -1215,7 +1258,9 @@ KdbpCmdBackTrace(
GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
if (GotNextFrame)
Context.Ebp = Frame;
{
KeSetContextFrameRegister(&Context, Frame);
}
// else
// Frame = 0;
@ -1237,6 +1282,9 @@ KdbpCmdBackTrace(
continue;
CheckForParentTSS:
#ifndef _M_IX86
break;
#else
/*
* We have ended the stack walking for the current (active) TSS.
* 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);
break; // Cannot retrieve the parent TSS, we stop there.
}
Address = Context.Eip;
Frame = Context.Ebp;
@ -1260,6 +1310,7 @@ CheckForParentTSS:
KdbpPrint("<%08x>\n", Address);
else
KdbpPrint("\n");
#endif
}
return TRUE;
@ -1359,8 +1410,8 @@ KdbpCmdBreakPointList(
else
{
GlobalOrLocal = Buffer;
sprintf(Buffer, " PID 0x%08lx",
(ULONG)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
sprintf(Buffer, " PID 0x%lx",
(ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
}
if (Type == KdbBreakPointSoftware || Type == KdbBreakPointTemporary)
@ -1579,10 +1630,10 @@ KdbpCmdThread(
PETHREAD Thread = NULL;
PEPROCESS Process = NULL;
BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
PULONG Esp;
PULONG Ebp;
ULONG Eip;
ULONG ul = 0;
PULONG_PTR Stack;
PULONG_PTR Frame;
ULONG_PTR Pc;
ULONG_PTR ul = 0;
PCHAR State, pend, str1, str2;
static const PCHAR ThreadStateToString[DeferredReady+1] =
{
@ -1599,7 +1650,7 @@ KdbpCmdThread(
if (Argc >= 3)
{
ul = strtoul(Argv[2], &pend, 0);
ul = strtoulptr(Argv[2], &pend, 0);
if (Argv[2] == pend)
{
KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
@ -1620,7 +1671,7 @@ KdbpCmdThread(
if (Entry == &Process->ThreadListHead)
{
if (Argc >= 3)
KdbpPrint("No threads in process 0x%08x!\n", ul);
KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
else
KdbpPrint("No threads in current process!\n");
@ -1649,27 +1700,23 @@ KdbpCmdThread(
if (!Thread->Tcb.InitialStack)
{
/* Thread has no kernel stack (probably terminated) */
Esp = Ebp = NULL;
Eip = 0;
Stack = Frame = NULL;
Pc = 0;
}
else if (Thread->Tcb.TrapFrame)
{
if (Thread->Tcb.TrapFrame->PreviousPreviousMode == KernelMode)
Esp = (PULONG)Thread->Tcb.TrapFrame->TempEsp;
else
Esp = (PULONG)Thread->Tcb.TrapFrame->HardwareEsp;
Ebp = (PULONG)Thread->Tcb.TrapFrame->Ebp;
Eip = Thread->Tcb.TrapFrame->Eip;
Stack = (PULONG_PTR)KeGetTrapFrameStackRegister(Thread->Tcb.TrapFrame);
Frame = (PULONG_PTR)KeGetTrapFrameFrameRegister(Thread->Tcb.TrapFrame);
Pc = KeGetTrapFramePc(Thread->Tcb.TrapFrame);
}
else
{
Esp = (PULONG)Thread->Tcb.KernelStack;
Ebp = (PULONG)Esp[4];
Eip = 0;
Stack = (PULONG_PTR)Thread->Tcb.KernelStack;
Frame = (PULONG_PTR)Stack[4];
Pc = 0;
if (Ebp) /* FIXME: Should we attach to the process to read Ebp[1]? */
KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof(Eip));
if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
}
if (Thread->Tcb.State < (DeferredReady + 1))
@ -1683,8 +1730,8 @@ KdbpCmdThread(
State,
Thread->Tcb.Priority,
Thread->Tcb.Affinity,
Ebp,
Eip,
Frame,
Pc,
str2);
Entry = Entry->Flink;
@ -1703,7 +1750,7 @@ KdbpCmdThread(
return TRUE;
}
ul = strtoul(Argv[2], &pend, 0);
ul = strtoulptr(Argv[2], &pend, 0);
if (Argv[2] == pend)
{
KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
@ -1723,7 +1770,7 @@ KdbpCmdThread(
if (Argc >= 2)
{
ul = strtoul(Argv[1], &pend, 0);
ul = strtoulptr(Argv[1], &pend, 0);
if (Argv[1] == pend)
{
KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
@ -1765,8 +1812,11 @@ KdbpCmdThread(
Thread->Tcb.StackLimit,
Thread->Tcb.StackBase,
Thread->Tcb.KernelStack,
Thread->Tcb.TrapFrame,
NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState);
Thread->Tcb.TrapFrame
#ifndef _M_AMD64
, NPX_STATE_TO_STRING(Thread->Tcb.NpxState), Thread->Tcb.NpxState
#endif
);
/* Release our reference if we had one */
if (ReferencedThread)
@ -1787,7 +1837,7 @@ KdbpCmdProc(
PEPROCESS Process;
BOOLEAN ReferencedProcess = FALSE;
PCHAR State, pend, str1, str2;
ULONG ul;
ULONG_PTR ul;
extern LIST_ENTRY PsActiveProcessHead;
if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
@ -1837,7 +1887,7 @@ KdbpCmdProc(
return TRUE;
}
ul = strtoul(Argv[2], &pend, 0);
ul = strtoulptr(Argv[2], &pend, 0);
if (Argv[2] == pend)
{
KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
@ -1849,8 +1899,8 @@ KdbpCmdProc(
return TRUE;
}
KdbpPrint("Attached to process 0x%08x, thread 0x%08x.\n", (ULONG)ul,
(ULONG)KdbCurrentThread->Cid.UniqueThread);
KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
KdbCurrentThread->Cid.UniqueThread);
}
else
{
@ -1858,7 +1908,7 @@ KdbpCmdProc(
if (Argc >= 2)
{
ul = strtoul(Argv[1], &pend, 0);
ul = strtoulptr(Argv[1], &pend, 0);
if (Argv[1] == pend)
{
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)
{
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;
}
@ -2046,7 +2096,7 @@ KdbpCmdGdtLdtIdt(
ASSERT(Argv[0][0] == 'l');
/* Read LDTR */
Reg.Limit = Ke386GetLocalDescriptorTable();
Ke386GetLocalDescriptorTable(&Reg.Limit);
Reg.Base = 0;
i = 0;
ul = 1 << 2;
@ -2065,9 +2115,9 @@ KdbpCmdGdtLdtIdt(
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;
}
@ -2194,36 +2244,80 @@ KdbpCmdPcr(
" Tib.FiberData/Version: 0x%08x\n"
" Tib.ArbitraryUserPointer: 0x%08x\n"
" Tib.Self: 0x%08x\n"
#ifdef _M_IX86
" SelfPcr: 0x%08x\n"
#else
" Self: 0x%p\n"
#endif
" PCRCB: 0x%08x\n"
" Irql: 0x%02x\n"
#ifdef _M_IX86
" IRR: 0x%08x\n"
" IrrActive: 0x%08x\n"
" IDR: 0x%08x\n"
#endif
" KdVersionBlock: 0x%08x\n"
#ifdef _M_IX86
" IDT: 0x%08x\n"
" GDT: 0x%08x\n"
" TSS: 0x%08x\n"
#endif
" MajorVersion: 0x%04x\n"
" MinorVersion: 0x%04x\n"
#ifdef _M_IX86
" SetMember: 0x%08x\n"
#endif
" StallScaleFactor: 0x%08x\n"
#ifdef _M_IX86
" Number: 0x%02x\n"
#endif
" L2CacheAssociativity: 0x%02x\n"
#ifdef _M_IX86
" VdmAlert: 0x%08x\n"
#endif
" L2CacheSize: 0x%08x\n"
" InterruptMode: 0x%08x\n",
Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
#ifdef _M_IX86
" 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.Self, Pcr->SelfPcr, Pcr->Prcb, Pcr->Irql, Pcr->IRR, Pcr->IrrActive,
Pcr->IDR, Pcr->KdVersionBlock, Pcr->IDT, Pcr->GDT, Pcr->TSS,
Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
Pcr->Number, Pcr->SecondLevelCacheAssociativity,
Pcr->VdmAlert, Pcr->SecondLevelCacheSize, Pcr->InterruptMode);
Pcr->NtTib.Self
#ifdef _M_IX86
, Pcr->SelfPcr
#else
, 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;
}
#ifdef _M_IX86
/*!\brief Displays the TSS
*/
static BOOLEAN
@ -2321,6 +2415,7 @@ KdbpCmdTss(
return TRUE;
}
#endif
/*!\brief Bugchecks the system.
*/
@ -3613,13 +3708,13 @@ KdbpCliMainLoop(
if (EnteredOnSingleStep)
{
if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Eip, KdbCurrentTrapFrame))
if (!KdbSymPrintAddress((PVOID)KeGetContextPc(KdbCurrentTrapFrame), KdbCurrentTrapFrame))
{
KdbpPrint("<%08x>", KdbCurrentTrapFrame->Eip);
KdbpPrint("<%p>", KeGetContextPc(KdbCurrentTrapFrame));
}
KdbpPrint(": ");
if (KdbpDisassemble(KdbCurrentTrapFrame->Eip, KdbUseIntelSyntax) < 0)
if (KdbpDisassemble(KeGetContextPc(KdbCurrentTrapFrame), KdbUseIntelSyntax) < 0)
{
KdbpPrint("<INVALID>");
}

View file

@ -111,8 +111,14 @@ static const struct
}
RegisterToTrapFrame[] =
{
/* FIXME: X86 only */
#ifdef _M_IX86
{"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)},
#ifdef _M_IX86
{"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)},
@ -121,6 +127,16 @@ RegisterToTrapFrame[] =
{"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)},
#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 */
{"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)},
@ -1009,7 +1025,7 @@ RpnpEvaluateStack(
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)
*ErrOffset = Op->CharacterOffset;

View file

@ -979,7 +979,7 @@ KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
__sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
ProcessorState->SpecialRegisters.Ldtr = Ke386GetLocalDescriptorTable();
Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
}
CODE_SEG("INIT")

View file

@ -395,6 +395,10 @@ if(NOT _WINKD_)
elseif(ARCH STREQUAL "amd64")
list(APPEND SOURCE
${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")
list(APPEND SOURCE ${REACTOS_SOURCE_DIR}/ntoskrnl/kd/arm/kdbg.c)
endif()