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

kdbreak.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1990 Microsoft Corporation 00004 00005 Module Name: 00006 00007 kdbreak.c 00008 00009 Abstract: 00010 00011 This module implements machine dependent functions to add and delete 00012 breakpoints from the kernel debugger breakpoint table. 00013 00014 Author: 00015 00016 David N. Cutler 2-Aug-1990 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #include "kdp.h" 00023 00024 // 00025 // Define external references. 00026 // 00027 00028 VOID 00029 KdSetOwedBreakpoints( 00030 VOID 00031 ); 00032 00033 BOOLEAN 00034 KdpLowWriteContent( 00035 ULONG Index 00036 ); 00037 00038 BOOLEAN 00039 KdpLowRestoreBreakpoint( 00040 ULONG Index 00041 ); 00042 00043 #ifdef ALLOC_PRAGMA 00044 #pragma alloc_text(PAGEKD, KdpAddBreakpoint) 00045 #pragma alloc_text(PAGEKD, KdpDeleteBreakpoint) 00046 #pragma alloc_text(PAGEKD, KdpDeleteBreakpointRange) 00047 #pragma alloc_text(PAGEKD, KdpSuspendBreakpoint) 00048 #pragma alloc_text(PAGEKD, KdpSuspendAllBreakpoints) 00049 #pragma alloc_text(PAGEKD, KdpRestoreAllBreakpoints) 00050 #pragma alloc_text(PAGEKD, KdpLowWriteContent) 00051 #pragma alloc_text(PAGEKD, KdpLowRestoreBreakpoint) 00052 #if defined(_IA64_) 00053 #pragma alloc_text(PAGEKD, KdpSuspendBreakpointRange) 00054 #pragma alloc_text(PAGEKD, KdpRestoreBreakpointRange) 00055 #endif 00056 #endif 00057 00058 00059 ULONG 00060 KdpAddBreakpoint ( 00061 IN PVOID Address 00062 ) 00063 00064 /*++ 00065 00066 Routine Description: 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 HARDWARE_PTE Opaque; 00090 PVOID AccessAddress; 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 AccessAddress = NULL; 00163 //DPRINT(("KD: memory inaccessible\n")); 00164 } else { 00165 //DPRINT(("KD: memory readable...\n")); 00166 00167 // 00168 // If the specified address is not write accessible, then return zero. 00169 // All references must be made through AccessAddress. 00170 // 00171 00172 AccessAddress = MmDbgWriteCheck((PVOID)Address, &Opaque); 00173 if (AccessAddress == NULL) { 00174 DPRINT(("KD: memory not writable!\n")); 00175 return 0; 00176 } 00177 } 00178 00179 #if defined(_IA64_) 00180 if ( AccessAddress != NULL ) { 00181 KDP_BREAKPOINT_TYPE mBuf; 00182 PVOID BundleAddress; 00183 00184 // change template to type 0 if current instruction is MLI 00185 00186 // read in intruction template if current instruction is NOT slot 0. 00187 // check for two-slot MOVL instruction. Reject request if attempt to 00188 // set break in slot 2 of MLI template. 00189 00190 if (((ULONG_PTR)Address & 0xf) != 0) { 00191 (ULONG_PTR)BundleAddress = (ULONG_PTR)AccessAddress & ~(0xf); 00192 if (KdpMoveMemory( 00193 (PCHAR)&mBuf, 00194 (PCHAR)BundleAddress, 00195 sizeof(KDP_BREAKPOINT_TYPE) 00196 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00197 //DPRINT(("KD: read 0x%08x template failed\n", BundleAddress)); 00198 MmDbgReleaseAddress(AccessAddress, &Opaque); 00199 return 0; 00200 } else { 00201 if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) { 00202 if (((ULONG_PTR)Address & 0xf) == 4) { 00203 // if template= type 2 MLI, change to type 0 00204 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); 00205 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IA64_MOVL; 00206 if (KdpMoveMemory( 00207 (PCHAR)BundleAddress, 00208 (PCHAR)&mBuf, 00209 sizeof(KDP_BREAKPOINT_TYPE) 00210 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00211 //DPRINT(("KD: write to 0x%08x template failed\n", BundleAddress)); 00212 MmDbgReleaseAddress(AccessAddress, &Opaque); 00213 return 0; 00214 } 00215 else { 00216 //DPRINT(("KD: change MLI template to type 0 at 0x%08x set\n", Address)); 00217 } 00218 } else { 00219 // set breakpoint at slot 2 of MOVL is illegal 00220 //DPRINT(("KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress)); 00221 MmDbgReleaseAddress(AccessAddress, &Opaque); 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 MmDbgReleaseAddress(AccessAddress, &Opaque); 00253 //DPRINT(("KD: KdpAddBreakpoint bad instruction slot#\n")); 00254 return 0; 00255 } 00256 if (KdpMoveMemory( 00257 (PCHAR)AccessAddress, 00258 (PCHAR)&Content, 00259 sizeof(KDP_BREAKPOINT_TYPE) 00260 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00261 00262 MmDbgReleaseAddress(AccessAddress, &Opaque); 00263 //DPRINT(("KD: KdpMoveMemory failed writing BP!\n")); 00264 return 0; 00265 } 00266 else { 00267 //DPRINT(("KD: breakpoint at 0x%08x set\n", Address)); 00268 } 00269 MmDbgReleaseAddress(AccessAddress, &Opaque); 00270 00271 } else { // memory not accessible 00272 KdpBreakpointTable[Index].Address = Address; 00273 KdpBreakpointTable[Index].Flags &= ~(KD_BREAKPOINT_STATE_MASK); 00274 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IN_USE; 00275 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 00276 KdpOweBreakpoint = TRUE; 00277 //DPRINT(("KD: breakpoint write deferred\n")); 00278 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00279 KdpBreakpointTable[Index].DirectoryTableBase = 00280 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00281 } 00282 } 00283 #else 00284 if ( AccessAddress != NULL ) { 00285 KdpBreakpointTable[Index].Address = Address; 00286 KdpBreakpointTable[Index].Content = Content; 00287 KdpBreakpointTable[Index].Flags = KD_BREAKPOINT_IN_USE; 00288 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00289 KdpBreakpointTable[Index].DirectoryTableBase = 00290 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00291 } 00292 if (KdpMoveMemory( 00293 (PCHAR)AccessAddress, 00294 (PCHAR)&KdpBreakpointInstruction, 00295 sizeof(KDP_BREAKPOINT_TYPE) 00296 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00297 00298 DPRINT(("KD: KdpMoveMemory failed writing BP!\n")); 00299 } 00300 MmDbgReleaseAddress(AccessAddress, &Opaque); 00301 } else { 00302 KdpBreakpointTable[Index].Address = Address; 00303 KdpBreakpointTable[Index].Flags = KD_BREAKPOINT_IN_USE | KD_BREAKPOINT_NEEDS_WRITE; 00304 KdpOweBreakpoint = TRUE; 00305 //DPRINT(("KD: breakpoint write deferred\n")); 00306 if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) { 00307 KdpBreakpointTable[Index].DirectoryTableBase = 00308 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0]; 00309 } 00310 } 00311 #endif // IA64 00312 00313 return Index + 1; 00314 00315 } 00316 00317 00318 00319 VOID 00320 KdSetOwedBreakpoints( 00321 VOID 00322 ) 00323 00324 /*++ 00325 00326 Routine Description: 00327 00328 This function is called after returning from memory management calls 00329 that may cause an inpage. Its purpose is to store pending 00330 breakpoints in pages just made valid. 00331 00332 Arguments: 00333 00334 None. 00335 00336 Return Value: 00337 00338 None. 00339 00340 --*/ 00341 00342 { 00343 00344 KDP_BREAKPOINT_TYPE Content; 00345 BOOLEAN Enable; 00346 LONG Index; 00347 HARDWARE_PTE Opaque; 00348 PVOID AccessAddress; 00349 00350 // 00351 // If we don't owe any breakpoints then return 00352 // 00353 00354 if ( !KdpOweBreakpoint ) { 00355 return; 00356 } 00357 00358 00359 // 00360 // Freeze all other processors, disable interrupts, and save debug 00361 // port state. 00362 // 00363 00364 Enable = KdEnterDebugger(NULL, NULL); 00365 KdpOweBreakpoint = FALSE; 00366 AccessAddress = NULL; 00367 00368 // 00369 // Search the breakpoint table for breakpoints that need to be 00370 // written or replaced. 00371 // 00372 00373 for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index += 1) { 00374 if (KdpBreakpointTable[Index].Flags & 00375 (KD_BREAKPOINT_NEEDS_WRITE | KD_BREAKPOINT_NEEDS_REPLACE) ) { 00376 00377 // 00378 // Breakpoint needs to be written 00379 // 00380 //DPRINT(("KD: Breakpoint %d at 0x%08x: trying to %s after page in.\n", 00381 // Index, 00382 // KdpBreakpointTable[Index].Address, 00383 // (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_WRITE) ? 00384 // "set" : "clear")); 00385 00386 if ((KdpBreakpointTable[Index].Address >= (PVOID)GLOBAL_BREAKPOINT_LIMIT) || 00387 (KdpBreakpointTable[Index].DirectoryTableBase == 00388 KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0])) { 00389 00390 // 00391 // Check to see if we have write access to the memory 00392 // 00393 00394 AccessAddress = MmDbgWriteCheck((PVOID)KdpBreakpointTable[Index].Address, &Opaque); 00395 00396 if (AccessAddress == NULL) { 00397 KdpOweBreakpoint = TRUE; 00398 //DPRINT(("KD: address not writeable.\n")); 00399 break; 00400 } 00401 00402 // 00403 // Breakpoint is global, or its directory base matches 00404 // 00405 00406 if (KdpMoveMemory( 00407 (PCHAR)&Content, 00408 (PCHAR)AccessAddress, 00409 sizeof(KDP_BREAKPOINT_TYPE) 00410 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00411 00412 // 00413 // Memory is still inaccessible (is this possible after 00414 // the call above to MmDbgWriteCheck?) 00415 // 00416 00417 DPRINT(("KD: read from 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00418 00419 KdpOweBreakpoint = TRUE; 00420 00421 } else { 00422 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_WRITE) { 00423 KdpBreakpointTable[Index].Content = Content; 00424 #if defined(_IA64_) 00425 switch ((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) { 00426 case 0: 00427 Content = (Content & ~(INST_SLOT0_MASK)) | (KdpBreakpointInstruction << 5); 00428 break; 00429 00430 case 4: 00431 Content = (Content & ~(INST_SLOT1_MASK)) | (KdpBreakpointInstruction << 14); 00432 break; 00433 00434 case 8: 00435 Content = (Content & ~(INST_SLOT2_MASK)) | (KdpBreakpointInstruction << 23); 00436 break; 00437 00438 default: 00439 //DPRINT(("KD: illegal instruction address 0x%08x\n", KdpBreakpointTable[Index].Address)); 00440 break; 00441 } 00442 if (KdpMoveMemory( 00443 (PCHAR)AccessAddress, 00444 (PCHAR)&Content, 00445 sizeof(KDP_BREAKPOINT_TYPE) 00446 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00447 KdpOweBreakpoint = TRUE; 00448 //DPRINT(("KD: write to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00449 } 00450 00451 // read in intruction template if current instruction is NOT slot 0. 00452 // check for two-slot MOVL instruction. Reject request if attempt to 00453 // set break in slot 2 of MLI template. 00454 00455 else if (((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) != 0) { 00456 KDP_BREAKPOINT_TYPE mBuf; 00457 PVOID BundleAddress; 00458 00459 (ULONG_PTR)BundleAddress = (ULONG_PTR)AccessAddress & ~(0xf); 00460 if (KdpMoveMemory( 00461 (PCHAR)&mBuf, 00462 (PCHAR)BundleAddress, 00463 sizeof(KDP_BREAKPOINT_TYPE) 00464 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00465 KdpOweBreakpoint = TRUE; 00466 //DPRINT(("KD: read 0x%08x template failed\n", KdpBreakpointTable[Index].Address)); 00467 } else { 00468 if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) { 00469 if (((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) == 4) { 00470 // if template= type 2 MLI, change to type 0 00471 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); 00472 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IA64_MOVL; 00473 if (KdpMoveMemory( 00474 (PCHAR)BundleAddress, 00475 (PCHAR)&mBuf, 00476 sizeof(KDP_BREAKPOINT_TYPE) 00477 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00478 KdpOweBreakpoint = TRUE; 00479 //DPRINT(("KD: write to 0x%08x template failed\n", KdpBreakpointTable[Index].Address)); 00480 } 00481 else { 00482 KdpBreakpointTable[Index].Flags &= ~(KD_BREAKPOINT_STATE_MASK); 00483 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IN_USE; 00484 //DPRINT(("KD: write to 0x%08x ok\n", KdpBreakpointTable[Index].Address)); 00485 } 00486 } else { 00487 // set breakpoint at slot 2 of MOVL is illegal 00488 KdpOweBreakpoint = TRUE; 00489 //DPRINT(("KD: illegal attempt to set BP at slot 2 of 0x%08x\n", KdpBreakpointTable[Index].Address)); 00490 } 00491 } 00492 else { 00493 KdpBreakpointTable[Index].Flags &= ~(KD_BREAKPOINT_STATE_MASK); 00494 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IN_USE; 00495 //DPRINT(("KD: write to 0x%08x ok\n", KdpBreakpointTable[Index].Address)); 00496 } 00497 } 00498 } 00499 #else 00500 if (KdpMoveMemory( 00501 (PCHAR)AccessAddress, 00502 (PCHAR)&KdpBreakpointInstruction, 00503 sizeof(KDP_BREAKPOINT_TYPE) 00504 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00505 KdpOweBreakpoint = TRUE; 00506 DPRINT(("KD: write to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00507 } else { 00508 KdpBreakpointTable[Index].Flags = KD_BREAKPOINT_IN_USE; 00509 DPRINT(("KD: write to 0x%08x ok\n", KdpBreakpointTable[Index].Address)); 00510 } 00511 #endif 00512 } else { 00513 #if defined(_IA64_) 00514 00515 KDP_BREAKPOINT_TYPE mBuf; 00516 PVOID BundleAddress; 00517 00518 // restore original instruction content 00519 00520 // Read in memory since adjancent instructions in the same bundle may have 00521 // been modified after we save them. 00522 if (KdpMoveMemory( 00523 (PCHAR)&mBuf, 00524 (PCHAR)AccessAddress, 00525 sizeof(KDP_BREAKPOINT_TYPE)) != sizeof(KDP_BREAKPOINT_TYPE)) { 00526 KdpOweBreakpoint = TRUE; 00527 //DPRINT(("KD: read 0x%08x template failed\n", KdpBreakpointTable[Index].Address)); 00528 } 00529 else { 00530 switch ((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) { 00531 case 0: 00532 mBuf = (mBuf & ~(INST_SLOT0_MASK)) 00533 | (KdpBreakpointTable[Index].Content & INST_SLOT0_MASK); 00534 break; 00535 00536 case 4: 00537 mBuf = (mBuf & ~(INST_SLOT1_MASK)) 00538 | (KdpBreakpointTable[Index].Content & INST_SLOT1_MASK); 00539 break; 00540 00541 case 8: 00542 mBuf = (mBuf & ~(INST_SLOT2_MASK)) 00543 | (KdpBreakpointTable[Index].Content & INST_SLOT2_MASK); 00544 break; 00545 00546 default: 00547 KdpOweBreakpoint = TRUE; 00548 //DPRINT(("KD: illegal instruction address 0x%08x\n", KdpBreakpointTable[Index].Address)); 00549 } 00550 00551 if (KdpMoveMemory( 00552 (PCHAR)AccessAddress, 00553 (PCHAR)&mBuf, 00554 sizeof(KDP_BREAKPOINT_TYPE)) != sizeof(KDP_BREAKPOINT_TYPE)) { 00555 KdpOweBreakpoint = TRUE; 00556 //DPRINT(("KD: write to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00557 } 00558 else { 00559 // restore template to MLI if displaced instruction was MOVL 00560 00561 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IA64_MOVL) { 00562 (ULONG_PTR)BundleAddress = (ULONG_PTR)AccessAddress & ~(0xf); 00563 if (KdpMoveMemory( 00564 (PCHAR)&mBuf, 00565 (PCHAR)BundleAddress, 00566 sizeof(KDP_BREAKPOINT_TYPE) 00567 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00568 KdpOweBreakpoint = TRUE; 00569 //DPRINT(("KD: read template 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00570 } 00571 else { 00572 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); // set template to MLI 00573 mBuf |= 0x4; 00574 00575 if (KdpMoveMemory( 00576 (PCHAR)BundleAddress, 00577 (PCHAR)&mBuf, 00578 sizeof(KDP_BREAKPOINT_TYPE) 00579 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00580 KdpOweBreakpoint = TRUE; 00581 //DPRINT(("KD: write template to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00582 } else { 00583 //DPRINT(("KD: write to 0x%08x ok\n", KdpBreakpointTable[Index].Address)); 00584 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) { 00585 KdpBreakpointTable[Index].Flags |= (KD_BREAKPOINT_SUSPENDED | KD_BREAKPOINT_IN_USE); 00586 } else { 00587 KdpBreakpointTable[Index].Flags = 0; 00588 } 00589 } 00590 } 00591 } else { 00592 //DPRINT(("KD: write to 0x%08x ok\n", KdpBreakpointTable[Index].Address)); 00593 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) { 00594 KdpBreakpointTable[Index].Flags |= (KD_BREAKPOINT_SUSPENDED | KD_BREAKPOINT_IN_USE); 00595 } else { 00596 KdpBreakpointTable[Index].Flags = 0; 00597 } 00598 } 00599 } 00600 } 00601 #else 00602 if (KdpMoveMemory( 00603 (PCHAR)AccessAddress, 00604 (PCHAR)&KdpBreakpointTable[Index].Content, 00605 sizeof(KDP_BREAKPOINT_TYPE) 00606 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00607 KdpOweBreakpoint = TRUE; 00608 DPRINT(("KD: write to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00609 } else { 00610 //DPRINT(("KD: write to 0x%08x ok\n", KdpBreakpointTable[Index].Address)); 00611 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) { 00612 KdpBreakpointTable[Index].Flags = KD_BREAKPOINT_SUSPENDED | KD_BREAKPOINT_IN_USE; 00613 } else { 00614 KdpBreakpointTable[Index].Flags = 0; 00615 } 00616 } 00617 #endif // _IA64_ 00618 00619 } 00620 } 00621 00622 if (AccessAddress != NULL) { 00623 MmDbgReleaseAddress( 00624 AccessAddress, 00625 &Opaque 00626 ); 00627 AccessAddress = NULL; 00628 } 00629 00630 } else { 00631 00632 // 00633 // Breakpoint is local and its directory base does not match 00634 // 00635 00636 KdpOweBreakpoint = TRUE; 00637 } 00638 } 00639 } 00640 00641 if (AccessAddress != NULL) { 00642 MmDbgReleaseAddress( 00643 AccessAddress, 00644 &Opaque 00645 ); 00646 } 00647 00648 KdExitDebugger(Enable); 00649 return; 00650 } 00651 00652 00653 BOOLEAN 00654 KdpLowWriteContent ( 00655 IN ULONG Index 00656 ) 00657 00658 /*++ 00659 00660 Routine Description: 00661 00662 This routine attempts to replace the code that a breakpoint is 00663 written over. This routine, KdpAddBreakpoint, 00664 KdpLowRestoreBreakpoint and KdSetOwedBreakpoints are responsible 00665 for getting data written as requested. Callers should not 00666 examine or use KdpOweBreakpoints, and they should not set the 00667 NEEDS_WRITE or NEEDS_REPLACE flags. 00668 00669 Callers must still look at the return value from this function, 00670 however: if it returns FALSE, the breakpoint record must not be 00671 reused until KdSetOwedBreakpoints has finished with it. 00672 00673 Arguments: 00674 00675 Index - Supplies the index of the breakpoint table entry 00676 which is to be deleted. 00677 00678 Return Value: 00679 00680 Returns TRUE if the breakpoint was removed, FALSE if it was deferred. 00681 00682 --*/ 00683 00684 { 00685 #if defined(_IA64_) 00686 KDP_BREAKPOINT_TYPE mBuf; 00687 PVOID BundleAddress; 00688 #endif 00689 00690 // 00691 // Do the contents need to be replaced at all? 00692 // 00693 00694 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_WRITE) { 00695 00696 // 00697 // The breakpoint was never written out. Clear the flag 00698 // and we are done. 00699 // 00700 00701 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_WRITE; 00702 //DPRINT(("KD: Breakpoint at 0x%08x never written; flag cleared.\n", 00703 // KdpBreakpointTable[Index].Address)); 00704 return TRUE; 00705 } 00706 00707 #if !defined(_IA64_) 00708 if (KdpBreakpointTable[Index].Content == KdpBreakpointInstruction) { 00709 00710 // 00711 // The instruction is a breakpoint anyway. 00712 // 00713 00714 //DPRINT(("KD: Breakpoint at 0x%08x; instr is really BP; flag cleared.\n", 00715 // KdpBreakpointTable[Index].Address)); 00716 00717 return TRUE; 00718 } 00719 #endif 00720 00721 00722 // 00723 // Restore the instruction contents. 00724 // 00725 00726 #if defined(_IA64_) 00727 // Read in memory since adjancent instructions in the same bundle may have 00728 // been modified after we save them. 00729 if (KdpMoveMemory( 00730 (PCHAR)&mBuf, 00731 (PCHAR)KdpBreakpointTable[Index].Address, 00732 sizeof(KDP_BREAKPOINT_TYPE)) != sizeof(KDP_BREAKPOINT_TYPE)) { 00733 KdpOweBreakpoint = TRUE; 00734 //DPRINT(("KD: read 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00735 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00736 return FALSE; 00737 } 00738 else { 00739 00740 switch ((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) { 00741 case 0: 00742 mBuf = (mBuf & ~(INST_SLOT0_MASK)) 00743 | (KdpBreakpointTable[Index].Content & INST_SLOT0_MASK); 00744 break; 00745 00746 case 4: 00747 mBuf = (mBuf & ~(INST_SLOT1_MASK)) 00748 | (KdpBreakpointTable[Index].Content & INST_SLOT1_MASK); 00749 break; 00750 00751 case 8: 00752 mBuf = (mBuf & ~(INST_SLOT2_MASK)) 00753 | (KdpBreakpointTable[Index].Content & INST_SLOT2_MASK); 00754 break; 00755 00756 default: 00757 KdpOweBreakpoint = TRUE; 00758 //DPRINT(("KD: illegal instruction address 0x%08x\n", KdpBreakpointTable[Index].Address)); 00759 return FALSE; 00760 } 00761 00762 if (KdpMoveMemory( 00763 (PCHAR)KdpBreakpointTable[Index].Address, 00764 (PCHAR)&mBuf, 00765 sizeof(KDP_BREAKPOINT_TYPE)) != sizeof(KDP_BREAKPOINT_TYPE)) { 00766 KdpOweBreakpoint = TRUE; 00767 //DPRINT(("KD: write to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00768 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00769 return FALSE; 00770 } 00771 else { 00772 00773 if (KdpMoveMemory( 00774 (PCHAR)&mBuf, 00775 (PCHAR)KdpBreakpointTable[Index].Address, 00776 sizeof(KDP_BREAKPOINT_TYPE)) == sizeof(KDP_BREAKPOINT_TYPE)) { 00777 //DPRINT(("\tcontent after memory move = 0x%08x 0x%08x\n", (ULONG)(mBuf >> 32), (ULONG)mBuf)); 00778 } 00779 00780 // restore template to MLI if displaced instruction was MOVL 00781 00782 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IA64_MOVL) { 00783 (ULONG_PTR)BundleAddress = (ULONG_PTR)KdpBreakpointTable[Index].Address & ~(0xf); 00784 if (KdpMoveMemory( 00785 (PCHAR)&mBuf, 00786 (PCHAR)BundleAddress, 00787 sizeof(KDP_BREAKPOINT_TYPE) 00788 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00789 KdpOweBreakpoint = TRUE; 00790 //DPRINT(("KD: read template 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00791 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00792 return FALSE; 00793 } 00794 else { 00795 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); // set template to MLI 00796 mBuf |= 0x4; 00797 00798 if (KdpMoveMemory( 00799 (PCHAR)BundleAddress, 00800 (PCHAR)&mBuf, 00801 sizeof(KDP_BREAKPOINT_TYPE) 00802 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00803 KdpOweBreakpoint = TRUE; 00804 //DPRINT(("KD: write template to 0x%08x failed\n", KdpBreakpointTable[Index].Address)); 00805 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00806 return FALSE; 00807 } else { 00808 //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n", 00809 // KdpBreakpointTable[Index].Address)); 00810 return TRUE; 00811 } 00812 } 00813 } 00814 else { // not MOVL 00815 //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n", 00816 // KdpBreakpointTable[Index].Address)); 00817 return TRUE; 00818 } 00819 } 00820 } 00821 #else 00822 if (KdpMoveMemory( (PCHAR)KdpBreakpointTable[Index].Address, 00823 (PCHAR)&KdpBreakpointTable[Index].Content, 00824 sizeof(KDP_BREAKPOINT_TYPE) ) != sizeof(KDP_BREAKPOINT_TYPE)) { 00825 00826 KdpOweBreakpoint = TRUE; 00827 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_REPLACE; 00828 //DPRINT(("KD: Breakpoint at 0x%08x; unable to clear, flag set.\n", 00829 //KdpBreakpointTable[Index].Address)); 00830 return FALSE; 00831 } else { 00832 //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n", 00833 //KdpBreakpointTable[Index].Address)); 00834 return TRUE; 00835 } 00836 #endif 00837 00838 } 00839 00840 00841 00842 BOOLEAN 00843 KdpDeleteBreakpoint ( 00844 IN ULONG Handle 00845 ) 00846 00847 /*++ 00848 00849 Routine Description: 00850 00851 This routine deletes an entry from the breakpoint table. 00852 00853 Arguments: 00854 00855 Handle - Supplies the index plus one of the breakpoint table entry 00856 which is to be deleted. 00857 00858 Return Value: 00859 00860 A value of FALSE is returned if the specified handle is not a valid 00861 value or the breakpoint cannot be deleted because the old instruction 00862 cannot be replaced. Otherwise, a value of TRUE is returned. 00863 00864 --*/ 00865 00866 { 00867 ULONG Index = Handle - 1; 00868 00869 // 00870 // If the specified handle is not valid, then return FALSE. 00871 // 00872 00873 if ((Handle == 0) || (Handle > BREAKPOINT_TABLE_SIZE)) { 00874 DPRINT(("KD: Breakpoint %d invalid.\n", Index)); 00875 return FALSE; 00876 } 00877 00878 // 00879 // If the specified breakpoint table entry is not valid, then return FALSE. 00880 // 00881 00882 if (KdpBreakpointTable[Index].Flags == 0) { 00883 //DPRINT(("KD: Breakpoint %d already clear.\n", Index)); 00884 return FALSE; 00885 } 00886 00887 // 00888 // If the breakpoint is already suspended, just delete it from the table. 00889 // 00890 00891 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) { 00892 //DPRINT(("KD: Deleting suspended breakpoint %d \n", Index)); 00893 if ( !(KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_REPLACE) ) { 00894 //DPRINT(("KD: already clear.\n")); 00895 KdpBreakpointTable[Index].Flags = 0; 00896 return TRUE; 00897 } 00898 } 00899 00900 // 00901 // Replace the instruction contents. 00902 // 00903 00904 if (KdpLowWriteContent(Index)) { 00905 00906 // 00907 // Delete breakpoint table entry 00908 // 00909 00910 //DPRINT(("KD: Breakpoint %d deleted successfully.\n", Index)); 00911 KdpBreakpointTable[Index].Flags = 0; 00912 } 00913 00914 return TRUE; 00915 } 00916 00917 00918 BOOLEAN 00919 KdpDeleteBreakpointRange ( 00920 IN PVOID Lower, 00921 IN PVOID Upper 00922 ) 00923 00924 /*++ 00925 00926 Routine Description: 00927 00928 This routine deletes all breakpoints falling in a given range 00929 from the breakpoint table. 00930 00931 Arguments: 00932 00933 Lower - inclusive lower address of range from which to remove BPs. 00934 00935 Upper - include upper address of range from which to remove BPs. 00936 00937 Return Value: 00938 00939 TRUE if any breakpoints removed, FALSE otherwise. 00940 00941 --*/ 00942 00943 { 00944 ULONG Index; 00945 BOOLEAN ReturnStatus = FALSE; 00946 00947 // 00948 // Examine each entry in the table in turn 00949 // 00950 00951 for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++) { 00952 00953 if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 00954 ((KdpBreakpointTable[Index].Address >= Lower) && 00955 (KdpBreakpointTable[Index].Address <= Upper)) 00956 ) { 00957 00958 // 00959 // Breakpoint is in use and falls in range, clear it. 00960 // 00961 00962 ReturnStatus = ReturnStatus || KdpDeleteBreakpoint(Index+1); 00963 } 00964 } 00965 00966 return ReturnStatus; 00967 00968 } 00969 00970 VOID 00971 KdpSuspendBreakpoint ( 00972 ULONG Handle 00973 ) 00974 { 00975 ULONG Index = Handle - 1; 00976 00977 if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 00978 !(KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) ) { 00979 00980 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_SUSPENDED; 00981 KdpLowWriteContent(Index); 00982 } 00983 00984 return; 00985 00986 } // KdpSuspendBreakpoint 00987 00988 VOID 00989 KdpSuspendAllBreakpoints ( 00990 VOID 00991 ) 00992 { 00993 ULONG Handle; 00994 00995 BreakpointsSuspended = TRUE; 00996 00997 for ( Handle = 1; Handle <= BREAKPOINT_TABLE_SIZE; Handle++ ) { 00998 KdpSuspendBreakpoint(Handle); 00999 } 01000 01001 return; 01002 01003 } // KdpSuspendAllBreakpoints 01004 01005 #if defined(_IA64_) 01006 01007 01008 BOOLEAN 01009 KdpSuspendBreakpointRange ( 01010 IN PVOID Lower, 01011 IN PVOID Upper 01012 ) 01013 01014 /*++ 01015 01016 Routine Description: 01017 01018 This routine suspend all breakpoints falling in a given range 01019 from the breakpoint table. 01020 01021 Arguments: 01022 01023 Lower - inclusive lower address of range from which to suspend BPs. 01024 01025 Upper - include upper address of range from which to suspend BPs. 01026 01027 Return Value: 01028 01029 TRUE if any breakpoints suspended, FALSE otherwise. 01030 01031 Notes: 01032 The order of suspending breakpoints is opposite that of setting 01033 them in KdpAddBreakpoint() in case of duplicate addresses. 01034 01035 --*/ 01036 01037 { 01038 ULONG Index; 01039 BOOLEAN ReturnStatus = FALSE; 01040 01041 //DPRINT(("\nKD: entering KdpSuspendBreakpointRange() at 0x%08x 0x%08x\n", Lower, Upper)); 01042 01043 // 01044 // Examine each entry in the table in turn 01045 // 01046 01047 for (Index = BREAKPOINT_TABLE_SIZE - 1; Index != -1; Index--) { 01048 01049 if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 01050 ((KdpBreakpointTable[Index].Address >= Lower) && 01051 (KdpBreakpointTable[Index].Address <= Upper)) 01052 ) { 01053 01054 // 01055 // Breakpoint is in use and falls in range, suspend it. 01056 // 01057 01058 KdpSuspendBreakpoint(Index+1); 01059 ReturnStatus = TRUE; 01060 } 01061 } 01062 //DPRINT(("KD: exiting KdpSuspendBreakpointRange() return 0x%d\n", ReturnStatus)); 01063 01064 return ReturnStatus; 01065 01066 } // KdpSuspendBreakpointRange 01067 01068 01069 01070 BOOLEAN 01071 KdpRestoreBreakpointRange ( 01072 IN PVOID Lower, 01073 IN PVOID Upper 01074 ) 01075 01076 /*++ 01077 01078 Routine Description: 01079 01080 This routine writes back breakpoints falling in a given range 01081 from the breakpoint table. 01082 01083 Arguments: 01084 01085 Lower - inclusive lower address of range from which to rewrite BPs. 01086 01087 Upper - include upper address of range from which to rewrite BPs. 01088 01089 Return Value: 01090 01091 TRUE if any breakpoints written, FALSE otherwise. 01092 01093 Notes: 01094 The order of writing breakpoints is opposite that of removing 01095 them in KdpSuspendBreakpointRange() in case of duplicate addresses. 01096 01097 --*/ 01098 01099 { 01100 ULONG Index; 01101 BOOLEAN ReturnStatus = FALSE; 01102 01103 //DPRINT(("\nKD: entering KdpRestoreBreakpointRange() at 0x%08x 0x%08x\n", Lower, Upper)); 01104 01105 // 01106 // Examine each entry in the table in turn 01107 // 01108 01109 for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++) { 01110 01111 if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 01112 ((KdpBreakpointTable[Index].Address >= Lower) && 01113 (KdpBreakpointTable[Index].Address <= Upper)) 01114 ) { 01115 01116 // 01117 // suspended breakpoint that falls in range, unsuspend it. 01118 // 01119 01120 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) { 01121 01122 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_SUSPENDED; 01123 ReturnStatus = ReturnStatus || KdpLowRestoreBreakpoint(Index); 01124 } 01125 } 01126 } 01127 01128 //DPRINT(("KD: exiting KdpRestoreBreakpointRange() return 0x%d\n", ReturnStatus)); 01129 01130 return ReturnStatus; 01131 01132 } // KdpRestoreBreakpointRange 01133 01134 #endif // _IA64_ 01135 01136 01137 BOOLEAN 01138 KdpLowRestoreBreakpoint ( 01139 IN ULONG Index 01140 ) 01141 01142 /*++ 01143 01144 Routine Description: 01145 01146 This routine attempts to write a breakpoint instruction. 01147 The old contents must have already been stored in the 01148 breakpoint record. 01149 01150 Arguments: 01151 01152 Index - Supplies the index of the breakpoint table entry 01153 which is to be written. 01154 01155 Return Value: 01156 01157 Returns TRUE if the breakpoint was written, FALSE if it was 01158 not and has been marked for writing later. 01159 01160 --*/ 01161 01162 { 01163 KDP_BREAKPOINT_TYPE Content; 01164 01165 #if defined(_IA64_) 01166 KDP_BREAKPOINT_TYPE mBuf; 01167 PVOID BundleAddress; 01168 #endif 01169 // 01170 // Does the breakpoint need to be written at all? 01171 // 01172 01173 if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_NEEDS_REPLACE) { 01174 01175 // 01176 // The breakpoint was never removed. Clear the flag 01177 // and we are done. 01178 // 01179 01180 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_REPLACE; 01181 return TRUE; 01182 } 01183 01184 if (KdpBreakpointTable[Index].Content == KdpBreakpointInstruction) { 01185 01186 // 01187 // The instruction is a breakpoint anyway. 01188 // 01189 01190 return TRUE; 01191 } 01192 01193 // 01194 // Replace the instruction contents. 01195 // 01196 01197 #if !defined(_IA64_) 01198 if (KdpBreakpointTable[Index].Content == KdpBreakpointInstruction) { 01199 01200 // 01201 // The instruction is a breakpoint anyway. 01202 // 01203 01204 return TRUE; 01205 } 01206 #endif 01207 01208 // 01209 // Replace the instruction contents. 01210 // 01211 01212 #if defined(_IA64_) 01213 01214 // read in intruction in case the adjacent instruction has been modified. 01215 01216 if (KdpMoveMemory( 01217 (PCHAR)&mBuf, 01218 (PCHAR)KdpBreakpointTable[Index].Address, 01219 sizeof(KDP_BREAKPOINT_TYPE) 01220 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01221 //DPRINT(("KD: read 0x%p template failed\n", KdpBreakpointTable[Index].Address)); 01222 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01223 KdpOweBreakpoint = TRUE; 01224 return FALSE; 01225 } 01226 01227 switch ((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) { 01228 case 0: 01229 mBuf = (mBuf & ~(INST_SLOT0_MASK)) | (KdpBreakpointInstruction << 5); 01230 break; 01231 01232 case 4: 01233 mBuf = (mBuf & ~(INST_SLOT1_MASK)) | (KdpBreakpointInstruction << 14); 01234 break; 01235 01236 case 8: 01237 mBuf = (mBuf & ~(INST_SLOT2_MASK)) | (KdpBreakpointInstruction << 23); 01238 break; 01239 01240 default: 01241 //DPRINT(("KD: KdpAddBreakpoint bad instruction slot#\n")); 01242 return FALSE; 01243 } 01244 if (KdpMoveMemory( 01245 (PCHAR)KdpBreakpointTable[Index].Address, 01246 (PCHAR)&mBuf, 01247 sizeof(KDP_BREAKPOINT_TYPE) 01248 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01249 01250 //DPRINT(("KD: KdpMoveMemory failed writing BP!\n")); 01251 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01252 KdpOweBreakpoint = TRUE; 01253 return FALSE; 01254 } 01255 else { 01256 01257 // check for two-slot MOVL instruction. Reject request if attempt to 01258 // set break in slot 2 of MLI template. 01259 // change template to type 0 if current instruction is MLI 01260 01261 if (((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) != 0) { 01262 (ULONG_PTR)BundleAddress = (ULONG_PTR)KdpBreakpointTable[Index].Address & ~(0xf); 01263 if (KdpMoveMemory( 01264 (PCHAR)&mBuf, 01265 (PCHAR)BundleAddress, 01266 sizeof(KDP_BREAKPOINT_TYPE) 01267 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01268 //DPRINT(("KD: read template failed at 0x%08x\n", BundleAddress)); 01269 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01270 KdpOweBreakpoint = TRUE; 01271 return FALSE; 01272 } 01273 else { 01274 if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) { 01275 if (((ULONG_PTR)KdpBreakpointTable[Index].Address & 0xf) == 4) { 01276 // if template= type 2 MLI, change to type 0 01277 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); 01278 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_IA64_MOVL; 01279 if (KdpMoveMemory( 01280 (PCHAR)BundleAddress, 01281 (PCHAR)&mBuf, 01282 sizeof(KDP_BREAKPOINT_TYPE) 01283 ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01284 //DPRINT(("KD: write to 0x%08x template failed\n", BundleAddress)); 01285 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01286 KdpOweBreakpoint = TRUE; 01287 return FALSE; 01288 } 01289 else { 01290 //DPRINT(("KD: change MLI template to type 0 at 0x%08x set\n", Address)); 01291 } 01292 } else { 01293 // set breakpoint at slot 2 of MOVL is illegal 01294 //DPRINT(("KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress)); 01295 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01296 KdpOweBreakpoint = TRUE; 01297 return FALSE; 01298 } 01299 } 01300 } 01301 } 01302 //DPRINT(("KD: breakpoint at 0x%08x set\n", Address)); 01303 return TRUE; 01304 } 01305 01306 #else 01307 if (KdpMoveMemory( (PCHAR)KdpBreakpointTable[Index].Address, 01308 (PCHAR)&KdpBreakpointInstruction, 01309 sizeof(KDP_BREAKPOINT_TYPE) ) != sizeof(KDP_BREAKPOINT_TYPE)) { 01310 01311 KdpBreakpointTable[Index].Flags |= KD_BREAKPOINT_NEEDS_WRITE; 01312 KdpOweBreakpoint = TRUE; 01313 return FALSE; 01314 01315 } else { 01316 01317 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_NEEDS_WRITE; 01318 return TRUE; 01319 } 01320 #endif 01321 01322 } 01323 01324 01325 VOID 01326 KdpRestoreAllBreakpoints ( 01327 VOID 01328 ) 01329 { 01330 ULONG Index; 01331 01332 BreakpointsSuspended = FALSE; 01333 01334 for ( Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++ ) { 01335 01336 if ((KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) && 01337 (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_SUSPENDED) ) { 01338 01339 KdpBreakpointTable[Index].Flags &= ~KD_BREAKPOINT_SUSPENDED; 01340 KdpLowRestoreBreakpoint(Index); 01341 } 01342 } 01343 01344 return; 01345 01346 } // KdpRestoreAllBreakpoints 01347 01348 VOID 01349 KdDeleteAllBreakpoints( 01350 VOID 01351 ) 01352 { 01353 ULONG Handle; 01354 01355 if (KdDebuggerEnabled == FALSE || KdPitchDebugger != FALSE) { 01356 return; 01357 } 01358 01359 BreakpointsSuspended = FALSE; 01360 01361 for ( Handle = 1; Handle <= BREAKPOINT_TABLE_SIZE; Handle++ ) { 01362 KdpDeleteBreakpoint(Handle); 01363 } 01364 01365 return; 01366 } // KdDeleteAllBreakpoints

Generated on Sat May 15 19:40:34 2004 for test by doxygen 1.3.7