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

kdbreak.c File Reference

#include "kdp.h"

Go to the source code of this file.

Functions

VOID KdSetOwedBreakpoints (VOID)
BOOLEAN KdpLowWriteContent (ULONG Index)
BOOLEAN KdpLowRestoreBreakpoint (ULONG Index)
ULONG KdpAddBreakpoint (IN PVOID Address)
BOOLEAN KdpLowWriteContent (IN ULONG Index)
BOOLEAN KdpDeleteBreakpoint (IN ULONG Handle)
BOOLEAN KdpDeleteBreakpointRange (IN PVOID Lower, IN PVOID Upper)
VOID KdpSuspendBreakpoint (ULONG Handle)
VOID KdpSuspendAllBreakpoints (VOID)
BOOLEAN KdpLowRestoreBreakpoint (IN ULONG Index)
VOID KdpRestoreAllBreakpoints (VOID)
VOID KdDeleteAllBreakpoints (VOID)


Function Documentation

VOID KdDeleteAllBreakpoints VOID   ) 
 

Definition at line 1332 of file kdbreak.c.

References BreakpointsSuspended, FALSE, Handle, KdDebuggerEnabled, KdpDeleteBreakpoint(), and KdPitchDebugger.

01335 { 01336 ULONG Handle; 01337 01338 if (KdDebuggerEnabled == FALSE || KdPitchDebugger != FALSE) { 01339 return; 01340 } 01341 01342 BreakpointsSuspended = FALSE; 01343 01344 for ( Handle = 1; Handle <= BREAKPOINT_TABLE_SIZE; Handle++ ) { 01345 KdpDeleteBreakpoint(Handle); 01346 } 01347 01348 return; 01349 } // KdDeleteAllBreakpoints

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 }

BOOLEAN KdpLowRestoreBreakpoint IN ULONG  Index  ) 
 

Definition at line 1121 of file kdbreak.c.

References _BREAKPOINT_ENTRY::Address, _BREAKPOINT_ENTRY::Content, DPRINT, FALSE, _BREAKPOINT_ENTRY::Flags, Index, KD_BREAKPOINT_IA64_MOVL, KD_BREAKPOINT_NEEDS_REPLACE, KD_BREAKPOINT_NEEDS_WRITE, KDP_BREAKPOINT_TYPE, KdpBreakpointInstruction, KdpBreakpointTable, KdpMoveMemory(), KdpOweBreakpoint, and TRUE.

