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

kdp.h File Reference

#include "ntos.h"
#include "ki.h"
#include "ntdbg.h"
#include "string.h"
#include "stdlib.h"
#include "kdpcpu.h"

Go to the source code of this file.

Classes

struct  _BREAKPOINT_ENTRY
struct  _TRACE_DATA_SYM
struct  DBGKD_INTERNAL_BREAKPOINT

Defines

#define GLOBAL_BREAKPOINT_LIMIT   1610612736L
#define KD_BREAKPOINT_IN_USE   0x00000001
#define KD_BREAKPOINT_NEEDS_WRITE   0x00000002
#define KD_BREAKPOINT_SUSPENDED   0x00000004
#define KD_BREAKPOINT_NEEDS_REPLACE   0x00000008
#define KD_BREAKPOINT_STATE_MASK   0x0000000f
#define KD_BREAKPOINT_IA64_MASK   0x000f0000
#define KD_BREAKPOINT_IA64_MODE   0x00010000
#define KD_BREAKPOINT_IA64_MOVL   0x00020000
#define KDP_PACKET_RECEIVED   0
#define KDP_PACKET_TIMEOUT   1
#define KDP_PACKET_RESEND   2
#define MAXIMUM_RETRIES   20
#define DBGKD_MAX_SPECIAL_CALLS   10
#define KDP_MESSAGE_BUFFER_SIZE   4096
#define DBGKD_MAX_INTERNAL_BREAKPOINTS   20
#define DPRINT(s)

Typedefs

typedef _BREAKPOINT_ENTRY BREAKPOINT_ENTRY
typedef _BREAKPOINT_ENTRYPBREAKPOINT_ENTRY
typedef _TRACE_DATA_SYM TRACE_DATA_SYM
typedef _TRACE_DATA_SYMPTRACE_DATA_SYM
typedef * PDBGKD_INTERNAL_BREAKPOINT

Functions

