Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

kdapi.c File Reference

#include "kdp.h"

Go to the source code of this file.

Defines

#define SHIFT10000   13
#define Convert100nsToMilliseconds(LARGE_INTEGER)

Functions

LARGE_INTEGER KdpQueryPerformanceCounter (IN PKTRAP_FRAME TrapFrame)
VOID KdpProcessInternalBreakpoint (ULONG BreakpointNumber)
VOID KdpGetVersion (IN PDBGKD_MANIPULATE_STATE64 m)
NTSTATUS KdpNotSupported (IN PDBGKD_MANIPULATE_STATE64 m)
VOID KdpCauseBugCheck (IN PDBGKD_MANIPULATE_STATE64 m)
NTSTATUS KdpWriteBreakPointEx (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpRestoreBreakPointEx (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpSearchMemory (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
ULONG KdpSearchHammingDistance (ULONG_PTR Left, ULONG_PTR Right)
LOGICAL KdpSearchPhysicalPage (IN PFN_NUMBER PageFrameIndex, ULONG_PTR RangeStart, ULONG_PTR RangeEnd, ULONG Flags)
LOGICAL KdpSearchPhysicalMemoryRequested (VOID)
LOGICAL KdpSearchPhysicalPageRange (VOID)
BOOLEAN KdEnterDebugger (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
VOID KdExitDebugger (IN BOOLEAN Enable)
VOID KdUpdateTimeSlipEvent (PVOID Event)
VOID KdpTimeSlipDpcRoutine (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
VOID KdpTimeSlipWork (IN PVOID Context)
KCONTINUE_STATUS KdpSendWaitContinue (IN ULONG OutPacketType, IN PSTRING OutMessageHeader, IN PSTRING OutMessageData OPTIONAL, IN OUT PCONTEXT ContextRecord)
VOID KdpReadVirtualMemory (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteVirtualMemory (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpGetContext (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpSetContext (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteBreakpoint (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpRestoreBreakpoint (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
BOOLEAN KdpSwitchProcessor (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChance)
BOOLEAN KdpReportExceptionStateChange (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChance)
BOOLEAN KdpReportLoadSymbolsStateChange (IN PSTRING PathName, IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN UnloadSymbols, IN OUT PCONTEXT ContextRecord)
VOID KdpReadPhysicalMemory (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWritePhysicalMemory (IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdDisableDebugger (VOID)
VOID KdEnableDebugger (VOID)
VOID KdpCheckLowMemory (IN PDBGKD_MANIPULATE_STATE64 Message)

Variables

LARGE_INTEGER Magic10000
LONG KdDisableCount = 0
BOOLEAN KdPreviouslyEnabled


Define Documentation

#define Convert100nsToMilliseconds LARGE_INTEGER   ) 
 

Value:

( \ RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000, SHIFT10000 ) \ )

Definition at line 44 of file 4/kdapi.c.

#define SHIFT10000   13
 

Definition at line 43 of file 4/kdapi.c.


Function Documentation

VOID KdDisableDebugger VOID   ) 
 

Definition at line 3330 of file 4/kdapi.c.

References DISPATCH_LEVEL, FALSE, KdDebuggerEnabled, KdDisableCount, KdPitchDebugger, KdpPortLock(), KdpPortUnlock(), KdPreviouslyEnabled, KdpStub(), KdpSuspendAllBreakpoints(), KeLowerIrql(), KeRaiseIrql(), and KiDebugRoutine.

03335 : 03336 03337 This function is called to disable the debugger. 03338 03339 Arguments: 03340 03341 None. 03342 03343 Return Value: 03344 03345 None. 03346 03347 --*/ 03348 03349 { 03350 KIRQL oldIrql ; 03351 03352 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql) ; 03353 KdpPortLock(); 03354 03355 if (!KdDisableCount) { 03356 03357 KdPreviouslyEnabled = KdDebuggerEnabled && (!KdPitchDebugger) ; 03358 if (KdDebuggerEnabled) { 03359 03360 KdpSuspendAllBreakpoints() ; 03361 KiDebugRoutine = KdpStub; 03362 KdDebuggerEnabled = FALSE ; 03363 } 03364 } 03365 KdDisableCount++ ; 03366 KdpPortUnlock(); 03367 KeLowerIrql(oldIrql); 03368 }

VOID KdEnableDebugger VOID   ) 
 

Definition at line 3371 of file 4/kdapi.c.

References ASSERT, DISPATCH_LEVEL, FALSE, KdDisableCount, KdInitSystem(), KdpPortLock(), KdpPortUnlock(), KdpRestoreAllBreakpoints(), KdPreviouslyEnabled, KeLowerIrql(), KeRaiseIrql(), NULL, PoHiberInProgress, and TRUE.

03376 : 03377 03378 This function is called to reenable the debugger after a call to 03379 KdDisableDebugger. 03380 03381 Arguments: 03382 03383 None. 03384 03385 Return Value: 03386 03387 None. 03388 03389 --*/ 03390 { 03391 KIRQL oldIrql ; 03392 03393 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql) ; 03394 KdpPortLock(); 03395 03396 ASSERT(KdDisableCount > 0) ; 03397 KdDisableCount-- ; 03398 03399 if (!KdDisableCount) { 03400 if (KdPreviouslyEnabled) { 03401 03402 // 03403 // Ugly HACKHACK - Make sure the timers aren't reset. 03404 // 03405 PoHiberInProgress = TRUE ; 03406 KdInitSystem(NULL, FALSE) ; 03407 KdpRestoreAllBreakpoints(); 03408 PoHiberInProgress = FALSE ; 03409 } 03410 } 03411 KdpPortUnlock(); 03412 KeLowerIrql(oldIrql); 03413 }

BOOLEAN KdEnterDebugger IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

Definition at line 277 of file 4/kdapi.c.

References DPRINT, FALSE, FREEZE_BACKUP, FREEZE_SKIPPED_PROCESSOR, KdEnteredDebugger, KdpDebuggerLock, KdPortSave(), KdpPortLocked, KdpQueryPerformanceCounter(), KdTimerDifference, KdTimerStart, KdTimerStop, KeFreezeExecution(), KiFreezeFlag, KiTryToAcquireSpinLock(), TimeFields, and TRUE.

Referenced by KdpTrap(), and KdSetOwedBreakpoints().

00284 : 00285 00286 This function is used to enter the kernel debugger. Its purpose 00287 is to freeze all other processors and aqcuire the kernel debugger 00288 comm port. 00289 00290 Arguments: 00291 00292 TrapFrame - Supplies a pointer to a trap frame that describes the 00293 trap. 00294 00295 ExceptionFrame - Supplies a pointer to an exception frame that 00296 describes the trap. 00297 00298 Return Value: 00299 00300 Returns the previous interrupt enable. 00301 00302 --*/ 00303 00304 { 00305 00306 BOOLEAN Enable; 00307 TIME_FIELDS TimeFields; 00308 #if DBG 00309 extern ULONG KiFreezeFlag; 00310 #endif 00311 00312 // 00313 // HACKHACK - do some crude timer support 00314 // but not if called from KdSetOwedBreakpoints() 00315 // 00316 00317 if (TrapFrame) { 00318 KdTimerStop = KdpQueryPerformanceCounter (TrapFrame); 00319 KdTimerDifference.QuadPart = KdTimerStop.QuadPart - KdTimerStart.QuadPart; 00320 } else { 00321 KdTimerStop.QuadPart = 0; 00322 } 00323 00324 // 00325 // Freeze all other processors, raise IRQL to HIGH_LEVEL, and save debug 00326 // port state. We lock the port so that KdPollBreakin and a debugger 00327 // operation don't interfere with each other. 00328 // 00329 00330 Enable = KeFreezeExecution(TrapFrame, ExceptionFrame); 00331 KdpPortLocked = KiTryToAcquireSpinLock(&KdpDebuggerLock); 00332 KdPortSave(); 00333 KdEnteredDebugger = TRUE; 00334 00335 #if DBG 00336 00337 if ((KiFreezeFlag & FREEZE_BACKUP) != 0) { 00338 DPRINT(("FreezeLock was jammed! Backup SpinLock was used!\n")); 00339 } 00340 00341 if ((KiFreezeFlag & FREEZE_SKIPPED_PROCESSOR) != 0) { 00342 DPRINT(("Some processors not frozen in debugger!\n")); 00343 } 00344 00345 if (KdpPortLocked == FALSE) { 00346 DPRINT(("Port lock was not acquired!\n")); 00347 } 00348 00349 #endif 00350 00351 return Enable; 00352 }

VOID KdExitDebugger IN BOOLEAN  Enable  ) 
 

Definition at line 355 of file 4/kdapi.c.

References KdPortRestore(), KdpPortLocked, KdpPortUnlock(), KdpTimeSlipDpc, KdpTimeSlipPending, KdTimerStart, KdTimerStop, KeInsertQueueDpc(), KeQueryPerformanceCounter(), KeThawExecution(), NULL, PoHiberInProgress, and TimeFields.

Referenced by KdpTrap(), and KdSetOwedBreakpoints().

00361 : 00362 00363 This function is used to exit the kernel debugger. It is the reverse 00364 of KdEnterDebugger. 00365 00366 Arguments: 00367 00368 Enable - Supplies the previous interrupt enable which is to be restored. 00369 00370 Return Value: 00371 00372 None. 00373 00374 --*/ 00375 00376 { 00377 ULONG ElapsedTime; 00378 ULARGE_INTEGER TimeDifference; 00379 TIME_FIELDS TimeFields; 00380 ULONG Pending; 00381 00382 // 00383 // restore stuff and exit 00384 // 00385 00386 KdPortRestore(); 00387 if (KdpPortLocked) { 00388 KdpPortUnlock(); 00389 } 00390 00391 KeThawExecution(Enable); 00392 00393 // 00394 // Do some crude timer support. If KdEnterDebugger didn't 00395 // Query the performance counter, then don't do it here either. 00396 // 00397 00398 if (KdTimerStop.QuadPart == 0) { 00399 KdTimerStart = KdTimerStop; 00400 } else { 00401 KdTimerStart = KeQueryPerformanceCounter(NULL); 00402 } 00403 00404 // 00405 // Process a time slip 00406 // 00407 00408 if (!PoHiberInProgress) { 00409 00410 Pending = InterlockedIncrement(&KdpTimeSlipPending); 00411 00412 // 00413 // If there's wasn't a time slip pending, queue the DPC to handle it 00414 // 00415 00416 if (Pending == 1) { 00417 InterlockedIncrement(&KdpTimeSlipPending); 00418 KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL); 00419 } 00420 } 00421 00422 return; 00423 }

VOID KdpCauseBugCheck IN PDBGKD_MANIPULATE_STATE64  m  ) 
 

Definition at line 3097 of file 4/kdapi.c.

References KeBugCheckEx().

Referenced by KdpSendWaitContinue().

03103 : 03104 03105 This routine causes a bugcheck. It is used for testing the debugger. 03106 03107 Arguments: 03108 03109 m - Supplies the state manipulation message. 03110 03111 Return Value: 03112 03113 None. 03114 03115 --*/ 03116 03117 { 03118 03119 KeBugCheckEx( MANUALLY_INITIATED_CRASH, 0, 0, 0, 0 ); 03120 03121 } // KdCauseBugCheck

VOID KdpCheckLowMemory IN PDBGKD_MANIPULATE_STATE64  Message  ) 
 

Definition at line 3633 of file 4/kdapi.c.

References KdpSearchPhysicalMemoryRequested(), KdpSearchPhysicalPageRange(), KdpSendPacket(), MiNoLowMemory, MmHighestPhysicalPage, MmLowestPhysicalPage, and NULL.

Referenced by KdpSendWaitContinue().

03639 : 03640 03641 03642 Arguments: 03643 03644 Message - Supplies the state manipulation message. 03645 03646 Return Value: 03647 03648 None. 03649 03650 Description: 03651 03652 This function gets called when the !chklowmem 03653 debugger extension is used. 03654 03655 --*/ 03656 03657 { 03658 //+silviuc: move to a header 03659 #if defined (_X86PAE_) 03660 LOGICAL 03661 MiCheckPhysicalPagePattern ( 03662 PFN_NUMBER Page, 03663 PULONG CorruptionOffset 03664 ); 03665 03666 extern PFN_NUMBER MmLowestPhysicalPage; 03667 extern PFN_NUMBER MmHighestPhysicalPage; 03668 extern LOGICAL MiNoLowMemory; 03669 #endif // #if defined (_X86PAE_) 03670 //-silviuc 03671 03672 STRING MessageHeader; 03673 PFN_NUMBER Page; 03674 PHYSICAL_ADDRESS P; 03675 PVOID64 VirtualAddress; 03676 ULONG CorruptionOffset; 03677 03678 Message->ReturnStatus = STATUS_SUCCESS; 03679 MessageHeader.Length = sizeof(*Message); 03680 MessageHeader.Buffer = (PCHAR)Message; 03681 03682 if (KdpSearchPhysicalMemoryRequested()) { 03683 03684 // 03685 // This is a !search kd extension call. 03686 // 03687 03688 KdpSearchPhysicalPageRange(); 03689 } 03690 else { 03691 03692 // 03693 // Check PAE low physical memory 03694 // 03695 03696 #if defined (_X86PAE_) 03697 03698 if (MiNoLowMemory) { 03699 03700 for (Page = MmLowestPhysicalPage; 03701 Page < MmHighestPhysicalPage && Page < 1024 * 1024; 03702 Page += 1) { 03703 03704 03705 if (! MiCheckPhysicalPagePattern (Page, &CorruptionOffset)) { 03706 Message->ReturnStatus = Page; 03707 break; 03708 } 03709 } 03710 } 03711 03712 #endif // #if defined (_X86PAE_) 03713 } 03714 03715 // 03716 // Acknowledge the packet received. 03717 // 03718 03719 KdpSendPacket ( 03720 PACKET_TYPE_KD_STATE_MANIPULATE, 03721 &MessageHeader, 03722 NULL 03723 ); 03724 }

VOID KdpGetContext IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1569 of file 4/kdapi.c.

References ASSERT, KdpQuickMoveMemory(), KdpSendPacket(), KeGetCurrentPrcb, KeNumberProcessors, KiProcessorBlock, and USHORT.

Referenced by KdpSendWaitContinue().

01577 : 01578 01579 This function is called in response of a get context state 01580 manipulation message. Its function is to return the current 01581 context. 01582 01583 Arguments: 01584 01585 m - Supplies the state manipulation message. 01586 01587 AdditionalData - Supplies any additional data for the message. 01588 01589 Context - Supplies the current context. 01590 01591 Return Value: 01592 01593 None. 01594 01595 --*/ 01596 01597 { 01598 PDBGKD_GET_CONTEXT a = &m->u.GetContext; 01599 STRING MessageHeader; 01600 01601 MessageHeader.Length = sizeof(*m); 01602 MessageHeader.Buffer = (PCHAR)m; 01603 01604 ASSERT(AdditionalData->Length == 0); 01605 01606 if (m->Processor >= (USHORT)KeNumberProcessors) { 01607 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01608 } else { 01609 m->ReturnStatus = STATUS_SUCCESS; 01610 AdditionalData->Length = sizeof(CONTEXT); 01611 if (m->Processor == (USHORT)KeGetCurrentPrcb()->Number) { 01612 KdpQuickMoveMemory(AdditionalData->Buffer, (PCHAR)Context, sizeof(CONTEXT)); 01613 } else { 01614 KdpQuickMoveMemory(AdditionalData->Buffer, 01615 (PCHAR)&KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame, 01616 sizeof(CONTEXT) 01617 ); 01618 } 01619 } 01620 01621 KdpSendPacket( 01622 PACKET_TYPE_KD_STATE_MANIPULATE, 01623 &MessageHeader, 01624 AdditionalData 01625 ); 01626 }

VOID KdpGetVersion IN PDBGKD_MANIPULATE_STATE64  m  ) 
 

Definition at line 2945 of file 4/kdapi.c.

References KdpDebuggerDataListHead, KdpNtosImageBase, KdpSendPacket(), NtBuildNumber, NULL, PsLoadedModuleList, and PsNtosImageBase.

Referenced by KdpSendWaitContinue().

02951 : 02952 02953 This function returns to the caller a general information packet 02954 that contains useful information to a debugger. This packet is also 02955 used for a debugger to determine if the writebreakpointex and 02956 readbreakpointex apis are available. 02957 02958 Arguments: 02959 02960 m - Supplies the state manipulation message. 02961 02962 Return Value: 02963 02964 None. 02965 02966 --*/ 02967 02968 { 02969 STRING messageHeader; 02970 02971 02972 messageHeader.Length = sizeof(*m); 02973 messageHeader.Buffer = (PCHAR)m; 02974 02975 RtlZeroMemory(&m->u.GetVersion64, sizeof(m->u.GetVersion64)); 02976 // 02977 // the current build number 02978 // 02979 m->u.GetVersion64.MinorVersion = (short)NtBuildNumber; 02980 m->u.GetVersion64.MajorVersion = (short)((NtBuildNumber >> 28) & 0xFFFFFFF); 02981 02982 // 02983 // kd protocol version number. this should be incremented if the 02984 // protocol changes. 02985 // 02986 m->u.GetVersion64.ProtocolVersion = 5; 02987 m->u.GetVersion64.Flags = DBGKD_VERS_FLAG_DATA; 02988 02989 #if !defined(NT_UP) 02990 m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_MP; 02991 #endif 02992 02993 #if defined(_M_IX86) 02994 m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_I386; 02995 #elif defined(_M_MRX000) 02996 m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_R4000; 02997 #elif defined(_M_ALPHA) 02998 m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_ALPHA; 02999 #if defined(_AXP64_) 03000 m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_PTR64; 03001 #endif 03002 #elif defined(_M_PPC) 03003 m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_POWERPC; 03004 #elif defined(_M_IA64) 03005 m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_IA64; 03006 m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_PTR64; 03007 #else 03008 #error( "unknown target machine" ); 03009 #endif 03010 03011 // 03012 // address of the loader table 03013 // 03014 m->u.GetVersion64.PsLoadedModuleList = (ULONG64)(LONG64)(LONG_PTR)&PsLoadedModuleList; 03015 03016 // 03017 // If the debugger is being initialized during boot, PsNtosImageBase 03018 // and PsLoadedModuleList are not yet valid. KdInitSystem got 03019 // the image base from the loader block. 03020 // On the other hand, if the debugger was initialized by a bugcheck, 03021 // it didn't get a loader block to look at, but the system was 03022 // running so the other variables are valid. 03023 // 03024 03025 if (KdpNtosImageBase) { 03026 m->u.GetVersion64.KernBase = (ULONG64)(LONG64)(LONG_PTR)KdpNtosImageBase; 03027 } else { 03028 m->u.GetVersion64.KernBase = (ULONG64)(LONG64)(LONG_PTR)PsNtosImageBase; 03029 } 03030 03031 m->u.GetVersion64.DebuggerDataList = (ULONG64)(LONG64)(LONG_PTR)&KdpDebuggerDataListHead; 03032 03033 // 03034 // the usual stuff 03035 // 03036 m->ReturnStatus = STATUS_SUCCESS; 03037 m->ApiNumber = DbgKdGetVersionApi; 03038 03039 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 03040 &messageHeader, 03041 NULL 03042 ); 03043 03044 return; 03045 } // KdGetVersion

NTSTATUS KdpNotSupported IN PDBGKD_MANIPULATE_STATE64  m  ) 
 

Definition at line 3049 of file 4/kdapi.c.

References KdpSendPacket(), and NULL.

Referenced by KdpSendWaitContinue().

03055 : 03056 03057 This routine returns STATUS_UNSUCCESSFUL to the debugger 03058 03059 Arguments: 03060 03061 m - Supplies a DBGKD_MANIPULATE_STATE64 struct to answer with 03062 03063 Return Value: 03064 03065 0, to indicate that the system should not continue 03066 03067 --*/ 03068 03069 { 03070 STRING MessageHeader; 03071 03072 // 03073 // setup packet 03074 // 03075 MessageHeader.Length = sizeof(*m); 03076 MessageHeader.Buffer = (PCHAR)m; 03077 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03078 03079 // 03080 // send back our response 03081 // 03082 KdpSendPacket( 03083 PACKET_TYPE_KD_STATE_MANIPULATE, 03084 &MessageHeader, 03085 NULL 03086 ); 03087 03088 // 03089 // return the caller's continue status value. if this is a non-zero 03090 // value the system is continued using this value as the continuestatus. 03091 // 03092 return 0; 03093 } // KdpNotSupported

VOID KdpProcessInternalBreakpoint ULONG  BreakpointNumber  ) 
 

LARGE_INTEGER KdpQueryPerformanceCounter IN PKTRAP_FRAME  TrapFrame  ) 
 

Definition at line 24 of file alpha/kdcmsup.c.

References KeQueryPerformanceCounter().

Referenced by KdEnterDebugger().

00030 : 00031 00032 This function returns the current value of the system performance 00033 counter. 00034 00035 Arguments: 00036 00037 None. 00038 00039 Return Value: 00040 00041 The value returned by KeQueryPerformanceCounter is returned as the 00042 function value. 00043 00044 --*/ 00045 00046 { 00047 00048 return KeQueryPerformanceCounter(0); 00049 } }

VOID KdpReadPhysicalMemory IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 2643 of file 4/kdapi.c.

References ASSERT, BYTE_OFFSET, KdpMoveMemory(), KdpSendPacket(), MmDbgTranslatePhysicalAddress64(), PAGE_SIZE, and USHORT.

Referenced by KdpSendWaitContinue().

02651 : 02652 02653 This function is called in response to a read physical memory 02654 state manipulation message. Its function is to read physical memory 02655 and return. 02656 02657 Arguments: 02658 02659 m - Supplies the state manipulation message. 02660 02661 AdditionalData - Supplies any additional data for the message. 02662 02663 Context - Supplies the current context. 02664 02665 Return Value: 02666 02667 None. 02668 02669 --*/ 02670 02671 { 02672 PDBGKD_READ_MEMORY64 a = &m->u.ReadMemory; 02673 ULONG Length; 02674 STRING MessageHeader; 02675 PVOID64 VirtualAddress; 02676 PHYSICAL_ADDRESS Source; 02677 UCHAR UNALIGNED *Destination; 02678 ULONG NumberBytes; 02679 ULONG BytesLeft; 02680 02681 MessageHeader.Length = sizeof(*m); 02682 MessageHeader.Buffer = (PCHAR)m; 02683 02684 // 02685 // make sure that nothing but a read memory message was transmitted 02686 // 02687 02688 ASSERT(AdditionalData->Length == 0); 02689 02690 // 02691 // Trim transfer count to fit in a single message 02692 // 02693 02694 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { 02695 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); 02696 } else { 02697 Length = a->TransferCount; 02698 } 02699 02700 // 02701 // Since the MmDbgTranslatePhysicalAddress64 only maps in one physical 02702 // page at a time (on non-alpha systems), 02703 // we need to break the memory move up into smaller 02704 // moves which don't cross page boundaries. It is important that we 02705 // access physical memory on naturally-aligned boundaries and with the 02706 // largest size possible. (We could be accessing memory-mapped I/O 02707 // space). These rules allow kdexts to read physical memory reliably. 02708 // 02709 02710 Source.QuadPart = a->TargetBaseAddress; 02711 Destination = AdditionalData->Buffer; 02712 while (Length > 0) { 02713 VirtualAddress = MmDbgTranslatePhysicalAddress64(Source); 02714 if (VirtualAddress == NULL64) { 02715 break; 02716 } 02717 NumberBytes = PAGE_SIZE - BYTE_OFFSET(Source.LowPart); 02718 if (NumberBytes > Length) { 02719 NumberBytes = Length; 02720 } 02721 02722 #ifdef _ALPHA_ 02723 BytesLeft = NumberBytes; 02724 while (BytesLeft > 0) { 02725 __MB(); 02726 02727 if (((ULONG64)VirtualAddress & 7) == 0 && BytesLeft > 7) { 02728 *((ULONGLONG UNALIGNED *)Destination)++ = 02729 *((ULONGLONG * POINTER_64)VirtualAddress)++; 02730 BytesLeft -= 8; 02731 } else { 02732 if (((ULONG64)VirtualAddress & 3) == 0 && BytesLeft > 3) { 02733 *((ULONG UNALIGNED *)Destination)++ = 02734 *((ULONG * POINTER_64)VirtualAddress)++; 02735 BytesLeft -= 4; 02736 } else { 02737 if (((ULONG64)VirtualAddress & 1) == 0 && BytesLeft > 1) { 02738 *((USHORT UNALIGNED *)Destination)++ = 02739 *((USHORT * POINTER_64)VirtualAddress)++; 02740 BytesLeft -= 2; 02741 } else { 02742 *Destination++ = 02743 *((UCHAR * POINTER_64)VirtualAddress)++; 02744 BytesLeft -= 1; 02745 } 02746 } 02747 } 02748 } 02749 #else 02750 KdpMoveMemory(Destination, VirtualAddress, NumberBytes); 02751 Destination += NumberBytes; 02752 02753 #endif 02754 Source.QuadPart += NumberBytes; 02755 Length -= NumberBytes; 02756 AdditionalData->Length += (USHORT)NumberBytes; 02757 } 02758 02759 if (Length == 0) { 02760 m->ReturnStatus = STATUS_SUCCESS; 02761 } else { 02762 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02763 } 02764 02765 a->ActualBytesRead = AdditionalData->Length; 02766 02767 KdpSendPacket( 02768 PACKET_TYPE_KD_STATE_MANIPULATE, 02769 &MessageHeader, 02770 AdditionalData 02771 ); 02772 UNREFERENCED_PARAMETER(Context); 02773 02774 }

VOID KdpReadVirtualMemory IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1126 of file 4/kdapi.c.

References KdpMoveMemory(), KdpSendPacket(), MmDbgReadCheck(), MmDbgReadCheck64(), and USHORT.

Referenced by KdpSendWaitContinue().

01134 : 01135 01136 This function is called in response to a read virtual memory 32-bit 01137 state manipulation message. Its function is to read virtual memory 01138 and return. 01139 01140 Arguments: 01141 01142 m - Supplies a pointer to the state manipulation message. 01143 01144 AdditionalData - Supplies a pointer to a descriptor for the data to read. 01145 01146 Context - Supplies a pointer to the current context. 01147 01148 Return Value: 01149 01150 None. 01151 01152 --*/ 01153 01154 { 01155 ULONG Length; 01156 STRING MessageHeader; 01157 #if defined(_ALPHA_) && !defined(_AXP64_) 01158 UCHAR * POINTER_64 Address; 01159 PUCHAR Destination; 01160 UCHAR * POINTER_64 Source; 01161 PUCHAR Source32; 01162 #endif 01163 01164 // 01165 // Trim the transfer count to fit in a single message. 01166 // 01167 01168 Length = m->u.ReadMemory.TransferCount; 01169 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { 01170 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); 01171 } 01172 01173 // 01174 // Move the data to the destination buffer. 01175 // 01176 01177 #if defined(_ALPHA_) && !defined(_AXP64_) 01178 01179 AdditionalData->Length = (USHORT)Length; 01180 01181 Destination = AdditionalData->Buffer; 01182 Source = (UCHAR * POINTER_64)m->u.ReadMemory.TargetBaseAddress; 01183 Source32 = (PUCHAR)m->u.ReadMemory.TargetBaseAddress; 01184 while (Length > 0) { 01185 if ((LONGLONG)Source != (LONGLONG)((LONG)Source)) { 01186 if ((Address = MmDbgReadCheck64(Source)) == NULL64) { 01187 break; 01188 } 01189 } else { 01190 if ((Address = MmDbgReadCheck(Source32)) == NULL64) { 01191 break; 01192 } 01193 } 01194 01195 *Destination++ = *Address; 01196 Source += 1; 01197 Source32 += 1; 01198 Length -= 1; 01199 } 01200 01201 // 01202 // If all the data is read, then return a success status. Otherwise, 01203 // return an unsuccessful status. 01204 // 01205 01206 m->ReturnStatus = STATUS_SUCCESS; 01207 if (Length != 0) { 01208 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01209 } 01210 01211 // 01212 // Set the actual number of bytes read, initialize the message header, 01213 // and send the reply packet to the host debugger. 01214 // 01215 01216 m->u.ReadMemory.ActualBytesRead = AdditionalData->Length - Length; 01217 #else 01218 AdditionalData->Length = (USHORT)KdpMoveMemory(AdditionalData->Buffer, 01219 (PVOID)m->u.ReadMemory.TargetBaseAddress, 01220 Length); 01221 01222 // 01223 // If all the data is read, then return a success status. Otherwise, 01224 // return an unsuccessful status. 01225 // 01226 01227 m->ReturnStatus = STATUS_SUCCESS; 01228 if (Length != AdditionalData->Length) { 01229 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01230 } 01231 01232 // 01233 // Set the actual number of bytes read, initialize the message header, 01234 // and send the reply packet to the host debugger. 01235 // 01236 01237 m->u.ReadMemory.ActualBytesRead = AdditionalData->Length; 01238 #endif 01239 01240 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE64); 01241 MessageHeader.Buffer = (PCHAR)m; 01242 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01243 &MessageHeader, 01244 AdditionalData); 01245 01246 return; 01247 }

BOOLEAN KdpReportExceptionStateChange IN PEXCEPTION_RECORD  ExceptionRecord,
IN OUT PCONTEXT  ContextRecord,
IN BOOLEAN  SecondChance
 

Definition at line 2459 of file 4/kdapi.c.

References ContinueProcessorReselected, KCONTINUE_STATUS, KdpCheckTracePoint(), KdpSendWaitContinue(), KdpSetStateChange(), Status, and TRUE.

Referenced by KdpSwitchProcessor(), and KdpTrap().

02467 : 02468 02469 This routine sends an exception state change packet to the kernel 02470 debugger and waits for a manipulate state message. 02471 02472 Arguments: 02473 02474 ExceptionRecord - Supplies a pointer to an exception record. 02475 02476 ContextRecord - Supplies a pointer to a context record. 02477 02478 SecondChance - Supplies a boolean value that determines whether this is 02479 the first or second chance for the exception. 02480 02481 Return Value: 02482 02483 A value of TRUE is returned if the exception is handled. Otherwise, a 02484 value of FALSE is returned. 02485 02486 --*/ 02487 02488 { 02489 STRING MessageData; 02490 STRING MessageHeader; 02491 DBGKD_WAIT_STATE_CHANGE64 WaitStateChange; 02492 KCONTINUE_STATUS Status; 02493 02494 #if i386 02495 if (KdpCheckTracePoint(ExceptionRecord,ContextRecord)) return TRUE; 02496 #endif 02497 02498 do { 02499 02500 // 02501 // Construct the wait state change message and message descriptor. 02502 // 02503 02504 KdpSetStateChange(&WaitStateChange, 02505 ExceptionRecord, 02506 ContextRecord, 02507 SecondChance 02508 ); 02509 02510 MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64); 02511 MessageHeader.Buffer = (PCHAR)&WaitStateChange; 02512 02513 #if i386 02514 // 02515 // Construct the wait state change data and data descriptor. 02516 // 02517 02518 DumpTraceData(&MessageData); 02519 #else 02520 MessageData.Length = 0; 02521 #endif 02522 02523 // 02524 // Send packet to the kernel debugger on the host machine, 02525 // wait for answer. 02526 // 02527 02528 Status = KdpSendWaitContinue( 02529 PACKET_TYPE_KD_STATE_CHANGE64, 02530 &MessageHeader, 02531 &MessageData, 02532 ContextRecord 02533 ); 02534 02535 } while (Status == ContinueProcessorReselected) ; 02536 02537 return (BOOLEAN) Status; 02538 }

BOOLEAN KdpReportLoadSymbolsStateChange IN PSTRING  PathName,
IN PKD_SYMBOLS_INFO  SymbolInfo,
IN BOOLEAN  UnloadSymbols,
IN OUT PCONTEXT  ContextRecord
 

Definition at line 2542 of file 4/kdapi.c.

References ContinueProcessorReselected, KCONTINUE_STATUS, KdpMoveMemory(), KdpPathBuffer, KdpSendWaitContinue(), KdpSetLoadState(), KeGetCurrentPrcb, KeGetCurrentThread, KeNumberProcessors, KeProcessorLevel, NULL, Status, and USHORT.

Referenced by KdpTrap().

02551 : 02552 02553 This routine sends a load symbols state change packet to the kernel 02554 debugger and waits for a manipulate state message. 02555 02556 Arguments: 02557 02558 PathName - Supplies a pointer to the pathname of the image whose 02559 symbols are to be loaded. 02560 02561 BaseOfDll - Supplies the base address where the image was loaded. 02562 02563 ProcessId - Unique 32-bit identifier for process that is using 02564 the symbols. -1 for system process. 02565 02566 CheckSum - Unique 32-bit identifier from image header. 02567 02568 UnloadSymbol - TRUE if the symbols that were previously loaded for 02569 the named image are to be unloaded from the debugger. 02570 02571 Return Value: 02572 02573 A value of TRUE is returned if the exception is handled. Otherwise, a 02574 value of FALSE is returned. 02575 02576 --*/ 02577 02578 { 02579 02580 PSTRING AdditionalData; 02581 STRING MessageData; 02582 STRING MessageHeader; 02583 DBGKD_WAIT_STATE_CHANGE64 WaitStateChange; 02584 KCONTINUE_STATUS Status; 02585 02586 do { 02587 02588 // 02589 // Construct the wait state change message and message descriptor. 02590 // 02591 02592 WaitStateChange.NewState = DbgKdLoadSymbolsStateChange; 02593 WaitStateChange.ProcessorLevel = KeProcessorLevel; 02594 WaitStateChange.Processor = (USHORT)KeGetCurrentPrcb()->Number; 02595 WaitStateChange.NumberProcessors = (ULONG)KeNumberProcessors; 02596 WaitStateChange.Thread = (ULONG64)(LONG64)(LONG_PTR) KeGetCurrentThread(); 02597 WaitStateChange.ProgramCounter = (ULONG64)(LONG64)(LONG_PTR) CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 02598 KdpSetLoadState(&WaitStateChange, ContextRecord); 02599 WaitStateChange.u.LoadSymbols.UnloadSymbols = UnloadSymbols; 02600 WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG64)SymbolInfo->BaseOfDll; 02601 WaitStateChange.u.LoadSymbols.ProcessId = (ULONG) SymbolInfo->ProcessId; 02602 WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum; 02603 WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage; 02604 if (ARGUMENT_PRESENT( PathName )) { 02605 WaitStateChange.u.LoadSymbols.PathNameLength = 02606 KdpMoveMemory( 02607 (PCHAR)KdpPathBuffer, 02608 (PCHAR)PathName->Buffer, 02609 PathName->Length 02610 ) + 1; 02611 02612 MessageData.Buffer = KdpPathBuffer; 02613 MessageData.Length = (USHORT)WaitStateChange.u.LoadSymbols.PathNameLength; 02614 MessageData.Buffer[MessageData.Length-1] = '\0'; 02615 AdditionalData = &MessageData; 02616 } else { 02617 WaitStateChange.u.LoadSymbols.PathNameLength = 0; 02618 AdditionalData = NULL; 02619 } 02620 02621 MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64); 02622 MessageHeader.Buffer = (PCHAR)&WaitStateChange; 02623 02624 // 02625 // Send packet to the kernel debugger on the host machine, wait 02626 // for the reply. 02627 // 02628 02629 Status = KdpSendWaitContinue( 02630 PACKET_TYPE_KD_STATE_CHANGE64, 02631 &MessageHeader, 02632 AdditionalData, 02633 ContextRecord 02634 ); 02635 02636 } while (Status == ContinueProcessorReselected); 02637 02638 return (BOOLEAN) Status; 02639 }

VOID KdpRestoreBreakpoint IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1740 of file 4/kdapi.c.

References ASSERT, KdpDeleteBreakpoint(), KdpSendPacket(), and NULL.

Referenced by KdpSendWaitContinue().

01748 : 01749 01750 This function is called in response of a restore breakpoint state 01751 manipulation message. Its function is to restore a breakpoint 01752 using the specified handle. 01753 01754 Arguments: 01755 01756 m - Supplies the state manipulation message. 01757 01758 AdditionalData - Supplies any additional data for the message. 01759 01760 Context - Supplies the current context. 01761 01762 Return Value: 01763 01764 None. 01765 01766 --*/ 01767 01768 { 01769 PDBGKD_RESTORE_BREAKPOINT a = &m->u.RestoreBreakPoint; 01770 STRING MessageHeader; 01771 01772 MessageHeader.Length = sizeof(*m); 01773 MessageHeader.Buffer = (PCHAR)m; 01774 01775 ASSERT(AdditionalData->Length == 0); 01776 if (KdpDeleteBreakpoint(a->BreakPointHandle)) { 01777 m->ReturnStatus = STATUS_SUCCESS; 01778 } else { 01779 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01780 } 01781 KdpSendPacket( 01782 PACKET_TYPE_KD_STATE_MANIPULATE, 01783 &MessageHeader, 01784 NULL 01785 ); 01786 UNREFERENCED_PARAMETER(Context); 01787 }

VOID KdpRestoreBreakPointEx IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 3247 of file 4/kdapi.c.

References KdpDeleteBreakpoint(), KdpMoveMemory(), and KdpSendPacket().

Referenced by KdpSendWaitContinue().

03255 : 03256 03257 This function is called in response of a restore breakpoint state 'ex' 03258 manipulation message. Its function is to clear a list of breakpoints. 03259 03260 Arguments: 03261 03262 m - Supplies the state manipulation message. 03263 03264 AdditionalData - Supplies any additional data for the message. 03265 03266 Context - Supplies the current context. 03267 03268 Return Value: 03269 03270 None. 03271 03272 --*/ 03273 03274 { 03275 PDBGKD_BREAKPOINTEX a = &m->u.BreakPointEx; 03276 PDBGKD_RESTORE_BREAKPOINT b; 03277 STRING MessageHeader; 03278 ULONG i; 03279 DBGKD_RESTORE_BREAKPOINT BpBuf[BREAKPOINT_TABLE_SIZE]; 03280 03281 03282 MessageHeader.Length = sizeof(*m); 03283 MessageHeader.Buffer = (PCHAR)m; 03284 03285 // 03286 // verify that the packet size is correct 03287 // 03288 if (AdditionalData->Length != 03289 a->BreakPointCount*sizeof(DBGKD_RESTORE_BREAKPOINT)) { 03290 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03291 KdpSendPacket( 03292 PACKET_TYPE_KD_STATE_MANIPULATE, 03293 &MessageHeader, 03294 AdditionalData 03295 ); 03296 return; 03297 } 03298 03299 KdpMoveMemory((PUCHAR)BpBuf, 03300 AdditionalData->Buffer, 03301 a->BreakPointCount*sizeof(DBGKD_RESTORE_BREAKPOINT)); 03302 03303 // 03304 // assume success 03305 // 03306 m->ReturnStatus = STATUS_SUCCESS; 03307 03308 // 03309 // loop thru the breakpoint handles passed in from the debugger and 03310 // clear any breakpoint that has a non-zero handle 03311 // 03312 b = BpBuf; 03313 for (i=0; i<a->BreakPointCount; i++,b++) { 03314 if (!KdpDeleteBreakpoint(b->BreakPointHandle)) { 03315 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03316 } 03317 } 03318 03319 // 03320 // send back our response 03321 // 03322 KdpSendPacket( 03323 PACKET_TYPE_KD_STATE_MANIPULATE, 03324 &MessageHeader, 03325 AdditionalData 03326 ); 03327 }

ULONG KdpSearchHammingDistance ULONG_PTR  Left,
ULONG_PTR  Right
 

Definition at line 3735 of file 4/kdapi.c.

References Index.

Referenced by KdpSearchPhysicalPage().

03741 : 03742 03743 This routine computes the Hamming distance (# of positions where the 03744 values are different). 03745 03746 If this function becomes a bottleneck we should switch to a function 03747 table version. 03748 03749 Arguments: 03750 03751 Left, Right operand. 03752 03753 Return Value: 03754 03755 Hamming distance. 03756 03757 Environment: 03758 03759 Any. 03760 03761 --*/ 03762 03763 { 03764 ULONG_PTR Value; 03765 ULONG Index; 03766 ULONG Distance; 03767 03768 Value = Left ^ Right; 03769 Distance = 0; 03770 03771 for (Index = 0; Index < 8 * sizeof(ULONG_PTR); Index++) { 03772 03773 if ((Value & (ULONG_PTR)0x01)) { 03774 03775 Distance += 1; 03776 } 03777 03778 Value >>= 1; 03779 } 03780 03781 return Distance; 03782 }

VOID KdpSearchMemory IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 3417 of file 4/kdapi.c.

References FALSE, KdpQuickMoveMemory(), KdpSendPacket(), MmDbgReadCheck(), NULL, PAGE_SIZE, and Pattern.

Referenced by KdpSendWaitContinue().

03425 : 03426 03427 This function implements a memory pattern searcher. This will 03428 find an instance of a pattern that begins in the range 03429 SearchAddress..SearchAddress+SearchLength. The pattern may 03430 end outside of the range. 03431 03432 Arguments: 03433 03434 m - Supplies the state manipulation message. 03435 03436 AdditionalData - Supplies the pattern to search for 03437 03438 Context - Supplies the current context. 03439 03440 Return Value: 03441 03442 None. 03443 03444 --*/ 03445 03446 { 03447 PUCHAR Pattern = AdditionalData->Buffer; 03448 ULONG_PTR StartAddress = (ULONG_PTR)m->u.SearchMemory.SearchAddress; 03449 ULONG_PTR EndAddress = (ULONG_PTR)(StartAddress + m->u.SearchMemory.SearchLength); 03450 ULONG PatternLength = m->u.SearchMemory.PatternLength; 03451 03452 STRING MessageHeader; 03453 ULONG MaskIndex; 03454 PUCHAR PatternTail; 03455 PUCHAR DataTail; 03456 ULONG TailLength; 03457 ULONG Data; 03458 ULONG FirstWordPattern[4]; 03459 ULONG FirstWordMask[4]; 03460 03461 03462 // 03463 // On failure, return STATUS_NO_MORE_ENTRIES. DON'T RETURN 03464 // STATUS_UNSUCCESSFUL! That return status indicates that the 03465 // operation is not supported, and the debugger will fall back 03466 // to a debugger-side search. 03467 // 03468 03469 m->ReturnStatus = STATUS_NO_MORE_ENTRIES; 03470 03471 // 03472 // Do a fast search for the beginning of the pattern 03473 // 03474 03475 if (PatternLength > 3) { 03476 FirstWordMask[0] = 0xffffffff; 03477 } else { 03478 FirstWordMask[0] = 0xffffffff >> (8*(4-PatternLength)); 03479 } 03480 03481 FirstWordMask[1] = FirstWordMask[0] << 8; 03482 FirstWordMask[2] = FirstWordMask[1] << 8; 03483 FirstWordMask[3] = FirstWordMask[2] << 8; 03484 03485 FirstWordPattern[0] = 0; 03486 KdpQuickMoveMemory((PVOID)FirstWordPattern, 03487 Pattern, 03488 PatternLength < 5 ? PatternLength : 4); 03489 03490 FirstWordPattern[1] = FirstWordPattern[0] << 8; 03491 FirstWordPattern[2] = FirstWordPattern[1] << 8; 03492 FirstWordPattern[3] = FirstWordPattern[2] << 8; 03493 03494 03495 /* 03496 { 03497 int i; 03498 for (i = 0; i < (int)PatternLength; i++) { 03499 KdpDprintf("%08x: %02x\n", &Pattern[i], Pattern[i]); 03500 } 03501 for (i = 0; i < 4; i++) { 03502 KdpDprintf("%d: %08x %08x\n", i, FirstWordPattern[i], FirstWordMask[i]); 03503 } 03504 } 03505 */ 03506 03507 03508 03509 // 03510 // Get starting mask 03511 // 03512 03513 MaskIndex = (ULONG) (StartAddress & 3); 03514 StartAddress = StartAddress & ~3; 03515 03516 // 03517 // check that the starting page is available 03518 // 03519 03520 if (MmDbgReadCheck((PVOID)StartAddress) == NULL) { 03521 StartAddress = (StartAddress + PAGE_SIZE) & ~(PAGE_SIZE-1); 03522 MaskIndex = 0; 03523 } 03524 03525 while (StartAddress < EndAddress) { 03526 03527 // 03528 // check when starting a new page 03529 // 03530 if ((StartAddress & (PAGE_SIZE-1)) == 0) { 03531 if (MmDbgReadCheck((PVOID)StartAddress) == NULL) { 03532 StartAddress = StartAddress + PAGE_SIZE; 03533 continue; 03534 } 03535 } 03536 03537 // 03538 // search for a match in each of the 4 starting positions 03539 // 03540 03541 Data = *(ULONG*)StartAddress; 03542 //KdpDprintf("\n%08x: %08x ", StartAddress, Data); 03543 03544 for ( ; MaskIndex < 4; MaskIndex++) { 03545 //KdpDprintf(" %d", MaskIndex); 03546 03547 if ( (Data & FirstWordMask[MaskIndex]) == FirstWordPattern[MaskIndex]) { 03548 03549 // 03550 // first word matched 03551 // 03552 03553 if ( (4-MaskIndex) >= PatternLength ) { 03554 03555 // 03556 // string is all in this word; good match 03557 // 03558 //KdpDprintf(" %d hit, complete\n", MaskIndex); 03559 03560 m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex; 03561 m->ReturnStatus = STATUS_SUCCESS; 03562 goto done; 03563 03564 } else { 03565 03566 // 03567 // string is longer; see if tail matches 03568 // 03569 //KdpDprintf(" %d hit, check tail\n", MaskIndex); 03570 03571 PatternTail = Pattern + 4 - MaskIndex; 03572 DataTail = (PUCHAR)StartAddress + 4; 03573 TailLength = PatternLength - 4 + MaskIndex; 03574 03575 //KdpDprintf("Pattern == %08x\n", Pattern); 03576 //KdpDprintf("PatternTail == %08x\n", PatternTail); 03577 //KdpDprintf("DataTail == %08x\n", DataTail); 03578 03579 while (TailLength) { 03580 if ( ((ULONG_PTR)DataTail & (PAGE_SIZE-1)) == 0 && 03581 MmDbgReadCheck(DataTail) == FALSE) { 03582 //KdpDprintf("Tail failed: page not present at %08x\n", DataTail); 03583 break; 03584 } else 03585 { 03586 //KdpDprintf("D: %02x P: %02x\n", *DataTail, *PatternTail); 03587 03588 if (*DataTail != *PatternTail) { 03589 //KdpDprintf("Tail failed at %08x\n", DataTail); 03590 break; 03591 } else { 03592 DataTail++; 03593 PatternTail++; 03594 TailLength--; 03595 } 03596 } 03597 } 03598 03599 if (TailLength == 0) { 03600 03601 // 03602 // A winner 03603 // 03604 03605 m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex; 03606 m->ReturnStatus = STATUS_SUCCESS; 03607 goto done; 03608 03609 } 03610 } 03611 } 03612 } 03613 03614 StartAddress += 4; 03615 MaskIndex = 0; 03616 } 03617 03618 done: 03619 //KdpDprintf("\n"); 03620 MessageHeader.Length = sizeof(*m); 03621 MessageHeader.Buffer = (PCHAR)m; 03622 03623 KdpSendPacket( 03624 PACKET_TYPE_KD_STATE_MANIPULATE, 03625 &MessageHeader, 03626 NULL 03627 ); 03628 03629 }

LOGICAL KdpSearchPhysicalMemoryRequested VOID   ) 
 

Definition at line 3869 of file 4/kdapi.c.

References FALSE, KdpSearchInProgress, and TRUE.

Referenced by KdpCheckLowMemory().

03874 : 03875 03876 This routine determines if a physical range search has been 03877 requested. This is controlled by a global variable set in 03878 the `!search' debug extension. 03879 03880 Arguments: 03881 03882 None 03883 03884 Return Value: 03885 03886 TRUE if physical range search was requested. 03887 03888 03889 Environment: 03890 03891 Call triggered only from Kd extension. 03892 03893 --*/ 03894 { 03895 if (KdpSearchInProgress) { 03896 03897 return TRUE; 03898 } 03899 else { 03900 03901 return FALSE; 03902 } 03903 03904 }

LOGICAL KdpSearchPhysicalPage IN PFN_NUMBER  PageFrameIndex,
ULONG_PTR  RangeStart,
ULONG_PTR  RangeEnd,
ULONG  Flags
 

Definition at line 3787 of file 4/kdapi.c.

References FALSE, Index, KDP_SEARCH_ALL_OFFSETS_IN_PAGE, KdpSearchHammingDistance(), KdpSearchPageHitIndex, KdpSearchPageHitOffsets, KdpSearchPageHits, MmDbgTranslatePhysicalAddress64(), PAGE_SHIFT, PAGE_SIZE, SEARCH_PAGE_HIT_DATABASE_SIZE, and TRUE.

Referenced by KdpSearchPhysicalPageRange().

03795 : 03796 03797 This routine searches the physical page corresponding to a 03798 certain PFN index for any ULONG_PTR values in range [Start..End]. 03799 03800 Arguments: 03801 03802 PageFrameIndex - PFN index 03803 03804 RangeStart - lowest possible value searched for 03805 03806 RangeEnd - highest possible value searched for 03807 03808 Flags - flags to control the search 03809 03810 Return Value: 03811 03812 TRUE if a hit has been found, FALSE otherwise. 03813 The function stops after the first hit in the page is 03814 encountered and the infromation related to the hit (PFN index, 03815 offset, corrsponding VA) is registered in the hit database. 03816 03817 Environment: 03818 03819 Call triggered only from Kd extension. 03820 03821 --*/ 03822 03823 { 03824 PCHAR Va; 03825 ULONG Index; 03826 PHYSICAL_ADDRESS Pa; 03827 ULONG_PTR Value; 03828 03829 // 03830 // Map the physical page using the debug PTE. 03831 // 03832 03833 Pa.QuadPart = ((ULONGLONG)PageFrameIndex) << PAGE_SHIFT; 03834 03835 Va = (PCHAR) MmDbgTranslatePhysicalAddress64 (Pa); 03836 03837 for (Index = 0; Index < PAGE_SIZE - sizeof(ULONG_PTR); Index += 1, Va += 1) { 03838 03839 Value = *((PULONG_PTR)Va); 03840 03841 if ((Value >= RangeStart && Value <= RangeEnd) 03842 || KdpSearchHammingDistance(Value, RangeStart) == 1) { 03843 03844 if (KdpSearchPageHitIndex < SEARCH_PAGE_HIT_DATABASE_SIZE) { 03845 03846 KdpSearchPageHits[KdpSearchPageHitIndex] = PageFrameIndex; 03847 KdpSearchPageHitOffsets[KdpSearchPageHitIndex] = Index; 03848 03849 KdpSearchPageHitIndex += 1; 03850 } 03851 03852 if ((Flags & KDP_SEARCH_ALL_OFFSETS_IN_PAGE)) { 03853 03854 continue; 03855 } 03856 else { 03857 03858 return TRUE; 03859 } 03860 } 03861 } 03862 03863 return FALSE; 03864 }

LOGICAL KdpSearchPhysicalPageRange VOID   ) 
 

Definition at line 3909 of file 4/kdapi.c.

References FALSE, KDP_SEARCH_ALL_OFFSETS_IN_PAGE, KdpSearchAddressRangeEnd, KdpSearchAddressRangeStart, KdpSearchEndPageFrame, KdpSearchInProgress, KdpSearchPhysicalPage(), KdpSearchStartPageFrame, and TRUE.

Referenced by KdpCheckLowMemory().

03914 : 03915 03916 This routine will start a search in a range of physical pages in case 03917 `KdpSearchInProgress' is true. the parameters for the search are picked up 03918 from global vairiables that are set inside a kernel debugger extension. 03919 03920 Arguments: 03921 03922 None 03923 03924 Return Value: 03925 03926 TRUE if the function executed a search and FALSE otherwise. 03927 The results of the search are specified in the KdpSearchPageHits 03928 and related variables. this global variables offers the mechanism 03929 for the debugger extension to pickup the results of the search. 03930 03931 03932 Environment: 03933 03934 Call triggered only from Kd extension. 03935 03936 Note. The !search extension make sure that the range requested 03937 is part of the system memory therefore we do not have to 03938 worry about sparse PFN databases here. 03939 03940 --*/ 03941 03942 { 03943 PFN_NUMBER CurrentFrame; 03944 ULONG Flags; 03945 03946 // 03947 // The debugger extension is supposed to set KdpSearchInProgress 03948 // to TRUE if a search is requested. 03949 // 03950 03951 if (!KdpSearchInProgress) { 03952 03953 return FALSE; 03954 } 03955 03956 03957 Flags = 0; 03958 03959 // 03960 // If the search range is only one page we will give all 03961 // hits inside a page. By default we get only the first hit inside 03962 // a page. 03963 // 03964 03965 if (KdpSearchEndPageFrame == KdpSearchStartPageFrame) { 03966 03967 KdpSearchEndPageFrame += 1; 03968 03969 Flags |= KDP_SEARCH_ALL_OFFSETS_IN_PAGE; 03970 } 03971 03972 for (CurrentFrame = KdpSearchStartPageFrame; 03973 CurrentFrame < KdpSearchEndPageFrame; 03974 CurrentFrame += 1) { 03975 03976 KdpSearchPhysicalPage (CurrentFrame, 03977 KdpSearchAddressRangeStart, 03978 KdpSearchAddressRangeEnd, 03979 Flags); 03980 03981 } 03982 03983 return TRUE; 03984 }

KCONTINUE_STATUS KdpSendWaitContinue IN ULONG  OutPacketType,
IN PSTRING  OutMessageHeader,
IN PSTRING OutMessageData  OPTIONAL,
IN OUT PCONTEXT  ContextRecord
 

Definition at line 821 of file 4/kdapi.c.

References ContinueError, ContinueSuccess, FALSE, KCONTINUE_STATUS, KdClearSpecialCalls(), KdDebuggerNotPresent, KDP_MESSAGE_BUFFER_SIZE, KDP_PACKET_RESEND, KDP_PACKET_TIMEOUT, KdpCauseBugCheck(), KdpCheckLowMemory(), KdpGetBusData(), KdpGetContext(), KdpGetStateChange(), KdpGetVersion(), KdpMessageBuffer, KdpNotSupported(), KdPortRestore(), KdPortSave(), KdpReadControlSpace(), KdpReadIoSpace(), KdpReadIoSpaceExtended(), KdpReadMachineSpecificRegister(), KdpReadPhysicalMemory(), KdpReadVirtualMemory(), KdpReadVirtualMemory64(), KdpReboot(), KdpReceivePacket(), KdpRestoreBreakpoint(), KdpRestoreBreakPointEx(), KdpSearchMemory(), KdpSendPacket(), KdpSetBusData(), KdpSetContext(), KdpWriteBreakpoint(), KdpWriteBreakPointEx(), KdpWriteControlSpace(), KdpWriteIoSpace(), KdpWriteIoSpaceExtended(), KdpWriteMachineSpecificRegister(), KdpWritePhysicalMemory(), KdpWriteVirtualMemory(), KdpWriteVirtualMemory64(), KdSetSpecialCall(), KeSwitchFrozenProcessor(), NT_SUCCESS, NTSTATUS(), Status, TRUE, and USHORT.

00830 : 00831 00832 This function sends a packet, and then waits for a continue message. 00833 BreakIns received while waiting will always cause a resend of the 00834 packet originally sent out. While waiting, manipulate messages 00835 will be serviced. 00836 00837 A resend always resends the original event sent to the debugger, 00838 not the last response to some debugger command. 00839 00840 Arguments: 00841 00842 OutPacketType - Supplies the type of packet to send. 00843 00844 OutMessageHeader - Supplies a pointer to a string descriptor that describes 00845 the message information. 00846 00847 OutMessageData - Supplies a pointer to a string descriptor that describes 00848 the optional message data. 00849 00850 ContextRecord - Exception context 00851 00852 Return Value: 00853 00854 A value of TRUE is returned if the continue message indicates 00855 success, Otherwise, a value of FALSE is returned. 00856 00857 --*/ 00858 00859 { 00860 00861 ULONG Length; 00862 STRING MessageData; 00863 STRING MessageHeader; 00864 DBGKD_MANIPULATE_STATE64 ManipulateState; 00865 ULONG ReturnCode; 00866 NTSTATUS Status; 00867 KCONTINUE_STATUS ContinueStatus; 00868 00869 // 00870 // Loop servicing state manipulation message until a continue message 00871 // is received. 00872 // 00873 00874 MessageHeader.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64); 00875 MessageHeader.Buffer = (PCHAR)&ManipulateState; 00876 MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE; 00877 MessageData.Buffer = (PCHAR)KdpMessageBuffer; 00878 00879 ResendPacket: 00880 00881 // 00882 // Send event notification packet to debugger on host. Come back 00883 // here any time we see a breakin sequence. 00884 // 00885 00886 KdpSendPacket( 00887 OutPacketType, 00888 OutMessageHeader, 00889 OutMessageData 00890 ); 00891 00892 // 00893 // After sending packet, if there is no response from debugger 00894 // AND the packet is for reporting symbol (un)load, the debugger 00895 // will be declared to be not present. Note If the packet is for 00896 // reporting exception, the KdpSendPacket will never stop. 00897 // 00898 00899 if (KdDebuggerNotPresent) { 00900 return ContinueSuccess; 00901 } 00902 00903 while (TRUE) { 00904 00905 // 00906 // Wait for State Manipulate Packet without timeout. 00907 // 00908 00909 do { 00910 00911 ReturnCode = KdpReceivePacket( 00912 PACKET_TYPE_KD_STATE_MANIPULATE, 00913 &MessageHeader, 00914 &MessageData, 00915 &Length 00916 ); 00917 if (ReturnCode == (USHORT)KDP_PACKET_RESEND) { 00918 goto ResendPacket; 00919 } 00920 } while (ReturnCode == KDP_PACKET_TIMEOUT); 00921 00922 // 00923 // Switch on the return message API number. 00924 // 00925 00926 switch (ManipulateState.ApiNumber) { 00927 00928 case DbgKdReadVirtualMemoryApi: 00929 KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord); 00930 break; 00931 #if 0 00932 case DbgKdReadVirtualMemory64Api: 00933 KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord); 00934 break; 00935 #endif 00936 case DbgKdWriteVirtualMemoryApi: 00937 KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord); 00938 break; 00939 #if 0 00940 case DbgKdWriteVirtualMemory64Api: 00941 KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord); 00942 break; 00943 #endif 00944 00945 case DbgKdCheckLowMemoryApi: 00946 KdpCheckLowMemory (&ManipulateState); 00947 break; 00948 00949 case DbgKdReadPhysicalMemoryApi: 00950 KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord); 00951 break; 00952 00953 case DbgKdWritePhysicalMemoryApi: 00954 KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord); 00955 break; 00956 00957 case DbgKdGetContextApi: 00958 KdpGetContext(&ManipulateState,&MessageData,ContextRecord); 00959 break; 00960 00961 case DbgKdSetContextApi: 00962 KdpSetContext(&ManipulateState,&MessageData,ContextRecord); 00963 break; 00964 00965 case DbgKdWriteBreakPointApi: 00966 KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord); 00967 break; 00968 00969 case DbgKdRestoreBreakPointApi: 00970 KdpRestoreBreakpoint(&ManipulateState,&MessageData,ContextRecord); 00971 break; 00972 00973 case DbgKdReadControlSpaceApi: 00974 KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord); 00975 break; 00976 00977 case DbgKdWriteControlSpaceApi: 00978 KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord); 00979 break; 00980 00981 case DbgKdReadIoSpaceApi: 00982 KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord); 00983 break; 00984 00985 case DbgKdWriteIoSpaceApi: 00986 KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord); 00987 break; 00988 00989 #ifdef _ALPHA_ 00990 00991 case DbgKdReadIoSpaceExtendedApi: 00992 KdpReadIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord); 00993 break; 00994 00995 case DbgKdWriteIoSpaceExtendedApi: 00996 KdpWriteIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord); 00997 break; 00998 00999 case DbgKdGetBusDataApi: 01000 KdpGetBusData(&ManipulateState,&MessageData,ContextRecord); 01001 break; 01002 01003 case DbgKdSetBusDataApi: 01004 KdpSetBusData(&ManipulateState,&MessageData,ContextRecord); 01005 break; 01006 01007 #endif // _ALPHA_ 01008 01009 case DbgKdContinueApi: 01010 if (NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) != FALSE) { 01011 return ContinueSuccess; 01012 } else { 01013 return ContinueError; 01014 } 01015 break; 01016 01017 case DbgKdContinueApi2: 01018 if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) != FALSE) { 01019 KdpGetStateChange(&ManipulateState,ContextRecord); 01020 return ContinueSuccess; 01021 } else { 01022 return ContinueError; 01023 } 01024 break; 01025 01026 case DbgKdRebootApi: 01027 KdpReboot(); 01028 break; 01029 01030 #if i386 01031 case DbgKdReadMachineSpecificRegister: 01032 KdpReadMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord); 01033 break; 01034 01035 case DbgKdWriteMachineSpecificRegister: 01036 KdpWriteMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord); 01037 break; 01038 01039 case DbgKdSetSpecialCallApi: 01040 KdSetSpecialCall(&ManipulateState,ContextRecord); 01041 break; 01042 01043 case DbgKdClearSpecialCallsApi: 01044 KdClearSpecialCalls(); 01045 break; 01046 01047 case DbgKdSetInternalBreakPointApi: 01048 KdSetInternalBreakpoint(&ManipulateState); 01049 break; 01050 01051 case DbgKdGetInternalBreakPointApi: 01052 KdGetInternalBreakpoint(&ManipulateState); 01053 break; 01054 #endif 01055 01056 case DbgKdGetVersionApi: 01057 KdpGetVersion(&ManipulateState); 01058 break; 01059 01060 case DbgKdCauseBugCheckApi: 01061 KdpCauseBugCheck(&ManipulateState); 01062 break; 01063 01064 case DbgKdPageInApi: 01065 KdpNotSupported(&ManipulateState); 01066 break; 01067 01068 case DbgKdWriteBreakPointExApi: 01069 Status = KdpWriteBreakPointEx(&ManipulateState, 01070 &MessageData, 01071 ContextRecord); 01072 if (Status) { 01073 ManipulateState.ApiNumber = DbgKdContinueApi; 01074 ManipulateState.u.Continue.ContinueStatus = Status; 01075 return ContinueError; 01076 } 01077 break; 01078 01079 case DbgKdRestoreBreakPointExApi: 01080 KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord); 01081 break; 01082 01083 case DbgKdSwitchProcessor: 01084 KdPortRestore (); 01085 ContinueStatus = KeSwitchFrozenProcessor(ManipulateState.Processor); 01086 KdPortSave (); 01087 return ContinueStatus; 01088 01089 case DbgKdSearchMemoryApi: 01090 KdpSearchMemory(&ManipulateState, &MessageData, ContextRecord); 01091 break; 01092 01093 // 01094 // Invalid message. 01095 // 01096 01097 default: 01098 MessageData.Length = 0; 01099 ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL; 01100 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, &MessageData); 01101 break; 01102 } 01103 01104 #ifdef _ALPHA_ 01105 01106 // 01107 //jnfix 01108 // this is embarrasing, we have an icache coherency problem that 01109 // the following imb fixes, later we must track this down to the 01110 // exact offending API but for now this statement allows the stub 01111 // work to appropriately for Alpha. 01112 // 01113 01114 #if defined(_MSC_VER) 01115 __PAL_IMB(); 01116 #else 01117 asm( "call_pal 0x86" ); // x86 = imb 01118 #endif 01119 01120 #endif 01121 01122 } 01123 }

VOID KdpSetContext IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1629 of file 4/kdapi.c.

References ASSERT, KdpQuickMoveMemory(), KdpSendPacket(), KeGetCurrentPrcb, KeNumberProcessors, KiProcessorBlock, NULL, and USHORT.

Referenced by KdpSendWaitContinue().

01637 : 01638 01639 This function is called in response of a set context state 01640 manipulation message. Its function is set the current 01641 context. 01642 01643 Arguments: 01644 01645 m - Supplies the state manipulation message. 01646 01647 AdditionalData - Supplies any additional data for the message. 01648 01649 Context - Supplies the current context. 01650 01651 Return Value: 01652 01653 None. 01654 01655 --*/ 01656 01657 { 01658 PDBGKD_SET_CONTEXT a = &m->u.SetContext; 01659 STRING MessageHeader; 01660 01661 MessageHeader.Length = sizeof(*m); 01662 MessageHeader.Buffer = (PCHAR)m; 01663 01664 ASSERT(AdditionalData->Length == sizeof(CONTEXT)); 01665 01666 if (m->Processor >= (USHORT)KeNumberProcessors) { 01667 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01668 } else { 01669 m->ReturnStatus = STATUS_SUCCESS; 01670 if (m->Processor == (USHORT)KeGetCurrentPrcb()->Number) { 01671 KdpQuickMoveMemory((PCHAR)Context, AdditionalData->Buffer, sizeof(CONTEXT)); 01672 } else { 01673 KdpQuickMoveMemory((PCHAR)&KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame, 01674 AdditionalData->Buffer, 01675 sizeof(CONTEXT) 01676 ); 01677 } 01678 } 01679 01680 KdpSendPacket( 01681 PACKET_TYPE_KD_STATE_MANIPULATE, 01682 &MessageHeader, 01683 NULL 01684 ); 01685 }

BOOLEAN KdpSwitchProcessor IN PEXCEPTION_RECORD  ExceptionRecord,
IN OUT PCONTEXT  ContextRecord,
IN BOOLEAN  SecondChance
 

Definition at line 2426 of file 4/kdapi.c.

References KdPortRestore(), KdPortSave(), KdpReportExceptionStateChange(), and Status.

02431 { 02432 BOOLEAN Status; 02433 02434 // 02435 // Save port state 02436 // 02437 02438 KdPortSave (); 02439 02440 // 02441 // Process state change for this processor 02442 // 02443 02444 Status = KdpReportExceptionStateChange ( 02445 ExceptionRecord, 02446 ContextRecord, 02447 SecondChance 02448 ); 02449 02450 // 02451 // Restore port state and return status 02452 // 02453 02454 KdPortRestore (); 02455 return Status; 02456 }

VOID KdpTimeSlipDpcRoutine PKDPC  Dpc,
PVOID  DeferredContext,
PVOID  SystemArgument1,
PVOID  SystemArgument2
 

Definition at line 468 of file 4/kdapi.c.

References DelayedWorkQueue, ExQueueWorkItem(), KdpTimeSlipPending, and KdpTimeSlipWorkItem.

00474 { 00475 LONG OldCount, NewCount, j; 00476 00477 // 00478 // Reset pending count. If the current count is 1, then clear 00479 // the pending count. if the current count is greater then 1, 00480 // then set to one and update the time now. 00481 // 00482 00483 j = KdpTimeSlipPending; 00484 do { 00485 OldCount = j; 00486 NewCount = OldCount > 1 ? 1 : 0; 00487 00488 j = InterlockedCompareExchange(&KdpTimeSlipPending, NewCount, OldCount); 00489 00490 } while (j != OldCount); 00491 00492 // 00493 // If new count is non-zero, then process a time slip now 00494 // 00495 00496 if (NewCount) { 00497 ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue); 00498 } 00499 }

VOID KdpTimeSlipWork IN PVOID  Context  ) 
 

Definition at line 502 of file 4/kdapi.c.

References ExAcquireTimeRefreshLock(), ExReleaseTimeRefreshLock(), ExUpdateSystemTimeFromCmos(), FALSE, KdpTimeSlipDpc, KdpTimeSlipEvent, KdpTimeSlipEventLock, KdpTimeSlipTimer, KeAcquireSpinLock, KeReleaseSpinLock(), KeSetEvent(), and KeSetTimer().

00505 { 00506 KIRQL OldIrql; 00507 LARGE_INTEGER DueTime; 00508 00509 // 00510 // Update time from the real time clock 00511 // 00512 00513 ExAcquireTimeRefreshLock(); 00514 ExUpdateSystemTimeFromCmos (FALSE, 0); 00515 ExReleaseTimeRefreshLock(); 00516 00517 // 00518 // If there's a time service installed, signal it's time slip event 00519 // 00520 00521 KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql); 00522 if (KdpTimeSlipEvent) { 00523 KeSetEvent (KdpTimeSlipEvent, 0, FALSE); 00524 } 00525 KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql); 00526 00527 // 00528 // Insert a forced delay between time slip operations 00529 // 00530 00531 DueTime.QuadPart = -1800000000; 00532 KeSetTimer (&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc); 00533 }

VOID KdpWriteBreakpoint IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1688 of file 4/kdapi.c.

References ASSERT, KdpAddBreakpoint(), KdpSendPacket(), and NULL.

Referenced by KdpSendWaitContinue().

01696 : 01697 01698 This function is called in response of a write breakpoint state 01699 manipulation message. Its function is to write a breakpoint 01700 and return a handle to the breakpoint. 01701 01702 Arguments: 01703 01704 m - Supplies the state manipulation message. 01705 01706 AdditionalData - Supplies any additional data for the message. 01707 01708 Context - Supplies the current context. 01709 01710 Return Value: 01711 01712 None. 01713 01714 --*/ 01715 01716 { 01717 PDBGKD_WRITE_BREAKPOINT64 a = &m->u.WriteBreakPoint; 01718 STRING MessageHeader; 01719 01720 MessageHeader.Length = sizeof(*m); 01721 MessageHeader.Buffer = (PCHAR)m; 01722 01723 ASSERT(AdditionalData->Length == 0); 01724 01725 a->BreakPointHandle = KdpAddBreakpoint((PVOID)a->BreakPointAddress); 01726 if (a->BreakPointHandle != 0) { 01727 m->ReturnStatus = STATUS_SUCCESS; 01728 } else { 01729 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01730 } 01731 KdpSendPacket( 01732 PACKET_TYPE_KD_STATE_MANIPULATE, 01733 &MessageHeader, 01734 NULL 01735 ); 01736 UNREFERENCED_PARAMETER(Context); 01737 }

NTSTATUS KdpWriteBreakPointEx IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 3125 of file 4/kdapi.c.

References KdpAddBreakpoint(), KdpDeleteBreakpoint(), KdpMoveMemory(), and KdpSendPacket().

Referenced by KdpSendWaitContinue().

03133 : 03134 03135 This function is called in response of a write breakpoint state 'ex' 03136 manipulation message. Its function is to clear breakpoints, write 03137 new breakpoints, and continue the target system. The clearing of 03138 breakpoints is conditional based on the presence of breakpoint handles. 03139 The setting of breakpoints is conditional based on the presence of 03140 valid, non-zero, addresses. The continueing of the target system 03141 is conditional based on a non-zero continuestatus. 03142 03143 This api allows a debugger to clear breakpoints, add new breakpoint, 03144 and continue the target system all in one api packet. This reduces the 03145 amount of traffic across the wire and greatly improves source stepping. 03146 03147 03148 Arguments: 03149 03150 m - Supplies the state manipulation message. 03151 03152 AdditionalData - Supplies any additional data for the message. 03153 03154 Context - Supplies the current context. 03155 03156 Return Value: 03157 03158 None. 03159 03160 --*/ 03161 03162 { 03163 PDBGKD_BREAKPOINTEX a = &m->u.BreakPointEx; 03164 PDBGKD_WRITE_BREAKPOINT64 b; 03165 STRING MessageHeader; 03166 ULONG i; 03167 DBGKD_WRITE_BREAKPOINT64 BpBuf[BREAKPOINT_TABLE_SIZE]; 03168 03169 03170 MessageHeader.Length = sizeof(*m); 03171 MessageHeader.Buffer = (PCHAR)m; 03172 03173 // 03174 // verify that the packet size is correct 03175 // 03176 if (AdditionalData->Length != 03177 a->BreakPointCount*sizeof(DBGKD_WRITE_BREAKPOINT64)) { 03178 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03179 KdpSendPacket( 03180 PACKET_TYPE_KD_STATE_MANIPULATE, 03181 &MessageHeader, 03182 AdditionalData 03183 ); 03184 return m->ReturnStatus; 03185 } 03186 03187 KdpMoveMemory((PUCHAR)BpBuf, 03188 AdditionalData->Buffer, 03189 a->BreakPointCount*sizeof(DBGKD_WRITE_BREAKPOINT64)); 03190 03191 // 03192 // assume success 03193 // 03194 m->ReturnStatus = STATUS_SUCCESS; 03195 03196 // 03197 // loop thru the breakpoint handles passed in from the debugger and 03198 // clear any breakpoint that has a non-zero handle 03199 // 03200 b = BpBuf; 03201 for (i=0; i<a->BreakPointCount; i++,b++) { 03202 if (b->BreakPointHandle) { 03203 if (!KdpDeleteBreakpoint(b->BreakPointHandle)) { 03204 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03205 } 03206 b->BreakPointHandle = 0; 03207 } 03208 } 03209 03210 // 03211 // loop thru the breakpoint addesses passed in from the debugger and 03212 // add any new breakpoints that have a non-zero address 03213 // 03214 b = BpBuf; 03215 for (i=0; i<a->BreakPointCount; i++,b++) { 03216 if (b->BreakPointAddress) { 03217 b->BreakPointHandle = KdpAddBreakpoint( (PVOID)b->BreakPointAddress ); 03218 if (!b->BreakPointHandle) { 03219 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03220 } 03221 } 03222 } 03223 03224 // 03225 // send back our response 03226 // 03227 03228 KdpMoveMemory(AdditionalData->Buffer, 03229 (PUCHAR)BpBuf, 03230 a->BreakPointCount*sizeof(DBGKD_WRITE_BREAKPOINT64)); 03231 03232 KdpSendPacket( 03233 PACKET_TYPE_KD_STATE_MANIPULATE, 03234 &MessageHeader, 03235 AdditionalData 03236 ); 03237 03238 // 03239 // return the caller's continue status value. if this is a non-zero 03240 // value the system is continued using this value as the continuestatus. 03241 // 03242 return a->ContinueStatus; 03243 }

VOID KdpWritePhysicalMemory IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 2779 of file 4/kdapi.c.

References BYTE_OFFSET, KdpMoveMemory(), KdpSendPacket(), MmDbgTranslatePhysicalAddress64(), NULL, PAGE_SIZE, and USHORT.

Referenced by KdpSendWaitContinue().

02787 : 02788 02789 This function is called in response to a write physical memory 02790 state manipulation message. Its function is to write physical memory 02791 and return. 02792 02793 Arguments: 02794 02795 m - Supplies the state manipulation message. 02796 02797 AdditionalData - Supplies any additional data for the message. 02798 02799 Context - Supplies the current context. 02800 02801 Return Value: 02802 02803 None. 02804 02805 --*/ 02806 02807 { 02808 PDBGKD_WRITE_MEMORY64 a = &m->u.WriteMemory; 02809 STRING MessageHeader; 02810 ULONG Length; 02811 PVOID64 VirtualAddress; 02812 PHYSICAL_ADDRESS Destination; 02813 UCHAR UNALIGNED *Source; 02814 ULONG NumberBytes; 02815 ULONG BytesLeft; 02816 02817 MessageHeader.Length = sizeof(*m); 02818 MessageHeader.Buffer = (PCHAR)m; 02819 02820 02821 Length = a->TransferCount; 02822 02823 // 02824 // The following code depends on the existence of the 02825 // MmDbgTranslatePhysicalAddress64() routine. This has only been 02826 // implemented for Alpha. 02827 // 02828 02829 // 02830 // Since the MmDbgTranslatePhysicalAddress64 only maps in one physical 02831 // page at a time, we need to break the memory move up into smaller 02832 // moves which don't cross page boundaries. It is important that we 02833 // access physical memory on naturally-aligned boundaries and with the 02834 // largest size possible. (We could be accessing memory-mapped I/O 02835 // space). These rules allow kdexts to write physical memory reliably. 02836 // 02837 02838 Source = AdditionalData->Buffer; 02839 Destination.QuadPart = a->TargetBaseAddress; 02840 while (Length > 0) { 02841 VirtualAddress = MmDbgTranslatePhysicalAddress64(Destination); 02842 if (VirtualAddress == NULL64) { 02843 break; 02844 } 02845 NumberBytes = PAGE_SIZE - BYTE_OFFSET(Destination.LowPart); 02846 if (NumberBytes > Length) { 02847 NumberBytes = Length; 02848 } 02849 #ifdef _ALPHA_ 02850 BytesLeft = NumberBytes; 02851 while (BytesLeft > 0) { 02852 if (((ULONG64)VirtualAddress & 7) == 0 && BytesLeft > 7) { 02853 *((ULONGLONG * POINTER_64)VirtualAddress)++ = 02854 *((ULONGLONG UNALIGNED *)Source)++; 02855 BytesLeft -= 8; 02856 } else { 02857 if (((ULONG64)VirtualAddress & 3) == 0 && BytesLeft > 3) { 02858 *((ULONG * POINTER_64)VirtualAddress)++ = 02859 *((ULONG UNALIGNED *)Source)++; 02860 BytesLeft -= 4; 02861 } else { 02862 if (((ULONG64)VirtualAddress & 1) == 0 && BytesLeft > 1) { 02863 *((USHORT * POINTER_64)VirtualAddress)++ = 02864 *((USHORT UNALIGNED *)Source)++; 02865 BytesLeft -= 2; 02866 } else { 02867 *((UCHAR * POINTER_64)VirtualAddress)++ = 02868 *(UCHAR UNALIGNED *)Source++; 02869 BytesLeft -= 1; 02870 } 02871 } 02872 } 02873 02874 __MB(); 02875 } 02876 #else 02877 KdpMoveMemory(VirtualAddress, Source, NumberBytes); 02878 Source += NumberBytes; 02879 02880 #endif 02881 Destination.QuadPart += NumberBytes; 02882 Length -= NumberBytes; 02883 a->ActualBytesWritten += NumberBytes; 02884 } 02885 02886 if (Length == 0) { 02887 m->ReturnStatus = STATUS_SUCCESS; 02888 } else { 02889 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02890 } 02891 02892 KdpSendPacket( 02893 PACKET_TYPE_KD_STATE_MANIPULATE, 02894 &MessageHeader, 02895 NULL 02896 ); 02897 UNREFERENCED_PARAMETER(Context); 02898 }

VOID KdpWriteVirtualMemory IN PDBGKD_MANIPULATE_STATE64  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1345 of file 4/kdapi.c.

References KdpMoveMemory(), KdpSendPacket(), MmDbgReleaseAddress(), MmDbgWriteCheck(), MmDbgWriteCheck64(), and NULL.

Referenced by KdpSendWaitContinue().

01353 : 01354 01355 This function is called in response of a write virtual memory 32-bit 01356 state manipulation message. Its function is to write virtual memory 01357 and return. 01358 01359 Arguments: 01360 01361 m - Supplies a pointer to the state manipulation message. 01362 01363 AdditionalData - Supplies a pointer to a descriptor for the data to write. 01364 01365 Context - Supplies a pointer to the current context. 01366 01367 Return Value: 01368 01369 None. 01370 01371 --*/ 01372 01373 { 01374 01375 ULONG Length; 01376 STRING MessageHeader; 01377 HARDWARE_PTE Opaque; 01378 01379 #if defined(_ALPHA_) && !defined(_AXP64_) 01380 UCHAR * POINTER_64 Address; 01381 UCHAR * POINTER_64 Destination; 01382 PUCHAR Address32; 01383 PUCHAR Source; 01384 PUCHAR Destination32; 01385 01386 01387 // 01388 // Move the data to the destination buffer. 01389 // 01390 01391 Length = AdditionalData->Length; 01392 01393 Destination = (UCHAR * POINTER_64)m->u.WriteMemory.TargetBaseAddress; 01394 Destination32 = (PUCHAR)m->u.WriteMemory.TargetBaseAddress; 01395 Source = AdditionalData->Buffer; 01396 while (Length > 0) { 01397 Address=Destination; 01398 Address32 = NULL; 01399 if ((LONGLONG)Destination != (LONGLONG)((LONG)Destination)) { 01400 if ((Address = MmDbgWriteCheck64(Destination)) == NULL64) { 01401 break; 01402 } 01403 } else { 01404 if ((Address32 = MmDbgWriteCheck(Destination32, &Opaque)) == NULL) { 01405 break; 01406 } 01407 } 01408 01409 if (Address32 != NULL) { 01410 *Address32 = *Source++; 01411 MmDbgReleaseAddress(Address32, &Opaque); 01412 } 01413 else { 01414 *Address = *Source++; 01415 } 01416 Destination += 1; 01417 Destination32 += 1; 01418 Length -= 1; 01419 } 01420 01421 // 01422 // If all the data is written, then return a success status. Otherwise, 01423 // return an unsuccessful status. 01424 // 01425 01426 m->ReturnStatus = STATUS_SUCCESS; 01427 if (Length != 0) { 01428 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01429 } 01430 01431 // 01432 // Set the actual number of bytes written, initialize the message header, 01433 // and send the reply packet to the host debugger. 01434 // 01435 01436 m->u.WriteMemory.ActualBytesWritten = AdditionalData->Length - Length; 01437 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE64); 01438 MessageHeader.Buffer = (PCHAR)m; 01439 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01440 &MessageHeader, 01441 NULL); 01442 01443 return; 01444 #else 01445 01446 // 01447 // Move the data to the destination buffer. 01448 // 01449 01450 Length = KdpMoveMemory((PVOID)m->u.WriteMemory.TargetBaseAddress, 01451 AdditionalData->Buffer, 01452 AdditionalData->Length); 01453 01454 // 01455 // If all the data is written, then return a success status. Otherwise, 01456 // return an unsuccessful status. 01457 // 01458 01459 m->ReturnStatus = STATUS_SUCCESS; 01460 if (Length != AdditionalData->Length) { 01461 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01462 } 01463 01464 // 01465 // Set the actual number of bytes written, initialize the message header, 01466 // and send the reply packet to the host debugger. 01467 // 01468 01469 m->u.WriteMemory.ActualBytesWritten = Length; 01470 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE64); 01471 MessageHeader.Buffer = (PCHAR)m; 01472 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01473 &MessageHeader, 01474 NULL); 01475 01476 return; 01477 #endif 01478 }

VOID KdUpdateTimeSlipEvent PVOID  Event  ) 
 

Definition at line 427 of file 4/kdapi.c.

References Event(), KdpTimeSlipEvent, KdpTimeSlipEventLock, KeAcquireSpinLock, KeReleaseSpinLock(), NULL, and ObDereferenceObject.

Referenced by NtSetSystemInformation().

00433 : 00434 00435 Update the reference to an event object which will be signalled when 00436 the debugger has caused the system clock to skew. 00437 00438 Arguments: 00439 00440 Event - Supplies a pointer to an event object 00441 00442 Return Value: 00443 00444 None 00445 00446 --*/ 00447 00448 { 00449 KIRQL OldIrql; 00450 00451 KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql); 00452 00453 // 00454 // Dereference the old event and forget about it. 00455 // Remember the new event if there is one. 00456 // 00457 00458 if (KdpTimeSlipEvent != NULL) { 00459 ObDereferenceObject(KdpTimeSlipEvent); 00460 } 00461 00462 KdpTimeSlipEvent = Event; 00463 00464 KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql); 00465 }


Variable Documentation

LONG KdDisableCount = 0
 

Definition at line 234 of file 4/kdapi.c.

BOOLEAN KdPreviouslyEnabled
 

Definition at line 235 of file 4/kdapi.c.

LARGE_INTEGER Magic10000
 

Definition at line 42 of file 4/kdapi.c.


Generated on Sat May 15 19:44:25 2004 for test by doxygen 1.3.7