00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "kdp.h"
00023
00024
00025
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
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 {
00086
00087
KDP_BREAKPOINT_TYPE Content;
00088 ULONG
Index;
00089 BOOLEAN Accessible;
00090 ULONG_PTR Opaque;
00091
00092
00093
00094
00095
00096
00097
00098
if (((ULONG_PTR)Address &
KDP_BREAKPOINT_ALIGN) != 0) {
00099
return 0;
00100 }
00101
00102
00103
00104
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
00115
00116
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
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
00142
00143
00144
00145
if (
Index == BREAKPOINT_TABLE_SIZE) {
00146
DPRINT((
"KD: ran out of breakpoints!\n"));
00147
return 0;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
if (
KdpMoveMemory(
00159 (PCHAR)&Content,
00160 (PCHAR)Address,
00161
sizeof(
KDP_BREAKPOINT_TYPE) ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00162 Accessible =
FALSE;
00163
00164 }
else {
00165
00166 Accessible =
TRUE;
00167 }
00168
00169
00170
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
00188
00189
00190
00191
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
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
00218 }
00219 }
else {
00220
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
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
00266 }
00267
00268 }
else {
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
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
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 }
00312
00313
00314
00315
VOID
00316 KdSetOwedBreakpoints(
00317 VOID
00318 )
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 {
00339
00340
KDP_BREAKPOINT_TYPE Content;
00341 BOOLEAN Enable;
00342 LONG
Index;
00343 ULONG_PTR Opaque;
00344
00345
00346
00347
00348
00349
if ( !
KdpOweBreakpoint ) {
00350
return;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 Enable =
KdEnterDebugger(
NULL,
NULL);
00360
KdpOweBreakpoint =
FALSE;
00361
00362
00363
00364
00365
00366
00367
for (
Index = 0;
Index < BREAKPOINT_TABLE_SIZE;
Index += 1) {
00368
if (
KdpBreakpointTable[
Index].
Flags &
00369 (
KD_BREAKPOINT_NEEDS_WRITE |
KD_BREAKPOINT_NEEDS_REPLACE) ) {
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
if ((
KdpBreakpointTable[
Index].
Address >= (PVOID)
GLOBAL_BREAKPOINT_LIMIT) ||
00381 (
KdpBreakpointTable[
Index].
DirectoryTableBase ==
00382
KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0])) {
00383
00384
00385
00386
00387
if (
MmDbgWriteCheck((PVOID)
KdpBreakpointTable[
Index].Address, &Opaque) ==
NULL) {
00388
KdpOweBreakpoint =
TRUE;
00389
00390
break;
00391 }
00392
00393
MmDbgReleaseAddress(
00394 (PVOID)
KdpBreakpointTable[
Index].Address,
00395 Opaque
00396 );
00397
00398
00399
00400
00401
00402
if (
KdpMoveMemory(
00403 (PCHAR)&Content,
00404 (PCHAR)
KdpBreakpointTable[
Index].Address,
00405
sizeof(
KDP_BREAKPOINT_TYPE)
00406 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00407
00408
00409
00410
00411
00412
00413
DPRINT((
"KD: read from 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00414
00415
KdpOweBreakpoint =
TRUE;
00416
00417 }
else {
00418
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_NEEDS_WRITE) {
00419
KdpBreakpointTable[
Index].
Content = Content;
00420
#if defined(_IA64_)
00421
switch ((ULONG_PTR)
KdpBreakpointTable[
Index].
Address & 0xf) {
00422
case 0:
00423 Content = (Content & ~(INST_SLOT0_MASK)) | (
KdpBreakpointInstruction << 5);
00424
break;
00425
00426
case 4:
00427 Content = (Content & ~(INST_SLOT1_MASK)) | (
KdpBreakpointInstruction << 14);
00428
break;
00429
00430
case 8:
00431 Content = (Content & ~(INST_SLOT2_MASK)) | (
KdpBreakpointInstruction << 23);
00432
break;
00433
00434
default:
00435
DPRINT((
"KD: illegal instruction address 0x%08x\n",
KdpBreakpointTable[
Index].Address));
00436
return;
00437 }
00438
if (
KdpMoveMemory(
00439 (PCHAR)
KdpBreakpointTable[
Index].Address,
00440 (PCHAR)&Content,
00441
sizeof(
KDP_BREAKPOINT_TYPE)
00442 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00443
KdpOweBreakpoint =
TRUE;
00444
DPRINT((
"KD: write to 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00445 }
00446
00447
00448
00449
00450
00451
else if (((ULONG_PTR)
KdpBreakpointTable[
Index].
Address & 0xf) != 0) {
00452
KDP_BREAKPOINT_TYPE mBuf;
00453 PVOID BundleAddress;
00454
00455 (ULONG_PTR)BundleAddress = (ULONG_PTR)
KdpBreakpointTable[
Index].
Address & ~(0xf);
00456
if (
KdpMoveMemory(
00457 (PCHAR)&mBuf,
00458 (PCHAR)BundleAddress,
00459
sizeof(
KDP_BREAKPOINT_TYPE)
00460 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00461
KdpOweBreakpoint =
TRUE;
00462
DPRINT((
"KD: read 0x%08x template failed\n",
KdpBreakpointTable[
Index].Address));
00463 }
else {
00464
if (((mBuf & INST_TEMPL_MASK) >> 1) == 0x2) {
00465
if (((ULONG_PTR)
KdpBreakpointTable[
Index].
Address & 0xf) == 4) {
00466
00467 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1);
00468
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_IA64_MOVL;
00469
if (
KdpMoveMemory(
00470 (PCHAR)BundleAddress,
00471 (PCHAR)&mBuf,
00472
sizeof(
KDP_BREAKPOINT_TYPE)
00473 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00474
KdpOweBreakpoint =
TRUE;
00475
DPRINT((
"KD: write to 0x%08x template failed\n",
KdpBreakpointTable[
Index].Address));
00476 }
00477
else {
00478
KdpBreakpointTable[
Index].
Flags &= ~(
KD_BREAKPOINT_STATE_MASK);
00479
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_IN_USE;
00480
00481 }
00482 }
else {
00483
00484
KdpOweBreakpoint =
TRUE;
00485
DPRINT((
"KD: illegal attempt to set BP at slot 2 of 0x%08x\n",
KdpBreakpointTable[
Index].Address));
00486 }
00487 }
00488
else {
00489
KdpBreakpointTable[
Index].
Flags &= ~(
KD_BREAKPOINT_STATE_MASK);
00490
KdpBreakpointTable[
Index].
Flags |=
KD_BREAKPOINT_IN_USE;
00491
00492 }
00493 }
00494 }
00495
#else
00496
if (
KdpMoveMemory(
00497 (PCHAR)
KdpBreakpointTable[
Index].Address,
00498 (PCHAR)&
KdpBreakpointInstruction,
00499
sizeof(
KDP_BREAKPOINT_TYPE)
00500 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00501
KdpOweBreakpoint =
TRUE;
00502
DPRINT((
"KD: write to 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00503 }
else {
00504
KdpBreakpointTable[
Index].
Flags =
KD_BREAKPOINT_IN_USE;
00505
DPRINT((
"KD: write to 0x%08x ok\n",
KdpBreakpointTable[
Index].Address));
00506 }
00507
#endif
00508
}
else {
00509
#if defined(_IA64_)
00510
00511
KDP_BREAKPOINT_TYPE mBuf;
00512 PVOID BundleAddress;
00513
00514
00515
00516
00517
00518
if (
KdpMoveMemory(
00519 (PCHAR)&mBuf,
00520 (PCHAR)
KdpBreakpointTable[
Index].Address,
00521
sizeof(
KDP_BREAKPOINT_TYPE)) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00522
KdpOweBreakpoint =
TRUE;
00523
DPRINT((
"KD: read 0x%08x template failed\n",
KdpBreakpointTable[
Index].Address));
00524 }
00525
else {
00526
switch ((ULONG_PTR)
KdpBreakpointTable[
Index].
Address & 0xf) {
00527
case 0:
00528 mBuf = (mBuf & ~(INST_SLOT0_MASK))
00529 | (
KdpBreakpointTable[
Index].
Content & INST_SLOT0_MASK);
00530
break;
00531
00532
case 4:
00533 mBuf = (mBuf & ~(INST_SLOT1_MASK))
00534 | (
KdpBreakpointTable[
Index].
Content & INST_SLOT1_MASK);
00535
break;
00536
00537
case 8:
00538 mBuf = (mBuf & ~(INST_SLOT2_MASK))
00539 | (
KdpBreakpointTable[
Index].
Content & INST_SLOT2_MASK);
00540
break;
00541
00542
default:
00543
KdpOweBreakpoint =
TRUE;
00544
DPRINT((
"KD: illegal instruction address 0x%08x\n",
KdpBreakpointTable[
Index].Address));
00545 }
00546
00547
if (
KdpMoveMemory(
00548 (PCHAR)
KdpBreakpointTable[
Index].Address,
00549 (PCHAR)&mBuf,
00550
sizeof(
KDP_BREAKPOINT_TYPE)) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00551
KdpOweBreakpoint =
TRUE;
00552
DPRINT((
"KD: write to 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00553 }
00554
else {
00555
00556
00557
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_IA64_MOVL) {
00558 (ULONG_PTR)BundleAddress = (ULONG_PTR)
KdpBreakpointTable[
Index].
Address & ~(0xf);
00559
if (
KdpMoveMemory(
00560 (PCHAR)&mBuf,
00561 (PCHAR)BundleAddress,
00562
sizeof(
KDP_BREAKPOINT_TYPE)
00563 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00564
KdpOweBreakpoint =
TRUE;
00565
DPRINT((
"KD: read template 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00566 }
00567
else {
00568 mBuf &= ~((INST_TEMPL_MASK >> 1) << 1);
00569 mBuf |= 0x4;
00570
00571
if (
KdpMoveMemory(
00572 (PCHAR)BundleAddress,
00573 (PCHAR)&mBuf,
00574
sizeof(
KDP_BREAKPOINT_TYPE)
00575 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00576
KdpOweBreakpoint =
TRUE;
00577
DPRINT((
"KD: write template to 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00578 }
else {
00579
00580
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_SUSPENDED) {
00581
KdpBreakpointTable[
Index].
Flags |= (
KD_BREAKPOINT_SUSPENDED |
KD_BREAKPOINT_IN_USE);
00582 }
else {
00583
KdpBreakpointTable[
Index].
Flags = 0;
00584 }
00585 }
00586 }
00587 }
else {
00588
00589
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_SUSPENDED) {
00590
KdpBreakpointTable[
Index].
Flags |= (
KD_BREAKPOINT_SUSPENDED |
KD_BREAKPOINT_IN_USE);
00591 }
else {
00592
KdpBreakpointTable[
Index].
Flags = 0;
00593 }
00594 }
00595 }
00596 }
00597
#else
00598
if (
KdpMoveMemory(
00599 (PCHAR)
KdpBreakpointTable[
Index].Address,
00600 (PCHAR)&
KdpBreakpointTable[
Index].Content,
00601
sizeof(
KDP_BREAKPOINT_TYPE)
00602 ) !=
sizeof(
KDP_BREAKPOINT_TYPE)) {
00603
KdpOweBreakpoint =
TRUE;
00604
DPRINT((
"KD: write to 0x%08x failed\n",
KdpBreakpointTable[
Index].Address));
00605 }
else {
00606
00607
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_SUSPENDED) {
00608
KdpBreakpointTable[
Index].
Flags =
KD_BREAKPOINT_SUSPENDED |
KD_BREAKPOINT_IN_USE;
00609 }
else {
00610
KdpBreakpointTable[
Index].
Flags = 0;
00611 }
00612 }
00613
#endif // _IA64_
00614
00615 }
00616 }
00617
00618 }
else {
00619
00620
00621
00622
00623
00624
KdpOweBreakpoint =
TRUE;
00625 }
00626 }
00627 }
00628
00629
KdExitDebugger(Enable);
00630
return;
00631 }
00632
00633
00634 BOOLEAN
00635 KdpLowWriteContent (
00636 IN ULONG Index
00637 )
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 {
00666
#if defined(_IA64_)
00667
KDP_BREAKPOINT_TYPE mBuf;
00668 PVOID BundleAddress;
00669
#endif
00670
00671
00672
00673
00674
00675
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_NEEDS_WRITE) {
00676
00677
00678
00679
00680
00681
00682
KdpBreakpointTable[
Index].
Flags &= ~
KD_BREAKPOINT_NEEDS_WRITE;
00683
00684
00685
return TRUE;
00686 }
00687
00688
#if !defined(_IA64_)
00689
if (
KdpBreakpointTable[
Index].
Content ==
KdpBreakpointInstruction) {
00690
00691
00692
00693
00694
00695
00696
00697
00698
return TRUE;
00699 }
00700
#endif
00701
00702
00703
00704
00705
00706
00707
#if defined(_IA64_)
00708
00709
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
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);
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
00792
00793
return TRUE;
00794 }
00795 }
00796 }
00797
else {
00798
00799
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
00812
00813
return FALSE;
00814 }
else {
00815
00816
00817
return TRUE;
00818 }
00819
#endif
00820
00821 }
00822
00823
00824
00825 BOOLEAN
00826 KdpDeleteBreakpoint (
00827 IN ULONG Handle
00828 )
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 {
00850 ULONG
Index =
Handle - 1;
00851
00852
00853
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
00863
00864
00865
if (
KdpBreakpointTable[
Index].
Flags == 0) {
00866
00867
return FALSE;
00868 }
00869
00870
00871
00872
00873
00874
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_SUSPENDED) {
00875
00876
if ( !(
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_NEEDS_REPLACE) ) {
00877
00878
KdpBreakpointTable[
Index].
Flags = 0;
00879
return TRUE;
00880 }
00881 }
00882
00883
00884
00885
00886
00887
if (
KdpLowWriteContent(
Index)) {
00888
00889
00890
00891
00892
00893
00894
KdpBreakpointTable[
Index].
Flags = 0;
00895 }
00896
00897
return TRUE;
00898 }
00899
00900
00901 BOOLEAN
00902 KdpDeleteBreakpointRange (
00903 IN PVOID Lower,
00904 IN PVOID Upper
00905 )
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 {
00927 ULONG
Index;
00928 BOOLEAN ReturnStatus =
FALSE;
00929
00930
00931
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
00943
00944
00945 ReturnStatus = ReturnStatus ||
KdpDeleteBreakpoint(
Index+1);
00946 }
00947 }
00948
00949
return ReturnStatus;
00950
00951 }
00952
00953
VOID
00954 KdpSuspendBreakpoint (
00955 ULONG Handle
00956 )
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 }
00970
00971
VOID
00972 KdpSuspendAllBreakpoints (
00973 VOID
00974 )
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 }
00987
00988
#if defined(_IA64_)
00989
00990
00991 BOOLEAN
00992 KdpSuspendBreakpointRange (
00993 IN PVOID Lower,
00994 IN PVOID Upper
00995 )
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 {
01021 ULONG
Index;
01022 BOOLEAN ReturnStatus =
FALSE;
01023
01024
DPRINT((
"\nKD: entering KdpSuspendBreakpointRange() at 0x%08x 0x%08x\n", Lower, Upper));
01025
01026
01027
01028
01029
01030
for (
Index = BREAKPOINT_TABLE_SIZE - 1;
Index != -1;
Index--) {
01031
01032
if ( (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_IN_USE) &&
01033 ((
KdpBreakpointTable[
Index].
Address >= Lower) &&
01034 (
KdpBreakpointTable[
Index].
Address <= Upper))
01035 ) {
01036
01037
01038
01039
01040
01041
KdpSuspendBreakpoint(Index+1);
01042 ReturnStatus =
TRUE;
01043 }
01044 }
01045
DPRINT((
"KD: exiting KdpSuspendBreakpointRange() return 0x%d\n", ReturnStatus));
01046
01047
return ReturnStatus;
01048
01049 }
01050
01051
01052
01053 BOOLEAN
01054 KdpRestoreBreakpointRange (
01055 IN PVOID Lower,
01056 IN PVOID Upper
01057 )
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 {
01083 ULONG
Index;
01084 BOOLEAN ReturnStatus =
FALSE;
01085
01086
DPRINT((
"\nKD: entering KdpRestoreBreakpointRange() at 0x%08x 0x%08x\n", Lower, Upper));
01087
01088
01089
01090
01091
01092
for (
Index = 0;
Index < BREAKPOINT_TABLE_SIZE;
Index++) {
01093
01094
if ( (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_IN_USE) &&
01095 ((
KdpBreakpointTable[
Index].
Address >= Lower) &&
01096 (
KdpBreakpointTable[
Index].
Address <= Upper))
01097 ) {
01098
01099
01100
01101
01102
01103
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_SUSPENDED) {
01104
01105
KdpBreakpointTable[
Index].
Flags &= ~
KD_BREAKPOINT_SUSPENDED;
01106 ReturnStatus = ReturnStatus ||
KdpLowRestoreBreakpoint(Index);
01107 }
01108 }
01109 }
01110
01111
DPRINT((
"KD: exiting KdpRestoreBreakpointRange() return 0x%d\n", ReturnStatus));
01112
01113
return ReturnStatus;
01114
01115 }
01116
01117
#endif // _IA64_
01118
01119
01120 BOOLEAN
01121 KdpLowRestoreBreakpoint (
01122 IN ULONG Index
01123 )
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
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
01154
01155
01156
if (
KdpBreakpointTable[
Index].
Flags &
KD_BREAKPOINT_NEEDS_REPLACE) {
01157
01158
01159
01160
01161
01162
01163
KdpBreakpointTable[
Index].
Flags &= ~
KD_BREAKPOINT_NEEDS_REPLACE;
01164
return TRUE;
01165 }
01166
01167
if (
KdpBreakpointTable[
Index].
Content ==
KdpBreakpointInstruction) {
01168
01169
01170
01171
01172
01173
return TRUE;
01174 }
01175
01176
01177
01178
01179
01180
#if !defined(_IA64_)
01181
if (
KdpBreakpointTable[
Index].
Content ==
KdpBreakpointInstruction) {
01182
01183
01184
01185
01186
01187
return TRUE;
01188 }
01189
#endif
01190
01191
01192
01193
01194
01195
#if defined(_IA64_)
01196
01197
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
01241
01242
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
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
01274 }
01275 }
else {
01276
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
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 }
01306
01307
01308
VOID
01309 KdpRestoreAllBreakpoints (
01310 VOID
01311 )
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 }
01330
01331
VOID
01332 KdDeleteAllBreakpoints(
01333 VOID
01334 )
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 }