https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3726b992ed3631c3571df…
commit 3726b992ed3631c3571df056da70839c35a05582
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Tue Apr 27 10:23:37 2021 +0200
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Wed Apr 28 13:10:23 2021 +0200
[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
---
ntoskrnl/include/internal/amd64/ke.h | 85 ++++++++++--
ntoskrnl/include/internal/i386/intrin_i.h | 64 +++++----
ntoskrnl/include/internal/i386/ke.h | 81 ++++++++++--
ntoskrnl/kd/kdio.c | 2 +-
ntoskrnl/kdbg/amd64/amd64-dis.c | 0
ntoskrnl/kdbg/amd64/kdb_help.S | 22 ++++
ntoskrnl/kdbg/kdb.c | 33 ++---
ntoskrnl/kdbg/kdb_cli.c | 209 ++++++++++++++++++++++--------
ntoskrnl/kdbg/kdb_expr.c | 18 ++-
ntoskrnl/ke/i386/cpu.c | 2 +-
ntoskrnl/ntos.cmake | 4 +
11 files changed, 396 insertions(+), 124 deletions(-)
diff --git a/ntoskrnl/include/internal/amd64/ke.h b/ntoskrnl/include/internal/amd64/ke.h
index d4e1354290d..9917b9334cd 100644
--- a/ntoskrnl/include/internal/amd64/ke.h
+++ b/ntoskrnl/include/internal/amd64/ke.h
@@ -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;
+}
+
+FORCEINLINE
+ULONG_PTR
+KeGetContextStackRegister(PCONTEXT Context)
+{
+ return Context->Rsp;
+}
-#define KeGetContextReturnRegister(Context) \
- ((Context)->Rax)
+FORCEINLINE
+ULONG_PTR
+KeGetContextFrameRegister(PCONTEXT Context)
+{
+ return Context->Rbp;
+}
-#define KeSetContextReturnRegister(Context, ReturnValue) \
- ((Context)->Rax = (ReturnValue))
+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
diff --git a/ntoskrnl/include/internal/i386/intrin_i.h
b/ntoskrnl/include/internal/i386/intrin_i.h
index 76e391e10ba..a458be957fb 100644
--- a/ntoskrnl/include/internal/i386/intrin_i.h
+++ b/ntoskrnl/include/internal/i386/intrin_i.h
@@ -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 */
diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h
index e91b8d6ad16..58adbf52906 100644
--- a/ntoskrnl/include/internal/i386/ke.h
+++ b/ntoskrnl/include/internal/i386/ke.h
@@ -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;
+}
+
+FORCEINLINE
+VOID
+KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter)
+{
+ Context->Eip = ProgramCounter;
+}
+
+FORCEINLINE
+ULONG_PTR
+KeGetContextReturnRegister(PCONTEXT Context)
+{
+ return Context->Eax;
+}
+
+FORCEINLINE
+VOID
+KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue)
+{
+ Context->Eax = ReturnValue;
+}
+
+FORCEINLINE
+ULONG_PTR
+KeGetContextFrameRegister(PCONTEXT Context)
+{
+ return Context->Ebp;
+}
-#define KeSetContextPc(Context, ProgramCounter) \
- ((Context)->Eip = (ProgramCounter))
+FORCEINLINE
+VOID
+KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
+{
+ Context->Ebp = Frame;
+}
+
+FORCEINLINE
+ULONG_PTR
+KeGetTrapFramePc(PKTRAP_FRAME TrapFrame)
+{
+ return TrapFrame->Eip;
+}
-#define KeGetTrapFramePc(TrapFrame) \
- ((TrapFrame)->Eip)
+FORCEINLINE
+PKTRAP_FRAME
+KiGetLinkedTrapFrame(PKTRAP_FRAME TrapFrame)
+{
+ return (PKTRAP_FRAME)TrapFrame->Edx;
+}
-#define KiGetLinkedTrapFrame(x) \
- (PKTRAP_FRAME)((x)->Edx)
-#define KeGetContextReturnRegister(Context) \
- ((Context)->Eax)
+FORCEINLINE
+ULONG_PTR
+KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
+{
+ if (TrapFrame->PreviousPreviousMode == KernelMode)
+ return TrapFrame->TempEsp;
+ return TrapFrame->HardwareEsp;
+}
-#define KeSetContextReturnRegister(Context, ReturnValue) \
- ((Context)->Eax = (ReturnValue))
+FORCEINLINE
+ULONG_PTR
+KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
+{
+ return TrapFrame->Ebp;
+}
//
// Macro to get trap and exception frame from a thread stack
diff --git a/ntoskrnl/kd/kdio.c b/ntoskrnl/kd/kdio.c
index af7accb3afc..9c35c9586e9 100644
--- a/ntoskrnl/kd/kdio.c
+++ b/ntoskrnl/kd/kdio.c
@@ -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,
diff --git a/ntoskrnl/kdbg/amd64/amd64-dis.c b/ntoskrnl/kdbg/amd64/amd64-dis.c
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/ntoskrnl/kdbg/amd64/kdb_help.S b/ntoskrnl/kdbg/amd64/kdb_help.S
new file mode 100644
index 00000000000..39ae8721f8e
--- /dev/null
+++ b/ntoskrnl/kdbg/amd64/kdb_help.S
@@ -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
diff --git a/ntoskrnl/kdbg/kdb.c b/ntoskrnl/kdbg/kdb.c
index f9a3b8792bb..8ec2e3bef1d 100644
--- a/ntoskrnl/kdbg/kdb.c
+++ b/ntoskrnl/kdbg/kdb.c
@@ -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) */
diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c
index 50805fe9f66..01473e99b0d 100644
--- a/ntoskrnl/kdbg/kdb_cli.c
+++ b/ntoskrnl/kdbg/kdb_cli.c
@@ -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>");
}
diff --git a/ntoskrnl/kdbg/kdb_expr.c b/ntoskrnl/kdbg/kdb_expr.c
index 9a1924852b6..69a57d8e8ae 100644
--- a/ntoskrnl/kdbg/kdb_expr.c
+++ b/ntoskrnl/kdbg/kdb_expr.c
@@ -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;
diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c
index 043ab2b62d2..3b07453af53 100644
--- a/ntoskrnl/ke/i386/cpu.c
+++ b/ntoskrnl/ke/i386/cpu.c
@@ -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")
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index c392bcd95ec..dbb9f911016 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -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()