01127 : 01128 01129 This routine attempts to write a breakpoint instruction. 01130 The old contents must have already been stored in the 01131 breakpoint record. 01132 01133 Arguments: 01134 01135 Index - Supplies the index of the breakpoint table entry 01136 which is to be written. 01137 01138 Return Value: 01139 01140 Returns TRUE if the breakpoint was written, FALSE if it was 01141 not and has been marked for writing later. 01142 01143 --*/ 01144 01145 { 01146 KDP_BREAKPOINT_TYPE Content; 01147 01148 #if defined(_IA64_) 01149 KDP_BREAKPOINT_TYPE mBuf; 01150 PVOID BundleAddress; 01151 #endif 01152 // 01153 // Does the breakpoint need to be written at all? 01154 // 01155 01156 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_REPLACE) { 01157 01158 // 01159 // The breakpoint was never removed. Clear the flag 01160 // and we are done. 01161 // 01162 01163 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_REPLACE; 01164 return TRUE; 01165 } 01166 01167 if (KdpBreakpointTable[Index].Content == KdpBreakpointInstruction) { 01168 01169 // 01170 // The instruction is a breakpoint anyway. 01171 // 01172 01173 return TRUE; 01174 } 01175 01176 // 01177 // Replace the instruction contents. 01178 // 01179 01180 #if !defined(_IA64_) 01181 if (KdpBreakpointTable[Index].Content == KdpBreakpointInstruction) { 01182 01183 // 01184 // The instruction is a breakpoint anyway. 01185 // 01186 01187 return TRUE; 01188 } 01189 #endif 01190 01191 // 01192 // Replace the instruction contents. 01193 // 01194 01195 #if defined(_IA64_) 01196 01197 // read in intruction in case the adjacent instruction has been modified. 01198 01199 if (KdpMoveMemory( 01200 (PCHAR)&mBuf, 01201 (PCHAR)KdpBreakpointTable[Index].Address, 01202 sizeof(KDP_BREAKPOINT_TYPE) 01203 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01204 DPRINT(("KD: read 0x%p template failed\n", KdpBreakpointTable[Index].Address)); 01205 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01206 KdpOweBreakpoint = TRUE; 01207 return FALSE; 01208 } 01209 01210 switch ((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) { 01211 case 0: 01212 mBuf = (mBuf & ~(INST_SLOT0_MASK)) | (KdpBreakpointInstruction << 5); 01213 break; 01214 01215 case 4: 01216 mBuf = (mBuf & ~(INST_SLOT1_MASK)) | (KdpBreakpointInstruction << 14); 01217 break; 01218 01219 case 8: 01220 mBuf = (mBuf & ~(INST_SLOT2_MASK)) | (KdpBreakpointInstruction << 23); 01221 break; 01222 01223 default: 01224 DPRINT(("KD: KdpAddBreakpoint bad instruction slot#\n")); 01225 return FALSE; 01226 } 01227 if (KdpMoveMemory( 01228 (PCHAR)KdpBreakpointTable[Index].Address, 01229 (PCHAR)&mBuf, 01230 sizeof(KDP_BREAKPOINT_TYPE) 01231 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01232 01233 DPRINT(("KD: KdpMoveMemory failed writing BP!\n")); 01234 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01235 KdpOweBreakpoint = TRUE; 01236 return FALSE; 01237 } 01238 else { 01239 01240 // check for two-slot MOVL instruction. Reject request if attempt to 01241 // set break in slot 2 of MLI template. 01242 // change template to type 0 if current instruction is MLI 01243 01244 if (((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) != 0) { 01245 (ULONG_PTR)BundleAddress = (ULONG_PTR)KdpBreakpointTable[Index].Address & ~(0xf); 01246 if (KdpMoveMemory( 01247 (PCHAR)&mBuf, 01248 (PCHAR)BundleAddress, 01249 sizeof(KDP_BREAKPOINT_TYPE) 01250 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01251 DPRINT(("KD: read template failed at 0x%08x\n", BundleAddress)); 01252 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01253 KdpOweBreakpoint = TRUE; 01254 return FALSE; 01255 } 01256 else { 01257 if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) { 01258 if (((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) == 4) { 01259 // if template= type 2 MLI, change to type 0 01260 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); 01261 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IA64_MOVL; 01262 if (KdpMoveMemory( 01263 (PCHAR)BundleAddress, 01264 (PCHAR)&mBuf, 01265 sizeof(KDP_BREAKPOINT_TYPE) 01266 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01267 DPRINT(("KD: write to 0x%08x template failed\n", BundleAddress)); 01268 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01269 KdpOweBreakpoint = TRUE; 01270 return FALSE; 01271 } 01272 else { 01273 //DPRINT(("KD: change MLI template to type 0 at 0x%08x set\n", Address)); 01274 } 01275 } else { 01276 // set breakpoint at slot 2 of MOVL is illegal 01277 DPRINT(("KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress)); 01278 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01279 KdpOweBreakpoint = TRUE; 01280 return FALSE; 01281 } 01282 } 01283 } 01284 } 01285 //DPRINT(("KD: breakpoint at 0x%08x set\n", Address)); 01286 return TRUE; 01287 } 01288 01289 #else 01290 if (KdpMoveMemory( (PCHAR)KdpBreakpointTable[Index].Address, 01291 (PCHAR)&KdpBreakpointInstruction, 01292 sizeof(KDP_BREAKPOINT_TYPE) ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01293 01294 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01295 KdpOweBreakpoint = TRUE; 01296 return FALSE; 01297 01298 } else { 01299 01300 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_WRITE; 01301 return TRUE; 01302 } 01303 #endif 01304 01305 }

BOOLEAN KdpLowRestoreBreakpoint ULONG  Index  ) 
 

