[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 #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

View file

@ -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 */

View file

@ -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

View file

@ -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,

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 */ 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) */

View file

@ -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>");
} }

View file

@ -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;

View file

@ -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")

View file

@ -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()