Author: sginsberg Date: Mon Sep 28 14:08:54 2015 New Revision: 69400
URL: http://svn.reactos.org/svn/reactos?rev=69400&view=rev Log: [NTOS] Implement the KD Get/SetContextEx functionality (copying part of a CONTEXT via Offset + Byte Count instead of copying a whole context), and stub out KdpWriteCustomBreakpoint. Newer WinDbg uses the GetContextEx functionality regardless of whether we report it as supported or not, and didn't seem to fall back on the regular GetContext functionality when it was missing, so whatever it was using it for should work awesome now. This had no impact on the broken Registers window though. Also small fix to use the _M_XXX checks consistently.
Modified: trunk/reactos/include/reactos/windbgkd.h trunk/reactos/ntoskrnl/kd64/kdapi.c trunk/reactos/ntoskrnl/kd64/kddata.c
Modified: trunk/reactos/include/reactos/windbgkd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/windbgkd.h?... ============================================================================== --- trunk/reactos/include/reactos/windbgkd.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/windbgkd.h [iso-8859-1] Mon Sep 28 14:08:54 2015 @@ -111,16 +111,10 @@ #define DbgKdFillMemoryApi 0x0000315B #define DbgKdQueryMemoryApi 0x0000315C #define DbgKdSwitchPartition 0x0000315D -#define DbgKdMaximumManipulate 0x0000315E - -/* - * Three possible new API messages as well as the new Max - * if these were to be added. Be careful about implementing these. - */ -//#define DbgKdWriteCustomBreakpointApi 0x0000315E -//#define DbgKdGetContextExApi 0x0000315F -//#define DbgKdSetContextExApi 0x00003160 -//#define DbgKdMaximumManipulate 0x00003161 +#define DbgKdWriteCustomBreakpointApi 0x0000315E +#define DbgKdGetContextExApi 0x0000315F +#define DbgKdSetContextExApi 0x00003160 +#define DbgKdMaximumManipulate 0x00003161
// // Debug I/O Types @@ -713,6 +707,22 @@ { ULONG Partition; } DBGKD_SWITCH_PARTITION; + +typedef struct _DBGKD_CONTEXT_EX +{ + ULONG Offset; + ULONG ByteCount; + ULONG BytesCopied; +} DBGKD_CONTEXT_EX, *PDBGKD_CONTEXT_EX; + +typedef struct _DBGKD_WRITE_CUSTOM_BREAKPOINT +{ + ULONG64 BreakPointAddress; + ULONG64 BreakPointInstruction; + ULONG BreakPointHandle; + UCHAR BreakPointInstructionSize; + UCHAR BreakPointInstructionAlignment; +} DBGKD_WRITE_CUSTOM_BREAKPOINT, *PDBGKD_WRITE_CUSTOM_BREAKPOINT;
// // DBGKD Structure for Manipulate @@ -782,6 +792,8 @@ DBGKD_FILL_MEMORY FillMemory; DBGKD_QUERY_MEMORY QueryMemory; DBGKD_SWITCH_PARTITION SwitchPartition; + DBGKD_WRITE_CUSTOM_BREAKPOINT WriteCustomBreakpoint; + DBGKD_CONTEXT_EX ContextEx; } u; } DBGKD_MANIPULATE_STATE64, *PDBGKD_MANIPULATE_STATE64;
@@ -878,22 +890,6 @@ } u; } DBGKD_TRACE_IO, *PDBGKD_TRACE_IO;
-typedef struct _DBGKD_WRITE_CUSTOM_BREAKPOINT -{ - ULONG64 BreakPointAddress; - ULONG64 BreakPointInstruction; - ULONG BreakPointHandle; - UCHAR BreakPointInstructionSize; - UCHAR BreakPointInstructionAlignment; -} DBGKD_WRITE_CUSTOM_BREAKPOINT, *PDBGKD_WRITE_CUSTOM_BREAKPOINT; - -typedef struct _DBGKD_CONTEXT_EX -{ - ULONG Offset; - ULONG ByteCount; - ULONG BytesCopied; -} DBGKD_CONTEXT_EX, *PDBGKD_CONTEXT_EX; - static __inline VOID
Modified: trunk/reactos/ntoskrnl/kd64/kdapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] Mon Sep 28 14:08:54 2015 @@ -315,6 +315,28 @@
VOID NTAPI +KdpWriteCustomBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + //PDBGKD_WRITE_CUSTOM_BREAKPOINT = &State->u.WriteCustomBreakpoint; + STRING Header; + + /* Not supported */ + KdpDprintf("Custom Breakpoint Write is unimplemented\n"); + + /* Send a failure packet */ + State->ReturnStatus = STATUS_UNSUCCESSFUL; + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); +} + +VOID +NTAPI DumpTraceData(IN PSTRING TraceData) { /* Update the buffer */ @@ -726,7 +748,8 @@ ASSERT(Data->Length == sizeof(CONTEXT));
/* Make sure that this is a valid request */ - if ((State->Processor < KeNumberProcessors) && (KdpContextSent != FALSE)) + if ((State->Processor < KeNumberProcessors) && + (KdpContextSent)) { /* Check if the request is for this CPU */ if (State->Processor == KeGetCurrentPrcb()->Number) @@ -750,6 +773,130 @@ else { /* Invalid request */ + State->ReturnStatus = STATUS_UNSUCCESSFUL; + } + + /* Send the reply */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + NULL, + &KdpContext); +} + +VOID +NTAPI +KdpGetContextEx(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + PDBGKD_CONTEXT_EX ContextEx; + PCONTEXT TargetContext; + ASSERT(Data->Length == 0); + + /* Get our struct */ + ContextEx = &State->u.ContextEx; + + /* Set up the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Make sure that this is a valid request */ + if ((State->Processor < KeNumberProcessors) && + (ContextEx->Offset + ContextEx->ByteCount) <= sizeof(CONTEXT)) + { + /* Check if the request is for this CPU */ + if (State->Processor == KeGetCurrentPrcb()->Number) + { + /* We're just copying our own context */ + TargetContext = Context; + } + else + { + /* Get the context from the PRCB array */ + TargetContext = &KiProcessorBlock[State->Processor]-> + ProcessorState.ContextFrame; + } + + /* Copy what is requested */ + RtlCopyMemory(Data->Buffer, + (PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), + ContextEx->ByteCount); + + /* KD copies all */ + Data->Length = ContextEx->BytesCopied = ContextEx->ByteCount; + + /* Let the debugger set the context now */ + KdpContextSent = TRUE; + + /* Finish up */ + State->ReturnStatus = STATUS_SUCCESS; + } + else + { + /* Invalid request */ + ContextEx->BytesCopied = 0; + State->ReturnStatus = STATUS_UNSUCCESSFUL; + } + + /* Send the reply */ + KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, + &Header, + Data, + &KdpContext); +} + +VOID +NTAPI +KdpSetContextEx(IN PDBGKD_MANIPULATE_STATE64 State, + IN PSTRING Data, + IN PCONTEXT Context) +{ + STRING Header; + PDBGKD_CONTEXT_EX ContextEx; + PCONTEXT TargetContext; + + /* Get our struct */ + ContextEx = &State->u.ContextEx; + ASSERT(Data->Length == ContextEx->ByteCount); + + /* Set up the header */ + Header.Length = sizeof(DBGKD_MANIPULATE_STATE64); + Header.Buffer = (PCHAR)State; + + /* Make sure that this is a valid request */ + if ((State->Processor < KeNumberProcessors) && + ((ContextEx->Offset + ContextEx->ByteCount) <= sizeof(CONTEXT)) && + (KdpContextSent)) + { + /* Check if the request is for this CPU */ + if (State->Processor == KeGetCurrentPrcb()->Number) + { + /* We're just copying our own context */ + TargetContext = Context; + } + else + { + /* Get the context from the PRCB array */ + TargetContext = &KiProcessorBlock[State->Processor]-> + ProcessorState.ContextFrame; + } + + /* Copy what is requested */ + RtlCopyMemory((PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), + Data->Buffer, + ContextEx->ByteCount); + + /* KD copies all */ + ContextEx->BytesCopied = ContextEx->ByteCount; + + /* Finish up */ + State->ReturnStatus = STATUS_SUCCESS; + } + else + { + /* Invalid request */ + ContextEx->BytesCopied = 0; State->ReturnStatus = STATUS_UNSUCCESSFUL; }
@@ -1359,27 +1506,29 @@ KdpNotSupported(&ManipulateState); break;
+ case DbgKdWriteCustomBreakpointApi: + + /* Write the customized breakpoint */ + KdpWriteCustomBreakpoint(&ManipulateState, &Data, Context); + break; + + case DbgKdGetContextExApi: + + /* Extended Context Get */ + KdpGetContextEx(&ManipulateState, &Data, Context); + break; + + case DbgKdSetContextExApi: + + /* Extended Context Set */ + KdpSetContextEx(&ManipulateState, &Data, Context); + break; + /* Unsupported Messages */ default:
/* Send warning */ - KdpDprintf("Received Unhandled API %lx\n", ManipulateState.ApiNumber); - - /* - * These 3 messages are unimplemented by us, but one (DbgKdGetContextExApi) - * is sent by WinDbg as of late during kernel debugging for some reason even though - * our MaxManipulate in the version block does not report it as being available. - * - * Any of these being sent to begin with is most likely a bug in WinDbg, so these - * are ignored and do not print a warning message to not spam the debug output. - * So far, WinDbg seems perfectly fine with this. - * - * DbgKdSetContextExApi complements the Get and DbgKdWriteCustomBreakpointApi - * fills the gap after DbgKdSwitchPartition (0x315D). - */ - case 0x315E: // DbgKdWriteCustomBreakpointApi - case 0x315F: // DbgKdGetContextExApi - case 0x3160: // DbgKdSetContextExApi + KdpDprintf("Received Unrecognized API 0x%lx\n", ManipulateState.ApiNumber);
/* Setup an empty message, with failure */ Data.Length = 0;
Modified: trunk/reactos/ntoskrnl/kd64/kddata.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kddata.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kddata.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kddata.c [iso-8859-1] Mon Sep 28 14:08:54 2015 @@ -19,11 +19,11 @@ // // Apply the KIPCR WDK workaround for x86 and AMD64 // -#if defined(_X86_) || defined(_AMD64_) +#if defined(_M_IX86) || defined(_M_AMD64) #define KPCR KIPCR #endif
-#if defined(_X86_) +#if defined(_M_IX86)
#define KPCR_SELF_PCR_OFFSET FIELD_OFFSET(KPCR, Self) #define KPCR_CURRENT_PRCB_OFFSET FIELD_OFFSET(KPCR, Prcb) @@ -33,7 +33,7 @@ #define KPRCB_PCR_PAGE_OFFSET 0 #define CBSTACK_FRAME_POINTER Ebp
-#elif defined(_AMD64_) +#elif defined(_M_AMD64)
#define KPCR_SELF_PCR_OFFSET FIELD_OFFSET(KPCR, Self) #define KPCR_CURRENT_PRCB_OFFSET FIELD_OFFSET(KPCR, CurrentPrcb) @@ -43,7 +43,7 @@ #define KPRCB_PCR_PAGE_OFFSET 0 #define CBSTACK_FRAME_POINTER Rbp
-#elif defined(_ARM_) +#elif defined(_M_ARM)
#define KPCR_SELF_PCR_OFFSET 0 #define KPCR_CURRENT_PRCB_OFFSET FIELD_OFFSET(KIPCR, Prcb) @@ -374,7 +374,7 @@ 0, DBGKD_64BIT_PROTOCOL_VERSION2, CURRENT_KD_SECONDARY_VERSION, -#if defined(_WIN64) +#if defined(_M_AMD64) || defined(_M_ARM64) DBGKD_VERS_FLAG_DATA | DBGKD_VERS_FLAG_PTR64, #else DBGKD_VERS_FLAG_DATA, @@ -521,7 +521,7 @@ KPRCB_PCR_PAGE_OFFSET, #endif FIELD_OFFSET(KPRCB, ProcessorState.SpecialRegisters), -#if defined(_X86_) +#if defined(_M_IX86) // // x86 GDT/LDT/TSS constants // @@ -535,7 +535,7 @@ KGDT_TSS, 0, 0, -#elif defined(_AMD64_) +#elif defined(_M_AMD64) // // AMD64 GDT/LDT/TSS constants //