#define CBSTACK_RESULT_LENGTH 0x24
//
-// NTSTATUS and Bugcheck Codes
+// NTSTATUS, Bugcheck Codes and Debug Codes
//
#ifdef __ASM__
#define STATUS_ACCESS_VIOLATION 0xC0000005
#define UNEXPECTED_KERNEL_MODE_TRAP 0x7F
#define ATTEMPTED_SWITCH_FROM_DPC 0xB8
#define HARDWARE_INTERRUPT_STORM 0xF2
+#define DBG_STATUS_CONTROL_C 0x01
//
// IRQL Levels
#define KD_SECONDARY_VERSION_AMD64_OBSOLETE_CONTEXT_1 0
#define KD_SECONDARY_VERSION_AMD64_OBSOLETE_CONTEXT_2 1
#define KD_SECONDARY_VERSION_AMD64_CONTEXT 2
+
+#if defined(_AMD64_)
+#define CURRENT_KD_SECONDARY_VERSION KD_SECONDARY_VERSION_AMD64_CONTEXT
+#else
#define CURRENT_KD_SECONDARY_VERSION KD_SECONDARY_VERSION_DEFAULT
+#endif
#define DBGKD_VERS_FLAG_MP 0x0001
#define DBGKD_VERS_FLAG_DATA 0x0002
USHORT FramePointer;
USHORT PaeEnabled:1;
GCC_ULONG64 KiCallUserMode;
- GCC_ULONG64 KeUserCallbackDispatcher;
+ ULONG64 KeUserCallbackDispatcher;
GCC_ULONG64 PsLoadedModuleList;
GCC_ULONG64 PsActiveProcessHead;
GCC_ULONG64 PspCidTable;
#ifndef _KDDLL_
#define _KDDLL_
-typedef enum _KDSTATUS
-{
- KdPacketReceived = 0,
- KdPacketTimedOut,
- KdPacketNeedsResend
-} KDSTATUS;
+typedef ULONG KDSTATUS;
+#define KdPacketReceived 0
+#define KdPacketTimedOut 1
+#define KdPacketNeedsResend 2
NTSTATUS
NTAPI
SharedUserData->NtMinorVersion = NtMinorVersion;
/* Set the machine type */
-#if defined(_X86_)
- SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_I386;
- SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_I386;
-#elif defined(_PPC_) // <3 Arty
- SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_POWERPC;
- SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_POWERPC;
-#elif defined(_MIPS_)
- SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_R4000;
- SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_R4000;
-#elif defined(_ARM_)
- SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_ARM;
- SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_ARM;
-#else
-#error "Unsupported ReactOS Target"
-#endif
+ SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_ARCHITECTURE;
+ SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_ARCHITECTURE;
}
VOID
#define PCR_ENTRY 0
#define PDR_ENTRY 2
+#define IMAGE_FILE_MACHINE_ARCHITECTURE IMAGE_FILE_MACHINE_ARM
+
+//
+// BKPT is 4 bytes long
+//
+#define KD_BREAKPOINT_SIZE 4
+
+//
+// Macros for getting and setting special purpose registers in portable code
+//
+#define KeGetContextPc(Context) \
+ ((Context)->Pc)
+
+#define KeSetContextPc(Context, ProgramCounter) \
+ ((Context)->Pc = (ProgramCounter))
+
+#define KeGetTrapFramePc(TrapFrame) \
+ ((TrapFrame)->Pc)
+
+#define KeGetContextReturnRegister(Context) \
+ ((Context)->R0)
+
+#define KeSetContextReturnRegister(Context, ReturnValue) \
+ ((Context)->R0 = (ReturnValue))
+
VOID
KiPassiveRelease(
VOID
extern ULONG Ke386CacheAlignment;
+#define IMAGE_FILE_MACHINE_ARCHITECTURE IMAGE_FILE_MACHINE_I386
+
+//
+// INT3 is 1 byte long
+//
+#define KD_BREAKPOINT_SIZE 1
+
+//
+// Macros for getting and setting special purpose registers in portable code
+//
+#define KeGetContextPc(Context) \
+ ((Context)->Eip)
+
+#define KeSetContextPc(Context, ProgramCounter) \
+ ((Context)->Eip = (ProgramCounter))
+
+#define KeGetTrapFramePc(TrapFrame) \
+ ((TrapFrame)->Eip)
+
+#define KeGetContextReturnRegister(Context) \
+ ((Context)->Eax)
+
+#define KeSetContextReturnRegister(Context, ReturnValue) \
+ ((Context)->Eax = (ReturnValue))
+
VOID
FASTCALL
Ki386InitializeTss(
PLOADER_PARAMETER_BLOCK LoaderBlock\r
);\r
\r
-//\r
-// Debug and Multi-Processor Switch Routines\r
-//\r
-BOOLEAN\r
+VOID\r
NTAPI\r
-KdpEnterDebuggerException(\r
- IN PKTRAP_FRAME TrapFrame,\r
- IN PKEXCEPTION_FRAME ExceptionFrame,\r
- IN PEXCEPTION_RECORD ExceptionRecord,\r
- IN PCONTEXT Context,\r
- IN KPROCESSOR_MODE PreviousMode,\r
- IN BOOLEAN SecondChance\r
+KdUpdateDataBlock(\r
+ VOID\r
);\r
\r
+//\r
+// Multi-Processor Switch Support\r
+//\r
BOOLEAN\r
NTAPI\r
KdpSwitchProcessor(\r
//\r
// Debug Event Handlers\r
//\r
-ULONG\r
+NTSTATUS\r
NTAPI\r
KdpPrint(\r
IN ULONG ComponentId,\r
IN ULONG ComponentMask,\r
IN LPSTR String,\r
- IN ULONG Length,\r
+ IN USHORT Length,\r
IN KPROCESSOR_MODE PreviousMode,\r
IN PKTRAP_FRAME TrapFrame,\r
IN PKEXCEPTION_FRAME ExceptionFrame,\r
OUT PBOOLEAN Status\r
);\r
\r
-ULONG\r
+BOOLEAN\r
+NTAPI\r
+KdpPrompt(\r
+ IN LPSTR InString,\r
+ IN USHORT InStringLength,\r
+ OUT LPSTR OutString,\r
+ IN USHORT OutStringLength,\r
+ IN KPROCESSOR_MODE PreviousMode,\r
+ IN PKTRAP_FRAME TrapFrame,\r
+ IN PKEXCEPTION_FRAME ExceptionFrame\r
+);\r
+\r
+VOID\r
NTAPI\r
KdpSymbol(\r
IN PSTRING DllPath,\r
IN PKEXCEPTION_FRAME ExceptionFrame\r
);\r
\r
+VOID\r
+NTAPI\r
+KdpCommandString(\r
+ IN ULONG Length,\r
+ IN LPSTR String,\r
+ IN KPROCESSOR_MODE PreviousMode,\r
+ IN PCONTEXT ContextRecord,\r
+ IN PKTRAP_FRAME TrapFrame,\r
+ IN PKEXCEPTION_FRAME ExceptionFrame\r
+);\r
+\r
//\r
// State Change Notifications\r
//\r
IN PVOID Address\r
);\r
\r
+//\r
+// Internal routine for sending strings directly to the debugger\r
+//\r
+VOID\r
+__cdecl\r
+KdpDprintf(\r
+ IN PCHAR Format,\r
+ ...\r
+);\r
+\r
//\r
// Global KD Data\r
//\r
extern ULONG KePPCCacheAlignment;
+#define IMAGE_FILE_MACHINE_ARCHITECTURE IMAGE_FILE_MACHINE_POWERPC
+
+//
+// Macros for getting and setting special purpose registers in portable code
+//
+#define KeGetContextPc(Context) \
+ ((Context)->Dr0)
+
+#define KeSetContextPc(Context, ProgramCounter) \
+ ((Context)->Dr0 = (ProgramCounter))
+
+#define KeGetTrapFramePc(TrapFrame) \
+ ((TrapFrame)->Dr0)
+
+#define KeGetContextReturnRegister(Context) \
+ ((Context)->Gpr3)
+
+#define KeSetContextReturnRegister(Context, ReturnValue) \
+ ((Context)->Gpr3 = (ReturnValue))
+
#define KePPCRdmsr(msr,val1,val2) __asm__ __volatile__("mfmsr 3")
#define KePPCWrmsr(msr,val1,val2) __asm__ __volatile__("mtmsr 3")
extern LARGE_INTEGER ShortPsLockDelay;
extern UNICODE_STRING PsNtDllPathName;
extern LIST_ENTRY PsLoadedModuleList;
-extern ULONG PsNtosImageBase;
+extern ULONG_PTR PsNtosImageBase;
//
// Inlined Functions
{
KD_CONTINUE_TYPE Return = kdHandleException;
ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
-#ifdef _M_IX86
- ULONG EipOld;
-#endif
/* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
KdpServiceDispatcher(BREAKPOINT_PRINT,
(PVOID)ExceptionRecord->ExceptionInformation[1],
ExceptionRecord->ExceptionInformation[2]);
-#ifdef _M_IX86
- Context->Eax = STATUS_SUCCESS;
-#elif _M_ARM
- Context->R0 = STATUS_SUCCESS;
-#else
-#error Please be portable when modifying code
-#endif
+
+ /* Return success */
+ KeSetContextReturnRegister(Context, STATUS_SUCCESS);
}
else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
{
#endif
}
- /* This we can handle: simply bump EIP */
-#ifdef _M_IX86
- Context->Eip++;
-#elif _M_ARM
- Context->Pc += sizeof(ULONG);
-#endif
+ /* This we can handle: simply bump the Program Counter */
+ KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
return TRUE;
}
/* Get out of here if the Debugger isn't connected */
if (KdDebuggerNotPresent) return FALSE;
- /* Save old EIP value */
-#ifdef _M_IX86
- EipOld = Context->Eip;
-#endif
-
#ifdef KDBG
/* Call KDBG if available */
Return = KdbEnterDebuggerException(ExceptionRecord,
}
#endif /* not KDBG */
- /* Bump EIP over int 3 if debugger did not already change it */
- if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
- {
- //DPRINT1("Address: %p. Return: %d\n", EipOld, Return);
- }
-
/* Debugger didn't handle it, please handle! */
if (Return == kdHandleException) return FALSE;
WaitStateChange->ProcessorLevel = KeProcessorLevel;\r
WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;\r
WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;\r
- WaitStateChange->Thread = (ULONG)(LONG_PTR)KeGetCurrentThread();\r
- WaitStateChange->ProgramCounter = (ULONG)(LONG_PTR)Context->Eip;\r
+ WaitStateChange->Thread = (ULONG64)(LONG_PTR)KeGetCurrentThread();\r
+ WaitStateChange->ProgramCounter = (ULONG64)(LONG_PTR)KeGetContextPc(Context);\r
\r
/* Zero out the Control Report */\r
RtlZeroMemory(&WaitStateChange->ControlReport,\r
/* Clear all the breakpoints in this region */\r
HadBreakpoints =\r
KdpDeleteBreakpointRange((PVOID)(LONG_PTR)WaitStateChange->ProgramCounter,\r
- (PVOID)((ULONG)WaitStateChange->ProgramCounter +\r
+ (PVOID)((ULONG_PTR)WaitStateChange->ProgramCounter +\r
WaitStateChange->ControlReport.InstructionCount - 1));\r
if (HadBreakpoints)\r
{\r
&KdpContext);\r
}\r
\r
+VOID\r
+NTAPI\r
+KdpCauseBugCheck(IN PDBGKD_MANIPULATE_STATE64 State)\r
+{\r
+ /* Crash with the special code */\r
+ KeBugCheck(MANUALLY_INITIATED_CRASH);\r
+}\r
+\r
KCONTINUE_STATUS\r
NTAPI\r
KdpSendWaitContinue(IN ULONG PacketType,\r
\r
case DbgKdRestoreBreakPointApi:\r
\r
- /* FIXME: TODO */\r
+ /* Restore the breakpoint */\r
KdpRestoreBreakpoint(&ManipulateState, &Data, Context);\r
break;\r
\r
\r
case DbgKdWriteControlSpaceApi:\r
\r
- /* FIXME: TODO */\r
+ /* Write control space */\r
KdpWriteControlSpace(&ManipulateState, &Data, Context);\r
break;\r
\r
\r
case DbgKdRebootApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdRebootApi);\r
- while (TRUE);\r
+ /* Reboot the system */\r
+ HalReturnToFirmware(HalRebootRoutine);\r
break;\r
\r
case DbgKdContinueApi2:\r
\r
case DbgKdCauseBugCheckApi:\r
\r
- /* FIXME: TODO */\r
- Ke386SetCr2(DbgKdCauseBugCheckApi);\r
- while (TRUE);\r
+ /* Crash the system */\r
+ KdpCauseBugCheck(&ManipulateState);\r
break;\r
\r
case DbgKdSwitchProcessor:\r
&Header,\r
ExtraData,\r
Context);\r
- } while(Status == ContinueProcessorReselected);\r
+ } while (Status == ContinueProcessorReselected);\r
\r
/* Return status */\r
return Status;\r
&Header,\r
&Data,\r
Context);\r
- } while (Status == KdPacketNeedsResend);\r
+ } while (Status == ContinueProcessorReselected);\r
\r
/* Return */\r
return Status;\r
if (KiFreezeFlag & 1)\r
{\r
/* Print out errror */\r
- DbgPrint("FreezeLock was jammed! Backup SpinLock was used!\n");\r
+ KdpDprintf("FreezeLock was jammed! Backup SpinLock was used!\n");\r
}\r
\r
/* Check processor state */\r
if (KiFreezeFlag & 2)\r
{\r
/* Print out errror */\r
- DbgPrint("Some processors not frozen in debugger!\n");\r
+ KdpDprintf("Some processors not frozen in debugger!\n");\r
}\r
\r
/* Make sure we acquired the port */\r
- if (!KdpPortLocked) DbgPrint("Port lock was not acquired!\n");\r
+ if (!KdpPortLocked) KdpDprintf("Port lock was not acquired!\n");\r
\r
/* Return enter state */\r
return Entered;\r
// Breakpoint Data\r
//\r
BREAKPOINT_ENTRY KdpBreakpointTable[20];\r
-ULONG KdpBreakpointInstruction = 0xCC;\r
+#if defined(_M_IX86) || defined(_M_AMD64)\r
+ULONG KdpBreakpointInstruction = 0xCC; // INT3\r
+#else\r
+#error TODO\r
+#endif\r
BOOLEAN KdpOweBreakpoint;\r
BOOLEAN BreakpointsSuspended;\r
ULONG KdpNumInternalBreakpoints;\r
DBGKD_64BIT_PROTOCOL_VERSION2,\r
KD_SECONDARY_VERSION_DEFAULT,\r
DBGKD_VERS_FLAG_DATA,\r
-#if defined(_M_IX86)\r
- IMAGE_FILE_MACHINE_I386,\r
-#elif defined(_M_PPC)\r
- IMAGE_FILE_MACHINE_POWERPC,\r
-#elif defined(_M_MIPS)\r
- IMAGE_FILE_MACHINE_R4000,\r
-#else\r
-#error Unknown platform\r
-#endif\r
+ IMAGE_FILE_MACHINE_ARCHITECTURE,\r
PACKET_TYPE_MAX,\r
0,\r
0,\r
FIELD_OFFSET(KTHREAD, CallbackStack),\r
CBSTACK_CALLBACK_STACK,\r
CBSTACK_EBP,\r
- 0,\r
+ FALSE,\r
{PtrToUlong(KiCallUserMode)},\r
- {0},\r
+ 0,\r
{PtrToUlong(&PsLoadedModuleList)},\r
{PtrToUlong(&PsActiveProcessHead)},\r
{PtrToUlong(&PspCidTable)},\r
\r
/* FUNCTIONS *****************************************************************/\r
\r
+VOID\r
+NTAPI\r
+KdUpdateDataBlock(VOID)\r
+{\r
+ /* Update the KeUserCallbackDispatcher pointer */\r
+ KdDebuggerDataBlock.KeUserCallbackDispatcher =\r
+ (ULONG64)(LONG_PTR)KeUserCallbackDispatcher;\r
+}\r
+\r
BOOLEAN\r
NTAPI\r
KdRegisterDebuggerDataBlock(IN ULONG Tag,\r
InLoadOrderLinks);\r
\r
/* Save the Kernel Base */\r
- PsNtosImageBase = (ULONG)LdrEntry->DllBase;\r
+ PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;\r
KdVersionBlock.KernBase = (ULONGLONG)(LONG_PTR)LdrEntry->DllBase;\r
\r
/* Check if we have a command line */\r
{\r
STRING Data, Header;\r
DBGKD_DEBUG_IO DebugIo;\r
- ULONG Length = Output->Length;\r
+ USHORT Length = Output->Length;\r
\r
/* Copy the string */\r
RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);\r
return KdpPollBreakInWithPortLock();\r
}\r
\r
-ULONG\r
+VOID\r
NTAPI\r
KdpCommandString(IN ULONG Length,\r
IN LPSTR String,\r
IN PKEXCEPTION_FRAME ExceptionFrame)\r
{\r
/* FIXME */\r
- return FALSE;\r
+ while (TRUE);\r
}\r
\r
-ULONG\r
+VOID\r
NTAPI\r
KdpSymbol(IN PSTRING DllPath,\r
IN PKD_SYMBOLS_INFO DllBase,\r
ULONG Status;\r
\r
/* Check if we need to do anything */\r
- if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0;\r
+ if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;\r
\r
/* Enter the debugger */\r
Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
RtlCopyMemory(ContextRecord,\r
&Prcb->ProcessorState.ContextFrame,\r
sizeof(CONTEXT));\r
- //KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
+ KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
\r
/* Exit the debugger and clear the CTRL-C state */\r
KdExitDebugger(Entered);\r
- return 0;\r
}\r
\r
-ULONG\r
+BOOLEAN\r
NTAPI\r
KdpPrompt(IN LPSTR InString,\r
- IN ULONG InStringLength,\r
+ IN USHORT InStringLength,\r
OUT LPSTR OutString,\r
- IN ULONG OutStringLength,\r
+ IN USHORT OutStringLength,\r
IN KPROCESSOR_MODE PreviousMode,\r
IN PKTRAP_FRAME TrapFrame,\r
IN PKEXCEPTION_FRAME ExceptionFrame)\r
{\r
/* FIXME */\r
+ while (TRUE);\r
return FALSE;\r
}\r
\r
-ULONG\r
+NTSTATUS\r
NTAPI\r
KdpPrint(IN ULONG ComponentId,\r
IN ULONG ComponentMask,\r
IN LPSTR String,\r
- IN ULONG Length,\r
+ IN USHORT Length,\r
IN KPROCESSOR_MODE PreviousMode,\r
IN PKTRAP_FRAME TrapFrame,\r
IN PKEXCEPTION_FRAME ExceptionFrame,\r
OUT PBOOLEAN Status)\r
{\r
- NTSTATUS ReturnValue;\r
+ NTSTATUS ReturnStatus;\r
BOOLEAN Entered;\r
ANSI_STRING AnsiString;\r
\r
*Status = FALSE;\r
\r
/* Validate the mask */\r
- if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask;\r
+ if (ComponentMask < 0x20) ComponentMask = 1 << ComponentMask;\r
if (!(Kd_WIN2000_Mask & ComponentMask) ||\r
((ComponentId < KdComponentTableSize) &&\r
!(*KdComponentTable[ComponentId] & ComponentMask)))\r
\r
/* Setup the ANSI string */\r
AnsiString.Buffer = String;\r
- AnsiString.Length = (USHORT)Length;\r
+ AnsiString.Length = Length;\r
\r
/* Log the print */\r
//KdLogDbgPrint(&AnsiString);\r
{\r
/* Fail */\r
*Status = TRUE;\r
- return (ULONG)STATUS_DEVICE_NOT_CONNECTED;\r
+ return STATUS_DEVICE_NOT_CONNECTED;\r
}\r
\r
/* Enter the debugger */\r
if (KdpPrintString(&AnsiString))\r
{\r
/* User pressed CTRL-C, breakpoint on return */\r
- ReturnValue = STATUS_BREAKPOINT;\r
+ ReturnStatus = STATUS_BREAKPOINT;\r
}\r
else\r
{\r
/* String was printed */\r
- ReturnValue = STATUS_SUCCESS;\r
+ ReturnStatus = STATUS_SUCCESS;\r
}\r
\r
/* Exit the debugger and return */\r
KdExitDebugger(Entered);\r
*Status = TRUE;\r
- return ReturnValue;\r
+ return ReturnStatus;\r
}\r
\r
+VOID\r
+__cdecl\r
+KdpDprintf(IN PCHAR Format,\r
+ ...)\r
+{\r
+ STRING String;\r
+ CHAR Buffer[100];\r
+ USHORT Length;\r
+ va_list ap;\r
+\r
+ /* Format the string */\r
+ va_start(ap, Format);\r
+ Length = (USHORT)_vsnprintf(Buffer,\r
+ sizeof(Buffer),\r
+ Format,\r
+ ap);\r
+\r
+ /* Set it up */\r
+ String.Buffer = Buffer;\r
+ String.Length = Length + 1;\r
+\r
+ /* Send it to the debugger directly */\r
+ KdpPrintString(&String);\r
+ va_end(ap);\r
+}\r
}\r
else if (SecondChanceException)\r
{\r
- /* We won't bother unless this is second chance */\r
+ /* We won't bother unless this is first chance */\r
return FALSE;\r
}\r
\r
RtlCopyMemory(ContextRecord,\r
&Prcb->ProcessorState.ContextFrame,\r
sizeof(CONTEXT));\r
- //KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
+ KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
\r
/* Exit the debugger and clear the CTRL-C state */\r
KdExitDebugger(Entered);\r
IN BOOLEAN SecondChanceException)\r
{\r
BOOLEAN Unload = FALSE;\r
- ULONG Eip, Eax;\r
+ ULONG_PTR ProgramCounter, ReturnValue;\r
BOOLEAN Status = FALSE;\r
\r
/*\r
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&\r
(ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))\r
{\r
- /* Save EIP */\r
- Eip = ContextRecord->Eip;\r
+ /* Save Program Counter */\r
+ ProgramCounter = KeGetContextPc(ContextRecord);\r
\r
/* Check what kind of operation was requested from us */\r
switch (ExceptionRecord->ExceptionInformation[0])\r
case BREAKPOINT_PRINT:\r
\r
/* Call the worker routine */\r
- Eax = KdpPrint(ContextRecord->Ebx,\r
- ContextRecord->Edi,\r
- (LPSTR)ExceptionRecord->ExceptionInformation[1],\r
- (ULONG)ExceptionRecord->ExceptionInformation[2],\r
- PreviousMode,\r
- TrapFrame,\r
- ExceptionFrame,\r
- &Status);\r
+ ReturnValue = KdpPrint((ULONG)ContextRecord->Ebx,\r
+ (ULONG)ContextRecord->Edi,\r
+ (LPSTR)ExceptionRecord->\r
+ ExceptionInformation[1],\r
+ (USHORT)ExceptionRecord->\r
+ ExceptionInformation[2],\r
+ PreviousMode,\r
+ TrapFrame,\r
+ ExceptionFrame,\r
+ &Status);\r
\r
/* Update the return value for the caller */\r
- ContextRecord->Eax = Eax;\r
+ KeSetContextReturnRegister(ContextRecord, ReturnValue);\r
break;\r
\r
/* DbgPrompt */\r
case BREAKPOINT_PROMPT:\r
\r
/* Call the worker routine */\r
- while (TRUE);\r
- Eax = 0;\r
+ ReturnValue = KdpPrompt((LPSTR)ExceptionRecord->\r
+ ExceptionInformation[1],\r
+ (USHORT)ExceptionRecord->\r
+ ExceptionInformation[2],\r
+ (LPSTR)ContextRecord->Ebx,\r
+ (USHORT)ContextRecord->Edi,\r
+ PreviousMode,\r
+ TrapFrame,\r
+ ExceptionFrame);\r
Status = TRUE;\r
\r
/* Update the return value for the caller */\r
- ContextRecord->Eax = Eax;\r
+ KeSetContextReturnRegister(ContextRecord, ReturnValue);\r
break;\r
\r
- /* DbgUnloadSymbols */\r
+ /* DbgUnloadImageSymbols */\r
case BREAKPOINT_UNLOAD_SYMBOLS:\r
\r
/* Drop into the load case below, with the unload parameter */\r
Unload = TRUE;\r
\r
- /* DbgLoadSymbols */\r
+ /* DbgLoadImageSymbols */\r
case BREAKPOINT_LOAD_SYMBOLS:\r
\r
/* Call the worker routine */\r
- KdpSymbol((PVOID)ExceptionRecord->ExceptionInformation[1],\r
- (PVOID)ExceptionRecord->ExceptionInformation[2],\r
+ KdpSymbol((PSTRING)ExceptionRecord->\r
+ ExceptionInformation[1],\r
+ (PKD_SYMBOLS_INFO)ExceptionRecord->\r
+ ExceptionInformation[2],\r
Unload,\r
PreviousMode,\r
ContextRecord,\r
Status = TRUE;\r
break;\r
\r
- /* DbgCommandString*/\r
+ /* DbgCommandString */\r
case BREAKPOINT_COMMAND_STRING:\r
\r
/* Call the worker routine */\r
- while (TRUE);\r
+ KdpCommandString((ULONG)ExceptionRecord->\r
+ ExceptionInformation[1],\r
+ (LPSTR)ExceptionRecord->\r
+ ExceptionInformation[2],\r
+ PreviousMode,\r
+ ContextRecord,\r
+ TrapFrame,\r
+ ExceptionFrame);\r
Status = TRUE;\r
\r
/* Anything else, do nothing */\r
}\r
\r
/*\r
- * If EIP was not updated, we'll increment it ourselves so execution\r
+ * If the PC was not updated, we'll increment it ourselves so execution\r
* continues past the breakpoint.\r
*/\r
- if (ContextRecord->Eip == Eip) ContextRecord->Eip++;\r
+ if (ProgramCounter == KeGetContextPc(ContextRecord))\r
+ {\r
+ /* Update it */\r
+ KeSetContextPc(ContextRecord,\r
+ ProgramCounter + KD_BREAKPOINT_SIZE);\r
+ }\r
}\r
else\r
{\r
(ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||\r
(ExceptionCommand == BREAKPOINT_PRINT)))\r
{\r
- /* This we can handle: simply bump EIP */\r
- ContextRecord->Eip++;\r
+ /* This we can handle: simply bump the Program Counter */\r
+ KeSetContextPc(ContextRecord,\r
+ KeGetContextPc(ContextRecord) + KD_BREAKPOINT_SIZE);\r
return TRUE;\r
}\r
else if (KdPitchDebugger)\r
else if ((KdAutoEnableOnEvent) &&\r
(KdPreviouslyEnabled) &&\r
!(KdDebuggerEnabled) &&\r
- (KdEnableDebugger()) &&\r
+ (NT_SUCCESS(KdEnableDebugger())) &&\r
(KdDebuggerEnabled))\r
{\r
/* Debugging was Auto-Enabled. We can now send this to KD. */\r
PVOID
NTAPI
-KiPcToFileHeader(IN PVOID Eip,
+KiPcToFileHeader(IN PVOID Pc,
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
IN BOOLEAN DriversOnly,
OUT PBOOLEAN InKernel)
{
ULONG i = 0;
- PVOID ImageBase, EipBase = NULL;
+ PVOID ImageBase, PcBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
ImageBase = Entry->DllBase;
/* Check if this is the right one */
- if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
- ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+ if (((ULONG_PTR)Pc >= (ULONG_PTR)Entry->DllBase) &&
+ ((ULONG_PTR)Pc < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
{
/* Return this entry */
*LdrEntry = Entry;
- EipBase = ImageBase;
+ PcBase = ImageBase;
/* Check if this was a kernel or HAL entry */
if (i <= 2) *InKernel = TRUE;
}
/* Return the base address */
- return EipBase;
+ return PcBase;
}
BOOLEAN
PVOID
NTAPI
-KiRosPcToUserFileHeader(IN PVOID Eip,
+KiRosPcToUserFileHeader(IN PVOID Pc,
OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
{
- PVOID ImageBase, EipBase = NULL;
+ PVOID ImageBase, PcBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
ImageBase = Entry->DllBase;
/* Check if this is the right one */
- if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
- ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+ if (((ULONG_PTR)Pc >= (ULONG_PTR)Entry->DllBase) &&
+ ((ULONG_PTR)Pc < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
{
/* Return this entry */
*LdrEntry = Entry;
- EipBase = ImageBase;
+ PcBase = ImageBase;
break;
}
}
}
/* Return the base address */
- return EipBase;
+ return PcBase;
}
USHORT
CHAR AnsiName[128];
BOOLEAN IsSystem, IsHardError = FALSE, Reboot = FALSE;
PCHAR HardErrCaption = NULL, HardErrMessage = NULL;
- PVOID Eip = NULL, Memory;
+ PVOID Pc = NULL, Memory;
PVOID DriverBase;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PULONG_PTR HardErrorParameters;
if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
}
- /* Check if we got one now and if we need to get EIP */
+ /* Check if we got one now and if we need to get the Program Counter */
if ((TrapFrame) &&
(BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED))
{
-#ifdef _M_IX86
- /* Get EIP */
- Eip = (PVOID)TrapFrame->Eip;
-#elif defined(_M_PPC)
- Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
-#endif
+ /* Get the Program Counter */
+ Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
}
break;
* and provide a more detailed analysis. For now, we don't.
*/
- /* Eip is in parameter 4 */
- Eip = (PVOID)BugCheckParameter4;
+ /* Program Counter is in parameter 4 */
+ Pc = (PVOID)BugCheckParameter4;
/* Get the driver base */
- DriverBase = KiPcToFileHeader(Eip, &LdrEntry, FALSE, &IsSystem);
+ DriverBase = KiPcToFileHeader(Pc,
+ &LdrEntry,
+ FALSE,
+ &IsSystem);
if (IsSystem)
{
/*
KiBugCheckData[0] = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
}
- /* Clear EIP so we don't look it up later */
- Eip = NULL;
+ /* Clear Pc so we don't look it up later */
+ Pc = NULL;
break;
/* Hard error */
/* Check if we have a frame now */
if (TrapFrame)
{
-#ifdef _M_IX86
- /* Get EIP */
- Eip = (PVOID)TrapFrame->Eip;
- KiBugCheckData[3] = (ULONG)Eip;
-#elif defined(_M_PPC)
- Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
- KiBugCheckData[3] = (ULONG)Eip;
-#endif
+ /* Get the Program Counter */
+ Pc = (PVOID)KeGetTrapFramePc(TrapFrame);
+ KiBugCheckData[3] = (ULONG_PTR)Pc;
/* Find out if was in the kernel or drivers */
- DriverBase = KiPcToFileHeader(Eip,
+ DriverBase = KiPcToFileHeader(Pc,
&LdrEntry,
FALSE,
&IsSystem);
/* Check if the driver forgot to unlock pages */
case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:
- /* EIP is in parameter 1 */
- Eip = (PVOID)BugCheckParameter1;
+ /* Program Counter is in parameter 1 */
+ Pc = (PVOID)BugCheckParameter1;
break;
/* Check if the driver consumed too many PTEs */
}
else
{
- /* Do we have an EIP? */
- if (Eip)
+ /* Do we have a Program Counter? */
+ if (Pc)
{
/* Dump image name */
KiDumpParameterImages(AnsiName,
- (PULONG_PTR)&Eip,
+ (PULONG_PTR)&Pc,
1,
KeBugCheckUnicodeToAnsi);
}
/* Intel CPUs */
case CPU_INTEL:
- /* Check if it's a P6 or higher */
+ /* Check if it's a P6 */
if (Prcb->CpuType == 6)
{
/* Perform the special sequence to get the MicroCode Signature */
NTAPI
KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
{
- /* Restore the CR registers */
+ PKGDTENTRY TssEntry;
+
+ //
+ // Restore the CR registers
+ //
__writecr0(ProcessorState->SpecialRegisters.Cr0);
Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
__writecr3(ProcessorState->SpecialRegisters.Cr3);
__writedr(7, ProcessorState->SpecialRegisters.KernelDr7);
//
- // Restore GDT, IDT, LDT and TSS
+ // Restore GDT and IDT
//
Ke386SetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
__lidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
+
+ //
+ // Clear the busy flag so we don't crash if we reload the same selector
+ //
+ TssEntry = (PKGDTENTRY)(ProcessorState->SpecialRegisters.Gdtr.Base +
+ ProcessorState->SpecialRegisters.Tr);
+ TssEntry->HighWord.Bytes.Flags1 &= ~0x2;
+
+ //
+ // Restore TSS and LDT
+ //
Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
}
/* Put tick count back in EBX */
mov ebx, eax
- /* Copyit in ECX and get hich count */
+ /* Copy it in ECX and get high count */
mov ecx, eax
mov edx, _KeTickCount + 4
jz NoDebug
/* Break-in requested! */
- push 1
+ push DBG_STATUS_CONTROL_C
call _DbgBreakPointWithStatus@4
jmp NoDebug
PULONG BucketValue;
PKPROFILE Profile;
PLIST_ENTRY NextEntry;
+ ULONG_PTR ProgramCounter;
+
+ /* Get the Program Counter */
+ ProgramCounter = KeGetTrapFramePc(TrapFrame);
/* Loop the List */
for (NextEntry = ListHead->Flink;
Profile = CONTAINING_RECORD(NextEntry, KPROFILE, ProfileListEntry);
/* Check if the source is good, and if it's within the range */
-#ifdef _M_IX86
if ((Profile->Source != Source) ||
- (TrapFrame->Eip < (ULONG_PTR)Profile->RangeBase) ||
- (TrapFrame->Eip > (ULONG_PTR)Profile->RangeLimit))
+ (ProgramCounter < (ULONG_PTR)Profile->RangeBase) ||
+ (ProgramCounter > (ULONG_PTR)Profile->RangeLimit))
{
continue;
}
- /* Get the Pointer to the Bucket Value representing this EIP */
+ /* Get the Pointer to the Bucket Value representing this Program Counter */
BucketValue = (PULONG)((((ULONG_PTR)Profile->Buffer +
- (TrapFrame->Eip - (ULONG_PTR)Profile->RangeBase))
+ (ProgramCounter - (ULONG_PTR)Profile->RangeBase))
>> Profile->BucketShift) &~ 0x3);
-#elif defined(_M_PPC)
- // XXX arty
-#endif
/* Increment the value */
++BucketValue;
\r
LIST_ENTRY PsLoadedModuleList;\r
KSPIN_LOCK PsLoadedModuleSpinLock;\r
-ULONG PsNtosImageBase;\r
+ULONG_PTR PsNtosImageBase;\r
KMUTANT MmSystemLoadLock;\r
extern ULONG NtGlobalFlag;\r
\r
LdrEntry = CONTAINING_RECORD(NextEntry,\r
LDR_DATA_TABLE_ENTRY,\r
InLoadOrderLinks);\r
- PsNtosImageBase = (ULONG)LdrEntry->DllBase;\r
+ PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;\r
\r
/* Loop the loader block */\r
while (NextEntry != ListHead)\r
KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 8, 0, 0);
}
+#ifdef _WINKD_
+ /* Let KD know we are done */
+ KdUpdateDataBlock();
+#endif
+
/* Return status */
return Status;
}
}
/* Set the Start Addresses */
-#if defined(_M_IX86)
- Thread->StartAddress = (PVOID)ThreadContext->Eip;
- Thread->Win32StartAddress = (PVOID)ThreadContext->Eax;
-#elif defined(_M_PPC)
- Thread->StartAddress = (PVOID)ThreadContext->Dr0;
- Thread->Win32StartAddress = (PVOID)ThreadContext->Gpr3;
-#elif defined(_M_MIPS)
- Thread->StartAddress = (PVOID)ThreadContext->Psr;
- Thread->Win32StartAddress = (PVOID)ThreadContext->IntA0;
-#elif defined(_M_ARM)
- Thread->StartAddress = (PVOID)ThreadContext->Pc;
- Thread->Win32StartAddress = (PVOID)ThreadContext->R0;
-#elif defined(_M_AMD64)
- Thread->StartAddress = (PVOID)ThreadContext->Rip;
- Thread->Win32StartAddress = (PVOID)ThreadContext->Rax;
-#else
-#error Unknown architecture
-#endif
+ Thread->StartAddress = (PVOID)KeGetContextPc(ThreadContext);
+ Thread->Win32StartAddress = (PVOID)KeGetContextReturnRegister(ThreadContext);
/* Let the kernel intialize the Thread */
Status = KeInitThread(&Thread->Tcb,
Stack = TrapFrame->Ebp;
#elif defined(_M_PPC)
Stack = TrapFrame->Gpr1;
+#else
+#error Unknown architecture
#endif
/* Validate them */