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

kdcpuapi.c File Reference

#include <stdio.h>
#include "kdp.h"

Go to the source code of this file.

Defines

#define END_OF_CONTROL_SPACE   (sizeof(KPROCESSOR_STATE))

Functions

LONG KdpLevelChange (ULONG Pc, PCONTEXT ContextRecord, PBOOLEAN SpecialCall)
LONG regValue (UCHAR reg, PCONTEXT ContextRecord)
BOOLEAN KdpIsSpecialCall (ULONG Pc, PCONTEXT ContextRecord, UCHAR opcode, UCHAR ModRM)
ULONG KdpGetReturnAddress (PCONTEXT ContextRecord)
ULONG KdpGetCallNextOffset (ULONG Pc, PCONTEXT ContextRecord)
BOOLEAN KdpIsTryFinallyReturn (ULONG Pc, PCONTEXT ContextRecord)
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 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 KdpWriteIoSpace (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 KdpWriteMachineSpecificRegister (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)

Variables

ULONG KdpCurrentSymbolStart
ULONG KdpCurrentSymbolEnd
ULONG KdSpecialCalls []
ULONG KdNumberOfSpecialCalls


Define Documentation

#define END_OF_CONTROL_SPACE   (sizeof(KPROCESSOR_STATE))
 

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

Referenced by KdpReadControlSpace(), and KdpWriteControlSpace().


Function Documentation

ULONG KdpGetCallNextOffset ULONG  Pc,
PCONTEXT  ContextRecord
 

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

References KdpGetReturnAddress(), and KdpMoveMemory().

01226 { 01227 UCHAR membuf[2]; 01228 UCHAR opcode; 01229 ULONG sib; 01230 ULONG disp; 01231 01232 KdpMoveMemory( membuf, (PVOID)Pc, 2 ); 01233 opcode = membuf[0]; 01234 01235 if ( opcode == 0xe8 ) { // CALL 32 bit disp 01236 return Pc+5; 01237 } else if ( opcode == 0x9a ) { // CALL 16:32 01238 return Pc+7; 01239 } else if ( opcode == 0xff ) { 01240 if ( membuf[1] == 0x25) { // JMP indirect 01241 return KdpGetReturnAddress( ContextRecord ); 01242 } 01243 sib = ((membuf[1] & 0x07) == 0x04) ? 1 : 0; 01244 disp = (membuf[1] & 0xc0) >> 6; 01245 switch (disp) { 01246 case 0: 01247 if ( (membuf[1] & 0x07) == 0x05 ) { 01248 disp = 4; // disp32 alone 01249 } else { 01250 // disp = 0; // no displacement with reg or sib 01251 } 01252 break; 01253 case 1: 01254 // disp = 1; // disp8 with reg or sib 01255 break; 01256 case 2: 01257 disp = 4; // disp32 with reg or sib 01258 break; 01259 case 3: 01260 disp = 0; // direct register addressing (e.g., call esi) 01261 break; 01262 } 01263 return Pc + 2 + sib + disp; 01264 } 01265 01266 return 0; 01267 01268 } // KdpGetCallNextOffset

ULONG KdpGetReturnAddress PCONTEXT  ContextRecord  ) 
 

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

References KdpMoveMemory().

00515 { 00516 ULONG retaddr; 00517 00518 KdpMoveMemory((PCHAR)(&retaddr), (PCHAR)(ContextRecord->Esp), 4 ); 00519 return retaddr; 00520 00521 } // KdpGetReturnAddress

VOID KdpGetStateChange IN PDBGKD_MANIPULATE_STATE  ManipulateState,
IN PCONTEXT  ContextRecord
 

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

References KdpCurrentSymbolEnd, KdpCurrentSymbolStart, KeNumberProcessors, KiProcessorBlock, L, NT_SUCCESS, and TRUE.

00732 : 00733 00734 Extract continuation control data from Manipulate_State message 00735 00736 Arguments: 00737 00738 ManipulateState - supplies pointer to Manipulate_State packet 00739 00740 ContextRecord - Supplies a pointer to a context record. 00741 00742 Return Value: 00743 00744 None. 00745 00746 --*/ 00747 00748 { 00749 PKPRCB Prcb; 00750 ULONG Processor; 00751 00752 if (NT_SUCCESS(ManipulateState->u.Continue2.ContinueStatus) == TRUE) { 00753 00754 // 00755 // If NT_SUCCESS returns TRUE, then the debugger is doing a 00756 // continue, and it makes sense to apply control changes. 00757 // Otherwise the debugger is saying that it doesn't know what 00758 // to do with this exception, so control values are ignored. 00759 // 00760 00761 if (ManipulateState->u.Continue2.ControlSet.TraceFlag == TRUE) { 00762 ContextRecord->EFlags |= 0x100L; 00763 00764 } else { 00765 ContextRecord->EFlags &= ~0x100L; 00766 00767 } 00768 00769 for (Processor = 0; Processor < (ULONG)KeNumberProcessors; Processor++) { 00770 Prcb = KiProcessorBlock[Processor]; 00771 00772 Prcb->ProcessorState.SpecialRegisters.KernelDr7 = 00773 ManipulateState->u.Continue2.ControlSet.Dr7; 00774 00775 Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0L; 00776 } 00777 if (ManipulateState->u.Continue2.ControlSet.CurrentSymbolStart != 1) { 00778 KdpCurrentSymbolStart = ManipulateState->u.Continue2.ControlSet.CurrentSymbolStart; 00779 KdpCurrentSymbolEnd = ManipulateState->u.Continue2.ControlSet.CurrentSymbolEnd; 00780 } 00781 } 00782 }

BOOLEAN KdpIsSpecialCall ULONG  Pc,
PCONTEXT  ContextRecord,
UCHAR  opcode,
UCHAR  ModRM
 

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

References ASSERT, FALSE, KdNumberOfSpecialCalls, KdpMoveMemory(), KdSpecialCalls, regValue(), TRUE, and USHORT.

00341 : 00342 00343 Check to see if the instruction at pc is a call to one of the 00344 SpecialCall routines. 00345 00346 Argument: 00347 00348 Pc - program counter of instruction in question. 00349 00350 --*/ 00351 { 00352 UCHAR sib; 00353 USHORT twoBytes; 00354 ULONG callAddr; 00355 ULONG addrAddr; 00356 LONG offset; 00357 ULONG i; 00358 char d8; 00359 00360 if ( opcode == 0xe8 ) { 00361 00362 // 00363 // Signed offset from pc 00364 // 00365 00366 KdpMoveMemory( (PCHAR)&offset, (PCHAR)Pc+1, 4 ); 00367 00368 callAddr = Pc + offset + 5; // +5 for instr len. 00369 00370 } else if ( opcode == 0xff ) { 00371 00372 if ( ((modRM & 0x38) != 0x10) && ((modRM & 0x38) != 0x20) ) { 00373 // not call or jump 00374 return FALSE; 00375 } 00376 if ( (modRM & 0x08) == 0x08 ) { 00377 // m16:16 or m16:32 -- we don't handle this 00378 return FALSE; 00379 } 00380 00381 if ( (modRM & 0xc0) == 0xc0 ) { 00382 00383 /* Direct register addressing */ 00384 callAddr = regValue( (UCHAR)(modRM&0x7), ContextRecord ); 00385 00386 } else if ( (modRM & 0xc7) == 0x05 ) { 00387 // 00388 // Calls across dll boundaries involve a call into a jump table, 00389 // wherein the jump address is set to the real called routine at DLL 00390 // load time. Check to see if we're calling such an instruction, 00391 // and if so, compute its target address and set callAddr there. 00392 // 00393 // ff15 or ff25 -- call or jump indirect with disp32. Get 00394 // address of address 00395 // 00396 KdpMoveMemory( (PCHAR)&addrAddr, (PCHAR)Pc+2, 4 ); 00397 00398 // 00399 // Get real destination address 00400 // 00401 KdpMoveMemory( (PCHAR)&callAddr, (PCHAR)addrAddr, 4 ); 00402 // DPRINT(( "Indirect call/jmp @ %x\n", Pc )); 00403 } else if ( (modRM & 0x7) == 0x4 ) { 00404 00405 LONG indexValue; 00406 00407 /* sib byte present */ 00408 KdpMoveMemory( (PCHAR)&sib, (PCHAR)Pc+2, 1 ); 00409 indexValue = regValue( (UCHAR)((sib & 0x31) >> 3), ContextRecord ); 00410 switch ( sib&0xc0 ) { 00411 case 0x0: /* x1 */ 00412 break; 00413 case 0x40: 00414 indexValue *= 2; 00415 break; 00416 case 0x80: 00417 indexValue *= 4; 00418 break; 00419 case 0xc0: 00420 indexValue *= 8; 00421 break; 00422 } /* switch */ 00423 00424 switch ( modRM & 0xc0 ) { 00425 00426 case 0x0: /* no displacement */ 00427 if ( (sib & 0x7) == 0x5 ) { 00428 // DPRINT(("funny call #1 at %x\n", Pc)); 00429 return FALSE; 00430 } 00431 callAddr = indexValue + regValue((UCHAR)(sib&0x7), ContextRecord ); 00432 break; 00433 00434 case 0x40: 00435 if ( (sib & 0x6) == 0x4 ) { 00436 // DPRINT(("Funny call #2\n")); /* calling into the stack */ 00437 return FALSE; 00438 } 00439 KdpMoveMemory( &d8, (PCHAR)Pc+3,1 ); 00440 callAddr = indexValue + d8 + 00441 regValue((UCHAR)(sib&0x7), ContextRecord ); 00442 break; 00443 00444 case 0x80: 00445 if ( (sib & 0x6) == 0x4 ) { 00446 // DPRINT(("Funny call #3\n")); /* calling into the stack */ 00447 return FALSE; 00448 } 00449 KdpMoveMemory( (PCHAR)&offset, (PCHAR)Pc+3, 4 ); 00450 callAddr = indexValue + offset + 00451 regValue((UCHAR)(sib&0x7), ContextRecord ); 00452 break; 00453 00454 case 0xc0: 00455 ASSERT( FALSE ); 00456 break; 00457 00458 } 00459 00460 } else { 00461 //KdPrint(( "undecoded call at %x\n", 00462 // CONTEXT_TO_PROGRAM_COUNTER(ContextRecord) )); 00463 return FALSE; 00464 } 00465 00466 } else if ( opcode == 0x9a ) { 00467 00468 /* Absolute address call (best I can tell, cc doesn't generate this) */ 00469 KdpMoveMemory( (PCHAR)&callAddr, (PCHAR)Pc+1, 4 ); 00470 00471 } else { 00472 return FALSE; 00473 } 00474 00475 // 00476 // Calls across dll boundaries involve a call into a jump table, 00477 // wherein the jump address is set to the real called routine at DLL 00478 // load time. Check to see if we're calling such an instruction, 00479 // and if so, compute its target address and set callAddr there. 00480 // 00481 00482 #if 0 00483 KdpMoveMemory( (PCHAR)&twoBytes, (PCHAR)callAddr, 2 ); 00484 if ( twoBytes == 0x25ff ) { /* i386 is little-Endian; really 0xff25 */ 00485 00486 // 00487 // This is a 'jmp dword ptr [mem]' instruction, which is the sort of 00488 // jump used for a dll-boundary crossing call. Fixup callAddr. 00489 // 00490 00491 KdpMoveMemory( (PCHAR)&addrAddr, (PCHAR)callAddr+2, 4 ); 00492 KdpMoveMemory( (PCHAR)&callAddr, (PCHAR)addrAddr, 4 ); 00493 } 00494 #endif 00495 00496 for ( i = 0; i < KdNumberOfSpecialCalls; i++ ) { 00497 if ( KdSpecialCalls[i] == callAddr ) { 00498 return TRUE; 00499 } 00500 } 00501 return FALSE; 00502 00503 }

BOOLEAN KdpIsTryFinallyReturn ULONG  Pc,
PCONTEXT  ContextRecord
 

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

References FALSE, KdpCurrentSymbolEnd, KdpCurrentSymbolStart, KdpMoveMemory(), and TRUE.

00100 { 00101 ULONG retaddr; 00102 ULONG calldisp; 00103 UCHAR inst; 00104 00105 // 00106 // The complier generates code for a try-finally that involves having 00107 // a ret instruction that does not match with a call instruction. 00108 // This ret never returns a value (ie, it's a c3 return and not a 00109 // c2). It always returns into the current symbol scope. It is never 00110 // preceeded by a leave, which (hopefully) should differentiate it 00111 // from recursive returns. Check for this, and if we find it count 00112 // it as *0* level change. 00113 // 00114 // As an optimization, the compiler will often change: 00115 // CALL 00116 // RET 00117 // into: 00118 // JMP 00119 // In either case, we figure out the return address. It's the first 4 bytes 00120 // on the stack. 00121 // 00122 00123 KdpMoveMemory( (PCHAR)&retaddr, (PCHAR)ContextRecord->Esp, 4 ); 00124 00125 // DPRINT(( "Start %x return %x end %x\n", KdpCurrentSymbolStart, retaddr, KdpCurrentSymbolEnd )); 00126 00127 if ( (KdpCurrentSymbolStart < retaddr) && (retaddr < KdpCurrentSymbolEnd) ) { 00128 00129 // 00130 // Well, things aren't this nice. We may have transferred but not yet 00131 // updated the start/end. This case occurs in a call to a thunk. We 00132 // look to see if the instruction before the return address is a call. 00133 // Gross and not 100% reliable. 00134 // 00135 00136 KdpMoveMemory( (PCHAR)&inst, (PCHAR)retaddr - 5, 1 ); 00137 KdpMoveMemory( (PCHAR)&calldisp, (PCHAR)retaddr - 4, 4 ); 00138 00139 if (inst == 0xe8 && calldisp + retaddr == Pc) { 00140 // DPRINT(( "call to thunk @ %x\n", Pc )); 00141 return FALSE; 00142 } 00143 00144 // 00145 // returning to the current function. Either a finally 00146 // or a recursive return. Check for a leave. This is not 100% 00147 // reliable since we are betting on an instruction longer than a byte 00148 // and not ending with 0xc9. 00149 // 00150 00151 KdpMoveMemory( (PCHAR)&inst, (PCHAR)Pc-1, 1 ); 00152 00153 if ( inst != 0xc9 ) { 00154 // not a leave. Assume a try-finally. 00155 // DPRINT(( "transfer at %x is try-finally\n", Pc )); 00156 return TRUE; 00157 } 00158 } 00159 00160 // 00161 // This appears to be a true RET instruction 00162 // 00163 00164 return FALSE; 00165 }

LONG KdpLevelChange ULONG  Pc,
PCONTEXT  ContextRecord,
PBOOLEAN  SpecialCall
 

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

References FALSE, KdpCurrentSymbolEnd, KdpCurrentSymbolStart, KdpIsSpecialCall(), KdpIsTryFinallyReturn(), and KdpMoveMemory().

00188 { 00189 UCHAR membuf[2]; 00190 ULONG Addr; 00191 00192 KdpMoveMemory( (PCHAR)membuf, (PCHAR)Pc, 2 ); 00193 00194 switch (membuf[0]) { 00195 case 0xe8: // CALL direct w/32 bit displacement 00196 // 00197 // For try/finally, the compiler may, in addition to the push/ret trick 00198 // below, use a call to the finally thunk. Since we treat a RET to 00199 // within the same symbol scope as not changing levels, we will also 00200 // treat such a call as not changing levels either 00201 // 00202 00203 KdpMoveMemory( (PCHAR)&Addr, (PCHAR)Pc+1, 4 ); 00204 Addr += Pc + 5; 00205 00206 if ((KdpCurrentSymbolStart <= Addr) && (Addr < KdpCurrentSymbolEnd)) { 00207 *SpecialCall = FALSE; 00208 return 0; 00209 } 00210 00211 00212 case 0x9a: // CALL segmented 16:32 00213 00214 *SpecialCall = KdpIsSpecialCall( Pc, ContextRecord, membuf[0], membuf[1] ); 00215 return 1; 00216 00217 case 0xff: 00218 // 00219 // This is a compound instruction. Dispatch on operation 00220 // 00221 switch (membuf[1] & 0x38) { 00222 case 0x10: // CALL with mod r/m 00223 *SpecialCall = KdpIsSpecialCall( Pc, ContextRecord, membuf[0], membuf[1] ); 00224 return 1; 00225 case 0x20: // JMP with mod r/m 00226 *SpecialCall = KdpIsSpecialCall( Pc, ContextRecord, membuf[0], membuf[1] ); 00227 00228 // 00229 // If this is a try/finally, we'd like to treat it as call since the 00230 // return inside the destination will bring us back to this context. 00231 // However, if it is a jmp to a special routine, we must treat it 00232 // as a no-level change operation since we won't see the special 00233 // routines's return. 00234 // 00235 // If it is not a try/finally, we'd like to treat it as a no-level 00236 // change, unless again, it is a transfer to a special call which 00237 // views this as a level up. 00238 // 00239 00240 if (KdpIsTryFinallyReturn( Pc, ContextRecord )) { 00241 if (*SpecialCall) { 00242 // 00243 // We won't see the return, so pretend it is just 00244 // inline code 00245 // 00246 00247 return 0; 00248 00249 } else { 00250 // 00251 // The destinations return will bring us back to this 00252 // context 00253 // 00254 00255 return 1; 00256 } 00257 } else if (*SpecialCall) { 00258 // 00259 // We won't see the return but we are, indeed, doing one. 00260 // 00261 return -1; 00262 } else { 00263 return 0; 00264 } 00265 00266 default: 00267 *SpecialCall = FALSE; 00268 return 0; 00269 } 00270 00271 case 0xc3: // RET 00272 00273 // 00274 // If we are a try/finally ret, then we indicate that it is NOT a level 00275 // change 00276 // 00277 00278 if (KdpIsTryFinallyReturn( Pc, ContextRecord )) { 00279 *SpecialCall = FALSE; 00280 return 0; 00281 } 00282 00283 case 0xc2: // RET w/16 bit esp change 00284 case 0xca: // RETF w/16 bit esp change 00285 case 0xcb: // RETF 00286 *SpecialCall = FALSE; 00287 return -1; 00288 00289 default: 00290 *SpecialCall = FALSE; 00291 return 0; 00292 } 00293 00294 } // KdpLevelChange

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

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

References ASSERT, END_OF_CONTROL_SPACE, KdpMoveMemory(), KdpSendPacket(), KeNumberProcessors, KiProcessorBlock, t(), and USHORT.

00794 : 00795 00796 This function is called in response of a read control space state 00797 manipulation message. Its function is to read implementation 00798 specific system data. 00799 00800 IMPLEMENTATION NOTE: 00801 00802 On the X86, control space is defined as follows: 00803 00804 0: Base of KPROCESSOR_STATE structure. (KPRCB.ProcessorState) 00805 This includes CONTEXT record, 00806 followed by a SPECIAL_REGISTERs record 00807 00808 Arguments: 00809 00810 m - Supplies the state manipulation message. 00811 00812 AdditionalData - Supplies any additional data for the message. 00813 00814 Context - Supplies the current context. 00815 00816 Return Value: 00817 00818 None. 00819 00820 --*/ 00821 00822 { 00823 PDBGKD_READ_MEMORY a = &m->u.ReadMemory; 00824 STRING MessageHeader; 00825 ULONG Length, t; 00826 PVOID StartAddr; 00827 00828 MessageHeader.Length = sizeof(*m); 00829 MessageHeader.Buffer = (PCHAR)m; 00830 00831 ASSERT(AdditionalData->Length == 0); 00832 00833 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 00834 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 00835 } else { 00836 Length = a->TransferCount; 00837 } 00838 if ((a->TargetBaseAddress < (PVOID)END_OF_CONTROL_SPACE) && 00839 (m->Processor < (USHORT)KeNumberProcessors)) { 00840 t = (ULONG)END_OF_CONTROL_SPACE - (ULONG)(a->TargetBaseAddress); 00841 if (t < Length) { 00842 Length = t; 00843 } 00844 StartAddr = (PVOID)((ULONG)a->TargetBaseAddress + 00845 (ULONG)&(KiProcessorBlock[m->Processor]->ProcessorState)); 00846 AdditionalData->Length = (USHORT)KdpMoveMemory( 00847 AdditionalData->Buffer, 00848 StartAddr, 00849 Length 00850 ); 00851 00852 if (Length == AdditionalData->Length) { 00853 m->ReturnStatus = STATUS_SUCCESS; 00854 } else { 00855 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00856 } 00857 a->ActualBytesRead = AdditionalData->Length; 00858 00859 } else { 00860 AdditionalData->Length = 0; 00861 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00862 a->ActualBytesRead = 0; 00863 } 00864 00865 KdpSendPacket( 00866 PACKET_TYPE_KD_STATE_MANIPULATE, 00867 &MessageHeader, 00868 AdditionalData 00869 ); 00870 UNREFERENCED_PARAMETER(Context); 00871 }

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

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

References ASSERT, KdpSendPacket(), and NULL.

00955 : 00956 00957 This function is called in response of a read io space state 00958 manipulation message. Its function is to read system io 00959 locations. 00960 00961 Arguments: 00962 00963 m - Supplies the state manipulation message. 00964 00965 AdditionalData - Supplies any additional data for the message. 00966 00967 Context - Supplies the current context. 00968 00969 Return Value: 00970 00971 None. 00972 00973 --*/ 00974 00975 { 00976 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 00977 STRING MessageHeader; 00978 00979 MessageHeader.Length = sizeof(*m); 00980 MessageHeader.Buffer = (PCHAR)m; 00981 00982 ASSERT(AdditionalData->Length == 0); 00983 00984 m->ReturnStatus = STATUS_SUCCESS; 00985 00986 // 00987 // Check Size and Alignment 00988 // 00989 00990 switch ( a->DataSize ) { 00991 case 1: 00992 a->DataValue = (ULONG)READ_PORT_UCHAR(a->IoAddress); 00993 break; 00994 case 2: 00995 if ((ULONG)a->IoAddress & 1 ) { 00996 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 00997 } else { 00998 a->DataValue = (ULONG)READ_PORT_USHORT(a->IoAddress); 00999 } 01000 break; 01001 case 4: 01002 if ((ULONG)a->IoAddress & 3 ) { 01003 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 01004 } else { 01005 a->DataValue = READ_PORT_ULONG(a->IoAddress); 01006 } 01007 break; 01008 default: 01009 m->ReturnStatus = STATUS_INVALID_PARAMETER; 01010 } 01011 01012 KdpSendPacket( 01013 PACKET_TYPE_KD_STATE_MANIPULATE, 01014 &MessageHeader, 01015 NULL 01016 ); 01017 UNREFERENCED_PARAMETER(Context); 01018 }

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

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

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 KdpSetLoadState IN PDBGKD_WAIT_STATE_CHANGE  WaitStateChange,
IN PCONTEXT  ContextRecord
 

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

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

00531 : 00532 00533 Fill in the Wait_State_Change message record for the load symbol case. 00534 00535 Arguments: 00536 00537 WaitStateChange - Supplies pointer to record to fill in 00538 00539 ContextRecord - Supplies a pointer to a context record. 00540 00541 Return Value: 00542 00543 None. 00544 00545 --*/ 00546 00547 { 00548 00549 ULONG Count; 00550 PVOID End; 00551 PKPRCB Prcb; 00552 00553 // 00554 // Store the special x86 register into the control report structure. 00555 // 00556 00557 Prcb = KeGetCurrentPrcb(); 00558 WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.KernelDr6; 00559 WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.KernelDr7; 00560 00561 // 00562 // Copy the immediate instruction stream into the control report structure. 00563 // 00564 00565 Count = KdpMoveMemory((PCHAR)(&(WaitStateChange->ControlReport.InstructionStream[0])), 00566 (PCHAR)(WaitStateChange->ProgramCounter), 00567 DBGKD_MAXSTREAM); 00568 00569 WaitStateChange->ControlReport.InstructionCount = (USHORT)Count; 00570 00571 // 00572 // Clear breakpoints in the copied instruction stream. If any breakpoints 00573 // are cleared, then recopy the instruction stream. 00574 // 00575 00576 End = (PVOID)((PUCHAR)(WaitStateChange->ProgramCounter) + Count - 1); 00577 if (KdpDeleteBreakpointRange(WaitStateChange->ProgramCounter, End) != FALSE) { 00578 KdpMoveMemory(&(WaitStateChange->ControlReport.InstructionStream[0]), 00579 WaitStateChange->ProgramCounter, 00580 Count); 00581 } 00582 00583 // 00584 // Store the segment registers into the control report structure and set the 00585 // control flags. 00586 // 00587 00588 WaitStateChange->ControlReport.SegCs = (USHORT)(ContextRecord->SegCs); 00589 WaitStateChange->ControlReport.SegDs = (USHORT)(ContextRecord->SegDs); 00590 WaitStateChange->ControlReport.SegEs = (USHORT)(ContextRecord->SegEs); 00591 WaitStateChange->ControlReport.SegFs = (USHORT)(ContextRecord->SegFs); 00592 WaitStateChange->ControlReport.EFlags = ContextRecord->EFlags; 00593 WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS; 00594 00595 // 00596 // Copy context record into wait state change structure. 00597 // 00598 00599 KdpMoveMemory((PCHAR)(&WaitStateChange->Context), 00600 (PCHAR)ContextRecord, 00601 sizeof(CONTEXT)); 00602 00603 return; 00604 }

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

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

References KdpDeleteBreakpointRange(), KdpMoveMemory(), KdpQuickMoveMemory(), KeGetCurrentPrcb, KeGetCurrentThread, KeNumberProcessors, KeProcessorLevel, TRUE, and USHORT.

00617 : 00618 00619 Fill in the Wait_State_Change message record. 00620 00621 Arguments: 00622 00623 WaitStateChange - Supplies pointer to record to fill in 00624 00625 ExceptionRecord - Supplies a pointer to an exception record. 00626 00627 ContextRecord - Supplies a pointer to a context record. 00628 00629 SecondChance - Supplies a boolean value that determines whether this is 00630 the first or second chance for the exception. 00631 00632 Return Value: 00633 00634 None. 00635 00636 --*/ 00637 00638 { 00639 PKPRCB Prcb; 00640 BOOLEAN status; 00641 00642 // 00643 // Set up description of event, including exception record 00644 // 00645 00646 WaitStateChange->NewState = DbgKdExceptionStateChange; 00647 WaitStateChange->ProcessorLevel = KeProcessorLevel; 00648 WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number; 00649 WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors; 00650 WaitStateChange->Thread = (PVOID)KeGetCurrentThread(); 00651 WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 00652 KdpQuickMoveMemory( 00653 (PCHAR)&WaitStateChange->u.Exception.ExceptionRecord, 00654 (PCHAR)ExceptionRecord, 00655 sizeof(EXCEPTION_RECORD) 00656 ); 00657 WaitStateChange->u.Exception.FirstChance = !SecondChance; 00658 00659 // 00660 // Copy instruction stream immediately following location of event 00661 // 00662 00663 WaitStateChange->ControlReport.InstructionCount = 00664 (USHORT)KdpMoveMemory( 00665 (PCHAR)(&(WaitStateChange->ControlReport.InstructionStream[0])), 00666 (PCHAR)(WaitStateChange->ProgramCounter), 00667 DBGKD_MAXSTREAM 00668 ); 00669 00670 // 00671 // Copy context record immediately following instruction stream 00672 // 00673 00674 KdpMoveMemory( 00675 (PCHAR)(&WaitStateChange->Context), 00676 (PCHAR)ContextRecord, 00677 sizeof(*ContextRecord) 00678 ); 00679 00680 // 00681 // Clear breakpoints in copied area 00682 // 00683 00684 status = KdpDeleteBreakpointRange( 00685 WaitStateChange->ProgramCounter, 00686 (PVOID)((PUCHAR)WaitStateChange->ProgramCounter + 00687 WaitStateChange->ControlReport.InstructionCount - 1) 00688 ); 00689 00690 // 00691 // If there were any breakpoints cleared, recopy the area without them 00692 // 00693 00694 if (status == TRUE) { 00695 KdpMoveMemory( 00696 &(WaitStateChange->ControlReport.InstructionStream[0]), 00697 WaitStateChange->ProgramCounter, 00698 WaitStateChange->ControlReport.InstructionCount 00699 ); 00700 } 00701 00702 00703 // 00704 // Special registers for the x86 00705 // 00706 Prcb = KeGetCurrentPrcb(); 00707 00708 WaitStateChange->ControlReport.Dr6 = 00709 Prcb->ProcessorState.SpecialRegisters.KernelDr6; 00710 00711 WaitStateChange->ControlReport.Dr7 = 00712 Prcb->ProcessorState.SpecialRegisters.KernelDr7; 00713 00714 WaitStateChange->ControlReport.SegCs = (USHORT)(ContextRecord->SegCs); 00715 WaitStateChange->ControlReport.SegDs = (USHORT)(ContextRecord->SegDs); 00716 WaitStateChange->ControlReport.SegEs = (USHORT)(ContextRecord->SegEs); 00717 WaitStateChange->ControlReport.SegFs = (USHORT)(ContextRecord->SegFs); 00718 WaitStateChange->ControlReport.EFlags = ContextRecord->EFlags; 00719 00720 WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS; 00721 00722 }

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

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

References END_OF_CONTROL_SPACE, KdpMoveMemory(), KdpSendPacket(), KeNumberProcessors, KiProcessorBlock, and USHORT.

00882 : 00883 00884 This function is called in response of a write control space state 00885 manipulation message. Its function is to write implementation 00886 specific system data. 00887 00888 Control space for x86 is as defined above. 00889 00890 Arguments: 00891 00892 m - Supplies the state manipulation message. 00893 00894 AdditionalData - Supplies any additional data for the message. 00895 00896 Context - Supplies the current context. 00897 00898 Return Value: 00899 00900 None. 00901 00902 --*/ 00903 00904 { 00905 PDBGKD_WRITE_MEMORY a = &m->u.WriteMemory; 00906 ULONG Length; 00907 STRING MessageHeader; 00908 PVOID StartAddr; 00909 00910 MessageHeader.Length = sizeof(*m); 00911 MessageHeader.Buffer = (PCHAR)m; 00912 00913 if ((((PUCHAR)a->TargetBaseAddress + a->TransferCount) <= 00914 (PUCHAR)END_OF_CONTROL_SPACE) && (m->Processor < (USHORT)KeNumberProcessors)) { 00915 00916 StartAddr = (PVOID)((ULONG)a->TargetBaseAddress + 00917 (ULONG)&(KiProcessorBlock[m->Processor]->ProcessorState)); 00918 00919 Length = KdpMoveMemory( 00920 StartAddr, 00921 AdditionalData->Buffer, 00922 AdditionalData->Length 00923 ); 00924 00925 if (Length == AdditionalData->Length) { 00926 m->ReturnStatus = STATUS_SUCCESS; 00927 } else { 00928 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00929 } 00930 a->ActualBytesWritten = Length; 00931 00932 } else { 00933 AdditionalData->Length = 0; 00934 m->ReturnStatus = STATUS_UNSUCCESSFUL; 00935 a->ActualBytesWritten = 0; 00936 } 00937 00938 KdpSendPacket( 00939 PACKET_TYPE_KD_STATE_MANIPULATE, 00940 &MessageHeader, 00941 AdditionalData 00942 ); 00943 UNREFERENCED_PARAMETER(Context); 00944 }

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

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

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

01029 : 01030 01031 This function is called in response of a write io space state 01032 manipulation message. Its function is to write to system io 01033 locations. 01034 01035 Arguments: 01036 01037 m - Supplies the state manipulation message. 01038 01039 AdditionalData - Supplies any additional data for the message. 01040 01041 Context - Supplies the current context. 01042 01043 Return Value: 01044 01045 None. 01046 01047 --*/ 01048 01049 { 01050 PDBGKD_READ_WRITE_IO a = &m->u.ReadWriteIo; 01051 STRING MessageHeader; 01052 01053 MessageHeader.Length = sizeof(*m); 01054 MessageHeader.Buffer = (PCHAR)m; 01055 01056 ASSERT(AdditionalData->Length == 0); 01057 01058 m->ReturnStatus = STATUS_SUCCESS; 01059 01060 // 01061 // Check Size and Alignment 01062 // 01063 01064 switch ( a->DataSize ) { 01065 case 1: 01066 WRITE_PORT_UCHAR(a->IoAddress, (UCHAR)a->DataValue); 01067 break; 01068 case 2: 01069 if ((ULONG)a->IoAddress & 1 ) { 01070 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 01071 } else { 01072 WRITE_PORT_USHORT(a->IoAddress, (USHORT)a->DataValue); 01073 } 01074 break; 01075 case 4: 01076 if ((ULONG)a->IoAddress & 3 ) { 01077 m->ReturnStatus = STATUS_DATATYPE_MISALIGNMENT; 01078 } else { 01079 WRITE_PORT_ULONG(a->IoAddress, a->DataValue); 01080 } 01081 break; 01082 default: 01083 m->ReturnStatus = STATUS_INVALID_PARAMETER; 01084 } 01085 01086 KdpSendPacket( 01087 PACKET_TYPE_KD_STATE_MANIPULATE, 01088 &MessageHeader, 01089 NULL 01090 ); 01091 UNREFERENCED_PARAMETER(Context); 01092 }

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

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

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 }

LONG regValue UCHAR  reg,
PCONTEXT  ContextRecord
 

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

Referenced by MapperPhantomizeDetectedComPorts().

00301 { 00302 switch (reg) { 00303 case 0x0: 00304 return(ContextRecord->Eax); 00305 break; 00306 case 0x1: 00307 return(ContextRecord->Ecx); 00308 break; 00309 case 0x2: 00310 return(ContextRecord->Edx); 00311 break; 00312 case 0x3: 00313 return(ContextRecord->Ebx); 00314 break; 00315 case 0x4: 00316 return(ContextRecord->Esp); 00317 break; 00318 case 0x5: 00319 return(ContextRecord->Ebp); 00320 break; 00321 case 0x6: 00322 return(ContextRecord->Esi); 00323 break; 00324 case 0x7: 00325 return(ContextRecord->Edi); 00326 break; 00327 } 00328 return 0; // Bash compiler warning 00329 }


Variable Documentation

ULONG KdNumberOfSpecialCalls
 

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

Referenced by KdpIsSpecialCall().

ULONG KdpCurrentSymbolEnd
 

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

Referenced by KdpGetStateChange(), KdpIsTryFinallyReturn(), and KdpLevelChange().

ULONG KdpCurrentSymbolStart
 

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

Referenced by KdpGetStateChange(), KdpIsTryFinallyReturn(), and KdpLevelChange().

ULONG KdSpecialCalls[]
 

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

Referenced by KdpIsSpecialCall().


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