BOOLEAN KdpLowWriteContent IN ULONG  Index  ) 
 

Definition at line 635 of file kdbreak.c.

References _BREAKPOINT_ENTRY::Address, _BREAKPOINT_ENTRY::Content, DPRINT, FALSE, _BREAKPOINT_ENTRY::Flags, Index, KD_BREAKPOINT_IA64_MOVL, KD_BREAKPOINT_NEEDS_REPLACE, KD_BREAKPOINT_NEEDS_WRITE, KDP_BREAKPOINT_TYPE, KdpBreakpointInstruction, KdpBreakpointTable, KdpMoveMemory(), KdpOweBreakpoint, and TRUE.

00641 : 00642 00643 This routine attempts to replace the code that a breakpoint is 00644 written over. This routine, KdpAddBreakpoint, 00645 KdpLowRestoreBreakpoint and KdSetOwedBreakpoints are responsible 00646 for getting data written as requested. Callers should not 00647 examine or use KdpOweBreakpoints, and they should not set the 00648 NEEDS_WRITE or NEEDS_REPLACE flags. 00649 00650 Callers must still look at the return value from this function, 00651 however: if it returns FALSE, the breakpoint record must not be 00652 reused until KdSetOwedBreakpoints has finished with it. 00653 00654 Arguments: 00655 00656 Index - Supplies the index of the breakpoint table entry 00657 which is to be deleted. 00658 00659 Return Value: 00660 00661 Returns TRUE if the breakpoint was removed, FALSE if it was deferred. 00662 00663 --*/ 00664 00665 { 00666 #if defined(_IA64_) 00667 KDP_BREAKPOINT_TYPE mBuf; 00668 PVOID BundleAddress; 00669 #endif 00670 00671 // 00672 // Do the contents need to be replaced at all? 00673 // 00674 00675 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_WRITE) { 00676 00677 // 00678 // The breakpoint was never written out. Clear the flag 00679 // and we are done. 00680 // 00681 00682 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_WRITE; 00683 //DPRINT(("KD: Breakpoint at 0x%08x never written; flag cleared.\n", 00684 // KdpBreakpointTable[Index].Address)); 00685 return TRUE; 00686 } 00687 00688 #if !defined(_IA64_) 00689 if (KdpBreakpointTable[Index].Content == KdpBreakpointInstruction) { 00690 00691 // 00692 // The instruction is a breakpoint anyway. 00693 // 00694 00695 //DPRINT(("KD: Breakpoint at 0x%08x; instr is really BP; flag cleared.\n", 00696 // KdpBreakpointTable[Index].Address)); 00697 00698 return TRUE; 00699 } 00700 #endif 00701 00702 00703 // 00704 // Restore the instruction contents. 00705 // 00706 00707 #if defined(_IA64_) 00708 // Read in memory since adjancent instructions in the same bundle may have 00709 // been modified after we save them. 00710 if (KdpMoveMemory( 00711 (PCHAR)&mBuf, 00712 (PCHAR)KdpBreakpointTable[Index].Address, 00713 sizeof(KDP_BREAKPOINT_TYPE)) != sizeof(KDP_BREAKPOINT_TYPE)) { 00714 KdpOweBreakpoint = TRUE; 00715 DPRINT(("KD: read 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00716 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00717 return FALSE; 00718 } 00719 else { 00720 00721 switch ((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) { 00722 case 0: 00723 mBuf = (mBuf & ~(INST_SLOT0_MASK)) 00724 | (KdpBreakpointTable[Index].Content & INST_SLOT0_MASK); 00725 break; 00726 00727 case 4: 00728 mBuf = (mBuf & ~(INST_SLOT1_MASK)) 00729 | (KdpBreakpointTable[Index].Content & INST_SLOT1_MASK); 00730 break; 00731 00732 case 8: 00733 mBuf = (mBuf & ~(INST_SLOT2_MASK)) 00734 | (KdpBreakpointTable[Index].Content & INST_SLOT2_MASK); 00735 break; 00736 00737 default: 00738 KdpOweBreakpoint = TRUE; 00739 DPRINT(("KD: illegal instruction address 0x%08x\n", KdpBreakpointTable[Index].Address)); 00740 return FALSE; 00741 } 00742 00743 if (KdpMoveMemory( 00744 (PCHAR)KdpBreakpointTable[Index].Address, 00745 (PCHAR)&mBuf, 00746 sizeof(KDP_BREAKPOINT_TYPE)) != sizeof(KDP_BREAKPOINT_TYPE)) { 00747 KdpOweBreakpoint = TRUE; 00748 DPRINT(("KD: write to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00749 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00750 return FALSE; 00751 } 00752 else { 00753 #ifdef _GAMBIT_ 00754 if (KdpMoveMemory( 00755 (PCHAR)&mBuf, 00756 (PCHAR)KdpBreakpointTable[Index].Address, 00757 sizeof(KDP_BREAKPOINT_TYPE)) == sizeof(KDP_BREAKPOINT_TYPE)) { 00758 DPRINT(("\tcontent after memory move = 0x%08x 0x%08x\n", (ULONG)(mBuf >> 32), (ULONG)mBuf)); 00759 } 00760 #endif // _GAMBIT_ 00761 00762 00763 // restore template to MLI if displaced instruction was MOVL 00764 00765 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IA64_MOVL) { 00766 (ULONG_PTR)BundleAddress = (ULONG_PTR)KdpBreakpointTable[Index].Address & ~(0xf); 00767 if (KdpMoveMemory( 00768 (PCHAR)&mBuf, 00769 (PCHAR)BundleAddress, 00770 sizeof(KDP_BREAKPOINT_TYPE) 00771 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00772 KdpOweBreakpoint = TRUE; 00773 DPRINT(("KD: read template 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00774 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00775 return FALSE; 00776 } 00777 else { 00778 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); // set template to MLI 00779 mBuf |= 0x4; 00780 00781 if (KdpMoveMemory( 00782 (PCHAR)BundleAddress, 00783 (PCHAR)&mBuf, 00784 sizeof(KDP_BREAKPOINT_TYPE) 00785 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00786 KdpOweBreakpoint = TRUE; 00787 DPRINT(("KD: write template to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00788 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00789 return FALSE; 00790 } else { 00791 //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n", 00792 // KdpBreakpointTable[Index].Address)); 00793 return TRUE; 00794 } 00795 } 00796 } 00797 else { // not MOVL 00798 //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n", 00799 // KdpBreakpointTable[Index].Address)); 00800 return TRUE; 00801 } 00802 } 00803 } 00804 #else 00805 if (KdpMoveMemory( (PCHAR)KdpBreakpointTable[Index].Address, 00806 (PCHAR)&KdpBreakpointTable[Index].Content, 00807 sizeof(KDP_BREAKPOINT_TYPE) ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00808 00809 KdpOweBreakpoint = TRUE; 00810 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00811 //DPRINT(("KD: Breakpoint at 0x%08x; unable to clear, flag set.\n", 00812 //KdpBreakpointTable[Index].Address)); 00813 return FALSE; 00814 } else { 00815 //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n", 00816 //KdpBreakpointTable[Index].Address)); 00817 return TRUE; 00818 } 00819 #endif 00820 00821 }

BOOLEAN KdpLowWriteContent ULONG  Index  ) 
 

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 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

VOID KdSetOwedBreakpoints VOID   ) 
 


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