Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

781 lines
23 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. break.c
  5. Abstract:
  6. This module implements machine dependent functions to add and delete
  7. breakpoints from the kernel debugger breakpoint table.
  8. Author:
  9. David N. Cutler 2-Aug-1990
  10. Revision History:
  11. --*/
  12. #include "bd.h"
  13. LOGICAL BreakpointsSuspended = FALSE;
  14. //
  15. // Define external references.
  16. //
  17. LOGICAL
  18. BdLowWriteContent(
  19. ULONG Index
  20. );
  21. LOGICAL
  22. BdLowRestoreBreakpoint(
  23. ULONG Index
  24. );
  25. ULONG
  26. BdAddBreakpoint (
  27. IN ULONG64 Address
  28. )
  29. /*++
  30. Routine Description:
  31. This routine adds an entry to the breakpoint table and returns a handle
  32. to the breakpoint table entry.
  33. Arguments:
  34. Address - Supplies the address where to set the breakpoint.
  35. Return Value:
  36. A value of zero is returned if the specified address is already in the
  37. breakpoint table, there are no free entries in the breakpoint table, the
  38. specified address is not correctly aligned, or the specified address is
  39. not valid. Otherwise, the index of the assigned breakpoint table entry
  40. plus one is returned as the function value.
  41. --*/
  42. {
  43. BD_BREAKPOINT_TYPE Content;
  44. ULONG Index;
  45. BOOLEAN Accessible;
  46. #if defined(_IA64_)
  47. HARDWARE_PTE Opaque;
  48. #endif
  49. //DPRINT(("KD: Setting breakpoint at 0x%08x\n", Address));
  50. //
  51. // If the specified address is not properly aligned, then return zero.
  52. //
  53. if (((ULONG_PTR)Address & BD_BREAKPOINT_ALIGN) != 0) {
  54. return 0;
  55. }
  56. //
  57. // Get the instruction to be replaced. If the instruction cannot be read,
  58. // then mark the breakpoint as not accessible.
  59. //
  60. if (BdMoveMemory((PCHAR)&Content,
  61. (PCHAR)Address,
  62. sizeof(BD_BREAKPOINT_TYPE) ) != sizeof(BD_BREAKPOINT_TYPE)) {
  63. Accessible = FALSE;
  64. //DPRINT(("KD: memory inaccessible\n"));
  65. } else {
  66. //DPRINT(("KD: memory readable...\n"));
  67. Accessible = TRUE;
  68. }
  69. //
  70. // If the specified address is not write accessible, then return zero.
  71. //
  72. if (Accessible && BdWriteCheck((PVOID)Address) == NULL) {
  73. //DPRINT(("KD: memory not writable!\n"));
  74. return 0;
  75. }
  76. //
  77. // Search the breakpoint table for a free entry and check if the specified
  78. // address is already in the breakpoint table.
  79. //
  80. for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index += 1) {
  81. if (BdBreakpointTable[Index].Flags == 0) {
  82. break;
  83. }
  84. }
  85. //
  86. // If a free entry was found, then write breakpoint and return the handle
  87. // value plus one. Otherwise, return zero.
  88. //
  89. if (Index == BREAKPOINT_TABLE_SIZE) {
  90. //DPRINT(("KD: ran out of breakpoints!\n"));
  91. return 0;
  92. }
  93. //DPRINT(("KD: using Index %d\n", Index));
  94. #if defined(_IA64_)
  95. if (Accessible) {
  96. BD_BREAKPOINT_TYPE mBuf;
  97. PVOID BundleAddress;
  98. // change template to type 0 if current instruction is MLI
  99. // read in intruction template if current instruction is NOT slot 0.
  100. // check for two-slot MOVL instruction. Reject request if attempt to
  101. // set break in slot 2 of MLI template.
  102. if (((ULONG_PTR)Address & 0xf) != 0) {
  103. (ULONG_PTR)BundleAddress = (ULONG_PTR)Address & ~(0xf);
  104. if (BdMoveMemory(
  105. (PCHAR)&mBuf,
  106. (PCHAR)BundleAddress,
  107. sizeof(BD_BREAKPOINT_TYPE)
  108. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  109. //DPRINT(("KD: read 0x%08x template failed\n", BundleAddress));
  110. // MmDbgReleaseAddress((PVOID) Address, &Opaque);
  111. return 0;
  112. } else {
  113. if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) {
  114. if (((ULONG_PTR)Address & 0xf) == 4) {
  115. // if template= type 2 MLI, change to type 0
  116. mBuf &= ~((INST_TEMPL_MASK >> 1) << 1);
  117. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_IA64_MOVL;
  118. if (BdMoveMemory(
  119. (PCHAR)BundleAddress,
  120. (PCHAR)&mBuf,
  121. sizeof(BD_BREAKPOINT_TYPE)
  122. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  123. //DPRINT(("KD: write to 0x%08x template failed\n", BundleAddress));
  124. // MmDbgReleaseAddress((PVOID) Address, &Opaque);
  125. return 0;
  126. }
  127. else {
  128. //DPRINT(("KD: change MLI template to type 0 at 0x%08x set\n", Address));
  129. }
  130. } else {
  131. // set breakpoint at slot 2 of MOVL is illegal
  132. //DPRINT(("KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress));
  133. // MmDbgReleaseAddress((PVOID) Address, &Opaque);
  134. return 0;
  135. }
  136. }
  137. }
  138. }
  139. // insert break instruction
  140. BdBreakpointTable[Index].Address = Address;
  141. BdBreakpointTable[Index].Content = Content;
  142. BdBreakpointTable[Index].Flags &= ~(BD_BREAKPOINT_STATE_MASK);
  143. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_IN_USE;
  144. #if 0
  145. if (Address < (PVOID)GLOBAL_BREAKPOINT_LIMIT) {
  146. BdBreakpointTable[Index].DirectoryTableBase =
  147. KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
  148. }
  149. #endif
  150. switch ((ULONG_PTR)Address & 0xf) {
  151. case 0:
  152. Content = (Content & ~(INST_SLOT0_MASK)) | (BdBreakpointInstruction << 5);
  153. break;
  154. case 4:
  155. Content = (Content & ~(INST_SLOT1_MASK)) | (BdBreakpointInstruction << 14);
  156. break;
  157. case 8:
  158. Content = (Content & ~(INST_SLOT2_MASK)) | (BdBreakpointInstruction << 23);
  159. break;
  160. default:
  161. // MmDbgReleaseAddress((PVOID) Address, &Opaque);
  162. //DPRINT(("KD: BdAddBreakpoint bad instruction slot#\n"));
  163. return 0;
  164. }
  165. if (BdMoveMemory(
  166. (PCHAR)Address,
  167. (PCHAR)&Content,
  168. sizeof(BD_BREAKPOINT_TYPE)
  169. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  170. // MmDbgReleaseAddress((PVOID) Address, &Opaque);
  171. //DPRINT(("KD: BdMoveMemory failed writing BP!\n"));
  172. return 0;
  173. }
  174. else {
  175. //DPRINT(("KD: breakpoint at 0x%08x set\n", Address));
  176. }
  177. // MmDbgReleaseAddress((PVOID) Address, &Opaque);
  178. } else { // memory not accessible
  179. BdBreakpointTable[Index].Address = Address;
  180. BdBreakpointTable[Index].Flags &= ~(BD_BREAKPOINT_STATE_MASK);
  181. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_IN_USE;
  182. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_WRITE;
  183. //DPRINT(("KD: breakpoint write deferred\n"));
  184. }
  185. #else // _IA64_
  186. if (Accessible) {
  187. BdBreakpointTable[Index].Address = Address;
  188. BdBreakpointTable[Index].Content = Content;
  189. BdBreakpointTable[Index].Flags = BD_BREAKPOINT_IN_USE;
  190. if (BdMoveMemory((PCHAR)Address,
  191. (PCHAR)&BdBreakpointInstruction,
  192. sizeof(BD_BREAKPOINT_TYPE)) != sizeof(BD_BREAKPOINT_TYPE)) {
  193. //DPRINT(("KD: BdMoveMemory failed writing BP!\n"));
  194. }
  195. } else {
  196. BdBreakpointTable[Index].Address = Address;
  197. BdBreakpointTable[Index].Flags = BD_BREAKPOINT_IN_USE | BD_BREAKPOINT_NEEDS_WRITE;
  198. //DPRINT(("KD: breakpoint write deferred\n"));
  199. }
  200. #endif // _IA64_
  201. return Index + 1;
  202. }
  203. LOGICAL
  204. BdLowWriteContent (
  205. IN ULONG Index
  206. )
  207. /*++
  208. Routine Description:
  209. This routine attempts to replace the code that a breakpoint is
  210. written over. This routine, BdAddBreakpoint,
  211. BdLowRestoreBreakpoint and KdSetOwedBreakpoints are responsible
  212. for getting data written as requested. Callers should not
  213. examine or use BdOweBreakpoints, and they should not set the
  214. NEEDS_WRITE or NEEDS_REPLACE flags.
  215. Callers must still look at the return value from this function,
  216. however: if it returns FALSE, the breakpoint record must not be
  217. reused until KdSetOwedBreakpoints has finished with it.
  218. Arguments:
  219. Index - Supplies the index of the breakpoint table entry
  220. which is to be deleted.
  221. Return Value:
  222. Returns TRUE if the breakpoint was removed, FALSE if it was deferred.
  223. --*/
  224. {
  225. #if defined(_IA64_)
  226. BD_BREAKPOINT_TYPE mBuf;
  227. PVOID BundleAddress;
  228. #endif
  229. //
  230. // Do the contents need to be replaced at all?
  231. //
  232. if (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_NEEDS_WRITE) {
  233. //
  234. // The breakpoint was never written out. Clear the flag
  235. // and we are done.
  236. //
  237. BdBreakpointTable[Index].Flags &= ~BD_BREAKPOINT_NEEDS_WRITE;
  238. //DPRINT(("KD: Breakpoint at 0x%08x never written; flag cleared.\n",
  239. // BdBreakpointTable[Index].Address));
  240. return TRUE;
  241. }
  242. #if !defined(_IA64_)
  243. if (BdBreakpointTable[Index].Content == BdBreakpointInstruction) {
  244. //
  245. // The instruction is a breakpoint anyway.
  246. //
  247. //DPRINT(("KD: Breakpoint at 0x%08x; instr is really BP; flag cleared.\n",
  248. // BdBreakpointTable[Index].Address));
  249. return TRUE;
  250. }
  251. #endif
  252. //
  253. // Restore the instruction contents.
  254. //
  255. #if defined(_IA64_)
  256. // Read in memory since adjancent instructions in the same bundle may have
  257. // been modified after we save them.
  258. if (BdMoveMemory(
  259. (PCHAR)&mBuf,
  260. (PCHAR)BdBreakpointTable[Index].Address,
  261. sizeof(BD_BREAKPOINT_TYPE)) != sizeof(BD_BREAKPOINT_TYPE)) {
  262. //DPRINT(("KD: read 0x%08x failed\n", BdBreakpointTable[Index].Address));
  263. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_REPLACE;
  264. return FALSE;
  265. }
  266. else {
  267. switch ((ULONG_PTR)BdBreakpointTable[Index].Address & 0xf) {
  268. case 0:
  269. mBuf = (mBuf & ~(INST_SLOT0_MASK))
  270. | (BdBreakpointTable[Index].Content & INST_SLOT0_MASK);
  271. break;
  272. case 4:
  273. mBuf = (mBuf & ~(INST_SLOT1_MASK))
  274. | (BdBreakpointTable[Index].Content & INST_SLOT1_MASK);
  275. break;
  276. case 8:
  277. mBuf = (mBuf & ~(INST_SLOT2_MASK))
  278. | (BdBreakpointTable[Index].Content & INST_SLOT2_MASK);
  279. break;
  280. default:
  281. //DPRINT(("KD: illegal instruction address 0x%08x\n", BdBreakpointTable[Index].Address));
  282. return FALSE;
  283. }
  284. if (BdMoveMemory(
  285. (PCHAR)BdBreakpointTable[Index].Address,
  286. (PCHAR)&mBuf,
  287. sizeof(BD_BREAKPOINT_TYPE)) != sizeof(BD_BREAKPOINT_TYPE)) {
  288. //DPRINT(("KD: write to 0x%08x failed\n", BdBreakpointTable[Index].Address));
  289. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_REPLACE;
  290. return FALSE;
  291. }
  292. else {
  293. if (BdMoveMemory(
  294. (PCHAR)&mBuf,
  295. (PCHAR)BdBreakpointTable[Index].Address,
  296. sizeof(BD_BREAKPOINT_TYPE)) == sizeof(BD_BREAKPOINT_TYPE)) {
  297. //DPRINT(("\tcontent after memory move = 0x%08x 0x%08x\n", (ULONG)(mBuf >> 32), (ULONG)mBuf));
  298. }
  299. // restore template to MLI if displaced instruction was MOVL
  300. if (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_IA64_MOVL) {
  301. (ULONG_PTR)BundleAddress = (ULONG_PTR)BdBreakpointTable[Index].Address & ~(0xf);
  302. if (BdMoveMemory(
  303. (PCHAR)&mBuf,
  304. (PCHAR)BundleAddress,
  305. sizeof(BD_BREAKPOINT_TYPE)
  306. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  307. //DPRINT(("KD: read template 0x%08x failed\n", BdBreakpointTable[Index].Address));
  308. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_REPLACE;
  309. return FALSE;
  310. }
  311. else {
  312. mBuf &= ~((INST_TEMPL_MASK >> 1) << 1); // set template to MLI
  313. mBuf |= 0x4;
  314. if (BdMoveMemory(
  315. (PCHAR)BundleAddress,
  316. (PCHAR)&mBuf,
  317. sizeof(BD_BREAKPOINT_TYPE)
  318. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  319. //DPRINT(("KD: write template to 0x%08x failed\n", BdBreakpointTable[Index].Address));
  320. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_REPLACE;
  321. return FALSE;
  322. } else {
  323. //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n",
  324. // BdBreakpointTable[Index].Address));
  325. return TRUE;
  326. }
  327. }
  328. }
  329. else { // not MOVL
  330. //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n",
  331. // BdBreakpointTable[Index].Address));
  332. return TRUE;
  333. }
  334. }
  335. }
  336. #else // _IA64_
  337. if (BdMoveMemory( (PCHAR)BdBreakpointTable[Index].Address,
  338. (PCHAR)&BdBreakpointTable[Index].Content,
  339. sizeof(BD_BREAKPOINT_TYPE) ) != sizeof(BD_BREAKPOINT_TYPE)) {
  340. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_REPLACE;
  341. //DPRINT(("KD: Breakpoint at 0x%08x; unable to clear, flag set.\n",
  342. //BdBreakpointTable[Index].Address));
  343. return FALSE;
  344. } else {
  345. //DPRINT(("KD: Breakpoint at 0x%08x cleared.\n",
  346. //BdBreakpointTable[Index].Address));
  347. return TRUE;
  348. }
  349. #endif // _IA64_
  350. }
  351. LOGICAL
  352. BdDeleteBreakpoint (
  353. IN ULONG Handle
  354. )
  355. /*++
  356. Routine Description:
  357. This routine deletes an entry from the breakpoint table.
  358. Arguments:
  359. Handle - Supplies the index plus one of the breakpoint table entry
  360. which is to be deleted.
  361. Return Value:
  362. A value of FALSE is returned if the specified handle is not a valid
  363. value or the breakpoint cannot be deleted because the old instruction
  364. cannot be replaced. Otherwise, a value of TRUE is returned.
  365. --*/
  366. {
  367. ULONG Index = Handle - 1;
  368. //
  369. // If the specified handle is not valid, then return FALSE.
  370. //
  371. if ((Handle == 0) || (Handle > BREAKPOINT_TABLE_SIZE)) {
  372. //DPRINT(("KD: Breakpoint %d invalid.\n", Index));
  373. return FALSE;
  374. }
  375. //
  376. // If the specified breakpoint table entry is not valid, then return FALSE.
  377. //
  378. if (BdBreakpointTable[Index].Flags == 0) {
  379. //DPRINT(("KD: Breakpoint %d already clear.\n", Index));
  380. return FALSE;
  381. }
  382. //
  383. // If the breakpoint is already suspended, just delete it from the table.
  384. //
  385. if (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_SUSPENDED) {
  386. //DPRINT(("KD: Deleting suspended breakpoint %d \n", Index));
  387. if ( !(BdBreakpointTable[Index].Flags & BD_BREAKPOINT_NEEDS_REPLACE) ) {
  388. //DPRINT(("KD: already clear.\n"));
  389. BdBreakpointTable[Index].Flags = 0;
  390. return TRUE;
  391. }
  392. }
  393. //
  394. // Replace the instruction contents.
  395. //
  396. if (BdLowWriteContent(Index)) {
  397. //
  398. // Delete breakpoint table entry
  399. //
  400. //DPRINT(("KD: Breakpoint %d deleted successfully.\n", Index));
  401. BdBreakpointTable[Index].Flags = 0;
  402. }
  403. return TRUE;
  404. }
  405. LOGICAL
  406. BdDeleteBreakpointRange (
  407. IN ULONG64 Lower,
  408. IN ULONG64 Upper
  409. )
  410. /*++
  411. Routine Description:
  412. This routine deletes all breakpoints falling in a given range
  413. from the breakpoint table.
  414. Arguments:
  415. Lower - inclusive lower address of range from which to remove BPs.
  416. Upper - include upper address of range from which to remove BPs.
  417. Return Value:
  418. TRUE if any breakpoints removed, FALSE otherwise.
  419. --*/
  420. {
  421. ULONG Index;
  422. BOOLEAN ReturnStatus = FALSE;
  423. //
  424. // Examine each entry in the table in turn
  425. //
  426. for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++) {
  427. if ( (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_IN_USE) &&
  428. ((BdBreakpointTable[Index].Address >= Lower) &&
  429. (BdBreakpointTable[Index].Address <= Upper))
  430. ) {
  431. //
  432. // Breakpoint is in use and falls in range, clear it.
  433. //
  434. ReturnStatus = ReturnStatus || BdDeleteBreakpoint(Index+1);
  435. }
  436. }
  437. return ReturnStatus;
  438. }
  439. VOID
  440. BdSuspendBreakpoint (
  441. ULONG Handle
  442. )
  443. {
  444. ULONG Index = Handle - 1;
  445. if ( (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_IN_USE) &&
  446. !(BdBreakpointTable[Index].Flags & BD_BREAKPOINT_SUSPENDED) ) {
  447. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_SUSPENDED;
  448. BdLowWriteContent(Index);
  449. }
  450. return;
  451. }
  452. VOID
  453. BdSuspendAllBreakpoints (
  454. VOID
  455. )
  456. {
  457. ULONG Handle;
  458. BreakpointsSuspended = TRUE;
  459. for ( Handle = 1; Handle <= BREAKPOINT_TABLE_SIZE; Handle++ ) {
  460. BdSuspendBreakpoint(Handle);
  461. }
  462. return;
  463. }
  464. LOGICAL
  465. BdLowRestoreBreakpoint (
  466. IN ULONG Index
  467. )
  468. /*++
  469. Routine Description:
  470. This routine attempts to write a breakpoint instruction.
  471. The old contents must have already been stored in the
  472. breakpoint record.
  473. Arguments:
  474. Index - Supplies the index of the breakpoint table entry
  475. which is to be written.
  476. Return Value:
  477. Returns TRUE if the breakpoint was written, FALSE if it was
  478. not and has been marked for writing later.
  479. --*/
  480. {
  481. BD_BREAKPOINT_TYPE Content;
  482. #if defined(_IA64_)
  483. BD_BREAKPOINT_TYPE mBuf;
  484. PVOID BundleAddress;
  485. #endif
  486. //
  487. // Does the breakpoint need to be written at all?
  488. //
  489. if (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_NEEDS_REPLACE) {
  490. //
  491. // The breakpoint was never removed. Clear the flag
  492. // and we are done.
  493. //
  494. BdBreakpointTable[Index].Flags &= ~BD_BREAKPOINT_NEEDS_REPLACE;
  495. return TRUE;
  496. }
  497. #if !defined(_IA64_)
  498. if (BdBreakpointTable[Index].Content == BdBreakpointInstruction) {
  499. //
  500. // The instruction is a breakpoint anyway.
  501. //
  502. return TRUE;
  503. }
  504. #endif
  505. //
  506. // Replace the instruction contents.
  507. //
  508. #if defined(_IA64_)
  509. // read in intruction in case the adjacent instruction has been modified.
  510. if (BdMoveMemory(
  511. (PCHAR)&mBuf,
  512. (PCHAR)BdBreakpointTable[Index].Address,
  513. sizeof(BD_BREAKPOINT_TYPE)
  514. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  515. //DPRINT(("KD: read 0x%p template failed\n", BdBreakpointTable[Index].Address));
  516. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_WRITE;
  517. return FALSE;
  518. }
  519. switch ((ULONG_PTR)BdBreakpointTable[Index].Address & 0xf) {
  520. case 0:
  521. mBuf = (mBuf & ~(INST_SLOT0_MASK)) | (BdBreakpointInstruction << 5);
  522. break;
  523. case 4:
  524. mBuf = (mBuf & ~(INST_SLOT1_MASK)) | (BdBreakpointInstruction << 14);
  525. break;
  526. case 8:
  527. mBuf = (mBuf & ~(INST_SLOT2_MASK)) | (BdBreakpointInstruction << 23);
  528. break;
  529. default:
  530. //DPRINT(("KD: BdAddBreakpoint bad instruction slot#\n"));
  531. return FALSE;
  532. }
  533. if (BdMoveMemory(
  534. (PCHAR)BdBreakpointTable[Index].Address,
  535. (PCHAR)&mBuf,
  536. sizeof(BD_BREAKPOINT_TYPE)
  537. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  538. //DPRINT(("KD: BdMoveMemory failed writing BP!\n"));
  539. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_WRITE;
  540. return FALSE;
  541. }
  542. else {
  543. // check for two-slot MOVL instruction. Reject request if attempt to
  544. // set break in slot 2 of MLI template.
  545. // change template to type 0 if current instruction is MLI
  546. if (((ULONG_PTR)BdBreakpointTable[Index].Address & 0xf) != 0) {
  547. (ULONG_PTR)BundleAddress = (ULONG_PTR)BdBreakpointTable[Index].Address & ~(0xf);
  548. if (BdMoveMemory(
  549. (PCHAR)&mBuf,
  550. (PCHAR)BundleAddress,
  551. sizeof(BD_BREAKPOINT_TYPE)
  552. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  553. //DPRINT(("KD: read template failed at 0x%08x\n", BundleAddress));
  554. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_WRITE;
  555. return FALSE;
  556. }
  557. else {
  558. if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) {
  559. if (((ULONG_PTR)BdBreakpointTable[Index].Address & 0xf) == 4) {
  560. // if template= type 2 MLI, change to type 0
  561. mBuf &= ~((INST_TEMPL_MASK >> 1) << 1);
  562. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_IA64_MOVL;
  563. if (BdMoveMemory(
  564. (PCHAR)BundleAddress,
  565. (PCHAR)&mBuf,
  566. sizeof(BD_BREAKPOINT_TYPE)
  567. ) != sizeof(BD_BREAKPOINT_TYPE)) {
  568. //DPRINT(("KD: write to 0x%08x template failed\n", BundleAddress));
  569. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_WRITE;
  570. return FALSE;
  571. }
  572. else {
  573. //DPRINT(("KD: change MLI template to type 0 at 0x%08x set\n", Address));
  574. }
  575. } else {
  576. // set breakpoint at slot 2 of MOVL is illegal
  577. //DPRINT(("KD: illegal to set BP at slot 2 of MOVL at 0x%08x\n", BundleAddress));
  578. BdBreakpointTable[Index].Flags |= BD_BREAKPOINT_NEEDS_WRITE;
  579. return FALSE;
  580. }
  581. }
  582. }
  583. }
  584. //DPRINT(("KD: breakpoint at 0x%08x set\n", Address));
  585. return TRUE;
  586. }
  587. #else // _IA64_
  588. BdMoveMemory((PCHAR)BdBreakpointTable[Index].Address,
  589. (PCHAR)&BdBreakpointInstruction,
  590. sizeof(BD_BREAKPOINT_TYPE));
  591. return TRUE;
  592. #endif // _IA64_
  593. }
  594. VOID
  595. BdRestoreAllBreakpoints (
  596. VOID
  597. )
  598. {
  599. ULONG Index;
  600. BreakpointsSuspended = FALSE;
  601. for ( Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++ ) {
  602. if ((BdBreakpointTable[Index].Flags & BD_BREAKPOINT_IN_USE) &&
  603. (BdBreakpointTable[Index].Flags & BD_BREAKPOINT_SUSPENDED) ) {
  604. BdBreakpointTable[Index].Flags &= ~BD_BREAKPOINT_SUSPENDED;
  605. BdLowRestoreBreakpoint(Index);
  606. }
  607. }
  608. return;
  609. }