VOID KdpReboot (VOID)
BOOLEAN KdpPrintString (IN PSTRING Output)
BOOLEAN KdpPromptString (IN PSTRING Output, IN OUT PSTRING Input)
ULONG KdpAddBreakpoint (IN PVOID Address)
BOOLEAN KdpDeleteBreakpoint (IN ULONG Handle)
BOOLEAN KdpDeleteBreakpointRange (IN PVOID Lower, IN PVOID Upper)
ULONG KdpMoveMemory (IN PCHAR Destination, IN PCHAR Source, IN ULONG Length)
VOID KdpQuickMoveMemory (IN PCHAR Destination, IN PCHAR Source, IN ULONG Length)
ULONG KdpReceivePacket (IN ULONG ExpectedPacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength)
VOID KdpSetLoadState (IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange, IN PCONTEXT ContextRecord)
VOID KdpSetStateChange (IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN BOOLEAN SecondChance)
VOID KdpGetStateChange (IN PDBGKD_MANIPULATE_STATE ManipulateState, IN PCONTEXT ContextRecord)
VOID KdpSendPacket (IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL)
BOOLEAN KdpStub (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
BOOLEAN KdpTrap (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
VOID KdpDisplayString (IN PCHAR Output)
VOID KdpWriteComPacket (USHORT, USHORT, PVOID, PVOID, PVOID)
BOOLEAN KdpReadComPacket (VOID)
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)
KCONTINUE_STATUS KdpSendWaitContinue (IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData OPTIONAL, IN OUT PCONTEXT ContextRecord)
VOID KdpReadVirtualMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpReadVirtualMemory64 (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteVirtualMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteVirtualMemory64 (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpReadPhysicalMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWritePhysicalMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpGetContext (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpSetContext (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteBreakpoint (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpRestoreBreakpoint (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpReadControlSpace (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteControlSpace (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpReadIoSpace (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpReadMachineSpecificRegister (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteIoSpace (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteMachineSpecificRegister (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpSuspendBreakpoint (ULONG Handle)
VOID KdpSuspendAllBreakpoints (VOID)
VOID KdpRestoreAllBreakpoints (VOID)
VOID KdpTimeSlipDpcRoutine (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
VOID KdpTimeSlipWork (IN PVOID Context)
VOID RtlpBreakWithStatusInstruction (VOID)
VOID KdpInitCom (VOID)
VOID KdpPortLock (VOID)
VOID KdpPortUnlock (VOID)
BOOLEAN KdpPollBreakInWithPortLock (VOID)
USHORT KdpReceivePacketLeader (IN ULONG PacketType, OUT PULONG PacketLeader)

Variables

BREAKPOINT_ENTRY KdpBreakpointTable [BREAKPOINT_TABLE_SIZE]
BOOLEAN KdpControlCPending
KSPIN_LOCK KdpDebuggerLock
PKDEBUG_ROUTINE KiDebugRoutine
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine
KDP_BREAKPOINT_TYPE KdpBreakpointInstruction
UCHAR KdpMessageBuffer [KDP_MESSAGE_BUFFER_SIZE]
UCHAR KdpPathBuffer [KDP_MESSAGE_BUFFER_SIZE]
ULONG KdpOweBreakpoint
ULONG KdpNextPacketIdToSend
ULONG KdpPacketIdExpected
LARGE_INTEGER KdPerformanceCounterRate
LARGE_INTEGER KdTimerStart
LARGE_INTEGER KdTimerStop
LARGE_INTEGER KdTimerDifference
BOOLEAN BreakpointsSuspended
PVOID KdpNtosImageBase
LIST_ENTRY KdpDebuggerDataListHead
DBGKD_INTERNAL_BREAKPOINT KdpInternalBPs [DBGKD_MAX_INTERNAL_BREAKPOINTS]
ULONG_PTR KdpCurrentSymbolStart
ULONG_PTR KdpCurrentSymbolEnd
LONG KdpNextCallLevelChange
ULONG_PTR KdSpecialCalls []
ULONG KdNumberOfSpecialCalls
ULONG_PTR InitialSP
ULONG KdpNumInternalBreakpoints
KTIMER InternalBreakpointTimer
KDPC InternalBreakpointCheckDpc
BOOLEAN KdpPortLocked
LARGE_INTEGER KdpTimeEntered
DBGKD_TRACE_DATA TraceDataBuffer []
ULONG TraceDataBufferPosition
TRACE_DATA_SYM TraceDataSyms []
UCHAR NextTraceDataSym
UCHAR NumTraceDataSyms
ULONG IntBPsSkipping
BOOLEAN WatchStepOver
PVOID WSOThread
ULONG WSOEsp
ULONG WatchStepOverHandle
ULONG_PTR WatchStepOverBreakAddr
BOOLEAN WatchStepOverSuspended
ULONG InstructionsTraced
BOOLEAN SymbolRecorded
LONG CallLevelChange
LONG oldpc
BOOLEAN InstrCountInternal
BOOLEAN KdpControlCPressed
ULONG KdpRetryCount
ULONG KdpNumberRetries
UCHAR KdPrintCircularBuffer [KDPRINTBUFFERSIZE]
PUCHAR KdPrintWritePointer
ULONG KdPrintRolloverCount
KSPIN_LOCK KdpPrintSpinLock
DEBUG_PARAMETERS KdDebugParameters
KSPIN_LOCK KdpDataSpinLock
KDDEBUGGER_DATA KdDebuggerDataBlock
KDPC KdpTimeSlipDpc
WORK_QUEUE_ITEM KdpTimeSlipWorkItem
KTIMER KdpTimeSlipTimer
ULONG KdpTimeSlipPending
KSPIN_LOCK KdpTimeSlipEventLock
PVOID KdpTimeSlipEvent
BOOLEAN KdpDebuggerStructuresInitialized
ULONG KdEnteredDebugger


Define Documentation

#define DBGKD_MAX_INTERNAL_BREAKPOINTS   20
 

Definition at line 470 of file kdp.h.

#define DBGKD_MAX_SPECIAL_CALLS   10
 

Definition at line 81 of file kdp.h.

#define DPRINT  ) 
 

Definition at line 573 of file kdp.h.

Referenced by KdEnterDebugger(), KdpAddBreakpoint(), KdpDeleteBreakpoint(), KdpLowRestoreBreakpoint(), KdpLowWriteContent(), and KdSetOwedBreakpoints().

#define GLOBAL_BREAKPOINT_LIMIT   1610612736L
 

Definition at line 42 of file kdp.h.

Referenced by KdpAddBreakpoint(), and KdSetOwedBreakpoints().

#define KD_BREAKPOINT_IA64_MASK   0x000f0000
 

Definition at line 54 of file kdp.h.

#define KD_BREAKPOINT_IA64_MODE   0x00010000
 

Definition at line 55 of file kdp.h.

#define KD_BREAKPOINT_IA64_MOVL   0x00020000
 

Definition at line 56 of file kdp.h.

Referenced by KdpAddBreakpoint(), KdpLowRestoreBreakpoint(), KdpLowWriteContent(), and KdSetOwedBreakpoints().

#define KD_BREAKPOINT_IN_USE   0x00000001
 

Definition at line 48 of file kdp.h.

Referenced by KdpAddBreakpoint(), KdpDeleteBreakpointRange(), KdpRestoreAllBreakpoints(), KdpSuspendBreakpoint(), and KdSetOwedBreakpoints().

#define KD_BREAKPOINT_NEEDS_REPLACE   0x00000008
 

Definition at line 51 of file kdp.h.

Referenced by KdpAddBreakpoint(), KdpDeleteBreakpoint(), KdpLowRestoreBreakpoint(), KdpLowWriteContent(), and KdSetOwedBreakpoints().

#define KD_BREAKPOINT_NEEDS_WRITE   0x00000002
 

Definition at line 49 of file kdp.h.

Referenced by KdpAddBreakpoint(), KdpLowRestoreBreakpoint(), KdpLowWriteContent(), and KdSetOwedBreakpoints().

#define KD_BREAKPOINT_STATE_MASK   0x0000000f
 

Definition at line 53 of file kdp.h.

Referenced by KdpAddBreakpoint(), and KdSetOwedBreakpoints().

#define KD_BREAKPOINT_SUSPENDED   0x00000004
 

Definition at line 50 of file kdp.h.

Referenced by KdpDeleteBreakpoint(), KdpRestoreAllBreakpoints(), KdpSuspendBreakpoint(), and KdSetOwedBreakpoints().

#define KDP_MESSAGE_BUFFER_SIZE   4096
 

Definition at line 432 of file kdp.h.

Referenced by KdpMoveMemory(), KdpPromptString(), KdpReadControlSpace(), and KdpSendWaitContinue().

#define KDP_PACKET_RECEIVED   0
 

Definition at line 62 of file kdp.h.

Referenced by KdpPromptString(), KdpReceivePacket(), KdpReceivePacketLeader(), and KdpSendPacket().

#define KDP_PACKET_RESEND   2
 

Definition at line 64 of file kdp.h.

Referenced by KdpPromptString(), KdpReceivePacket(), KdpReceivePacketLeader(), and KdpSendWaitContinue().

#define KDP_PACKET_TIMEOUT   1
 

Definition at line 63 of file kdp.h.

Referenced by KdpReceivePacket(), KdpReceivePacketLeader(), KdpSendPacket(), and KdpSendWaitContinue().

#define MAXIMUM_RETRIES   20
 

Definition at line 79 of file kdp.h.


Typedef Documentation

typedef struct _BREAKPOINT_ENTRY BREAKPOINT_ENTRY
 

typedef struct _BREAKPOINT_ENTRY * PBREAKPOINT_ENTRY
 

typedef * PDBGKD_INTERNAL_BREAKPOINT
 

typedef struct _TRACE_DATA_SYM * PTRACE_DATA_SYM
 

typedef struct _TRACE_DATA_SYM TRACE_DATA_SYM
 


Function Documentation

ULONG KdpAddBreakpoint IN PVOID  Address  ) 
 

Definition at line 60 of file kdbreak.c.

00066 : 00067 00068 This routine adds an entry to the breakpoint table and returns a handle 00069 to the breakpoint table entry. 00070 00071 Arguments: 00072 00073 Address - Supplies the address where to set the breakpoint. 00074 00075 Return Value: 00076 00077 A value of zero is returned if the specified address is already in the 00078 breakpoint table, there are no free entries in the breakpoint table, the 00079 specified address is not correctly aligned, or the specified address is 00080 not valid. Otherwise, the index of the assigned breakpoint table entry 00081 plus one is returned as the function value. 00082 00083 --*/ 00084 00085 { 00086 00087 KDP_BREAKPOINT_TYPE Content; 00088 ULONG Index; 00089 BOOLEAN Accessible; 00090 ULONG_PTR Opaque; 00091 00092 //DPRINT(("KD: Setting breakpoint at 0x%08x\n", Address)); 00093 00094 // 00095 // If the specified address is not properly aligned, then return zero. 00096 // 00097 00098 if (((ULONG_PTR)Address & KDP_BREAKPOINT_ALIGN) != 0) { 00099 return 0; 00100 } 00101 00102 00103 // 00104 // Don't allow setting the same breakpoint twice. 00105 // 00106 00107 for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index += 1) { 00108 if ((KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) != 0 && 00109 KdpBreakpointTable[Index].Address == Address) { 00110 00111 if ((KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_REPLACE) != 0) { 00112 00113 // 00114 // Breakpoint was set, the page was written out and was not 00115 // accessible when the breakpoint was cleared. Now the breakpoint 00116 // is being set again. Just clear the defer flag: 00117 // 00118 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_REPLACE; 00119 return Index + 1; 00120 00121 } else { 00122 00123 DPRINT(("KD: Attempt to set breakpoint %08x twice!\n", Address)); 00124 return 0; 00125 00126 } 00127 } 00128 } 00129 00130 // 00131 // Search the breakpoint table for a free entry. 00132 // 00133 00134 for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index += 1) { 00135 if (KdpBreakpointTable[Index].Flags == 0) { 00136 break; 00137 } 00138 } 00139 00140 // 00141 // If a free entry was found, then write breakpoint and return the handle 00142 // value plus one. Otherwise, return zero. 00143 // 00144 00145 if (Index == BREAKPOINT_TABLE_SIZE) { 00146 DPRINT(("KD: ran out of breakpoints!\n")); 00147 return 0; 00148 } 00149 00150 00151 //DPRINT(("KD: using Index %d\n", Index)); 00152 00153 // 00154 // Get the instruction to be replaced. If the instruction cannot be read, 00155 // then mark breakpoint as not accessible. 00156 // 00157 00158 if (KdpMoveMemory( 00159 (PCHAR)&Content, 00160 (PCHAR)Address, 00161 sizeof(KDP_BREAKPOINT_TYPE) ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00162 Accessible = FALSE; 00163 //DPRINT(("KD: memory inaccessible\n")); 00164 } else { 00165 //DPRINT(("KD: memory readable...\n")); 00166 Accessible = TRUE; 00167 } 00168 00169 // 00170 // If the specified address is not write accessible, then return zero. 00171 // 00172 00173 if (Accessible) { 00174 if (MmDbgWriteCheck((PVOID)Address, &Opaque) != NULL) { 00175 MmDbgReleaseAddress((PVOID)Address, Opaque); 00176 } else { 00177 DPRINT(("KD: memory not writable!\n")); 00178 return 0; 00179 } 00180 } 00181 00182 #if defined(_IA64_) 00183 if ( Accessible ) { 00184 KDP_BREAKPOINT_TYPE mBuf; 00185 PVOID BundleAddress; 00186 00187 // change template to type 0 if current instruction is MLI 00188 00189 // read in intruction template if current instruction is NOT slot 0. 00190 // check for two-slot MOVL instruction. Reject request if attempt to 00191 // set break in slot 2 of MLI template. 00192 00193 if (((ULONG_PTR)Address & 0xf) != 0) { 00194 (ULONG_PTR)BundleAddress = (ULONG_PTR)Address & ~(0xf); 00195 if (KdpMoveMemory( 00196 (PCHAR)&mBuf, 00197 (PCHAR)BundleAddress, 00198 sizeof(KDP_BREAKPOINT_TYPE) 00199 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00200 DPRINT(("KD: read 0x%08x template failed\n", BundleAddress)); 00201 return 0; 00202 } else { 00203 if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) { 00204 if (((ULONG_PTR)Address & 0xf) == 4) { 00205 // if template= type 2 MLI, change to type 0 00206 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); 00207 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IA64_MOVL; 00208 if (KdpMoveMemory( 00209 (PCHAR)BundleAddress, 00210 (PCHAR)&mBuf, 00211 sizeof(KDP_BREAKPOINT_TYPE) 00212 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00213 DPRINT(("KD: write to 0x%08x template failed\n", BundleAddress)); 00214 return 0; 00215 } 00216 else { 00217 //DPRINT(("KD: change MLI template to type 0 at 0x%08x set\n", Address)); 00218 } 00219 } else { 00220 // set breakpoint at slot 2 of MOVL is illegal 00221 DPRINT(("KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress)); 00222 return 0; 00223 } 00224 } 00225 } 00226 } 00227 00228 // insert break instruction 00229 00230 KdpBreakpointTable[Index].Address = Address; 00231 KdpBreakpointTable[Index].Content = Content; 00232 KdpBreakpointTable[Index].Flags &= ~(KD_BREAKPOINT_STATE_MASK); 00233 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IN_USE; 00234 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00235 KdpBreakpointTable[Index].DirectoryTableBase = 00236 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00237 } 00238 switch ((ULONG_PTR)Address & 0xf) { 00239 case 0: 00240 Content = (Content & ~(INST_SLOT0_MASK)) | (KdpBreakpointInstruction << 5); 00241 break; 00242 00243 case 4: 00244 Content = (Content & ~(INST_SLOT1_MASK)) | (KdpBreakpointInstruction << 14); 00245 break; 00246 00247 case 8: 00248 Content = (Content & ~(INST_SLOT2_MASK)) | (KdpBreakpointInstruction << 23); 00249 break; 00250 00251 default: 00252 DPRINT(("KD: KdpAddBreakpoint bad instruction slot#\n")); 00253 return 0; 00254 } 00255 if (KdpMoveMemory( 00256 (PCHAR)Address, 00257 (PCHAR)&Content, 00258 sizeof(KDP_BREAKPOINT_TYPE) 00259 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00260 00261 DPRINT(("KD: KdpMoveMemory failed writing BP!\n")); 00262 return 0; 00263 } 00264 else { 00265 //DPRINT(("KD: breakpoint at 0x%08x set\n", Address)); 00266 } 00267 00268 } else { // memory not accessible 00269 KdpBreakpointTable[Index].Address = Address; 00270 KdpBreakpointTable[Index].Flags &= ~(KD_BREAKPOINT_STATE_MASK); 00271 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IN_USE; 00272 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 00273 KdpOweBreakpoint = TRUE; 00274 //DPRINT(("KD: breakpoint write deferred\n")); 00275 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00276 KdpBreakpointTable[Index].DirectoryTableBase = 00277 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00278 } 00279 } 00280 #else 00281 if ( Accessible ) { 00282 KdpBreakpointTable[Index].Address = Address; 00283 KdpBreakpointTable[Index].Content = Content; 00284 KdpBreakpointTable[Index].Flags = KD_BREAKPOINT_IN_USE; 00285 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00286 KdpBreakpointTable[Index].DirectoryTableBase = 00287 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00288 } 00289 if (KdpMoveMemory( 00290 (PCHAR)Address, 00291 (PCHAR)&KdpBreakpointInstruction, 00292 sizeof(KDP_BREAKPOINT_TYPE) 00293 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00294 00295 DPRINT(("KD: KdpMoveMemory failed writing BP!\n")); 00296 } 00297 } else { 00298 KdpBreakpointTable[Index].Address = Address; 00299 KdpBreakpointTable[Index].Flags = KD_BREAKPOINT_IN_USE | KD_BREAKPOINT_NEEDS_WRITE; 00300 KdpOweBreakpoint = TRUE; 00301 //DPRINT(("KD: breakpoint write deferred\n")); 00302 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00303 KdpBreakpointTable[Index].DirectoryTableBase = 00304 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00305 } 00306 } 00307 #endif // IA64 00308 00309 return Index + 1; 00310 00311 }

BOOLEAN KdpDeleteBreakpoint IN ULONG  Handle  ) 
 

Definition at line 826 of file kdbreak.c.

00832 : 00833 00834 This routine deletes an entry from the breakpoint table. 00835 00836 Arguments: 00837 00838 Handle - Supplies the index plus one of the breakpoint table entry 00839 which is to be deleted. 00840 00841 Return Value: 00842 00843 A value of FALSE is returned if the specified handle is not a valid 00844 value or the breakpoint cannot be deleted because the old instruction 00845 cannot be replaced. Otherwise, a value of TRUE is returned. 00846 00847 --*/ 00848 00849 { 00850 ULONG Index = Handle - 1; 00851 00852 // 00853 // If the specified handle is not valid, then return FALSE. 00854 // 00855 00856 if ((Handle == 0) || (Handle > BREAKPOINT_TABLE_SIZE)) { 00857 DPRINT(("KD: Breakpoint %d invalid.\n", Index)); 00858 return FALSE; 00859 } 00860 00861 // 00862 // If the specified breakpoint table entry is not valid, then return FALSE. 00863 // 00864 00865 if (KdpBreakpointTable[Index].Flags == 0) { 00866 //DPRINT(("KD: Breakpoint %d already clear.\n", Index)); 00867 return FALSE; 00868 } 00869 00870 // 00871 // If the breakpoint is already suspended, just delete it from the table. 00872 // 00873 00874 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) { 00875 //DPRINT(("KD: Deleting suspended breakpoint %d \n", Index)); 00876 if ( !(KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_REPLACE) ) { 00877 //DPRINT(("KD: already clear.\n")); 00878 KdpBreakpointTable[Index].Flags = 0; 00879 return TRUE; 00880 } 00881 } 00882 00883 // 00884 // Replace the instruction contents. 00885 // 00886 00887 if (KdpLowWriteContent(Index)) { 00888 00889 // 00890 // Delete breakpoint table entry 00891 // 00892 00893 //DPRINT(("KD: Breakpoint %d deleted successfully.\n", Index)); 00894 KdpBreakpointTable[Index].Flags = 0; 00895 } 00896 00897 return TRUE; 00898 }

BOOLEAN KdpDeleteBreakpointRange IN PVOID  Lower,
IN PVOID  Upper
 

Definition at line 902 of file kdbreak.c.

00909 : 00910 00911 This routine deletes all breakpoints falling in a given range 00912 from the breakpoint table. 00913 00914 Arguments: 00915 00916 Lower - inclusive lower address of range from which to remove BPs. 00917 00918 Upper - include upper address of range from which to remove BPs. 00919 00920 Return Value: 00921 00922 TRUE if any breakpoints removed, FALSE otherwise. 00923 00924 --*/ 00925 00926 { 00927 ULONG Index; 00928 BOOLEAN ReturnStatus = FALSE; 00929 00930 // 00931 // Examine each entry in the table in turn 00932 // 00933 00934 for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++) { 00935 00936 if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 00937 ((KdpBreakpointTable[Index].Address >= Lower) && 00938 (KdpBreakpointTable[Index].Address <= Upper)) 00939 ) { 00940 00941 // 00942 // Breakpoint is in use and falls in range, clear it. 00943 // 00944 00945 ReturnStatus = ReturnStatus || KdpDeleteBreakpoint(Index+1); 00946 } 00947 } 00948 00949 return ReturnStatus; 00950 00951 }

VOID KdpDisplayString IN PCHAR  Output  ) 
 

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

Definition at line 1461 of file kdapi.c.

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

01469 : 01470 01471 This function is called in response of a get context state 01472 manipulation message. Its function is to return the current 01473 context. 01474 01475 Arguments: 01476 01477 m - Supplies the state manipulation message. 01478 01479 AdditionalData - Supplies any additional data for the message. 01480 01481 Context - Supplies the current context. 01482 01483 Return Value: 01484 01485 None. 01486 01487 --*/ 01488 01489 { 01490 PDBGKD_GET_CONTEXT a = &m->u.GetContext; 01491 STRING MessageHeader; 01492 01493 MessageHeader.Length = sizeof(*m); 01494 MessageHeader.Buffer = (PCHAR)m; 01495 01496 ASSERT(AdditionalData->Length == 0); 01497 01498 if (m->Processor >= (USHORT)KeNumberProcessors) { 01499 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01500 } else { 01501 m->ReturnStatus = STATUS_SUCCESS; 01502 AdditionalData->Length = sizeof(CONTEXT); 01503 if (m->Processor == (USHORT)KeGetCurrentPrcb()->Number) { 01504 KdpQuickMoveMemory(AdditionalData->Buffer, (PCHAR)Context, sizeof(CONTEXT)); 01505 } else { 01506 KdpQuickMoveMemory(AdditionalData->Buffer, 01507 (PCHAR)&KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame, 01508 sizeof(CONTEXT) 01509 ); 01510 } 01511 } 01512 01513 KdpSendPacket( 01514 PACKET_TYPE_KD_STATE_MANIPULATE, 01515 &MessageHeader, 01516 AdditionalData 01517 ); 01518 }

VOID KdpGetStateChange IN PDBGKD_MANIPULATE_STATE  ManipulateState,
IN PCONTEXT  ContextRecord
 

Definition at line 183 of file alpha/kdcpuapi.c.

00190 : 00191 00192 Extract continuation control data from Manipulate_State message 00193 00194 N.B. This is a noop for MIPS. 00195 00196 Arguments: 00197 00198 ManipulateState - supplies pointer to Manipulate_State packet 00199 00200 ContextRecord - Supplies a pointer to a context record. 00201 00202 Return Value: 00203 00204 None. 00205 00206 --*/ 00207 00208 { 00209 }

VOID KdpInitCom VOID   ) 
 

ULONG KdpMoveMemory IN PCHAR  Destination,
IN PCHAR  Source,
IN ULONG  Length
 

Definition at line 31 of file kdmove.c.

00039 : 00040 00041 This routine moves data to or from the message buffer and returns the 00042 actual length of the information that was moved. As data is moved, checks 00043 are made to ensure that the data is resident in memory and a page fault 00044 will not occur. If a page fault would occur, then the move is truncated. 00045 00046 Arguments: 00047 00048 Destination - Supplies a pointer to destination of the move operation. 00049 00050 Source - Supplies a pointer to the source of the move operation. 00051 00052 Length - Supplies the length of the move operation. 00053 00054 Return Value: 00055 00056 The actual length of the move is returned as the fucntion value. 00057 00058 --*/ 00059 00060 { 00061 00062 PVOID Address1; 00063 PVOID Address2; 00064 ULONG ActualLength; 00065 ULONG_PTR Opaque; 00066 00067 // 00068 // If the length is greater than the size of the message buffer, then 00069 // reduce the length to the size of the message buffer. 00070 // 00071 00072 if (Length > KDP_MESSAGE_BUFFER_SIZE) { 00073 Length = KDP_MESSAGE_BUFFER_SIZE; 00074 } 00075 00076 // 00077 // Move the source information to the destination address. 00078 // 00079 00080 ActualLength = Length; 00081 00082 while (((ULONG_PTR)Source & 3) && (Length > 0)) { 00083 00084 // 00085 // Check to determine if the move will succeed before actually performing 00086 // the operation. 00087 // 00088 00089 Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque); 00090 Address2 = MmDbgReadCheck((PVOID)Source); 00091 if ((Address1 == NULL) || (Address2 == NULL)) { 00092 break; 00093 } 00094 *(PCHAR)Address1 = *(PCHAR)Address2; 00095 MmDbgReleaseAddress((PVOID)Destination, Opaque); 00096 Destination += 1; 00097 Source += 1; 00098 Length -= 1; 00099 } 00100 00101 while (Length > 3) { 00102 00103 // 00104 // Check to determine if the move will succeed before actually performing 00105 // the operation. 00106 // 00107 00108 Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque); 00109 Address2 = MmDbgReadCheck((PVOID)Source); 00110 if ((Address1 == NULL) || (Address2 == NULL)) { 00111 break; 00112 } 00113 *(ULONG UNALIGNED *)Address1 = *(PULONG)Address2; 00114 MmDbgReleaseAddress((PVOID)Destination, Opaque); 00115 Destination += 4; 00116 Source += 4; 00117 Length -= 4; 00118 00119 } 00120 00121 while (Length > 0) { 00122 00123 // 00124 // Check to determine if the move will succeed before actually performing 00125 // the operation. 00126 // 00127 00128 Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque); 00129 Address2 = MmDbgReadCheck((PVOID)Source); 00130 if ((Address1 == NULL) || (Address2 == NULL)) { 00131 break; 00132 } 00133 *(PCHAR)Address1 = *(PCHAR)Address2; 00134 MmDbgReleaseAddress((PVOID)Destination, Opaque); 00135 Destination += 1; 00136 Source += 1; 00137 Length -= 1; 00138 } 00139 00140 // 00141 // Flush the instruction cache in case the write was into the instruction 00142 // stream. 00143 // 00144 00145 KeSweepCurrentIcache(); 00146 return ActualLength - Length; 00147 }

BOOLEAN KdpPollBreakInWithPortLock VOID   ) 
 

Definition at line 165 of file kdlock.c.

00171 : 00172 00173 This procedure same as KdPollBreakIn, but assumes the caller 00174 already holds the port lock. Returns TRUE if a breakin packet 00175 is pending. 00176 00177 A packet is present if: 00178 00179 There is a valid character which matches BREAK_CHAR. 00180 00181 N.B. Interrupts must be OFF around this call 00182 00183 Return Value: 00184 00185 TRUE if breakin sequence present, caller should execute int-3. 00186 FALSE if no breakin seen. 00187 00188 --*/ 00189 00190 { 00191 00192 BOOLEAN BreakIn; 00193 BOOLEAN Enable; 00194 UCHAR Input; 00195 ULONG Status; 00196 00197 // 00198 // If the debugger is enabled, see if a breakin by the kernel 00199 // debugger is pending. 00200 // 00201 00202 BreakIn = FALSE; 00203 if (KdDebuggerEnabled != FALSE) { 00204 if (KdpControlCPending != FALSE) { 00205 BreakIn = TRUE; 00206 KdpControlCPending = FALSE; 00207 00208 } else { 00209 Status = KdPortPollByte(&Input); 00210 if ((Status == CP_GET_SUCCESS) && 00211 (Input == BREAKIN_PACKET_BYTE)) { 00212 BreakIn = TRUE; 00213 } 00214 } 00215 } 00216 00217 return BreakIn; 00218 } }

VOID KdpPortLock VOID   ) 
 

Definition at line 26 of file kdlock.c.

00032 : 00033 00034 Acquire the spinlock for the debug port. 00035 00036 Note that user must call this explicitly, the get/put routines 00037 do NOT make any use of the lock. 00038 00039 CALLER MUST HAVE SET PROPER IRQL BEFORE CALLING US. 00040 00041 We use KiAcquireSpinLock and NOT Ke... because our IRQL may 00042 be above DISPATCH_LEVEL. 00043 00044 Arguments: 00045 00046 None. 00047 00048 Return value: 00049 00050 None. 00051 00052 --*/ 00053 00054 { 00055 KiAcquireSpinLock(&KdpDebuggerLock); 00056 }

VOID KdpPortUnlock VOID   ) 
 

Definition at line 60 of file kdlock.c.

00066 : 00067 00068 Release the spinlock for the debug port. 00069 00070 Note that user must call this explicitly, the get/put routines 00071 do NOT make any use of the lock. 00072 00073 CALLER MUST HAVE SET PROPER IRQL BEFORE CALLING US. 00074 00075 We use KiReleaseSpinLock and NOT Ke... because our IRQL may 00076 be above DISPATCH_LEVEL. 00077 00078 Arguments: 00079 00080 None. 00081 00082 Return value: 00083 00084 None. 00085 00086 --*/ 00087 00088 { 00089 KiReleaseSpinLock(&KdpDebuggerLock); 00090 }

BOOLEAN KdpPrintString IN PSTRING  Output  ) 
 

Definition at line 30 of file kddbgio.c.

00036 : 00037 00038 This routine prints a string. 00039 00040 Arguments: 00041 00042 Output - Supplies a pointer to a string descriptor for the output string. 00043 00044 Return Value: 00045 00046 TRUE if Control-C present in input buffer after print is done. 00047 FALSE otherwise. 00048 00049 --*/ 00050 00051 { 00052 00053 ULONG Length; 00054 STRING MessageData; 00055 STRING MessageHeader; 00056 DBGKD_DEBUG_IO DebugIo; 00057 00058 // 00059 // Move the output string to the message buffer. 00060 // 00061 00062 Length = KdpMoveMemory( 00063 (PCHAR)KdpMessageBuffer, 00064 (PCHAR)Output->Buffer, 00065 Output->Length 00066 ); 00067 00068 // 00069 // If the total message length is greater than the maximum packet size, 00070 // then truncate the output string. 00071 // 00072 00073 if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) { 00074 Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO); 00075 } 00076 00077 // 00078 // Construct the print string message and message descriptor. 00079 // 00080 00081 DebugIo.ApiNumber = DbgKdPrintStringApi; 00082 DebugIo.ProcessorLevel = KeProcessorLevel; 00083 DebugIo.Processor = (USHORT)KeGetCurrentPrcb()->Number; 00084 DebugIo.u.PrintString.LengthOfString = Length; 00085 MessageHeader.Length = sizeof(DBGKD_DEBUG_IO); 00086 MessageHeader.Buffer = (PCHAR)&DebugIo; 00087 00088 // 00089 // Construct the print string data and data descriptor. 00090 // 00091 00092 MessageData.Length = (USHORT)Length; 00093 MessageData.Buffer = KdpMessageBuffer; 00094 00095 // 00096 // Send packet to the kernel debugger on the host machine. 00097 // 00098 00099 KdpSendPacket( 00100 PACKET_TYPE_KD_DEBUG_IO, 00101 &MessageHeader, 00102 &MessageData 00103 ); 00104 00105 return KdpPollBreakInWithPortLock(); 00106 }

BOOLEAN KdpPromptString IN PSTRING  Output,
IN OUT PSTRING  Input
 

Definition at line 110 of file kddbgio.c.

00117 : 00118 00119 This routine prints a string, then reads a reply string. 00120 00121 Arguments: 00122 00123 Output - Supplies a pointer to a string descriptor for the output string. 00124 00125 Input - Supplies a pointer to a string descriptor for the input string. 00126 (Length stored/returned in Input->Length) 00127 00128 Return Value: 00129 00130 TRUE - A Breakin sequence was seen, caller should breakpoint and retry 00131 FALSE - No Breakin seen. 00132 00133 --*/ 00134 00135 { 00136 00137 ULONG Length; 00138 STRING MessageData; 00139 STRING MessageHeader; 00140 DBGKD_DEBUG_IO DebugIo; 00141 ULONG ReturnCode; 00142 00143 // 00144 // Move the output string to the message buffer. 00145 // 00146 00147 Length = KdpMoveMemory( 00148 (PCHAR)KdpMessageBuffer, 00149 (PCHAR)Output->Buffer, 00150 Output->Length 00151 ); 00152 00153 // 00154 // If the total message length is greater than the maximum packet size, 00155 // then truncate the output string. 00156 // 00157 00158 if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) { 00159 Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO); 00160 } 00161 00162 // 00163 // Construct the prompt string message and message descriptor. 00164 // 00165 00166 DebugIo.ApiNumber = DbgKdGetStringApi; 00167 DebugIo.ProcessorLevel = KeProcessorLevel; 00168 DebugIo.Processor = (USHORT)KeGetCurrentPrcb()->Number; 00169 DebugIo.u.GetString.LengthOfPromptString = Length; 00170 DebugIo.u.GetString.LengthOfStringRead = Input->MaximumLength; 00171 MessageHeader.Length = sizeof(DBGKD_DEBUG_IO); 00172 MessageHeader.Buffer = (PCHAR)&DebugIo; 00173 00174 // 00175 // Construct the prompt string data and data descriptor. 00176 // 00177 00178 MessageData.Length = (USHORT)Length; 00179 MessageData.Buffer = KdpMessageBuffer; 00180 00181 // 00182 // Send packet to the kernel debugger on the host machine. 00183 // 00184 00185 KdpSendPacket( 00186 PACKET_TYPE_KD_DEBUG_IO, 00187 &MessageHeader, 00188 &MessageData 00189 ); 00190 00191 00192 // 00193 // Receive packet from the kernel debugger on the host machine. 00194 // 00195 00196 MessageHeader.MaximumLength = sizeof(DBGKD_DEBUG_IO); 00197 MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE; 00198 00199 do { 00200 ReturnCode = KdpReceivePacket( 00201 PACKET_TYPE_KD_DEBUG_IO, 00202 &MessageHeader, 00203 &MessageData, 00204 &Length 00205 ); 00206 if (ReturnCode == KDP_PACKET_RESEND) { 00207 return TRUE; 00208 } 00209 } while (ReturnCode != KDP_PACKET_RECEIVED); 00210 00211 00212 if (Length > Input->MaximumLength) { 00213 Length = Input->MaximumLength; 00214 } 00215 00216 Input->Length = (USHORT)KdpMoveMemory( 00217 (PCHAR)Input->Buffer, 00218 (PCHAR)KdpMessageBuffer, 00219 Length 00220 ); 00221 00222 return FALSE; 00223 } }

VOID KdpQuickMoveMemory IN PCHAR  Destination,
IN PCHAR  Source,
IN ULONG  Length
 

Definition at line 150 of file kdmove.c.

00158 : 00159 00160 This routine does the exact same thing as RtlMoveMemory, BUT it is 00161 private to the debugger. This allows folks to set breakpoints and 00162 watch points in RtlMoveMemory without risk of recursive debugger 00163 entry and the accompanying hang. 00164 00165 N.B. UNLIKE KdpMoveMemory, this routine does NOT check for accessability 00166 and may fault! Use it ONLY in the debugger and ONLY where you 00167 could use RtlMoveMemory. 00168 00169 Arguments: 00170 00171 Destination - Supplies a pointer to destination of the move operation. 00172 00173 Source - Supplies a pointer to the source of the move operation. 00174 00175 Length - Supplies the length of the move operation. 00176 00177 Return Value: 00178 00179 None. 00180 00181 --*/ 00182 { 00183 while (Length > 0) { 00184 *Destination = *Source; 00185 Destination++; 00186 Source++; 00187 Length--; 00188 } 00189 } }

BOOLEAN KdpReadComPacket VOID   ) 
 

VOID KdpReadControlSpace IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 212 of file alpha/kdcpuapi.c.

References ASSERT, Buffer, KDP_MESSAGE_BUFFER_SIZE, KdpGetCurrentPrcb(), KdpGetCurrentThread(), KdpGetPcr(), KdpReadInternalProcessorCounters(), KdpReadInternalProcessorState(), KdpSendPacket(), and USHORT.

00220 : 00221 00222 This function is called in response of a read control space state 00223 manipulation message. Its function is to read implementation 00224 specific system data. 00225 00226 Arguments: 00227 00228 m - Supplies the state manipulation message. 00229 00230 AdditionalData - Supplies any additional data for the message. 00231 00232 Context - Supplies the current context. 00233 00234 Return Value: 00235 00236 None. 00237 00238 --*/ 00239 00240 { 00241 00242 PDBGKD_READ_MEMORY a = &m->u.ReadMemory; 00243 ULONG Length; 00244 STRING MessageHeader; 00245 PVOID Buffer = AdditionalData->Buffer; 00246 00247 MessageHeader.Length = sizeof(*m); 00248 MessageHeader.Buffer = (PCHAR)m; 00249 00250 ASSERT(AdditionalData->Length == 0); 00251 00252 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 00253 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 00254 } else { 00255 Length = a->TransferCount; 00256 } 00257 00258 ASSERT(sizeof(PVOID) == sizeof(ULONG)); 00259 00260 //NOTENOTE 00261 // This code will in fact only work on a uni-processor as the 00262 // m->Processor field is ignored for now 00263 00264 // 00265 // Case on address to determine what part of Control 00266 // space is being read 00267 // 00268 00269 switch( (ULONG_PTR)a->TargetBaseAddress ){ 00270 00271 // 00272 // Return the pcr address for the current processor. 00273 // 00274 00275 case DEBUG_CONTROL_SPACE_PCR: 00276 00277 *(PKPCR *)Buffer = KdpGetPcr(); 00278 AdditionalData->Length = sizeof( PKPCR ); 00279 a->ActualBytesRead = AdditionalData->Length; 00280 m->ReturnStatus = STATUS_SUCCESS; 00281 break; 00282 00283 // 00284 // Return the prcb address for the current processor. 00285 // 00286 00287 case DEBUG_CONTROL_SPACE_PRCB: 00288 00289 *(PKPRCB *)Buffer = KdpGetCurrentPrcb(); 00290 AdditionalData->Length = sizeof( PKPRCB ); 00291 a->ActualBytesRead = AdditionalData->Length; 00292 m->ReturnStatus = STATUS_SUCCESS; 00293 break; 00294 00295 // 00296 // Return the pointer to the current thread address for the 00297 // current processor. 00298 // 00299 00300 case DEBUG_CONTROL_SPACE_THREAD: 00301 00302 *(PKTHREAD *)Buffer = KdpGetCurrentThread(); 00303 AdditionalData->Length = sizeof( PKTHREAD ); 00304 a->ActualBytesRead = AdditionalData->Length; 00305 m->ReturnStatus = STATUS_SUCCESS; 00306 break; 00307 00308 // 00309 // Return the current Thread Environment Block pointer for the 00310 // current thread on the current processor. 00311 // 00312 00313 case DEBUG_CONTROL_SPACE_TEB: 00314 00315 *(PVOID *)Buffer = (PVOID)NtCurrentTeb(); 00316 AdditionalData->Length = sizeof( struct _TEB * ); 00317 a->ActualBytesRead = AdditionalData->Length; 00318 m->ReturnStatus = STATUS_SUCCESS; 00319 break; 00320 00321 // 00322 // Return the dpc active flag for the current processor. 00323 // 00324 00325 case DEBUG_CONTROL_SPACE_DPCACTIVE: 00326 00327 *(BOOLEAN *)Buffer = KeIsExecutingDpc(); 00328 AdditionalData->Length = sizeof( ULONG ); 00329 a->ActualBytesRead = AdditionalData->Length; 00330 m->ReturnStatus = STATUS_SUCCESS; 00331 break; 00332 00333 // 00334 // Return the internal processor register state. 00335 // 00336 // N.B. - the kernel debugger buffer is expected to be allocated 00337 // in the 32-bit superpage 00338 // 00339 // N.B. - the size of the internal state cannot exceed the size of 00340 // the buffer allocated to the kernel debugger via 00341 // KDP_MESSAGE_BUFFER_SIZE 00342 // 00343 00344 case DEBUG_CONTROL_SPACE_IPRSTATE: 00345 00346 // 00347 // Guarantee that Buffer is quadword-aligned, and adjust the 00348 // size of the available buffer accordingly. 00349 // 00350 00351 Buffer = (PVOID)( ((ULONG_PTR)Buffer + 7) & ~7); 00352 00353 Length = (ULONG)((ULONG_PTR)&AdditionalData->Buffer[KDP_MESSAGE_BUFFER_SIZE] - 00354 (ULONG_PTR)Buffer); 00355 00356 AdditionalData->Length = (USHORT)KdpReadInternalProcessorState( 00357 Buffer, 00358 Length ); 00359 00360 // 00361 // Check the returned size, if greater than the buffer size than 00362 // we didn't have a sufficient buffer. If zero then the call 00363 // failed otherwise. 00364 // 00365 00366 if( (AdditionalData->Length > KDP_MESSAGE_BUFFER_SIZE) || 00367 (AdditionalData->Length == 0) ){ 00368 00369 AdditionalData->Length = 0; 00370 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00371 a->ActualBytesRead = 0; 00372 00373 } else { 00374 00375 m->ReturnStatus = STATUS_SUCCESS; 00376 a->ActualBytesRead = AdditionalData->Length; 00377 00378 } 00379 00380 break; 00381 00382 // 00383 // Return the internal processor counter values. 00384 // 00385 // N.B. - the kernel debugger buffer is expected to be allocated 00386 // in the 32-bit superpage 00387 // 00388 // N.B. - the size of the counters structure cannot exceed the size of 00389 // the buffer allocated to the kernel debugger via 00390 // KDP_MESSAGE_BUFFER_SIZE 00391 // 00392 00393 case DEBUG_CONTROL_SPACE_COUNTERS: 00394 00395 // 00396 // Guarantee that Buffer is quadword-aligned, and adjust the 00397 // size of the available buffer accordingly. 00398 // 00399 00400 Buffer = (PVOID)( ((ULONG_PTR)Buffer + 7) & ~7); 00401 00402 Length = (ULONG)((ULONG_PTR)&AdditionalData->Buffer[KDP_MESSAGE_BUFFER_SIZE] - 00403 (ULONG_PTR)Buffer); 00404 00405 AdditionalData->Length = (USHORT)KdpReadInternalProcessorCounters( 00406 Buffer, 00407 Length ); 00408 00409 // 00410 // Check the returned size, if greater than the buffer size than 00411 // we didn't have a sufficient buffer. If zero then the call 00412 // failed otherwise. 00413 // 00414 00415 if( (AdditionalData->Length > KDP_MESSAGE_BUFFER_SIZE) || 00416 (AdditionalData->Length == 0) ){ 00417 00418 AdditionalData->Length = 0; 00419 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00420 a->ActualBytesRead = 0; 00421 00422 } else { 00423 00424 m->ReturnStatus = STATUS_SUCCESS; 00425 a->ActualBytesRead = AdditionalData->Length; 00426 00427 } 00428 00429 break; 00430 00431 // 00432 // Uninterpreted Special Space 00433 // 00434 00435 default: 00436 00437 AdditionalData->Length = 0; 00438 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00439 a->ActualBytesRead = 0; 00440 00441 } 00442 00443 KdpSendPacket( 00444 PACKET_TYPE_KD_STATE_MANIPULATE, 00445 &MessageHeader, 00446 AdditionalData 00447 ); 00448 }

VOID KdpReadIoSpace IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 499 of file alpha/kdcpuapi.c.

References ASSERT, BusNumber, HalTranslateBusAddress(), InterfaceType, KdpSendPacket(), NULL, and PUSHORT.

00507 : 00508 00509 This function is called in response of a read io space state 00510 manipulation message. Its function is to read system io 00511 locations. 00512 00513 Arguments: 00514 00515 m - Supplies the state manipulation message. 00516 00517 AdditionalData - Supplies any additional data for the message. 00518 00519 Context - Supplies the current context. 00520 00521 Return Value: 00522 00523 None. 00524 00525 --*/ 00526 00527 { 00528 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00529 STRING MessageHeader; 00530 INTERFACE_TYPE InterfaceType; 00531 ULONG BusNumber; 00532 PHYSICAL_ADDRESS IoAddress; 00533 PHYSICAL_ADDRESS TranslatedAddress; 00534 ULONG AddressSpace; 00535 ULONG DataSize; 00536 00537 MessageHeader.Length = sizeof(*m); 00538 MessageHeader.Buffer = (PCHAR)m; 00539 00540 ASSERT(AdditionalData->Length == 0); 00541 00542 m->ReturnStatus = STATUS_SUCCESS; 00543 00544 // 00545 // Capture the input parameters and use the default values for those 00546 // parameters not specified in the Api. 00547 // 00548 00549 InterfaceType = Isa; 00550 BusNumber = 0; 00551 AddressSpace = 1; 00552 IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; 00553 DataSize = a->DataSize; 00554 00555 // 00556 // Zero the return data value. 00557 // 00558 00559 a->DataValue = 0; 00560 00561 // 00562 // Translate the bus address to the physical system address 00563 // or QVA. 00564 // 00565 00566 if( !HalTranslateBusAddress( InterfaceType, 00567 BusNumber, 00568 IoAddress, 00569 &AddressSpace, 00570 &TranslatedAddress ) ){ 00571 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00572 goto SendReadIoSpaceResponse; 00573 } 00574 00575 // 00576 // N.B. - for the moment we will only support QVAs ie. when AddressSpace 00577 // is one. It may be in later systems that we will have to 00578 // check the address space, map it, perform the virtual read 00579 // unmap, and then return the data - only we will have to be 00580 // careful about what Irql we are to make sure the memory mgmt 00581 // stuff will all work 00582 // 00583 00584 if( !AddressSpace ){ 00585 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00586 goto SendReadIoSpaceResponse; 00587 } 00588 00589 // 00590 // Do the IO space read using the appropriate HAL routines based upon 00591 // the default address space (io) and the data size requested. 00592 // 00593 00594 switch( DataSize ){ 00595 00596 case 1: 00597 a->DataValue = READ_PORT_UCHAR( (PUCHAR)TranslatedAddress.LowPart ); 00598 break; 00599 00600 case 2: 00601 a->DataValue = READ_PORT_USHORT( (PUSHORT)TranslatedAddress.LowPart ); 00602 break; 00603 00604 case 4: 00605 a->DataValue = READ_PORT_ULONG((PULONG)TranslatedAddress.LowPart ); 00606 break; 00607 00608 default: 00609 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00610 } 00611 00612 00613 SendReadIoSpaceResponse: 00614 00615 KdpSendPacket( 00616 PACKET_TYPE_KD_STATE_MANIPULATE, 00617 &MessageHeader, 00618 NULL 00619 ); 00620 }

VOID KdpReadMachineSpecificRegister IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1095 of file i386/kdcpuapi.c.

References ASSERT, EXCEPTION_EXECUTE_HANDLER, KdpSendPacket(), NULL, and RDMSR().

01103 : 01104 01105 This function is called in response of a read MSR 01106 manipulation message. Its function is to read the MSR. 01107 01108 Arguments: 01109 01110 m - Supplies the state manipulation message. 01111 01112 AdditionalData - Supplies any additional data for the message. 01113 01114 Context - Supplies the current context. 01115 01116 Return Value: 01117 01118 None. 01119 01120 --*/ 01121 01122 { 01123 PDBGKD_READ_WRITE_MSR a = &m->u.ReadWriteMsr; 01124 STRING MessageHeader; 01125 LARGE_INTEGER l; 01126 01127 MessageHeader.Length = sizeof(*m); 01128 MessageHeader.Buffer = (PCHAR)m; 01129 01130 ASSERT(AdditionalData->Length == 0); 01131 01132 m->ReturnStatus = STATUS_SUCCESS; 01133 01134 try { 01135 l.QuadPart = RDMSR(a->Msr); 01136 } except (EXCEPTION_EXECUTE_HANDLER) { 01137 l.QuadPart = 0; 01138 m->ReturnStatus = STATUS_NO_SUCH_DEVICE; 01139 } 01140 01141 a->DataValueLow = l.LowPart; 01142 a->DataValueHigh = l.HighPart; 01143 01144 KdpSendPacket( 01145 PACKET_TYPE_KD_STATE_MANIPULATE, 01146 &MessageHeader, 01147 NULL 01148 ); 01149 UNREFERENCED_PARAMETER(Context); 01150 }

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

Definition at line 2534 of file kdapi.c.

References ASSERT, BYTE_OFFSET, KdpMoveMemory(), KdpSendPacket(), MmDbgTranslatePhysicalAddress(), NULL, PAGE_ALIGN, PAGE_SIZE, and USHORT.

02542 : 02543 02544 This function is called in response to a read physical memory 02545 state manipulation message. Its function is to read physical memory 02546 and return. 02547 02548 N.B. This is now more dangerous than ever: if the modified physical 02549 memory is mapped to a virtual page which is protected as readonly text, 02550 the memory manager will eventually bugcheck when it discovers that 02551 the page has been modified. 02552 02553 Arguments: 02554 02555 m - Supplies the state manipulation message. 02556 02557 AdditionalData - Supplies any additional data for the message. 02558 02559 Context - Supplies the current context. 02560 02561 Return Value: 02562 02563 None. 02564 02565 --*/ 02566 02567 { 02568 PDBGKD_READ_MEMORY a = &m->u.ReadMemory; 02569 ULONG Length; 02570 STRING MessageHeader; 02571 PVOID VirtualAddress; 02572 PHYSICAL_ADDRESS Source; 02573 PUCHAR Destination; 02574 USHORT NumberBytes; 02575 USHORT BytesLeft; 02576 02577 MessageHeader.Length = sizeof(*m); 02578 MessageHeader.Buffer = (PCHAR)m; 02579 02580 // 02581 // make sure that nothing but a read memory message was transmitted 02582 // 02583 02584 ASSERT(AdditionalData->Length == 0); 02585 02586 // 02587 // Trim transfer count to fit in a single message 02588 // 02589 02590 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 02591 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 02592 } else { 02593 Length = a->TransferCount; 02594 } 02595 02596 // 02597 // Since the MmDbgTranslatePhysicalAddress only maps in one physical 02598 // page at a time, we need to break the memory move up into smaller 02599 // moves which don't cross page boundaries. There are two cases we 02600 // need to deal with. The area to be moved may start and end on the 02601 // same page, or it may start and end on different pages (with an 02602 // arbitrary number of pages in between) 02603 // 02604 Source.QuadPart = (ULONG_PTR)a->TargetBaseAddress; 02605 Destination = AdditionalData->Buffer; 02606 BytesLeft = (USHORT)Length; 02607 if(PAGE_ALIGN((PUCHAR)a->TargetBaseAddress) == 02608 PAGE_ALIGN((PUCHAR)(a->TargetBaseAddress)+Length)) { 02609 // 02610 // Memory move starts and ends on the same page. 02611 // 02612 VirtualAddress=MmDbgTranslatePhysicalAddress(Source); 02613 if (VirtualAddress == NULL) { 02614 AdditionalData->Length = 0; 02615 } else { 02616 AdditionalData->Length = (USHORT)KdpMoveMemory( 02617 Destination, 02618 VirtualAddress, 02619 BytesLeft 02620 ); 02621 BytesLeft -= AdditionalData->Length; 02622 } 02623 } else { 02624 // 02625 // Memory move spans page boundaries 02626 // 02627 VirtualAddress=MmDbgTranslatePhysicalAddress(Source); 02628 if (VirtualAddress == NULL) { 02629 AdditionalData->Length = 0; 02630 } else { 02631 NumberBytes = (USHORT)(PAGE_SIZE - BYTE_OFFSET(VirtualAddress)); 02632 AdditionalData->Length = (USHORT)KdpMoveMemory( 02633 Destination, 02634 VirtualAddress, 02635 NumberBytes 02636 ); 02637 Source.LowPart += NumberBytes; 02638 Destination += NumberBytes; 02639 BytesLeft -= NumberBytes; 02640 while(BytesLeft > 0) { 02641 // 02642 // Transfer a full page or the last bit, 02643 // whichever is smaller. 02644 // 02645 VirtualAddress = MmDbgTranslatePhysicalAddress(Source); 02646 if (VirtualAddress == NULL) { 02647 break; 02648 } else { 02649 NumberBytes = (USHORT) ((PAGE_SIZE < BytesLeft) ? PAGE_SIZE : BytesLeft); 02650 AdditionalData->Length += (USHORT)KdpMoveMemory( 02651 Destination, 02652 VirtualAddress, 02653 NumberBytes 02654 ); 02655 Source.LowPart += NumberBytes; 02656 Destination += NumberBytes; 02657 BytesLeft -= NumberBytes; 02658 } 02659 } 02660 } 02661 } 02662 02663 if (Length == AdditionalData->Length) { 02664 m->ReturnStatus = STATUS_SUCCESS; 02665 } else { 02666 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02667 } 02668 a->ActualBytesRead = AdditionalData->Length; 02669 02670 KdpSendPacket( 02671 PACKET_TYPE_KD_STATE_MANIPULATE, 02672 &MessageHeader, 02673 AdditionalData 02674 ); 02675 UNREFERENCED_PARAMETER(Context); 02676 }

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

Definition at line 1139 of file kdapi.c.

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

01147 : 01148 01149 This function is called in response to a read virtual memory 32-bit 01150 state manipulation message. Its function is to read virtual memory 01151 and return. 01152 01153 Arguments: 01154 01155 m - Supplies a pointer to the state manipulation message. 01156 01157 AdditionalData - Supplies a pointer to a descriptor for the data to read. 01158 01159 Context - Supplies a pointer to the current context. 01160 01161 Return Value: 01162 01163 None. 01164 01165 --*/ 01166 01167 { 01168 01169 ULONG Length; 01170 STRING MessageHeader; 01171 01172 // 01173 // Trim the transfer count to fit in a single message. 01174 // 01175 01176 Length = m->u.ReadMemory.TransferCount; 01177 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 01178 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 01179 } 01180 01181 // 01182 // Move the data to the destination buffer. 01183 // 01184 01185 AdditionalData->Length = (USHORT)KdpMoveMemory(AdditionalData->Buffer, 01186 m->u.ReadMemory.TargetBaseAddress, 01187 Length); 01188 01189 // 01190 // If all the data is read, then return a success status. Otherwise, 01191 // return unsuccessful. 01192 // 01193 01194 m->ReturnStatus = STATUS_SUCCESS; 01195 if (Length != AdditionalData->Length) { 01196 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01197 } 01198 01199 // 01200 // Set the actual number of bytes read, initialize the message header, 01201 // and send the reply packet to the host debugger. 01202 // 01203 01204 m->u.ReadMemory.ActualBytesRead = AdditionalData->Length; 01205 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01206 MessageHeader.Buffer = (PCHAR)m; 01207 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01208 &MessageHeader, 01209 AdditionalData); 01210 01211 return; 01212 }

VOID KdpReadVirtualMemory64 IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1215 of file kdapi.c.

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

Referenced by KdpSendWaitContinue().

01223 : 01224 01225 This function is called in response of a read virtual memory 64-bit 01226 state manipulation message. Its function is to read virtual memory 01227 and return. 01228 01229 Arguments: 01230 01231 m - Supplies a pointer to a state manipulation message. 01232 01233 AdditionalData - Supplies a pointer to descriptor for the data to read. 01234 01235 Context - Supplies a pointer to the current context. 01236 01237 Return Value: 01238 01239 None. 01240 01241 --*/ 01242 01243 { 01244 01245 UCHAR * POINTER_64 Address; 01246 PUCHAR Destination; 01247 ULONG Length; 01248 STRING MessageHeader; 01249 UCHAR * POINTER_64 Source; 01250 01251 // 01252 // Trim the transfer count to fit in a single message. 01253 // 01254 01255 Length = m->u.ReadMemory64.TransferCount; 01256 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 01257 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 01258 } 01259 01260 // 01261 // Move the data to the destination buffer. 01262 // 01263 01264 AdditionalData->Length = (USHORT)Length; 01265 01266 #if defined(_MIPS_) || defined(_ALPHA_) 01267 01268 Destination = AdditionalData->Buffer; 01269 Source = (UCHAR * POINTER_64)m->u.ReadMemory64.TargetBaseAddress; 01270 while (Length > 0) { 01271 if ((Address = MmDbgReadCheck64(Source)) == NULL64) { 01272 break; 01273 } 01274 01275 *Destination++ = *Address; 01276 Source += 1; 01277 Length -= 1; 01278 } 01279 01280 #endif 01281 01282 // 01283 // If all the data is read, then return a success status. Otherwise, 01284 // return an unsuccessful status. 01285 // 01286 01287 m->ReturnStatus = STATUS_SUCCESS; 01288 if (Length != 0) { 01289 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01290 } 01291 01292 // 01293 // Set the actual number of bytes read, initialize the message header, 01294 // and send the reply packet to the host debugger. 01295 // 01296 01297 m->u.ReadMemory64.ActualBytesRead = AdditionalData->Length - Length; 01298 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01299 MessageHeader.Buffer = (PCHAR)m; 01300 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01301 &MessageHeader, 01302 AdditionalData); 01303 01304 return; 01305 }

VOID KdpReboot VOID   ) 
 

Definition at line 25 of file alpha/kdreboot.c.

00031 : 00032 00033 Reboot the system via the Hal. 00034 00035 --*/ 00036 00037 { 00038 00039 HalReturnToFirmware(HalRebootRoutine); 00040 } }

ULONG KdpReceivePacket IN ULONG  ExpectedPacketType,
OUT PSTRING  MessageHeader,
OUT PSTRING  MessageData,
OUT PULONG  DataLength
 

Definition at line 342 of file kdcomio.c.

00351 : 00352 00353 This routine receives a packet from the host machine that is running 00354 the kernel debugger UI. This routine is ALWAYS called after packet being 00355 sent by caller. It first waits for ACK packet for the packet sent and 00356 then waits for the packet desired. 00357 00358 N.B. If caller is KdPrintString, the parameter PacketType is 00359 PACKET_TYPE_KD_ACKNOWLEDGE. In this case, this routine will return 00360 right after the ack packet is received. 00361 00362 Arguments: 00363 00364 PacketType - Supplies the type of packet that is excepted. 00365 00366 MessageHeader - Supplies a pointer to a string descriptor for the input 00367 message. 00368 00369 MessageData - Supplies a pointer to a string descriptor for the input data. 00370 00371 DataLength - Supplies pointer to ULONG to receive length of recv. data. 00372 00373 Return Value: 00374 00375 KDP_PACKET_RESEND - if resend is required. 00376 KDP_PAKCET_TIMEOUT - if timeout. 00377 KDP_PACKET_RECEIVED - if packet received. 00378 00379 --*/ 00380 00381 { 00382 00383 UCHAR Input; 00384 ULONG MessageLength; 00385 KD_PACKET PacketHeader; 00386 ULONG ReturnCode; 00387 ULONG Checksum; 00388 00389 WaitForPacketLeader: 00390 00391 // 00392 // Read Packet Leader 00393 // 00394 00395 ReturnCode = KdpReceivePacketLeader(PacketType, &PacketHeader.PacketLeader); 00396 00397 // 00398 // If we can successfully read packet leader, it has high possibility that 00399 // kernel debugger is alive. So reset count. 00400 // 00401 00402 if (ReturnCode != KDP_PACKET_TIMEOUT) { 00403 KdpNumberRetries = KdpRetryCount; 00404 } 00405 if (ReturnCode != KDP_PACKET_RECEIVED) { 00406 return ReturnCode; 00407 } 00408 00409 // 00410 // Read packet type. 00411 // 00412 00413 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketType, 00414 sizeof(PacketHeader.PacketType)); 00415 if (ReturnCode == CP_GET_NODATA) { 00416 return KDP_PACKET_TIMEOUT; 00417 } else if (ReturnCode == CP_GET_ERROR) { 00418 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00419 00420 // 00421 // If read error and it is for a control packet, simply 00422 // preptend that we have not seen this packet. Hopefully 00423 // we will receive the packet we desire which automatically acks 00424 // the packet we just sent. 00425 // 00426 00427 goto WaitForPacketLeader; 00428 } else { 00429 00430 // 00431 // if read error while reading data packet, we have to ask 00432 // kernel debugger to resend us the packet. 00433 // 00434 00435 goto SendResendPacket; 00436 } 00437 } 00438 00439 // 00440 // if the packet we received is a resend request, we return true and 00441 // let caller resend the packet. 00442 // 00443 00444 if ( PacketHeader.PacketLeader == CONTROL_PACKET_LEADER && 00445 PacketHeader.PacketType == PACKET_TYPE_KD_RESEND ) { 00446 return KDP_PACKET_RESEND; 00447 } 00448 00449 // 00450 // Read data length. 00451 // 00452 00453 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.ByteCount, 00454 sizeof(PacketHeader.ByteCount)); 00455 if (ReturnCode == CP_GET_NODATA) { 00456 return KDP_PACKET_TIMEOUT; 00457 } else if (ReturnCode == CP_GET_ERROR) { 00458 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00459 goto WaitForPacketLeader; 00460 } else { 00461 goto SendResendPacket; 00462 } 00463 } 00464 00465 // 00466 // Read Packet Id. 00467 // 00468 00469 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.PacketId, 00470 sizeof(PacketHeader.PacketId)); 00471 00472 if (ReturnCode == CP_GET_NODATA) { 00473 return KDP_PACKET_TIMEOUT; 00474 } else if (ReturnCode == CP_GET_ERROR) { 00475 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00476 goto WaitForPacketLeader; 00477 } else { 00478 goto SendResendPacket; 00479 } 00480 } 00481 00482 // 00483 // Read packet checksum. 00484 // 00485 00486 ReturnCode = KdpReceiveString((PCHAR)&PacketHeader.Checksum, 00487 sizeof(PacketHeader.Checksum)); 00488 if (ReturnCode == CP_GET_NODATA) { 00489 return KDP_PACKET_TIMEOUT; 00490 } else if (ReturnCode == CP_GET_ERROR) { 00491 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER) { 00492 goto WaitForPacketLeader; 00493 } else { 00494 goto SendResendPacket; 00495 } 00496 } 00497 00498 // 00499 // A complete packet header is received. Check its validity and 00500 // perform appropriate action depending on packet type. 00501 // 00502 00503 if (PacketHeader.PacketLeader == CONTROL_PACKET_LEADER ) { 00504 if (PacketHeader.PacketType == PACKET_TYPE_KD_ACKNOWLEDGE ) { 00505 00506 // 00507 // If we received an expected ACK packet and we are not 00508 // waiting for any new packet, update outgoing packet id 00509 // and return. If we are NOT waiting for ACK packet 00510 // we will keep on waiting. If the ACK packet 00511 // is not for the packet we send, ignore it and keep on waiting. 00512 // 00513 00514 if (PacketHeader.PacketId != 00515 (KdpNextPacketIdToSend & ~SYNC_PACKET_ID)) { 00516 goto WaitForPacketLeader; 00517 } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) { 00518 KdpNextPacketIdToSend ^= 1; 00519 return KDP_PACKET_RECEIVED; 00520 } else { 00521 goto WaitForPacketLeader; 00522 } 00523 } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESET) { 00524 00525 // 00526 // if we received Reset packet, reset the packet control variables 00527 // and resend earlier packet. 00528 // 00529 00530 KdpNextPacketIdToSend = INITIAL_PACKET_ID; 00531 KdpPacketIdExpected = INITIAL_PACKET_ID; 00532 KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0L); 00533 return KDP_PACKET_RESEND; 00534 } else if (PacketHeader.PacketType == PACKET_TYPE_KD_RESEND) { 00535 return KDP_PACKET_RESEND; 00536 } else { 00537 00538 // 00539 // Invalid packet header, ignore it. 00540 // 00541 00542 goto WaitForPacketLeader; 00543 } 00544 00545 // 00546 // The packet header is for data packet (not control packet). 00547 // 00548 00549 } else if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE) { 00550 00551 // 00552 // if we are waiting for ACK packet ONLY 00553 // and we receive a data packet header, check if the packet id 00554 // is what we expected. If yes, assume the acknowledge is lost (but 00555 // sent), ask sender to resend and return with PACKET_RECEIVED. 00556 // 00557 00558 if (PacketHeader.PacketId == KdpPacketIdExpected) { 00559 KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L); 00560 KdpNextPacketIdToSend ^= 1; 00561 return KDP_PACKET_RECEIVED; 00562 } else { 00563 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00564 PacketHeader.PacketId 00565 ); 00566 goto WaitForPacketLeader; 00567 } 00568 } 00569 00570 // 00571 // we are waiting for data packet and we received the packet header 00572 // for data packet. Perform the following checkings to make sure 00573 // it is the packet we are waiting for. 00574 // 00575 00576 // 00577 // Check ByteCount received is valid 00578 // 00579 00580 MessageLength = MessageHeader->MaximumLength; 00581 if ((PacketHeader.ByteCount > (USHORT)PACKET_MAX_SIZE) || 00582 (PacketHeader.ByteCount < (USHORT)MessageLength)) { 00583 goto SendResendPacket; 00584 } 00585 *DataLength = PacketHeader.ByteCount - MessageLength; 00586 00587 // 00588 // Read the message header. 00589 // 00590 00591 ReturnCode = KdpReceiveString(MessageHeader->Buffer, MessageLength); 00592 if (ReturnCode != CP_GET_SUCCESS) { 00593 goto SendResendPacket; 00594 } 00595 MessageHeader->Length = (USHORT)MessageLength; 00596 00597 // 00598 // Read the message data. 00599 // 00600 00601 ReturnCode = KdpReceiveString(MessageData->Buffer, *DataLength); 00602 if (ReturnCode != CP_GET_SUCCESS) { 00603 goto SendResendPacket; 00604 } 00605 MessageData->Length = (USHORT)*DataLength; 00606 00607 // 00608 // Read packet trailing byte 00609 // 00610 00611 ReturnCode = KdPortGetByte(&Input); 00612 if (ReturnCode != CP_GET_SUCCESS || Input != PACKET_TRAILING_BYTE) { 00613 goto SendResendPacket; 00614 } 00615 00616 // 00617 // Check PacketType is what we are waiting for. 00618 // 00619 00620 if (PacketType != PacketHeader.PacketType) { 00621 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00622 PacketHeader.PacketId 00623 ); 00624 goto WaitForPacketLeader; 00625 } 00626 00627 // 00628 // Check PacketId is valid. 00629 // 00630 00631 if (PacketHeader.PacketId == INITIAL_PACKET_ID || 00632 PacketHeader.PacketId == (INITIAL_PACKET_ID ^ 1)) { 00633 if (PacketHeader.PacketId != KdpPacketIdExpected) { 00634 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00635 PacketHeader.PacketId 00636 ); 00637 goto WaitForPacketLeader; 00638 } 00639 } else { 00640 goto SendResendPacket; 00641 } 00642 00643 // 00644 // Check checksum is valid. 00645 // 00646 00647 Checksum = KdpComputeChecksum( 00648 MessageHeader->Buffer, 00649 MessageHeader->Length 00650 ); 00651 00652 Checksum += KdpComputeChecksum( 00653 MessageData->Buffer, 00654 MessageData->Length 00655 ); 00656 if (Checksum != PacketHeader.Checksum) { 00657 goto SendResendPacket; 00658 } 00659 00660 // 00661 // Send Acknowledge byte and the Id of the packet received. 00662 // Then, update the ExpectId for next incoming packet. 00663 // 00664 00665 KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, 00666 PacketHeader.PacketId 00667 ); 00668 00669 // 00670 // We have successfully received the packet so update the 00671 // packet control variables and return sucess. 00672 // 00673 00674 KdpPacketIdExpected ^= 1; 00675 return KDP_PACKET_RECEIVED; 00676 00677 SendResendPacket: 00678 KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0L); 00679 goto WaitForPacketLeader; 00680 }

USHORT KdpReceivePacketLeader IN ULONG  PacketType,
OUT PULONG  PacketLeader
 

Definition at line 95 of file kdcomio.c.

00102 : 00103 00104 This routine waits for a packet header leader. 00105 00106 Arguments: 00107 00108 PacketType - supplies the type of packet we are expecting. 00109 00110 PacketLeader - supplies a pointer to a ulong variable to receive 00111 packet leader bytes. 00112 00113 Return Value: 00114 00115 KDP_PACKET_RESEND - if resend is required. 00116 KDP_PAKCET_TIMEOUT - if timeout. 00117 KDP_PACKET_RECEIVED - if packet received. 00118 00119 --*/ 00120 00121 { 00122 00123 UCHAR Input, PreviousByte = 0; 00124 ULONG PacketId = 0; 00125 ULONG Index; 00126 ULONG ReturnCode; 00127 BOOLEAN BreakinDetected = FALSE; 00128 00129 // 00130 // NOTE - With all the interrupts being off, it is very hard 00131 // to implement the actual timeout code. (Maybe, by reading the CMOS.) 00132 // Here we use a loop count to wait about 3 seconds. The CpGetByte 00133 // will return with error code = CP_GET_NODATA if it cannot find data 00134 // byte within 1 second. Kernel debugger's timeout period is 5 seconds. 00135 // 00136 00137 Index = 0; 00138 do { 00139 ReturnCode = KdPortGetByte(&Input); 00140 if (ReturnCode == CP_GET_NODATA) { 00141 if (BreakinDetected) { 00142 KdpControlCPending = TRUE; 00143 return KDP_PACKET_RESEND; 00144 } else { 00145 return KDP_PACKET_TIMEOUT; 00146 } 00147 } else if (ReturnCode == CP_GET_ERROR) { 00148 Index = 0; 00149 continue; 00150 } else { // if (ReturnCode == CP_GET_SUCCESS) 00151 if ( Input == PACKET_LEADER_BYTE || 00152 Input == CONTROL_PACKET_LEADER_BYTE ) { 00153 if ( Index == 0 ) { 00154 PreviousByte = Input; 00155 Index++; 00156 } else if (Input == PreviousByte ) { 00157 Index++; 00158 } else { 00159 PreviousByte = Input; 00160 Index = 1; 00161 } 00162 } else { 00163 00164 // 00165 // If we detect breakin character, we need to verify it 00166 // validity. (It is possible that we missed a packet leader 00167 // and the breakin character is simply a data byte in the 00168 // packet.) 00169 // Since kernel debugger send out breakin character ONLY 00170 // when it is waiting for State Change packet. The breakin 00171 // character should not be followed by any other character 00172 // except packet leader byte. 00173 // 00174 00175 if ( Input == BREAKIN_PACKET_BYTE ) { 00176 BreakinDetected = TRUE; 00177 } else { 00178 00179 // 00180 // The following statement is ABSOLUTELY necessary. 00181 // 00182 00183 BreakinDetected = FALSE; 00184 } 00185 Index = 0; 00186 } 00187 } 00188 } while ( Index < 4 ); 00189 00190 if (BreakinDetected) { 00191 KdpControlCPending = TRUE; 00192 } 00193 00194 // 00195 // return the packet leader and FALSE to indicate no resend is needed. 00196 // 00197 00198 if ( Input == PACKET_LEADER_BYTE ) { 00199 *PacketLeader = PACKET_LEADER; 00200 } else { 00201 *PacketLeader = CONTROL_PACKET_LEADER; 00202 } 00203 00204 KdDebuggerNotPresent = FALSE; 00205 return KDP_PACKET_RECEIVED; 00206 }

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

Definition at line 2351 of file kdapi.c.

02359 : 02360 02361 This routine sends an exception state change packet to the kernel 02362 debugger and waits for a manipulate state message. 02363 02364 Arguments: 02365 02366 ExceptionRecord - Supplies a pointer to an exception record. 02367 02368 ContextRecord - Supplies a pointer to a context record. 02369 02370 SecondChance - Supplies a boolean value that determines whether this is 02371 the first or second chance for the exception. 02372 02373 Return Value: 02374 02375 A value of TRUE is returned if the exception is handled. Otherwise, a 02376 value of FALSE is returned. 02377 02378 --*/ 02379 02380 { 02381 STRING MessageData; 02382 STRING MessageHeader; 02383 DBGKD_WAIT_STATE_CHANGE WaitStateChange; 02384 KCONTINUE_STATUS Status; 02385 02386 #if i386 02387 if (KdpCheckTracePoint(ExceptionRecord,ContextRecord)) return TRUE; 02388 #endif 02389 02390 do { 02391 02392 // 02393 // Construct the wait state change message and message descriptor. 02394 // 02395 02396 KdpSetStateChange(&WaitStateChange, 02397 ExceptionRecord, 02398 ContextRecord, 02399 SecondChance 02400 ); 02401 02402 MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE); 02403 MessageHeader.Buffer = (PCHAR)&WaitStateChange; 02404 02405 #if i386 02406 // 02407 // Construct the wait state change data and data descriptor. 02408 // 02409 02410 DumpTraceData(&MessageData); 02411 #else 02412 MessageData.Length = 0; 02413 #endif 02414 02415 // 02416 // Send packet to the kernel debugger on the host machine, 02417 // wait for answer. 02418 // 02419 02420 Status = KdpSendWaitContinue( 02421 PACKET_TYPE_KD_STATE_CHANGE, 02422 &MessageHeader, 02423 &MessageData, 02424 ContextRecord 02425 ); 02426 02427 } while (Status == ContinueProcessorReselected) ; 02428 02429 return (BOOLEAN) Status; 02430 }

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

Definition at line 2434 of file kdapi.c.

02443 : 02444 02445 This routine sends a load symbols state change packet to the kernel 02446 debugger and waits for a manipulate state message. 02447 02448 Arguments: 02449 02450 PathName - Supplies a pointer to the pathname of the image whose 02451 symbols are to be loaded. 02452 02453 BaseOfDll - Supplies the base address where the image was loaded. 02454 02455 ProcessId - Unique 32-bit identifier for process that is using 02456 the symbols. -1 for system process. 02457 02458 CheckSum - Unique 32-bit identifier from image header. 02459 02460 UnloadSymbol - TRUE if the symbols that were previously loaded for 02461 the named image are to be unloaded from the debugger. 02462 02463 Return Value: 02464 02465 A value of TRUE is returned if the exception is handled. Otherwise, a 02466 value of FALSE is returned. 02467 02468 --*/ 02469 02470 { 02471 02472 PSTRING AdditionalData; 02473 STRING MessageData; 02474 STRING MessageHeader; 02475 DBGKD_WAIT_STATE_CHANGE WaitStateChange; 02476 KCONTINUE_STATUS Status; 02477 02478 do { 02479 // 02480 // Construct the wait state change message and message descriptor. 02481 // 02482 02483 WaitStateChange.NewState = DbgKdLoadSymbolsStateChange; 02484 WaitStateChange.ProcessorLevel = KeProcessorLevel; 02485 WaitStateChange.Processor = (USHORT)KeGetCurrentPrcb()->Number; 02486 WaitStateChange.NumberProcessors = (ULONG)KeNumberProcessors; 02487 WaitStateChange.Thread = (PVOID)KeGetCurrentThread(); 02488 WaitStateChange.ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 02489 KdpSetLoadState(&WaitStateChange, ContextRecord); 02490 WaitStateChange.u.LoadSymbols.UnloadSymbols = UnloadSymbols; 02491 WaitStateChange.u.LoadSymbols.BaseOfDll = SymbolInfo->BaseOfDll; 02492 WaitStateChange.u.LoadSymbols.ProcessId = (ULONG)SymbolInfo->ProcessId; 02493 WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum; 02494 WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage; 02495 if (ARGUMENT_PRESENT( PathName )) { 02496 WaitStateChange.u.LoadSymbols.PathNameLength = 02497 KdpMoveMemory( 02498 (PCHAR)KdpPathBuffer, 02499 (PCHAR)PathName->Buffer, 02500 PathName->Length 02501 ) + 1; 02502 02503 MessageData.Buffer = KdpPathBuffer; 02504 MessageData.Length = (USHORT)WaitStateChange.u.LoadSymbols.PathNameLength; 02505 MessageData.Buffer[MessageData.Length-1] = '\0'; 02506 AdditionalData = &MessageData; 02507 } else { 02508 WaitStateChange.u.LoadSymbols.PathNameLength = 0; 02509 AdditionalData = NULL; 02510 } 02511 02512 MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE); 02513 MessageHeader.Buffer = (PCHAR)&WaitStateChange; 02514 02515 // 02516 // Send packet to the kernel debugger on the host machine, wait 02517 // for the reply. 02518 // 02519 02520 Status = KdpSendWaitContinue( 02521 PACKET_TYPE_KD_STATE_CHANGE, 02522 &MessageHeader, 02523 AdditionalData, 02524 ContextRecord 02525 ); 02526 02527 } while (Status == ContinueProcessorReselected); 02528 02529 return (BOOLEAN) Status; 02530 }

VOID KdpRestoreAllBreakpoints VOID   ) 
 

Definition at line 1309 of file kdbreak.c.

01312 { 01313 ULONG Index; 01314 01315 BreakpointsSuspended = FALSE; 01316 01317 for ( Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++ ) { 01318 01319 if ((KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 01320 (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) ) { 01321 01322 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_SUSPENDED; 01323 KdpLowRestoreBreakpoint(Index); 01324 } 01325 } 01326 01327 return; 01328 01329 } // KdpRestoreAllBreakpoints

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

Definition at line 1632 of file kdapi.c.

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

01640 : 01641 01642 This function is called in response of a restore breakpoint state 01643 manipulation message. Its function is to restore a breakpoint 01644 using the specified handle. 01645 01646 Arguments: 01647 01648 m - Supplies the state manipulation message. 01649 01650 AdditionalData - Supplies any additional data for the message. 01651 01652 Context - Supplies the current context. 01653 01654 Return Value: 01655 01656 None. 01657 01658 --*/ 01659 01660 { 01661 PDBGKD_RESTORE_BREAKPOINT a = &m->u.RestoreBreakPoint; 01662 STRING MessageHeader; 01663 01664 MessageHeader.Length = sizeof(*m); 01665 MessageHeader.Buffer = (PCHAR)m; 01666 01667 ASSERT(AdditionalData->Length == 0); 01668 if (KdpDeleteBreakpoint(a->BreakPointHandle)) { 01669 m->ReturnStatus = STATUS_SUCCESS; 01670 } else { 01671 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01672 } 01673 KdpSendPacket( 01674 PACKET_TYPE_KD_STATE_MANIPULATE, 01675 &MessageHeader, 01676 NULL 01677 ); 01678 UNREFERENCED_PARAMETER(Context); 01679 }

VOID KdpSendPacket IN ULONG  PacketType,
IN PSTRING  MessageHeader,
IN PSTRING MessageData  OPTIONAL
 

Definition at line 683 of file kdcomio.c.

00691 : 00692 00693 This routine sends a packet to the host machine that is running the 00694 kernel debugger and waits for an ACK. 00695 00696 Arguments: 00697 00698 PacketType - Supplies the type of packet to send. 00699 00700 MessageHeader - Supplies a pointer to a string descriptor that describes 00701 the message information. 00702 00703 MessageData - Supplies a pointer to a string descriptor that describes 00704 the optional message data. 00705 00706 Return Value: 00707 00708 None. 00709 00710 --*/ 00711 00712 { 00713 00714 KD_PACKET PacketHeader; 00715 ULONG MessageDataLength; 00716 ULONG ReturnCode; 00717 PDBGKD_DEBUG_IO DebugIo; 00718 PDBGKD_WAIT_STATE_CHANGE StateChange; 00719 00720 if ( ARGUMENT_PRESENT(MessageData) ) { 00721 MessageDataLength = MessageData->Length; 00722 PacketHeader.Checksum = KdpComputeChecksum( 00723 MessageData->Buffer, 00724 MessageData->Length 00725 ); 00726 } else { 00727 MessageDataLength = 0; 00728 PacketHeader.Checksum = 0; 00729 } 00730 00731 PacketHeader.Checksum += KdpComputeChecksum ( 00732 MessageHeader->Buffer, 00733 MessageHeader->Length 00734 ); 00735 00736 // 00737 // Initialize and send the packet header. 00738 // 00739 00740 PacketHeader.PacketLeader = PACKET_LEADER; 00741 PacketHeader.ByteCount = (USHORT)(MessageHeader->Length + MessageDataLength); 00742 PacketHeader.PacketType = (USHORT)PacketType; 00743 KdpNumberRetries = KdpRetryCount; 00744 do { 00745 if (KdpNumberRetries == 0) { 00746 00747 // 00748 // If the packet is not for reporting exception, we give up 00749 // and declare debugger not present. 00750 // 00751 00752 if (PacketType == PACKET_TYPE_KD_DEBUG_IO) { 00753 DebugIo = (PDBGKD_DEBUG_IO)MessageHeader->Buffer; 00754 if (DebugIo->ApiNumber == DbgKdPrintStringApi) { 00755 KdDebuggerNotPresent = TRUE; 00756 KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID; 00757 KdpPacketIdExpected = INITIAL_PACKET_ID; 00758 return; 00759 } 00760 } else if (PacketType == PACKET_TYPE_KD_STATE_CHANGE) { 00761 StateChange = (PDBGKD_WAIT_STATE_CHANGE)MessageHeader->Buffer; 00762 if (StateChange->NewState == DbgKdLoadSymbolsStateChange) { 00763 KdDebuggerNotPresent = TRUE; 00764 KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID; 00765 KdpPacketIdExpected = INITIAL_PACKET_ID; 00766 return; 00767 } 00768 } 00769 } 00770 00771 // 00772 // Setting PacketId has to be in the do loop in case Packet Id was 00773 // reset. 00774 // 00775 00776 PacketHeader.PacketId = KdpNextPacketIdToSend; 00777 KdpSendString((PCHAR)&PacketHeader, sizeof(KD_PACKET)); 00778 00779 // 00780 // Output message header. 00781 // 00782 00783 KdpSendString(MessageHeader->Buffer, MessageHeader->Length); 00784 00785 // 00786 // Output message data. 00787 // 00788 00789 if ( MessageDataLength ) { 00790 KdpSendString(MessageData->Buffer, MessageData->Length); 00791 } 00792 00793 // 00794 // Output a packet trailing byte 00795 // 00796 00797 KdPortPutByte(PACKET_TRAILING_BYTE); 00798 00799 // 00800 // Wait for the Ack Packet 00801 // 00802 00803 ReturnCode = KdpReceivePacket( 00804 PACKET_TYPE_KD_ACKNOWLEDGE, 00805 NULL, 00806 NULL, 00807 NULL 00808 ); 00809 if (ReturnCode == KDP_PACKET_TIMEOUT) { 00810 KdpNumberRetries--; 00811 } 00812 } while (ReturnCode != KDP_PACKET_RECEIVED); 00813 00814 // 00815 // Reset Sync bit in packet id. The packet we sent may have Sync bit set 00816 // 00817 00818 KdpNextPacketIdToSend &= ~SYNC_PACKET_ID; 00819 00820 // 00821 // Since we are able to talk to debugger, the retrycount is set to 00822 // maximum value. 00823 // 00824 00825 KdpRetryCount = MAXIMUM_RETRIES; 00826 } }

KCONTINUE_STATUS KdpSendWaitContinue IN ULONG  PacketType,
IN PSTRING  MessageHeader,
IN PSTRING MessageData  OPTIONAL,
IN OUT PCONTEXT  ContextRecord
 

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

Definition at line 1521 of file kdapi.c.

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

01529 : 01530 01531 This function is called in response of a set context state 01532 manipulation message. Its function is set the current 01533 context. 01534 01535 Arguments: 01536 01537 m - Supplies the state manipulation message. 01538 01539 AdditionalData - Supplies any additional data for the message. 01540 01541 Context - Supplies the current context. 01542 01543 Return Value: 01544 01545 None. 01546 01547 --*/ 01548 01549 { 01550 PDBGKD_SET_CONTEXT a = &m->u.SetContext; 01551 STRING MessageHeader; 01552 01553 MessageHeader.Length = sizeof(*m); 01554 MessageHeader.Buffer = (PCHAR)m; 01555 01556 ASSERT(AdditionalData->Length == sizeof(CONTEXT)); 01557 01558 if (m->Processor >= (USHORT)KeNumberProcessors) { 01559 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01560 } else { 01561 m->ReturnStatus = STATUS_SUCCESS; 01562 if (m->Processor == (USHORT)KeGetCurrentPrcb()->Number) { 01563 KdpQuickMoveMemory((PCHAR)Context, AdditionalData->Buffer, sizeof(CONTEXT)); 01564 } else { 01565 KdpQuickMoveMemory((PCHAR)&KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame, 01566 AdditionalData->Buffer, 01567 sizeof(CONTEXT) 01568 ); 01569 } 01570 } 01571 01572 KdpSendPacket( 01573 PACKET_TYPE_KD_STATE_MANIPULATE, 01574 &MessageHeader, 01575 NULL 01576 ); 01577 }

VOID KdpSetLoadState IN PDBGKD_WAIT_STATE_CHANGE  WaitStateChange,
IN PCONTEXT  ContextRecord
 

Definition at line 36 of file alpha/kdcpuapi.c.

References Count, End, FALSE, KdpDeleteBreakpointRange(), KdpMoveMemory(), and USHORT.

00043 : 00044 00045 Fill in the Wait_State_Change message record for the load symbol case. 00046 00047 Arguments: 00048 00049 WaitStateChange - Supplies pointer to record to fill in 00050 00051 ContextRecord - Supplies a pointer to a context record. 00052 00053 Return Value: 00054 00055 None. 00056 00057 --*/ 00058 00059 { 00060 00061 ULONG Count; 00062 PVOID End; 00063 00064 // 00065 // Copy the immediate instruction stream into the control report structure. 00066 // 00067 00068 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00069 WaitStateChange->ProgramCounter, 00070 DBGKD_MAXSTREAM); 00071 00072 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00073 00074 // 00075 // Clear breakpoints in the copied instruction stream. If any breakpoints 00076 // are clear, then recopy the instruction strasm. 00077 // 00078 00079 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00080 if (KdpDeleteBreakpointRange(WaitStateChange->ProgramCounter, End) != FALSE) { 00081 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00082 WaitStateChange->ProgramCounter, 00083 Count); 00084 } 00085 00086 // 00087 // Copy the context record into the wait state structure. 00088 // 00089 00090 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00091 (PCHAR)ContextRecord, 00092 sizeof(*ContextRecord)); 00093 00094 return; 00095 }

VOID KdpSetStateChange IN PDBGKD_WAIT_STATE_CHANGE  WaitStateChange,
IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  ContextRecord,
IN BOOLEAN  SecondChance
 

Definition at line 98 of file alpha/kdcpuapi.c.

References Count, End, FALSE, KdpDeleteBreakpointRange(), KdpGetCurrentPrcb(), KdpGetCurrentThread(), KdpMoveMemory(), KdpQuickMoveMemory(), KeNumberProcessors, KeProcessorLevel, and USHORT.

00107 : 00108 00109 Fill in the Wait_State_Change message record. 00110 00111 Arguments: 00112 00113 WaitStateChange - Supplies pointer to record to fill in 00114 00115 ExceptionRecord - Supplies a pointer to an exception record. 00116 00117 ContextRecord - Supplies a pointer to a context record. 00118 00119 SecondChance - Supplies a boolean value that determines whether this is 00120 the first or second chance for the exception. 00121 00122 Return Value: 00123 00124 None. 00125 00126 --*/ 00127 00128 { 00129 00130 ULONG Count; 00131 PVOID End; 00132 00133 // 00134 // Set up description of event, including exception record 00135 // 00136 00137 WaitStateChange->NewState = DbgKdExceptionStateChange; 00138 WaitStateChange->ProcessorLevel = KeProcessorLevel; 00139 WaitStateChange->Processor = (USHORT)KdpGetCurrentPrcb()->Number; 00140 WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; 00141 WaitStateChange->Thread = (PVOID)KdpGetCurrentThread(); 00142 WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 00143 KdpQuickMoveMemory((PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, 00144 (PCHAR)ExceptionRecord, 00145 sizeof(EXCEPTION_RECORD)); 00146 00147 WaitStateChange->u.Exception.FirstChance = !SecondChance; 00148 00149 // 00150 // Copy the immediate instruction stream into the control report structure. 00151 // 00152 00153 Count = KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00154 WaitStateChange->ProgramCounter, 00155 DBGKD_MAXSTREAM); 00156 00157 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00158 00159 // 00160 // Clear breakpoints in the copied instruction stream. If any breakpoints 00161 // are clear, then recopy the instruction strasm. 00162 // 00163 00164 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00165 if (KdpDeleteBreakpointRange(WaitStateChange->ProgramCounter, End) != FALSE) { 00166 KdpMoveMemory(&WaitStateChange->ControlReport.InstructionStream[0], 00167 WaitStateChange->ProgramCounter, 00168 Count); 00169 } 00170 00171 // 00172 // Copy the context record into the wait state structure. 00173 // 00174 00175 KdpMoveMemory((PCHAR)&WaitStateChange->Context, 00176 (PCHAR)ContextRecord, 00177 sizeof(*ContextRecord)); 00178 00179 return; 00180 }

BOOLEAN KdpStub IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  ContextRecord,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  SecondChance
 

Definition at line 386 of file alpha/kdtrap.c.

00397 : 00398 00399 This routine provides a kernel debugger stub routine that catchs debug 00400 prints in checked systems when the kernel debugger is not active. 00401 00402 Arguments: 00403 00404 TrapFrame - Supplies a pointer to a trap frame that describes the 00405 trap. 00406 00407 ExceptionFrame - Supplies a pointer to a exception frame that describes 00408 the trap. 00409 00410 ExceptionRecord - Supplies a pointer to an exception record that 00411 describes the exception. 00412 00413 ContextRecord - Supplies the context at the time of the exception. 00414 00415 PreviousMode - Supplies the previous processor mode. 00416 00417 SecondChance - Supplies a boolean value that determines whether this is 00418 the second chance (TRUE) that the exception has been raised. 00419 00420 Return Value: 00421 00422 A value of TRUE is returned if the exception is handled. Otherwise a 00423 value of FALSE is returned. 00424 00425 --*/ 00426 00427 { 00428 00429 ULONG_PTR BreakpointCode; 00430 00431 // 00432 // Isolate the breakpoint code from the breakpoint instruction which 00433 // is stored by the exception dispatch code in the information field 00434 // of the exception record. 00435 // 00436 00437 BreakpointCode = ExceptionRecord->ExceptionInformation[0]; 00438 00439 // 00440 // If the breakpoint is a debug print, debug load symbols, or debug 00441 // unload symbols, then return TRUE. Otherwise, return FALSE; 00442 // 00443 00444 if ((BreakpointCode == DEBUG_PRINT_BREAKPOINT) || 00445 (BreakpointCode == DEBUG_LOAD_SYMBOLS_BREAKPOINT) || 00446 (BreakpointCode == DEBUG_UNLOAD_SYMBOLS_BREAKPOINT) || 00447 (BreakpointCode == KERNEL_BREAKPOINT)) { 00448 ContextRecord->Fir += 4; 00449 return TRUE; 00450 } else { 00451 if ( (BreakpointCode == DEBUG_STOP_BREAKPOINT) && 00452 (PreviousMode == KernelMode) ){ 00453 ContextRecord->Fir += 4; 00454 return TRUE; 00455 } else { 00456 return FALSE; 00457 } 00458 } 00459 } }

VOID KdpSuspendAllBreakpoints VOID   ) 
 

Definition at line 972 of file kdbreak.c.

00975 { 00976 ULONG Handle; 00977 00978 BreakpointsSuspended = TRUE; 00979 00980 for ( Handle = 1; Handle <= BREAKPOINT_TABLE_SIZE; Handle++ ) { 00981 KdpSuspendBreakpoint(Handle); 00982 } 00983 00984 return; 00985 00986 } // KdpSuspendAllBreakpoints

VOID KdpSuspendBreakpoint ULONG  Handle  ) 
 

Definition at line 954 of file kdbreak.c.

00957 { 00958 ULONG Index = Handle - 1; 00959 00960 if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 00961 !(KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) ) { 00962 00963 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_SUSPENDED; 00964 KdpLowWriteContent(Index); 00965 } 00966 00967 return; 00968 00969 } // KdpSuspendBreakpoint

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

Definition at line 2318 of file kdapi.c.

02323 { 02324 BOOLEAN Status; 02325 02326 // 02327 // Save port state 02328 // 02329 02330 KdPortSave (); 02331 02332 // 02333 // Process state change for this processor 02334 // 02335 02336 Status = KdpReportExceptionStateChange ( 02337 ExceptionRecord, 02338 ContextRecord, 02339 SecondChance 02340 ); 02341 02342 // 02343 // Restore port state and return status 02344 // 02345 02346 KdPortRestore (); 02347 return Status; 02348 }

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

Definition at line 494 of file kdapi.c.

00500 { 00501 LONG OldCount, NewCount, j; 00502 00503 // 00504 // Reset pending count. If the current count is 1, then clear 00505 // the pending count. if the current count is greater then 1, 00506 // then set to one and update the time now. 00507 // 00508 00509 j = KdpTimeSlipPending; 00510 do { 00511 OldCount = j; 00512 NewCount = OldCount > 1 ? 1 : 0; 00513 00514 j = InterlockedCompareExchange(&KdpTimeSlipPending, NewCount, OldCount); 00515 00516 } while (j != OldCount); 00517 00518 // 00519 // If new count is non-zero, then process a time slip now 00520 // 00521 00522 if (NewCount) { 00523 ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue); 00524 } 00525 }

VOID KdpTimeSlipWork IN PVOID  Context  ) 
 

Definition at line 528 of file kdapi.c.

00531 { 00532 KIRQL OldIrql; 00533 LARGE_INTEGER DueTime; 00534 00535 // 00536 // Update time from the real time clock 00537 // 00538 00539 ExAcquireTimeRefreshLock(); 00540 ExUpdateSystemTimeFromCmos (FALSE, 0); 00541 ExReleaseTimeRefreshLock(); 00542 00543 // 00544 // If there's a time service installed, signal it's time slip event 00545 // 00546 00547 KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql); 00548 if (KdpTimeSlipEvent) { 00549 KeSetEvent (KdpTimeSlipEvent, 0, FALSE); 00550 } 00551 KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql); 00552 00553 // 00554 // Insert a forced delay between time slip operations 00555 // 00556 00557 DueTime.QuadPart = -1800000000; 00558 KeSetTimer (&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc); 00559 }

BOOLEAN KdpTrap IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  ContextRecord,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  SecondChance
 

Definition at line 28 of file alpha/kdtrap.c.

00039 : 00040 00041 This routine is called whenever a exception is dispatched and the kernel 00042 debugger is active. 00043 00044 Arguments: 00045 00046 TrapFrame - Supplies a pointer to a trap frame that describes the 00047 trap. 00048 00049 ExceptionFrame - Supplies a pointer to a exception frame that describes 00050 the trap. 00051 00052 ExceptionRecord - Supplies a pointer to an exception record that 00053 describes the exception. 00054 00055 ContextRecord - Supplies the context at the time of the exception. 00056 00057 PreviousMode - Supplies the previous processor mode. 00058 00059 SecondChance - Supplies a boolean value that determines whether this is 00060 the second chance (TRUE) that the exception has been raised. 00061 00062 Return Value: 00063 00064 A value of TRUE is returned if the exception is handled. Otherwise a 00065 value of FALSE is returned. 00066 00067 --*/ 00068 00069 { 00070 00071 BOOLEAN Completion; 00072 BOOLEAN Enable; 00073 BOOLEAN UnloadSymbols = FALSE; 00074 STRING Input; 00075 ULONGLONG OldFir; 00076 STRING Output; 00077 PKPRCB Prcb; 00078 00079 // 00080 // Enter debugger and synchronize processor execution. 00081 // 00082 00083 // 00084 // If this is a breakpoint instruction, then check to determine if is 00085 // an internal command. 00086 // 00087 00088 if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && 00089 (ExceptionRecord->ExceptionInformation[0] >= DEBUG_PRINT_BREAKPOINT)){ 00090 00091 // 00092 // Switch on the breakpoint code. 00093 // 00094 00095 switch (ExceptionRecord->ExceptionInformation[0]) { 00096 00097 // 00098 // Print a debug string. 00099 // 00100 // Arguments: 00101 // 00102 // a0 - Supplies a pointer to an output string buffer. 00103 // a1 - Supplies the length of the output string buffer. 00104 // 00105 00106 case DEBUG_PRINT_BREAKPOINT: 00107 ContextRecord->Fir += 4; 00108 Output.Buffer = (PCHAR)ContextRecord->IntA0; 00109 Output.Length = (USHORT)ContextRecord->IntA1; 00110 00111 KdLogDbgPrint(&Output); 00112 00113 if (KdDebuggerNotPresent == FALSE) { 00114 00115 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00116 if (KdpPrintString(&Output)) { 00117 ContextRecord->IntV0 = (ULONG)STATUS_BREAKPOINT; 00118 } else { 00119 ContextRecord->IntV0 = (ULONG)STATUS_SUCCESS; 00120 } 00121 KdExitDebugger(Enable); 00122 00123 } else { 00124 ContextRecord->IntV0 = (ULONG)STATUS_DEVICE_NOT_CONNECTED; 00125 } 00126 00127 return TRUE; 00128 00129 00130 // 00131 // Stop in the debugger 00132 // 00133 // As this is not a normal breakpoint we must increment the 00134 // context past the breakpoint instruction 00135 // 00136 00137 case BREAKIN_BREAKPOINT: 00138 ContextRecord->Fir += 4; 00139 break; 00140 00141 // 00142 // Print a debug prompt string, then input a string. 00143 // 00144 // a0 - Supplies a pointer to an output string buffer. 00145 // a1 - Supplies the length of the output string buffer.. 00146 // a2 - supplies a pointer to an input string buffer. 00147 // a3 - Supplies the length of the input string bufffer. 00148 // 00149 00150 case DEBUG_PROMPT_BREAKPOINT: 00151 ContextRecord->Fir += 4; 00152 Output.Buffer = (PCHAR)ContextRecord->IntA0; 00153 Output.Length = (USHORT)ContextRecord->IntA1; 00154 Input.Buffer = (PCHAR)ContextRecord->IntA2; 00155 Input.MaximumLength = (USHORT)ContextRecord->IntA3; 00156 00157 KdLogDbgPrint(&Output); 00158 00159 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00160 00161 KdpPromptString(&Output, &Input); 00162 00163 ContextRecord->IntV0 = Input.Length; 00164 00165 KdExitDebugger(Enable); 00166 return TRUE; 00167 00168 // 00169 // Load the symbolic information for an image. 00170 // 00171 // Arguments: 00172 // 00173 // a0 - Supplies a pointer to an output string descriptor. 00174 // a1 - Supplies a the base address of the image. 00175 // a2 - Supplies the current process id. 00176 // 00177 00178 case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT: 00179 UnloadSymbols = TRUE; 00180 00181 // 00182 // Fall through 00183 // 00184 00185 case DEBUG_LOAD_SYMBOLS_BREAKPOINT: 00186 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00187 Prcb = KeGetCurrentPrcb(); 00188 OldFir = ContextRecord->Fir; 00189 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, 00190 ContextRecord, 00191 sizeof(CONTEXT)); 00192 00193 if (KdDebuggerNotPresent == FALSE) { 00194 KdpReportLoadSymbolsStateChange((PSTRING)ContextRecord->IntA0, 00195 (PKD_SYMBOLS_INFO) ContextRecord->IntA1, 00196 UnloadSymbols, 00197 &Prcb->ProcessorState.ContextFrame); 00198 00199 } 00200 00201 RtlCopyMemory(ContextRecord, 00202 &Prcb->ProcessorState.ContextFrame, 00203 sizeof(CONTEXT)); 00204 00205 KdExitDebugger(Enable); 00206 00207 // 00208 // If the kernel debugger did not update the FIR, then increment 00209 // past the breakpoint instruction. 00210 // 00211 00212 if (ContextRecord->Fir == OldFir) { 00213 ContextRecord->Fir += 4; 00214 } 00215 00216 return TRUE; 00217 00218 // 00219 // Unknown internal command. 00220 // 00221 00222 default: 00223 break; 00224 } 00225 } 00226 00227 // 00228 // Report state change to kernel debugger on host machine. 00229 // 00230 00231 Enable = KdEnterDebugger(TrapFrame, ExceptionFrame); 00232 Prcb = KeGetCurrentPrcb(); 00233 00234 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, 00235 ContextRecord, 00236 sizeof (CONTEXT)); 00237 00238 Completion = KdpReportExceptionStateChange(ExceptionRecord, 00239 &Prcb->ProcessorState.ContextFrame, 00240 SecondChance); 00241 00242 RtlCopyMemory(ContextRecord, 00243 &Prcb->ProcessorState.ContextFrame, 00244 sizeof(CONTEXT)); 00245 00246 KdExitDebugger(Enable); 00247 00248 KdpControlCPressed = FALSE; 00249 00250 // 00251 // Always return TRUE if this is the first chance to handle the 00252 // exception. Otherwise, return the completion status of the 00253 // state change reporting. 00254 // 00255 00256 if( SecondChance ){ 00257 return Completion; 00258 } else { 00259 return TRUE; 00260 } 00261 }

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

Definition at line 1580 of file kdapi.c.

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

01588 : 01589 01590 This function is called in response of a write breakpoint state 01591 manipulation message. Its function is to write a breakpoint 01592 and return a handle to the breakpoint. 01593 01594 Arguments: 01595 01596 m - Supplies the state manipulation message. 01597 01598 AdditionalData - Supplies any additional data for the message. 01599 01600 Context - Supplies the current context. 01601 01602 Return Value: 01603 01604 None. 01605 01606 --*/ 01607 01608 { 01609 PDBGKD_WRITE_BREAKPOINT a = &m->u.WriteBreakPoint; 01610 STRING MessageHeader; 01611 01612 MessageHeader.Length = sizeof(*m); 01613 MessageHeader.Buffer = (PCHAR)m; 01614 01615 ASSERT(AdditionalData->Length == 0); 01616 01617 a->BreakPointHandle = KdpAddBreakpoint(a->BreakPointAddress); 01618 if (a->BreakPointHandle != 0) { 01619 m->ReturnStatus = STATUS_SUCCESS; 01620 } else { 01621 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01622 } 01623 KdpSendPacket( 01624 PACKET_TYPE_KD_STATE_MANIPULATE, 01625 &MessageHeader, 01626 NULL 01627 ); 01628 UNREFERENCED_PARAMETER(Context); 01629 }

VOID KdpWriteComPacket USHORT  ,
USHORT  ,
PVOID  ,
PVOID  ,
PVOID 
 

VOID KdpWriteControlSpace IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 451 of file alpha/kdcpuapi.c.

References KdpSendPacket().

00459 : 00460 00461 This function is called in response of a write control space state 00462 manipulation message. Its function is to write implementation 00463 specific system data. 00464 00465 Arguments: 00466 00467 m - Supplies the state manipulation message. 00468 00469 AdditionalData - Supplies any additional data for the message. 00470 00471 Context - Supplies the current context. 00472 00473 Return Value: 00474 00475 None. 00476 00477 --*/ 00478 00479 { 00480 PDBGKD_WRITE_MEMORY a = &m->u.WriteMemory; 00481 ULONG Length; 00482 STRING MessageHeader; 00483 00484 MessageHeader.Length = sizeof(*m); 00485 MessageHeader.Buffer = (PCHAR)m; 00486 00487 AdditionalData->Length = 0; 00488 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00489 a->ActualBytesWritten = 0; 00490 00491 KdpSendPacket( 00492 PACKET_TYPE_KD_STATE_MANIPULATE, 00493 &MessageHeader, 00494 AdditionalData 00495 ); 00496 }

VOID KdpWriteIoSpace IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 779 of file alpha/kdcpuapi.c.

References ASSERT, BusNumber, HalTranslateBusAddress(), InterfaceType, KdpSendPacket(), NULL, PUSHORT, and USHORT.

00787 : 00788 00789 This function is called in response of a read io space state 00790 manipulation message. Its function is to read system io 00791 locations. 00792 00793 Arguments: 00794 00795 m - Supplies the state manipulation message. 00796 00797 AdditionalData - Supplies any additional data for the message. 00798 00799 Context - Supplies the current context. 00800 00801 Return Value: 00802 00803 None. 00804 00805 --*/ 00806 00807 { 00808 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00809 STRING MessageHeader; 00810 INTERFACE_TYPE InterfaceType; 00811 ULONG BusNumber; 00812 PHYSICAL_ADDRESS IoAddress; 00813 PHYSICAL_ADDRESS TranslatedAddress; 00814 ULONG AddressSpace; 00815 ULONG DataSize; 00816 ULONG Value; 00817 00818 MessageHeader.Length = sizeof(*m); 00819 MessageHeader.Buffer = (PCHAR)m; 00820 00821 ASSERT(AdditionalData->Length == 0); 00822 00823 m->ReturnStatus = STATUS_SUCCESS; 00824 00825 // 00826 // Capture the input parameters and use the default values for those 00827 // parameters not specified in the Api. 00828 // 00829 00830 InterfaceType = Isa; 00831 BusNumber = 0; 00832 AddressSpace = 1; 00833 IoAddress.QuadPart = (ULONG_PTR)a->IoAddress; 00834 DataSize = a->DataSize; 00835 Value = a->DataValue; 00836 00837 // 00838 // Translate the bus address to the physical system address 00839 // or QVA. 00840 // 00841 00842 if( !HalTranslateBusAddress( InterfaceType, 00843 BusNumber, 00844 IoAddress, 00845 &AddressSpace, 00846 &TranslatedAddress ) ){ 00847 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00848 goto SendWriteIoSpaceResponse; 00849 } 00850 00851 // 00852 // N.B. - for the moment we will only support QVAs ie. when AddressSpace 00853 // is one. It may be in later systems that we will have to 00854 // check the address space, map it, perform the virtual read 00855 // unmap, and then return the data - only we will have to be 00856 // careful about what Irql we are to make sure the memory mgmt 00857 // stuff will all work 00858 // 00859 00860 if( !AddressSpace ){ 00861 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00862 goto SendWriteIoSpaceResponse; 00863 } 00864 00865 // 00866 // Do the IO space read using the appropriate HAL routines based upon 00867 // the default address space (io) and the data size requested. 00868 // 00869 00870 switch( DataSize ){ 00871 00872 case 1: 00873 WRITE_PORT_UCHAR( (PUCHAR)TranslatedAddress.QuadPart, (UCHAR)Value ); 00874 break; 00875 00876 case 2: 00877 WRITE_PORT_USHORT( (PUSHORT)TranslatedAddress.QuadPart, (USHORT)Value ); 00878 break; 00879 00880 case 4: 00881 WRITE_PORT_ULONG( (PULONG)TranslatedAddress.QuadPart, Value ); 00882 break; 00883 00884 default: 00885 m->ReturnStatus = STATUS_INVALID_PARAMETER; 00886 } 00887 00888 00889 SendWriteIoSpaceResponse: 00890 00891 KdpSendPacket( 00892 PACKET_TYPE_KD_STATE_MANIPULATE, 00893 &MessageHeader, 00894 NULL 00895 ); 00896 }

VOID KdpWriteMachineSpecificRegister IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1153 of file i386/kdcpuapi.c.

References ASSERT, EXCEPTION_EXECUTE_HANDLER, KdpSendPacket(), NULL, and WRMSR().

01161 : 01162 01163 This function is called in response of a write of a MSR 01164 manipulation message. Its function is to write to the MSR 01165 01166 Arguments: 01167 01168 m - Supplies the state manipulation message. 01169 01170 AdditionalData - Supplies any additional data for the message. 01171 01172 Context - Supplies the current context. 01173 01174 Return Value: 01175 01176 None. 01177 01178 --*/ 01179 01180 { 01181 PDBGKD_READ_WRITE_MSR a = &m->u.ReadWriteMsr; 01182 STRING MessageHeader; 01183 LARGE_INTEGER l; 01184 01185 MessageHeader.Length = sizeof(*m); 01186 MessageHeader.Buffer = (PCHAR)m; 01187 01188 ASSERT(AdditionalData->Length == 0); 01189 01190 m->ReturnStatus = STATUS_SUCCESS; 01191 01192 l.HighPart = a->DataValueHigh; 01193 l.LowPart = a->DataValueLow; 01194 01195 try { 01196 WRMSR (a->Msr, l.QuadPart); 01197 } except (EXCEPTION_EXECUTE_HANDLER) { 01198 m->ReturnStatus = STATUS_NO_SUCH_DEVICE; 01199 } 01200 01201 KdpSendPacket( 01202 PACKET_TYPE_KD_STATE_MANIPULATE, 01203 &MessageHeader, 01204 NULL 01205 ); 01206 UNREFERENCED_PARAMETER(Context); 01207 }

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

Definition at line 2680 of file kdapi.c.

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

02688 : 02689 02690 This function is called in response to a write physical memory 02691 state manipulation message. Its function is to write physical memory 02692 and return. 02693 02694 Arguments: 02695 02696 m - Supplies the state manipulation message. 02697 02698 AdditionalData - Supplies any additional data for the message. 02699 02700 Context - Supplies the current context. 02701 02702 Return Value: 02703 02704 None. 02705 02706 --*/ 02707 02708 { 02709 PDBGKD_WRITE_MEMORY a = &m->u.WriteMemory; 02710 ULONG Length; 02711 STRING MessageHeader; 02712 PVOID VirtualAddress; 02713 PHYSICAL_ADDRESS Destination; 02714 PUCHAR Source; 02715 USHORT NumberBytes; 02716 USHORT BytesLeft; 02717 02718 MessageHeader.Length = sizeof(*m); 02719 MessageHeader.Buffer = (PCHAR)m; 02720 02721 02722 // 02723 // Since the MmDbgTranslatePhysicalAddress only maps in one physical 02724 // page at a time, we need to break the memory move up into smaller 02725 // moves which don't cross page boundaries. There are two cases we 02726 // need to deal with. The area to be moved may start and end on the 02727 // same page, or it may start and end on different pages (with an 02728 // arbitrary number of pages in between) 02729 // 02730 Destination.QuadPart = (ULONG_PTR)a->TargetBaseAddress; 02731 Source = AdditionalData->Buffer; 02732 BytesLeft = (USHORT) a->TransferCount; 02733 if(PAGE_ALIGN((PUCHAR)Destination.LowPart) == 02734 PAGE_ALIGN((PUCHAR)(Destination.LowPart)+BytesLeft)) { 02735 // 02736 // Memory move starts and ends on the same page. 02737 // 02738 VirtualAddress=MmDbgTranslatePhysicalAddress(Destination); 02739 Length = (USHORT)KdpMoveMemory( 02740 VirtualAddress, 02741 Source, 02742 BytesLeft 02743 ); 02744 BytesLeft -= (USHORT) Length; 02745 } else { 02746 // 02747 // Memory move spans page boundaries 02748 // 02749 VirtualAddress=MmDbgTranslatePhysicalAddress(Destination); 02750 NumberBytes = (USHORT) (PAGE_SIZE - BYTE_OFFSET(VirtualAddress)); 02751 Length = (USHORT)KdpMoveMemory( 02752 VirtualAddress, 02753 Source, 02754 NumberBytes 02755 ); 02756 Source += NumberBytes; 02757 Destination.LowPart += NumberBytes; 02758 BytesLeft -= NumberBytes; 02759 while(BytesLeft > 0) { 02760 // 02761 // Transfer a full page or the last bit, 02762 // whichever is smaller. 02763 // 02764 VirtualAddress = MmDbgTranslatePhysicalAddress(Destination); 02765 NumberBytes = (USHORT) ((PAGE_SIZE < BytesLeft) ? PAGE_SIZE : BytesLeft); 02766 Length += (USHORT)KdpMoveMemory( 02767 VirtualAddress, 02768 Source, 02769 NumberBytes 02770 ); 02771 Source += NumberBytes; 02772 Destination.LowPart += NumberBytes; 02773 BytesLeft -= NumberBytes; 02774 } 02775 } 02776 02777 02778 if (Length == AdditionalData->Length) { 02779 m->ReturnStatus = STATUS_SUCCESS; 02780 } else { 02781 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02782 } 02783 02784 a->ActualBytesWritten = Length; 02785 02786 KdpSendPacket( 02787 PACKET_TYPE_KD_STATE_MANIPULATE, 02788 &MessageHeader, 02789 NULL 02790 ); 02791 UNREFERENCED_PARAMETER(Context); 02792 }

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

Definition at line 1308 of file kdapi.c.

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

01316 : 01317 01318 This function is called in response of a write virtual memory 32-bit 01319 state manipulation message. Its function is to write virtual memory 01320 and return. 01321 01322 Arguments: 01323 01324 m - Supplies a pointer to the state manipulation message. 01325 01326 AdditionalData - Supplies a pointer to a descriptor for the data to write. 01327 01328 Context - Supplies a pointer to the current context. 01329 01330 Return Value: 01331 01332 None. 01333 01334 --*/ 01335 01336 { 01337 01338 ULONG Length; 01339 STRING MessageHeader; 01340 01341 // 01342 // Move the data to the destination buffer. 01343 // 01344 01345 Length = KdpMoveMemory(m->u.WriteMemory.TargetBaseAddress, 01346 AdditionalData->Buffer, 01347 AdditionalData->Length); 01348 01349 // 01350 // If all the data is written, then return a success status. Otherwise, 01351 // return an unsuccessful status. 01352 // 01353 01354 m->ReturnStatus = STATUS_SUCCESS; 01355 if (Length != AdditionalData->Length) { 01356 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01357 } 01358 01359 // 01360 // Set the actual number of bytes written, initialize the message header, 01361 // and send the reply packet to the host debugger. 01362 // 01363 01364 m->u.WriteMemory.ActualBytesWritten = Length; 01365 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01366 MessageHeader.Buffer = (PCHAR)m; 01367 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01368 &MessageHeader, 01369 NULL); 01370 01371 return; 01372 }

VOID KdpWriteVirtualMemory64 IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1375 of file kdapi.c.

References KdpSendPacket(), MmDbgWriteCheck64(), and NULL.

Referenced by KdpSendWaitContinue().

01383 : 01384 01385 This function is called in response of a write virtual memory 64-bit 01386 state manipulation message. Its function is to write virtual memory 01387 and return. 01388 01389 Arguments: 01390 01391 m - Supplies a pointer to the state manipulation message. 01392 01393 AdditionalData - Supplies a pointer to a descriptor for the data to write. 01394 01395 Context - Supplies a pointer to the current context. 01396 01397 Return Value: 01398 01399 None. 01400 01401 --*/ 01402 01403 { 01404 01405 UCHAR * POINTER_64 Address; 01406 UCHAR * POINTER_64 Destination; 01407 ULONG Length; 01408 STRING MessageHeader; 01409 PUCHAR Source; 01410 ULONG_PTR Opaque; 01411 01412 // 01413 // Move the data to the destination buffer. 01414 // 01415 01416 Length = AdditionalData->Length; 01417 01418 #if defined(_MIPS_) || defined(_ALPHA_) 01419 01420 Destination = (UCHAR * POINTER_64)m->u.WriteMemory64.TargetBaseAddress; 01421 Source = AdditionalData->Buffer; 01422 while (Length > 0) { 01423 if ((Address = MmDbgWriteCheck64(Destination)) == NULL64) { 01424 break; 01425 } 01426 01427 *Address = *Source++; 01428 Destination += 1; 01429 Length -= 1; 01430 } 01431 01432 #endif 01433 01434 // 01435 // If all the data is written, then return a success status. Otherwise, 01436 // return an unsuccessful status. 01437 // 01438 01439 m->ReturnStatus = STATUS_SUCCESS; 01440 if (Length != 0) { 01441 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01442 } 01443 01444 // 01445 // Set the actual number of bytes written, initialize the message header, 01446 // and send the reply packet to the host debugger. 01447 // 01448 01449 m->u.WriteMemory64.ActualBytesWritten = AdditionalData->Length - Length; 01450 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01451 MessageHeader.Buffer = (PCHAR)m; 01452 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01453 &MessageHeader, 01454 NULL); 01455 01456 return; 01457 }

VOID RtlpBreakWithStatusInstruction VOID   ) 
 

Referenced by KdpGetVersion().


Variable Documentation

BOOLEAN BreakpointsSuspended
 

Definition at line 451 of file kdp.h.

LONG CallLevelChange
 

Definition at line 499 of file kdp.h.

ULONG_PTR InitialSP
 

Definition at line 478 of file kdp.h.

BOOLEAN InstrCountInternal
 

Definition at line 501 of file kdp.h.

ULONG InstructionsTraced
 

Definition at line 497 of file kdp.h.

ULONG IntBPsSkipping
 

Definition at line 490 of file kdp.h.

KDPC InternalBreakpointCheckDpc
 

Definition at line 481 of file kdp.h.

KTIMER InternalBreakpointTimer
 

Definition at line 480 of file kdp.h.

KDDEBUGGER_DATA KdDebuggerDataBlock
 

Definition at line 520 of file kdp.h.

DEBUG_PARAMETERS KdDebugParameters
 

Definition at line 517 of file kdp.h.

ULONG KdEnteredDebugger
 

Definition at line 528 of file kdp.h.

ULONG KdNumberOfSpecialCalls
 

Definition at line 477 of file kdp.h.

KDP_BREAKPOINT_TYPE KdpBreakpointInstruction
 

Definition at line 439 of file kdp.h.

BREAKPOINT_ENTRY KdpBreakpointTable[BREAKPOINT_TABLE_SIZE]
 

Definition at line 434 of file kdp.h.

BOOLEAN KdpControlCPending
 

Definition at line 435 of file kdp.h.

BOOLEAN KdpControlCPressed
 

Definition at line 504 of file kdp.h.

ULONG_PTR KdpCurrentSymbolEnd
 

Definition at line 474 of file kdp.h.

ULONG_PTR KdpCurrentSymbolStart
 

Definition at line 473 of file kdp.h.

KSPIN_LOCK KdpDataSpinLock
 

Definition at line 518 of file kdp.h.

LIST_ENTRY KdpDebuggerDataListHead
 

Definition at line 453 of file kdp.h.

KSPIN_LOCK KdpDebuggerLock
 

Definition at line 436 of file kdp.h.

BOOLEAN KdpDebuggerStructuresInitialized
 

Definition at line 527 of file kdp.h.

LARGE_INTEGER KdPerformanceCounterRate
 

Definition at line 446 of file kdp.h.

DBGKD_INTERNAL_BREAKPOINT KdpInternalBPs[DBGKD_MAX_INTERNAL_BREAKPOINTS]
 

Definition at line 471 of file kdp.h.

UCHAR KdpMessageBuffer[KDP_MESSAGE_BUFFER_SIZE]
 

Definition at line 440 of file kdp.h.

LONG KdpNextCallLevelChange
 

Definition at line 475 of file kdp.h.

ULONG KdpNextPacketIdToSend
 

Definition at line 443 of file kdp.h.

PVOID KdpNtosImageBase
 

Definition at line 452 of file kdp.h.

ULONG KdpNumberRetries
 

Definition at line 506 of file kdp.h.

ULONG KdpNumInternalBreakpoints
 

Definition at line 479 of file kdp.h.

ULONG KdpOweBreakpoint
 

Definition at line 442 of file kdp.h.

ULONG KdpPacketIdExpected
 

Definition at line 444 of file kdp.h.

UCHAR KdpPathBuffer[KDP_MESSAGE_BUFFER_SIZE]
 

Definition at line 441 of file kdp.h.

BOOLEAN KdpPortLocked
 

Definition at line 482 of file kdp.h.

KSPIN_LOCK KdpPrintSpinLock
 

Definition at line 516 of file kdp.h.

ULONG KdpRetryCount
 

Definition at line 505 of file kdp.h.

UCHAR KdPrintCircularBuffer[KDPRINTBUFFERSIZE]
 

Definition at line 513 of file kdp.h.

ULONG KdPrintRolloverCount
 

Definition at line 515 of file kdp.h.

PUCHAR KdPrintWritePointer
 

Definition at line 514 of file kdp.h.

LARGE_INTEGER KdpTimeEntered
 

Definition at line 483 of file kdp.h.

KDPC KdpTimeSlipDpc
 

Definition at line 521 of file kdp.h.

PVOID KdpTimeSlipEvent
 

Definition at line 526 of file kdp.h.

KSPIN_LOCK KdpTimeSlipEventLock
 

Definition at line 525 of file kdp.h.

ULONG KdpTimeSlipPending
 

Definition at line 524 of file kdp.h.

KTIMER KdpTimeSlipTimer
 

Definition at line 523 of file kdp.h.

WORK_QUEUE_ITEM KdpTimeSlipWorkItem
 

Definition at line 522 of file kdp.h.

ULONG_PTR KdSpecialCalls[]
 

Definition at line 476 of file kdp.h.

LARGE_INTEGER KdTimerDifference
 

Definition at line 449 of file kdp.h.

LARGE_INTEGER KdTimerStart
 

Definition at line 447 of file kdp.h.

LARGE_INTEGER KdTimerStop
 

Definition at line 448 of file kdp.h.

PKDEBUG_ROUTINE KiDebugRoutine
 

Definition at line 437 of file kdp.h.

Referenced by KdDisableDebugger(), KdInitSystem(), and KiDispatchException().

PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine
 

Definition at line 438 of file kdp.h.

Referenced by KdInitSystem(), and KiFreezeTargetExecution().

UCHAR NextTraceDataSym
 

Definition at line 488 of file kdp.h.

UCHAR NumTraceDataSyms
 

Definition at line 489 of file kdp.h.

LONG oldpc
 

Definition at line 500 of file kdp.h.

BOOLEAN SymbolRecorded
 

Definition at line 498 of file kdp.h.

DBGKD_TRACE_DATA TraceDataBuffer[]
 

Definition at line 485 of file kdp.h.

ULONG TraceDataBufferPosition
 

Definition at line 486 of file kdp.h.

TRACE_DATA_SYM TraceDataSyms[]
 

Definition at line 487 of file kdp.h.

BOOLEAN WatchStepOver
 

Definition at line 491 of file kdp.h.

ULONG_PTR WatchStepOverBreakAddr
 

Definition at line 495 of file kdp.h.

ULONG WatchStepOverHandle
 

Definition at line 494 of file kdp.h.

BOOLEAN WatchStepOverSuspended
 

Definition at line 496 of file kdp.h.

ULONG WSOEsp
 

Definition at line 493 of file kdp.h.

PVOID WSOThread
 

Definition at line 492 of file kdp.h.


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