mirror of
https://github.com/reactos/reactos.git
synced 2026-06-09 01:12:59 +08:00
[KDBG] Fix x64 KDBG
This commit is contained in:
@@ -22,6 +22,12 @@ EX_PUSH_LOCK HandleTableListLock;
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
#ifdef _WIN64
|
||||
#define strtoulptr strtoull
|
||||
#else
|
||||
#define strtoulptr strtoul
|
||||
#endif
|
||||
|
||||
CODE_SEG("INIT")
|
||||
VOID
|
||||
NTAPI
|
||||
@@ -1360,7 +1366,7 @@ BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessId = (HANDLE)strtoul(Argv[1], &endptr, 10);
|
||||
ProcessId = (HANDLE)strtoulptr(Argv[1], &endptr, 10);
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
KdbpPrint("Invalid parameter: %s\n", Argv[1]);
|
||||
|
||||
@@ -1,22 +1,162 @@
|
||||
|
||||
#include <asm.inc>
|
||||
|
||||
#include <ksamd64.inc>
|
||||
|
||||
.code64
|
||||
|
||||
EXTERN KdbEnterDebuggerException : PROC
|
||||
|
||||
PUBLIC KdbEnter
|
||||
FUNC KdbEnter
|
||||
|
||||
/* save flags */
|
||||
pushfq
|
||||
.allocstack 8
|
||||
|
||||
/* Make room for a KTRAP_FRAME */
|
||||
sub rsp, KTRAP_FRAME_LENGTH
|
||||
.allocstack KTRAP_FRAME_LENGTH
|
||||
.ENDPROLOG
|
||||
|
||||
/* Save rbp */
|
||||
mov [rsp + KTRAP_FRAME_Rbp], rbp
|
||||
|
||||
/* Save non-volatile registers */
|
||||
mov [rsp + KTRAP_FRAME_Rbx], rbx
|
||||
mov [rsp + KTRAP_FRAME_Rdi], rdi
|
||||
mov [rsp + KTRAP_FRAME_Rsi], rsi
|
||||
|
||||
/* Save volatile registers */
|
||||
mov [rsp + KTRAP_FRAME_Rax], rax
|
||||
mov [rsp + KTRAP_FRAME_Rcx], rcx
|
||||
mov [rsp + KTRAP_FRAME_Rdx], rdx
|
||||
mov [rsp + KTRAP_FRAME_R8], r8
|
||||
mov [rsp + KTRAP_FRAME_R9], r9
|
||||
mov [rsp + KTRAP_FRAME_R10], r10
|
||||
mov [rsp + KTRAP_FRAME_R11], r11
|
||||
|
||||
/* Save xmm registers */
|
||||
movdqa [rsp + KTRAP_FRAME_Xmm0], xmm0
|
||||
movdqa [rsp + KTRAP_FRAME_Xmm1], xmm1
|
||||
movdqa [rsp + KTRAP_FRAME_Xmm2], xmm2
|
||||
movdqa [rsp + KTRAP_FRAME_Xmm3], xmm3
|
||||
movdqa [rsp + KTRAP_FRAME_Xmm4], xmm4
|
||||
movdqa [rsp + KTRAP_FRAME_Xmm5], xmm5
|
||||
|
||||
/* Save cs and previous mode */
|
||||
mov ax, cs
|
||||
mov [rsp + KTRAP_FRAME_SegCs], ax
|
||||
and ax, 1
|
||||
mov [rsp + KTRAP_FRAME_PreviousMode], al
|
||||
|
||||
/* Save segment selectors */
|
||||
mov ax, ds
|
||||
mov [rsp + KTRAP_FRAME_SegDs], ax
|
||||
mov ax, es
|
||||
mov [rsp + KTRAP_FRAME_SegEs], ax
|
||||
mov ax, fs
|
||||
mov [rsp + KTRAP_FRAME_SegFs], ax
|
||||
mov ax, gs
|
||||
mov [rsp + KTRAP_FRAME_SegGs], ax
|
||||
|
||||
/* Save previous irql */
|
||||
mov rax, cr8
|
||||
mov [rsp + KTRAP_FRAME_PreviousIrql], al
|
||||
|
||||
/* Save debug registers */
|
||||
mov rax, dr0
|
||||
mov [rsp + KTRAP_FRAME_Dr0], rax
|
||||
mov rax, dr1
|
||||
mov [rsp + KTRAP_FRAME_Dr1], rax
|
||||
mov rax, dr2
|
||||
mov [rsp + KTRAP_FRAME_Dr2], rax
|
||||
mov rax, dr3
|
||||
mov [rsp + KTRAP_FRAME_Dr3], rax
|
||||
mov rax, dr6
|
||||
mov [rsp + KTRAP_FRAME_Dr6], rax
|
||||
mov rax, dr7
|
||||
mov [rsp + KTRAP_FRAME_Dr7], rax
|
||||
|
||||
/* Point rbp, where rsp was before */
|
||||
lea rbp, [rsp + KTRAP_FRAME_LENGTH]
|
||||
mov [rsp + KTRAP_FRAME_Rsp], rbp
|
||||
|
||||
/* Store the EFLAGS we previously pushed on the stack */
|
||||
mov rax, [rbp + 8]
|
||||
mov [rsp + KTRAP_FRAME_EFlags], rax
|
||||
|
||||
/* Get RIP from the stack */
|
||||
mov rax, [rbp + 16]
|
||||
mov [rsp + KTRAP_FRAME_Rip], rax
|
||||
|
||||
/* Make sure the direction flag is cleared */
|
||||
cld
|
||||
|
||||
/* Clear all breakpoint enables in dr7. */
|
||||
mov rax, dr7
|
||||
and rax, HEX(ffffffffFFFF0000)
|
||||
mov dr7, rax
|
||||
|
||||
/* Call KDB */
|
||||
mov byte ptr [rsp + KTRAP_FRAME_P5], 1 /* FirstChance */
|
||||
mov r9, rsp /* Pointer to the trap frame */
|
||||
mov r8, 0 /* Context */
|
||||
mov dl, 0 /* PreviousMode (KernelMode) */
|
||||
mov rcx, 0 /* ExceptionRecord */
|
||||
call KdbEnterDebuggerException
|
||||
|
||||
/* Restore segment selectors */
|
||||
mov ax, [rsp + KTRAP_FRAME_SegDs]
|
||||
mov ds, ax
|
||||
mov ax, [rsp + KTRAP_FRAME_SegEs]
|
||||
mov es, ax
|
||||
mov ax, [rsp + KTRAP_FRAME_SegFs]
|
||||
mov fs, ax
|
||||
|
||||
/* Restore non-volatile registers */
|
||||
mov rbx, [rsp + KTRAP_FRAME_Rbx]
|
||||
mov rdi, [rsp + KTRAP_FRAME_Rdi]
|
||||
mov rsi, [rsp + KTRAP_FRAME_Rsi]
|
||||
|
||||
/* Restore volatile registers */
|
||||
mov rax, [rsp + KTRAP_FRAME_Rax]
|
||||
mov rcx, [rsp + KTRAP_FRAME_Rcx]
|
||||
mov rdx, [rsp + KTRAP_FRAME_Rdx]
|
||||
mov r8, [rsp + KTRAP_FRAME_R8]
|
||||
mov r9, [rsp + KTRAP_FRAME_R9]
|
||||
mov r10, [rsp + KTRAP_FRAME_R10]
|
||||
mov r11, [rsp + KTRAP_FRAME_R11]
|
||||
|
||||
/* Restore RSP */
|
||||
mov rsp, [rsp + KTRAP_FRAME_Rsp]
|
||||
|
||||
/* Restore EFLAGS */
|
||||
popfq
|
||||
|
||||
ret
|
||||
ENDFUNC
|
||||
|
||||
PUBLIC KdbpStackSwitchAndCall
|
||||
KdbpStackSwitchAndCall:
|
||||
push rbp
|
||||
mov rbp, rsp /* Old stack - frame */
|
||||
|
||||
/* Switch stack */
|
||||
/* Save old stack */
|
||||
mov rax, rsp
|
||||
|
||||
/* Set new stack */
|
||||
mov rsp, rcx
|
||||
|
||||
/* Save old stack on new stack */
|
||||
push rax
|
||||
|
||||
/* Call function */
|
||||
call rdx
|
||||
|
||||
/* Switch back to old stack */
|
||||
pop rsp
|
||||
/* Restore old stack */
|
||||
pop rax
|
||||
mov rsp, rax
|
||||
|
||||
ret 8
|
||||
/* Return */
|
||||
ret
|
||||
|
||||
END
|
||||
|
||||
@@ -22,11 +22,11 @@ typedef enum bfd_architecture
|
||||
{
|
||||
bfd_arch_i386,
|
||||
} bfd_arch;
|
||||
typedef unsigned int bfd_vma;
|
||||
typedef uintptr_t bfd_vma;
|
||||
typedef unsigned char bfd_byte;
|
||||
enum bfd_endian { BFD_ENDIAN_BIG, BIG_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
|
||||
typedef void* bfd;
|
||||
typedef signed int bfd_signed_vma;
|
||||
typedef intptr_t bfd_signed_vma;
|
||||
#define bfd_mach_x86_64_intel_syntax 0
|
||||
#define bfd_mach_x86_64 1
|
||||
#define bfd_mach_i386_i386_intel_syntax 2
|
||||
@@ -36,7 +36,7 @@ typedef signed int bfd_signed_vma;
|
||||
#define _(X) X
|
||||
#define ATTRIBUTE_UNUSED
|
||||
extern int sprintf(char *str, const char *format, ...);
|
||||
#define sprintf_vma(BUF, VMA) sprintf(BUF, "0x%X", VMA)
|
||||
#define sprintf_vma(BUF, VMA) sprintf(BUF, "0x%IX", VMA)
|
||||
struct disassemble_info;
|
||||
|
||||
int
|
||||
@@ -63,20 +63,20 @@ KdbpNopPrintDisasm(void* Ignored, const char* fmt, ...)
|
||||
}
|
||||
|
||||
static int
|
||||
KdbpReadMemory(unsigned int Addr, unsigned char* Data, unsigned int Length,
|
||||
KdbpReadMemory(uintptr_t Addr, unsigned char* Data, unsigned int Length,
|
||||
struct disassemble_info * Ignored)
|
||||
{
|
||||
return KdbpSafeReadMemory(Data, (void *)Addr, Length); /* 0 means no error */
|
||||
}
|
||||
|
||||
static void
|
||||
KdbpMemoryError(int Status, unsigned int Addr,
|
||||
KdbpMemoryError(int Status, uintptr_t Addr,
|
||||
struct disassemble_info * Ignored)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
KdbpPrintAddressInCode(unsigned int Addr, struct disassemble_info * Ignored)
|
||||
KdbpPrintAddressInCode(uintptr_t Addr, struct disassemble_info * Ignored)
|
||||
{
|
||||
if (!KdbSymPrintAddress((void*)Addr, NULL))
|
||||
{
|
||||
@@ -85,14 +85,14 @@ KdbpPrintAddressInCode(unsigned int Addr, struct disassemble_info * Ignored)
|
||||
}
|
||||
|
||||
static void
|
||||
KdbpNopPrintAddress(unsigned int Addr, struct disassemble_info * Ignored)
|
||||
KdbpNopPrintAddress(uintptr_t Addr, struct disassemble_info * Ignored)
|
||||
{
|
||||
}
|
||||
|
||||
#include "dis-asm.h"
|
||||
|
||||
LONG
|
||||
KdbpGetInstLength(IN ULONG Address)
|
||||
KdbpGetInstLength(IN ULONG_PTR Address)
|
||||
{
|
||||
disassemble_info info;
|
||||
|
||||
@@ -101,7 +101,11 @@ KdbpGetInstLength(IN ULONG Address)
|
||||
info.application_data = NULL;
|
||||
info.flavour = bfd_target_unknown_flavour;
|
||||
info.arch = bfd_arch_i386;
|
||||
#ifdef _M_AMD64
|
||||
info.mach = bfd_mach_x86_64;
|
||||
#else
|
||||
info.mach = bfd_mach_i386_i386;
|
||||
#endif
|
||||
info.insn_sets = 0;
|
||||
info.flags = 0;
|
||||
info.read_memory_func = KdbpReadMemory;
|
||||
@@ -118,7 +122,7 @@ KdbpGetInstLength(IN ULONG Address)
|
||||
}
|
||||
|
||||
LONG
|
||||
KdbpDisassemble(IN ULONG Address, IN ULONG IntelSyntax)
|
||||
KdbpDisassemble(IN ULONG_PTR Address, IN ULONG IntelSyntax)
|
||||
{
|
||||
disassemble_info info;
|
||||
|
||||
@@ -263,7 +267,11 @@ struct dis_private {
|
||||
#define FWAIT_OPCODE (0x9b)
|
||||
|
||||
/* Set to 1 for 64bit mode disassembly. */
|
||||
#ifdef _M_AMD64
|
||||
static int mode_64bit = 1;
|
||||
#else
|
||||
static int mode_64bit;
|
||||
#endif
|
||||
|
||||
/* Flags for the prefixes for the current instruction. See below. */
|
||||
static int prefixes;
|
||||
@@ -2079,7 +2087,7 @@ static int
|
||||
print_insn (bfd_vma pc, disassemble_info *info)
|
||||
{
|
||||
const struct dis386 *dp;
|
||||
int i;
|
||||
intptr_t i;
|
||||
char *first, *second, *third;
|
||||
int needcomma;
|
||||
unsigned char uses_SSE_prefix;
|
||||
@@ -2151,8 +2159,12 @@ print_insn (bfd_vma pc, disassemble_info *info)
|
||||
if (p != NULL)
|
||||
p++;
|
||||
}
|
||||
#else
|
||||
#ifdef _M_AMD64
|
||||
mode_64bit = 1;
|
||||
#else
|
||||
mode_64bit = 0;
|
||||
#endif
|
||||
priv.orig_sizeflag = AFLAG | DFLAG;
|
||||
/*intel_syntax = 0;*/
|
||||
#endif
|
||||
@@ -3188,7 +3200,7 @@ print_operand_value (char *buf, int hex, bfd_vma disp)
|
||||
if (v < 0)
|
||||
{
|
||||
*(buf++) = '-';
|
||||
v = -disp;
|
||||
v = -v;
|
||||
/* Check for possible overflow on 0x8000000000000000. */
|
||||
if (v < 0)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
/* DEFINES *******************************************************************/
|
||||
|
||||
#define KDB_STACK_SIZE (4096*3)
|
||||
#ifdef _M_AMD64
|
||||
#define KDB_STACK_ALIGN 16
|
||||
#define KDB_STACK_RESERVE (5 * sizeof(PVOID)) /* Home space + return address */
|
||||
#else
|
||||
#define KDB_STACK_ALIGN 4
|
||||
#define KDB_STACK_RESERVE sizeof(ULONG) /* Return address */
|
||||
#endif
|
||||
#define KDB_MAXIMUM_BREAKPOINT_COUNT 256
|
||||
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT 4
|
||||
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT 256
|
||||
@@ -28,7 +35,7 @@
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static LONG KdbEntryCount = 0;
|
||||
static CHAR KdbStack[KDB_STACK_SIZE];
|
||||
static DECLSPEC_ALIGN(KDB_STACK_ALIGN) CHAR KdbStack[KDB_STACK_SIZE];
|
||||
|
||||
static ULONG KdbBreakPointCount = 0; /* Number of used breakpoints in the array */
|
||||
static KDB_BREAKPOINT KdbBreakPoints[KDB_MAXIMUM_BREAKPOINT_COUNT] = {{0}}; /* Breakpoint array */
|
||||
@@ -333,7 +340,7 @@ KdbpStepIntoInstruction(
|
||||
}
|
||||
|
||||
/* Get the interrupt descriptor */
|
||||
if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)(ULONG_PTR)(Idtr.Base + (IntVect * 8)), sizeof (IntDesc))))
|
||||
if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)((ULONG_PTR)Idtr.Base + (IntVect * 8)), sizeof(IntDesc))))
|
||||
{
|
||||
/*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
|
||||
return FALSE;
|
||||
@@ -479,7 +486,7 @@ KdbpInsertBreakPoint(
|
||||
IN BOOLEAN Global,
|
||||
OUT PLONG BreakPointNr OPTIONAL)
|
||||
{
|
||||
LONG i;
|
||||
LONG_PTR i;
|
||||
PVOID Condition;
|
||||
PCHAR ConditionExpressionDup;
|
||||
LONG ErrOffset;
|
||||
@@ -673,7 +680,7 @@ KdbpIsBreakPointOurs(
|
||||
KdbHwBreakPoints[i]->Enabled);
|
||||
DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
|
||||
|
||||
if ((Context->Dr6 & (1 << DebugReg)) != 0)
|
||||
if ((Context->Dr6 & ((ULONG_PTR)1 << DebugReg)) != 0)
|
||||
{
|
||||
return KdbHwBreakPoints[i] - KdbBreakPoints;
|
||||
}
|
||||
@@ -1174,7 +1181,7 @@ KdbpInternalEnter(VOID)
|
||||
|
||||
// KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);
|
||||
|
||||
KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - sizeof(ULONG), KdbpCallMainLoop);
|
||||
KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - KDB_STACK_RESERVE, KdbpCallMainLoop);
|
||||
|
||||
Thread->Tcb.InitialStack = SavedInitialStack;
|
||||
Thread->Tcb.StackBase = SavedStackBase;
|
||||
@@ -1489,7 +1496,7 @@ KdbEnterDebuggerException(
|
||||
}
|
||||
|
||||
KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
|
||||
Context->SegCs & 0xffff, KeGetContextPc(Context) - 1);
|
||||
Context->SegCs & 0xffff, KeGetContextPc(Context));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -64,12 +64,12 @@ typedef enum _KDB_OUTPUT_SETTINGS
|
||||
|
||||
LONG
|
||||
KdbpDisassemble(
|
||||
IN ULONG Address,
|
||||
IN ULONG_PTR Address,
|
||||
IN ULONG IntelSyntax);
|
||||
|
||||
LONG
|
||||
KdbpGetInstLength(
|
||||
IN ULONG Address);
|
||||
IN ULONG_PTR Address);
|
||||
|
||||
/* from i386/kdb_help.S */
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* FILE: ntoskrnl/kdbg/kdb_cli.c
|
||||
* PURPOSE: Kernel debugger command line interface
|
||||
* PROGRAMMER: Gregor Anich (blight@blight.eu.org)
|
||||
* Hervé Poussineau
|
||||
* Hervé Poussineau
|
||||
* UPDATE HISTORY:
|
||||
* Created 16/01/2005
|
||||
*/
|
||||
@@ -101,6 +101,8 @@ BOOLEAN ExpKdbgExtDefWrites(ULONG Argc, PCHAR Argv[]);
|
||||
BOOLEAN ExpKdbgExtIrpFind(ULONG Argc, PCHAR Argv[]);
|
||||
BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[]);
|
||||
|
||||
extern char __ImageBase;
|
||||
|
||||
#ifdef __ROS_DWARF__
|
||||
static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
|
||||
#endif
|
||||
@@ -364,7 +366,9 @@ static const struct
|
||||
/* Data */
|
||||
{ NULL, NULL, "Data", NULL },
|
||||
{ "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
|
||||
#ifdef _M_IX86 // FIXME: this is broken on x64
|
||||
{ "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
|
||||
#endif // _M_IX86
|
||||
{ "x", "x [address] [L count]", "Display count dwords, starting at address.", KdbpCmdDisassembleX },
|
||||
{ "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
|
||||
{ "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
|
||||
@@ -373,7 +377,6 @@ static const struct
|
||||
#ifdef __ROS_DWARF__
|
||||
{ "dt", "dt [mod] [type] [addr]", "Print a struct. The address is optional.", KdbpCmdPrintStruct },
|
||||
#endif
|
||||
|
||||
/* Flow control */
|
||||
{ NULL, NULL, "Flow control", NULL },
|
||||
{ "cont", "cont", "Continue execution (leave debugger).", KdbpCmdContinue },
|
||||
@@ -485,7 +488,8 @@ KdbpCmdEvalExpression(
|
||||
ULONG Argc,
|
||||
PCHAR Argv[])
|
||||
{
|
||||
ULONG i, len;
|
||||
ULONG i;
|
||||
SIZE_T len;
|
||||
ULONGLONG Result = 0;
|
||||
ULONG ul;
|
||||
LONG l = 0;
|
||||
@@ -882,7 +886,7 @@ KdbpCmdDisassembleX(
|
||||
while (Count > 0)
|
||||
{
|
||||
if (!KdbSymPrintAddress((PVOID)Address, NULL))
|
||||
KdbpPrint("<%08x>:", Address);
|
||||
KdbpPrint("<%p>:", (PVOID)Address);
|
||||
else
|
||||
KdbpPrint(":");
|
||||
|
||||
@@ -1085,6 +1089,10 @@ KdbpIsNestedTss(
|
||||
if (!Tss)
|
||||
return FALSE;
|
||||
|
||||
#ifdef _M_AMD64
|
||||
// HACK
|
||||
return FALSE;
|
||||
#else
|
||||
/* Retrieve the TSS Backlink */
|
||||
if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
|
||||
(PVOID)&Tss->Backlink,
|
||||
@@ -1092,6 +1100,7 @@ KdbpIsNestedTss(
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (Backlink != 0 && Backlink != TssSelector);
|
||||
}
|
||||
@@ -1107,6 +1116,10 @@ KdbpContextFromPrevTss(
|
||||
USHORT Backlink;
|
||||
PKTSS Tss = *pTss;
|
||||
|
||||
#ifdef _M_AMD64
|
||||
// HACK
|
||||
return FALSE;
|
||||
#else
|
||||
/* Retrieve the TSS Backlink */
|
||||
if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
|
||||
(PVOID)&Tss->Backlink,
|
||||
@@ -1139,10 +1152,103 @@ KdbpContextFromPrevTss(
|
||||
*pTss = Tss;
|
||||
Context->Eip = Eip;
|
||||
Context->Ebp = Ebp;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _M_AMD64
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
GetNextFrame(
|
||||
_Inout_ PCONTEXT Context)
|
||||
{
|
||||
PRUNTIME_FUNCTION FunctionEntry;
|
||||
ULONG64 ImageBase, EstablisherFrame;
|
||||
PVOID HandlerData;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Lookup the FunctionEntry for the current RIP */
|
||||
FunctionEntry = RtlLookupFunctionEntry(Context->Rip, &ImageBase, NULL);
|
||||
if (FunctionEntry == NULL)
|
||||
{
|
||||
/* No function entry, so this must be a leaf function. Pop the return address from the stack.
|
||||
Note: this can happen after the first frame as the result of an exception */
|
||||
Context->Rip = *(DWORD64*)Context->Rsp;
|
||||
Context->Rsp += sizeof(DWORD64);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlVirtualUnwind(UNW_FLAG_NHANDLER,
|
||||
ImageBase,
|
||||
Context->Rip,
|
||||
FunctionEntry,
|
||||
Context,
|
||||
&HandlerData,
|
||||
&EstablisherFrame,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
KdbpCmdBackTrace(
|
||||
ULONG Argc,
|
||||
PCHAR Argv[])
|
||||
{
|
||||
CONTEXT Context = *KdbCurrentTrapFrame;
|
||||
ULONG64 CurrentRsp, CurrentRip;
|
||||
|
||||
KdbpPrint("Rip:\n");
|
||||
if (!KdbSymPrintAddress((PVOID)KeGetContextPc(&Context), &Context))
|
||||
KdbpPrint("<%p>\n", KeGetContextPc(&Context));
|
||||
else
|
||||
KdbpPrint("\n");
|
||||
|
||||
/* Walk through the frames */
|
||||
KdbpPrint("Frames:\n");
|
||||
for (;;)
|
||||
{
|
||||
CurrentRip = Context.Rip;
|
||||
CurrentRsp = Context.Rsp;
|
||||
|
||||
BOOLEAN GotNextFrame = GetNextFrame(&Context);
|
||||
|
||||
KdbpPrint("[%p] ", (PVOID)CurrentRsp);
|
||||
Context.Rsp = Context.Rsp;
|
||||
|
||||
/* Print the location afrer the call instruction */
|
||||
if (!KdbSymPrintAddress((PVOID)CurrentRip, &Context))
|
||||
KdbpPrint("<%p>", (PVOID)Context.Rip);
|
||||
|
||||
KdbpPrint(" (stack: 0x%Ix)\n", Context.Rsp - CurrentRsp);
|
||||
|
||||
if (KdbOutputAborted)
|
||||
break;
|
||||
|
||||
if (Context.Rsp == 0)
|
||||
break;
|
||||
|
||||
if (!GotNextFrame)
|
||||
{
|
||||
KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)Context.Rsp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
/*!\brief Displays a backtrace.
|
||||
*/
|
||||
static BOOLEAN
|
||||
@@ -1316,6 +1422,8 @@ CheckForParentTSS:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif // M_AMD64
|
||||
|
||||
/*!\brief Continues execution of the system/leaves KDB.
|
||||
*/
|
||||
static BOOLEAN
|
||||
@@ -1410,7 +1518,7 @@ KdbpCmdBreakPointList(
|
||||
else
|
||||
{
|
||||
GlobalOrLocal = Buffer;
|
||||
sprintf(Buffer, " PID 0x%lx",
|
||||
sprintf(Buffer, " PID 0x%Ix",
|
||||
(ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
|
||||
}
|
||||
|
||||
@@ -1989,9 +2097,9 @@ KdbpCmdMod(
|
||||
{
|
||||
if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
|
||||
{
|
||||
ULONG_PTR ntoskrnlBase = ((ULONG_PTR)KdbpCmdMod) & 0xfff00000;
|
||||
ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
|
||||
KdbpPrint(" Base Size Name\n");
|
||||
KdbpPrint(" %08x %08x %s\n", ntoskrnlBase, 0, "ntoskrnl.exe");
|
||||
KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2239,6 +2347,7 @@ KdbpCmdPcr(
|
||||
PKIPCR Pcr = (PKIPCR)KeGetPcr();
|
||||
|
||||
KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
|
||||
#ifdef _M_IX86
|
||||
KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
|
||||
" Tib.StackBase: 0x%08x\n"
|
||||
" Tib.StackLimit: 0x%08x\n"
|
||||
@@ -2246,75 +2355,59 @@ 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"
|
||||
#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
|
||||
#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
|
||||
, Pcr->InterruptMode);
|
||||
#else
|
||||
KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
|
||||
KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
|
||||
KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
|
||||
KdbpPrint(" Self: 0x%p\n", Pcr->Self);
|
||||
KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
|
||||
KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
|
||||
KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
|
||||
KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
|
||||
KdbpPrint(" Irql: %u\n", Pcr->Irql);
|
||||
KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
|
||||
KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
|
||||
KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
|
||||
KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
|
||||
KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
|
||||
KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
|
||||
KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2417,7 +2510,7 @@ KdbpCmdTss(
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
#endif // _M_IX86
|
||||
|
||||
/*!\brief Bugchecks the system.
|
||||
*/
|
||||
@@ -2724,7 +2817,7 @@ KdbpPrint(
|
||||
CHAR c = '\0';
|
||||
PCHAR p, p2;
|
||||
ULONG Length;
|
||||
ULONG i, j;
|
||||
SIZE_T i, j;
|
||||
LONG RowsPrintedByTerminal;
|
||||
ULONG ScanCode;
|
||||
va_list ap;
|
||||
@@ -3039,7 +3132,7 @@ KdbpPager(
|
||||
CHAR c = '\0';
|
||||
PCHAR p, p2;
|
||||
ULONG Length;
|
||||
ULONG i, j;
|
||||
SIZE_T i, j;
|
||||
LONG RowsPrintedByTerminal;
|
||||
ULONG ScanCode;
|
||||
|
||||
@@ -3298,8 +3391,8 @@ static VOID
|
||||
KdbpCommandHistoryAppend(
|
||||
IN PCHAR Command)
|
||||
{
|
||||
ULONG Length1 = strlen(Command) + 1;
|
||||
ULONG Length2 = 0;
|
||||
SIZE_T Length1 = strlen(Command) + 1;
|
||||
SIZE_T Length2 = 0;
|
||||
INT i;
|
||||
PCHAR Buffer;
|
||||
|
||||
@@ -3380,7 +3473,7 @@ KdbpReadCommand(
|
||||
static CHAR LastCommand[1024];
|
||||
static CHAR NextKey = '\0';
|
||||
INT CmdHistIndex = -1;
|
||||
INT i;
|
||||
INT_PTR i;
|
||||
|
||||
EchoOn = !((KdbDebugState & KD_DEBUG_KDNOECHO) != 0);
|
||||
|
||||
@@ -3644,7 +3737,7 @@ static BOOLEAN
|
||||
KdbpDoCommand(
|
||||
IN PCHAR Command)
|
||||
{
|
||||
ULONG i;
|
||||
SIZE_T i;
|
||||
PCHAR p;
|
||||
ULONG Argc;
|
||||
// FIXME: for what do we need a 1024 characters command line and 256 tokens?
|
||||
@@ -3784,7 +3877,7 @@ VOID
|
||||
KdbpCliInterpretInitFile(VOID)
|
||||
{
|
||||
PCHAR p1, p2;
|
||||
INT i;
|
||||
INT_PTR i;
|
||||
CHAR c;
|
||||
|
||||
/* Execute the commands in the init file */
|
||||
|
||||
@@ -437,8 +437,8 @@ RpnpParseExpression(
|
||||
RPN_OP ComparativeOp;
|
||||
BOOLEAN ComparativeOpFilled = FALSE;
|
||||
BOOLEAN IsComparativeOp;
|
||||
INT i, i2;
|
||||
ULONG ul;
|
||||
INT_PTR i, i2;
|
||||
ULONG64 ull;
|
||||
UCHAR MemorySize;
|
||||
CHAR Buffer[16];
|
||||
BOOLEAN First;
|
||||
@@ -596,13 +596,12 @@ get_operand:
|
||||
else
|
||||
{
|
||||
/* Immediate value */
|
||||
/* FIXME: Need string to ULONGLONG function */
|
||||
ul = strtoul(p, &pend, 0);
|
||||
ull = strtoull(p, &pend, 0);
|
||||
if (p != pend)
|
||||
{
|
||||
RpnOp.Type = RpnOpImmediate;
|
||||
RpnOp.CharacterOffset = CharacterOffset;
|
||||
RpnOp.Data.Immediate = (ULONGLONG)ul;
|
||||
RpnOp.Data.Immediate = ull;
|
||||
CharacterOffset += pend - p;
|
||||
p = pend;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ KdbSymPrintAddress(
|
||||
/* Use KdpPrintString because KdpDprintf is limited wrt string size */
|
||||
KdpDprintf("<%s:%x (", ModuleNameAnsi, RelativeAddress);
|
||||
str.Buffer = FileName;
|
||||
str.Length = strnlen(FileName, sizeof(FileName));
|
||||
str.Length = (USHORT)strnlen(FileName, sizeof(FileName));
|
||||
str.MaximumLength = sizeof(FileName);
|
||||
KdpPrintString(&str);
|
||||
KdpDprintf(":%d (%s))>", LineNumber, FunctionName);
|
||||
|
||||
@@ -144,7 +144,7 @@ VOID
|
||||
ExpKdbgExtPoolUsedGetTag(PCHAR Arg, PULONG Tag, PULONG Mask)
|
||||
{
|
||||
CHAR Tmp[4];
|
||||
ULONG Len;
|
||||
SIZE_T Len;
|
||||
USHORT i;
|
||||
|
||||
/* Get the tag */
|
||||
@@ -175,7 +175,7 @@ ExpKdbgExtPoolUsed(
|
||||
{
|
||||
ULONG Tag = 0;
|
||||
ULONG Mask = 0;
|
||||
ULONG Flags = 0;
|
||||
ULONG_PTR Flags = 0;
|
||||
|
||||
if (Argc > 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user