00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
#include "kdp.h"
00032
00033
#if ACCASM && !defined(_MSC_VER)
00034
long asm(
const char *,...);
00035
#pragma intrinsic(asm)
00036
#endif
00037
00038 LARGE_INTEGER
KdpQueryPerformanceCounter (
00039 IN PKTRAP_FRAME TrapFrame
00040 );
00041
00042 extern LARGE_INTEGER
Magic10000;
00043 #define SHIFT10000 13
00044 #define Convert100nsToMilliseconds(LARGE_INTEGER) ( \
00045
RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000, SHIFT10000 ) \
00046
)
00047
00048
00049
00050
00051
00052
VOID
00053
KdpProcessInternalBreakpoint (
00054 ULONG BreakpointNumber
00055 );
00056
00057
VOID
00058
KdpGetVersion(
00059 IN PDBGKD_MANIPULATE_STATE64 m
00060 );
00061
00062
NTSTATUS
00063
KdpNotSupported(
00064 IN PDBGKD_MANIPULATE_STATE64 m
00065 );
00066
00067
VOID
00068
KdpCauseBugCheck(
00069 IN PDBGKD_MANIPULATE_STATE64 m
00070 );
00071
00072
NTSTATUS
00073
KdpWriteBreakPointEx(
00074 IN PDBGKD_MANIPULATE_STATE64 m,
00075 IN PSTRING AdditionalData,
00076 IN PCONTEXT Context
00077 );
00078
00079
VOID
00080
KdpRestoreBreakPointEx(
00081 IN PDBGKD_MANIPULATE_STATE64 m,
00082 IN PSTRING AdditionalData,
00083 IN PCONTEXT Context
00084 );
00085
00086
VOID
00087
KdpSearchMemory(
00088 IN PDBGKD_MANIPULATE_STATE64 m,
00089 IN PSTRING AdditionalData,
00090 IN PCONTEXT Context
00091 );
00092
00093 ULONG
00094
KdpSearchHammingDistance (
00095 ULONG_PTR Left,
00096 ULONG_PTR Right
00097 );
00098
00099 LOGICAL
00100
KdpSearchPhysicalPage (
00101 IN PFN_NUMBER PageFrameIndex,
00102 ULONG_PTR RangeStart,
00103 ULONG_PTR RangeEnd,
00104 ULONG Flags
00105 );
00106
00107 LOGICAL
00108
KdpSearchPhysicalMemoryRequested (
00109 VOID
00110 );
00111
00112 LOGICAL
00113
KdpSearchPhysicalPageRange (
00114 VOID
00115 );
00116
00117
00118
#if i386
00119
VOID
00120 InternalBreakpointCheck (
00121
PKDPC Dpc,
00122 PVOID DeferredContext,
00123 PVOID SystemArgument1,
00124 PVOID SystemArgument2
00125 );
00126
00127
VOID
00128 KdGetInternalBreakpoint(
00129 IN PDBGKD_MANIPULATE_STATE64 m
00130 );
00131
00132
long
00133 SymNumFor(
00134 ULONG_PTR pc
00135 );
00136
00137
void PotentialNewSymbol (ULONG_PTR pc);
00138
00139
void DumpTraceData(PSTRING MessageData);
00140
00141 BOOLEAN
00142 TraceDataRecordCallInfo(
00143 ULONG InstructionsTraced,
00144 LONG CallLevelChange,
00145 ULONG_PTR pc
00146 );
00147
00148 BOOLEAN
00149 SkippingWhichBP (
00150 PVOID thread,
00151 PULONG BPNum
00152 );
00153
00154 BOOLEAN
00155
KdpCheckTracePoint(
00156 IN PEXCEPTION_RECORD ExceptionRecord,
00157 IN OUT PCONTEXT ContextRecord
00158 );
00159
00160 ULONG_PTR
00161
KdpGetReturnAddress(
00162 IN PCONTEXT ContextRecord
00163 );
00164
00165 ULONG_PTR
00166
KdpGetCallNextOffset (
00167 ULONG_PTR Pc,
00168 IN PCONTEXT ContextRecord
00169 );
00170
00171 LONG
00172
KdpLevelChange (
00173 ULONG_PTR Pc,
00174 PCONTEXT ContextRecord,
00175 IN OUT PBOOLEAN SpecialCall
00176 );
00177
00178
#endif // i386
00179
00180
#ifdef ALLOC_PRAGMA
00181
#pragma alloc_text(PAGEKD, KdEnterDebugger)
00182
#pragma alloc_text(PAGEKD, KdExitDebugger)
00183
#pragma alloc_text(PAGEKD, KdpTimeSlipDpcRoutine)
00184
#pragma alloc_text(PAGEKD, KdpTimeSlipWork)
00185
#pragma alloc_text(PAGEKD, KdpSendWaitContinue)
00186
#pragma alloc_text(PAGEKD, KdpReadVirtualMemory)
00187
00188
#pragma alloc_text(PAGEKD, KdpWriteVirtualMemory)
00189
00190
#pragma alloc_text(PAGEKD, KdpGetContext)
00191
#pragma alloc_text(PAGEKD, KdpSetContext)
00192
#pragma alloc_text(PAGEKD, KdpWriteBreakpoint)
00193
#pragma alloc_text(PAGEKD, KdpRestoreBreakpoint)
00194
#pragma alloc_text(PAGEKD, KdpReportExceptionStateChange)
00195
#pragma alloc_text(PAGEKD, KdpReportLoadSymbolsStateChange)
00196
#pragma alloc_text(PAGEKD, KdpReadPhysicalMemory)
00197
#pragma alloc_text(PAGEKD, KdpWritePhysicalMemory)
00198
#pragma alloc_text(PAGEKD, KdpGetVersion)
00199
#pragma alloc_text(PAGEKD, KdpNotSupported)
00200
#pragma alloc_text(PAGEKD, KdpCauseBugCheck)
00201
#pragma alloc_text(PAGEKD, KdpWriteBreakPointEx)
00202
#pragma alloc_text(PAGEKD, KdpRestoreBreakPointEx)
00203
#pragma alloc_text(PAGEKD, KdpSearchMemory)
00204
#pragma alloc_text(PAGEKD, KdpSearchHammingDistance)
00205
#pragma alloc_text(PAGEKD, KdpSearchPhysicalPage)
00206
#pragma alloc_text(PAGEKD, KdpSearchPhysicalMemoryRequested)
00207
#pragma alloc_text(PAGEKD, KdpSearchPhysicalPageRange)
00208
#if DBG
00209
#pragma alloc_text(PAGEKD, KdpDprintf)
00210
#endif
00211
#if i386
00212
#pragma alloc_text(PAGEKD, InternalBreakpointCheck)
00213
#pragma alloc_text(PAGEKD, KdSetInternalBreakpoint)
00214
#pragma alloc_text(PAGEKD, KdGetTraceInformation)
00215
#pragma alloc_text(PAGEKD, KdGetInternalBreakpoint)
00216
#pragma alloc_text(PAGEKD, SymNumFor)
00217
#pragma alloc_text(PAGEKD, PotentialNewSymbol)
00218
#pragma alloc_text(PAGEKD, DumpTraceData)
00219
#pragma alloc_text(PAGEKD, TraceDataRecordCallInfo)
00220
#pragma alloc_text(PAGEKD, SkippingWhichBP)
00221
#pragma alloc_text(PAGEKD, KdQuerySpecialCalls)
00222
#pragma alloc_text(PAGEKD, KdSetSpecialCall)
00223
#pragma alloc_text(PAGEKD, KdClearSpecialCalls)
00224
#pragma alloc_text(PAGEKD, KdpCheckTracePoint)
00225
#pragma alloc_text(PAGEKD, KdpProcessInternalBreakpoint)
00226
#pragma alloc_text(PAGEKD, KdpCheckLowMemory)
00227
#endif // i386
00228
#endif // ALLOC_PRAGMA
00229
00230
00231
00232
00233
00234 LONG
KdDisableCount = 0 ;
00235 BOOLEAN
KdPreviouslyEnabled ;
00236
00237
00238
#if DBG
00239
VOID
00240 KdpDprintf(
00241 IN PCHAR f,
00242 ...
00243 )
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 {
00261
char buf[100];
00262 STRING Output;
00263 va_list mark;
00264
00265 va_start(mark, f);
00266 _vsnprintf(buf, 100, f, mark);
00267 va_end(mark);
00268
00269 Output.Buffer = buf;
00270 Output.Length =
strlen(Output.Buffer);
00271
KdpPrintString(&Output);
00272 }
00273
#endif // DBG
00274
00275
00276 BOOLEAN
00277 KdEnterDebugger(
00278 IN PKTRAP_FRAME TrapFrame,
00279 IN PKEXCEPTION_FRAME ExceptionFrame
00280 )
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 {
00305
00306 BOOLEAN Enable;
00307 TIME_FIELDS
TimeFields;
00308
#if DBG
00309
extern ULONG
KiFreezeFlag;
00310
#endif
00311
00312
00313
00314
00315
00316
00317
if (TrapFrame) {
00318
KdTimerStop =
KdpQueryPerformanceCounter (TrapFrame);
00319
KdTimerDifference.QuadPart =
KdTimerStop.QuadPart -
KdTimerStart.QuadPart;
00320 }
else {
00321
KdTimerStop.QuadPart = 0;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330 Enable =
KeFreezeExecution(TrapFrame, ExceptionFrame);
00331
KdpPortLocked =
KiTryToAcquireSpinLock(&
KdpDebuggerLock);
00332
KdPortSave();
00333
KdEnteredDebugger =
TRUE;
00334
00335
#if DBG
00336
00337
if ((
KiFreezeFlag &
FREEZE_BACKUP) != 0) {
00338
DPRINT((
"FreezeLock was jammed! Backup SpinLock was used!\n"));
00339 }
00340
00341
if ((
KiFreezeFlag &
FREEZE_SKIPPED_PROCESSOR) != 0) {
00342
DPRINT((
"Some processors not frozen in debugger!\n"));
00343 }
00344
00345
if (
KdpPortLocked ==
FALSE) {
00346
DPRINT((
"Port lock was not acquired!\n"));
00347 }
00348
00349
#endif
00350
00351
return Enable;
00352 }
00353
00354
VOID
00355 KdExitDebugger(
00356 IN BOOLEAN Enable
00357 )
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 {
00377 ULONG ElapsedTime;
00378 ULARGE_INTEGER TimeDifference;
00379 TIME_FIELDS
TimeFields;
00380 ULONG Pending;
00381
00382
00383
00384
00385
00386
KdPortRestore();
00387
if (
KdpPortLocked) {
00388
KdpPortUnlock();
00389 }
00390
00391
KeThawExecution(Enable);
00392
00393
00394
00395
00396
00397
00398
if (
KdTimerStop.QuadPart == 0) {
00399
KdTimerStart =
KdTimerStop;
00400 }
else {
00401
KdTimerStart =
KeQueryPerformanceCounter(
NULL);
00402 }
00403
00404
00405
00406
00407
00408
if (!
PoHiberInProgress) {
00409
00410 Pending = InterlockedIncrement(&
KdpTimeSlipPending);
00411
00412
00413
00414
00415
00416
if (Pending == 1) {
00417 InterlockedIncrement(&
KdpTimeSlipPending);
00418
KeInsertQueueDpc(&
KdpTimeSlipDpc,
NULL,
NULL);
00419 }
00420 }
00421
00422
return;
00423 }
00424
00425
00426
VOID
00427 KdUpdateTimeSlipEvent(
00428 PVOID Event
00429 )
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 {
00449 KIRQL OldIrql;
00450
00451
KeAcquireSpinLock(&
KdpTimeSlipEventLock, &OldIrql);
00452
00453
00454
00455
00456
00457
00458
if (
KdpTimeSlipEvent !=
NULL) {
00459
ObDereferenceObject(
KdpTimeSlipEvent);
00460 }
00461
00462
KdpTimeSlipEvent =
Event;
00463
00464
KeReleaseSpinLock(&
KdpTimeSlipEventLock, OldIrql);
00465 }
00466
00467
VOID
00468 KdpTimeSlipDpcRoutine (
00469
PKDPC Dpc,
00470 PVOID DeferredContext,
00471 PVOID SystemArgument1,
00472 PVOID SystemArgument2
00473 )
00474 {
00475 LONG OldCount, NewCount, j;
00476
00477
00478
00479
00480
00481
00482
00483 j =
KdpTimeSlipPending;
00484
do {
00485 OldCount = j;
00486 NewCount = OldCount > 1 ? 1 : 0;
00487
00488 j = InterlockedCompareExchange(&
KdpTimeSlipPending, NewCount, OldCount);
00489
00490 }
while (j != OldCount);
00491
00492
00493
00494
00495
00496
if (NewCount) {
00497
ExQueueWorkItem(&
KdpTimeSlipWorkItem,
DelayedWorkQueue);
00498 }
00499 }
00500
00501
VOID
00502 KdpTimeSlipWork (
00503 IN PVOID Context
00504 )
00505 {
00506 KIRQL OldIrql;
00507 LARGE_INTEGER DueTime;
00508
00509
00510
00511
00512
00513
ExAcquireTimeRefreshLock();
00514
ExUpdateSystemTimeFromCmos (
FALSE, 0);
00515
ExReleaseTimeRefreshLock();
00516
00517
00518
00519
00520
00521
KeAcquireSpinLock(&
KdpTimeSlipEventLock, &OldIrql);
00522
if (
KdpTimeSlipEvent) {
00523
KeSetEvent (
KdpTimeSlipEvent, 0,
FALSE);
00524 }
00525
KeReleaseSpinLock(&
KdpTimeSlipEventLock, OldIrql);
00526
00527
00528
00529
00530
00531 DueTime.QuadPart = -1800000000;
00532
KeSetTimer (&
KdpTimeSlipTimer, DueTime, &
KdpTimeSlipDpc);
00533 }
00534
00535
#if i386
00536
VOID
00537 InternalBreakpointCheck (
00538
PKDPC Dpc,
00539 PVOID DeferredContext,
00540 PVOID SystemArgument1,
00541 PVOID SystemArgument2
00542 )
00543 {
00544 LARGE_INTEGER dueTime;
00545 ULONG i;
00546
00547 UNREFERENCED_PARAMETER(Dpc);
00548 UNREFERENCED_PARAMETER(DeferredContext);
00549 UNREFERENCED_PARAMETER(SystemArgument1);
00550 UNREFERENCED_PARAMETER(SystemArgument2);
00551
00552 dueTime.LowPart = (ULONG)(-1 * 10 * 1000 * 1000);
00553 dueTime.HighPart = -1;
00554
00555
KeSetTimer(
00556 &InternalBreakpointTimer,
00557 dueTime,
00558 &InternalBreakpointCheckDpc
00559 );
00560
00561
for ( i = 0 ; i <
KdpNumInternalBreakpoints; i++ ) {
00562
if ( !(
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) &&
00563 (
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_COUNTONLY) ) {
00564
00565
PDBGKD_INTERNAL_BREAKPOINT b =
KdpInternalBPs + i;
00566 ULONG callsThisPeriod;
00567
00568 callsThisPeriod = b->
Calls - b->CallsLastCheck;
00569
if ( callsThisPeriod > b->MaxCallsPerPeriod ) {
00570 b->MaxCallsPerPeriod = callsThisPeriod;
00571 }
00572 b->CallsLastCheck = b->Calls;
00573 }
00574 }
00575
00576
return;
00577
00578 }
00579
00580
00581
VOID
00582 KdSetInternalBreakpoint (
00583 IN PDBGKD_MANIPULATE_STATE64 m
00584 )
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 {
00604 ULONG i;
00605
PDBGKD_INTERNAL_BREAKPOINT bp =
NULL;
00606 ULONG savedFlags;
00607
00608
for ( i = 0 ; i <
KdpNumInternalBreakpoints; i++ ) {
00609
if (
KdpInternalBPs[i].
Addr ==
00610 m->u.SetInternalBreakpoint.BreakpointAddress ) {
00611 bp = &
KdpInternalBPs[i];
00612
break;
00613 }
00614 }
00615
00616
if ( !bp ) {
00617
for ( i = 0; i <
KdpNumInternalBreakpoints; i++ ) {
00618
if (
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID ) {
00619 bp = &
KdpInternalBPs[i];
00620
break;
00621 }
00622 }
00623 }
00624
00625
if ( !bp ) {
00626
if (
KdpNumInternalBreakpoints >=
DBGKD_MAX_INTERNAL_BREAKPOINTS ) {
00627
return;
00628 }
00629 bp = &
KdpInternalBPs[
KdpNumInternalBreakpoints++];
00630 bp->
Flags |= DBGKD_INTERNAL_BP_FLAG_INVALID;
00631 }
00632
00633
if ( bp->Flags & DBGKD_INTERNAL_BP_FLAG_INVALID ) {
00634
if ( m->u.SetInternalBreakpoint.Flags &
00635 DBGKD_INTERNAL_BP_FLAG_INVALID ) {
00636
return;
00637 }
00638 bp->Calls = bp->MaxInstructions = bp->TotalInstructions = 0;
00639 bp->CallsLastCheck = bp->MaxCallsPerPeriod = 0;
00640 bp->MinInstructions = 0xffffffff;
00641 bp->Handle = 0;
00642 bp->Thread = 0;
00643 }
00644
00645 savedFlags = bp->Flags;
00646 bp->Flags = m->u.SetInternalBreakpoint.Flags;
00647 bp->Addr = m->u.SetInternalBreakpoint.BreakpointAddress;
00648
00649
if ( bp->Flags & (DBGKD_INTERNAL_BP_FLAG_INVALID |
00650 DBGKD_INTERNAL_BP_FLAG_SUSPENDED) ) {
00651
00652
if ( (bp->Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) &&
00653 (bp->Thread != 0) ) {
00654
00655 bp->Flags &= ~DBGKD_INTERNAL_BP_FLAG_INVALID;
00656 bp->Flags |= DBGKD_INTERNAL_BP_FLAG_DYING;
00657 }
00658
00659
00660
00661
if ( bp->Handle != 0 ) {
00662
KdpDeleteBreakpoint( bp->Handle );
00663 }
00664 bp->Handle = 0;
00665
00666
return;
00667 }
00668
00669
00670
00671
if ( savedFlags & (DBGKD_INTERNAL_BP_FLAG_INVALID |
00672 DBGKD_INTERNAL_BP_FLAG_SUSPENDED) ) {
00673
00674 bp->Handle =
KdpAddBreakpoint( (PVOID)bp->Addr );
00675 }
00676
00677
if (
BreakpointsSuspended ) {
00678
KdpSuspendBreakpoint( bp->Handle );
00679 }
00680
00681 }
00682
00683
NTSTATUS
00684 KdGetTraceInformation(
00685 PVOID SystemInformation,
00686 ULONG SystemInformationLength,
00687 PULONG ReturnLength
00688 )
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 {
00713 ULONG numEntries = 0;
00714 ULONG i = 0;
00715 PDBGKD_GET_INTERNAL_BREAKPOINT64 outPtr;
00716
00717
for ( i = 0; i <
KdpNumInternalBreakpoints; i++ ) {
00718
if ( !(
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) ) {
00719 numEntries++;
00720 }
00721 }
00722
00723 *ReturnLength = numEntries *
sizeof(DBGKD_GET_INTERNAL_BREAKPOINT64);
00724
if ( *ReturnLength > SystemInformationLength ) {
00725
return STATUS_INFO_LENGTH_MISMATCH;
00726 }
00727
00728
00729
00730
00731
00732 outPtr = (PDBGKD_GET_INTERNAL_BREAKPOINT64)SystemInformation;
00733
for ( i = 0; i <
KdpNumInternalBreakpoints; i++ ) {
00734
if ( !(
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) ) {
00735 outPtr->BreakpointAddress =
KdpInternalBPs[i].
Addr;
00736 outPtr->Flags =
KdpInternalBPs[i].
Flags;
00737 outPtr->Calls =
KdpInternalBPs[i].
Calls;
00738 outPtr->MaxCallsPerPeriod =
KdpInternalBPs[i].
MaxCallsPerPeriod;
00739 outPtr->MinInstructions =
KdpInternalBPs[i].
MinInstructions;
00740 outPtr->MaxInstructions =
KdpInternalBPs[i].
MaxInstructions;
00741 outPtr->TotalInstructions =
KdpInternalBPs[i].
TotalInstructions;
00742 outPtr++;
00743 }
00744 }
00745
00746
return STATUS_SUCCESS;
00747
00748 }
00749
00750
VOID
00751 KdGetInternalBreakpoint(
00752 IN PDBGKD_MANIPULATE_STATE64 m
00753 )
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 {
00773 ULONG i;
00774
PDBGKD_INTERNAL_BREAKPOINT bp =
NULL;
00775 STRING messageHeader;
00776
00777 messageHeader.Length =
sizeof(*m);
00778 messageHeader.Buffer = (PCHAR)m;
00779
00780
for ( i = 0; i <
KdpNumInternalBreakpoints; i++ ) {
00781
if ( !(
KdpInternalBPs[i].
Flags & (DBGKD_INTERNAL_BP_FLAG_INVALID |
00782 DBGKD_INTERNAL_BP_FLAG_SUSPENDED)) &&
00783 (
KdpInternalBPs[i].
Addr ==
00784 m->u.GetInternalBreakpoint.BreakpointAddress) ) {
00785 bp = &
KdpInternalBPs[i];
00786
break;
00787 }
00788 }
00789
00790
if ( !bp ) {
00791 m->u.GetInternalBreakpoint.
Flags = DBGKD_INTERNAL_BP_FLAG_INVALID;
00792 m->u.GetInternalBreakpoint.Calls = 0;
00793 m->u.GetInternalBreakpoint.MaxCallsPerPeriod = 0;
00794 m->u.GetInternalBreakpoint.MinInstructions = 0;
00795 m->u.GetInternalBreakpoint.MaxInstructions = 0;
00796 m->u.GetInternalBreakpoint.TotalInstructions = 0;
00797 m->ReturnStatus = STATUS_UNSUCCESSFUL;
00798 }
else {
00799 m->u.GetInternalBreakpoint.Flags = bp->Flags;
00800 m->u.GetInternalBreakpoint.Calls = bp->Calls;
00801 m->u.GetInternalBreakpoint.MaxCallsPerPeriod = bp->MaxCallsPerPeriod;
00802 m->u.GetInternalBreakpoint.MinInstructions = bp->MinInstructions;
00803 m->u.GetInternalBreakpoint.MaxInstructions = bp->MaxInstructions;
00804 m->u.GetInternalBreakpoint.TotalInstructions = bp->TotalInstructions;
00805 m->ReturnStatus = STATUS_SUCCESS;
00806 }
00807
00808 m->ApiNumber = DbgKdGetInternalBreakPointApi;
00809
00810
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
00811 &messageHeader,
00812 NULL
00813 );
00814
00815
return;
00816
00817 }
00818
#endif // i386
00819
00820
KCONTINUE_STATUS
00821 KdpSendWaitContinue (
00822 IN ULONG OutPacketType,
00823 IN PSTRING OutMessageHeader,
00824 IN PSTRING OutMessageData OPTIONAL,
00825 IN OUT PCONTEXT ContextRecord
00826 )
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 {
00860
00861 ULONG Length;
00862 STRING MessageData;
00863 STRING MessageHeader;
00864 DBGKD_MANIPULATE_STATE64 ManipulateState;
00865 ULONG ReturnCode;
00866
NTSTATUS Status;
00867
KCONTINUE_STATUS ContinueStatus;
00868
00869
00870
00871
00872
00873
00874 MessageHeader.MaximumLength =
sizeof(DBGKD_MANIPULATE_STATE64);
00875 MessageHeader.Buffer = (PCHAR)&ManipulateState;
00876 MessageData.MaximumLength =
KDP_MESSAGE_BUFFER_SIZE;
00877 MessageData.Buffer = (PCHAR)
KdpMessageBuffer;
00878
00879 ResendPacket:
00880
00881
00882
00883
00884
00885
00886
KdpSendPacket(
00887 OutPacketType,
00888 OutMessageHeader,
00889 OutMessageData
00890 );
00891
00892
00893
00894
00895
00896
00897
00898
00899
if (
KdDebuggerNotPresent) {
00900
return ContinueSuccess;
00901 }
00902
00903
while (
TRUE) {
00904
00905
00906
00907
00908
00909
do {
00910
00911 ReturnCode =
KdpReceivePacket(
00912 PACKET_TYPE_KD_STATE_MANIPULATE,
00913 &MessageHeader,
00914 &MessageData,
00915 &Length
00916 );
00917
if (ReturnCode == (
USHORT)
KDP_PACKET_RESEND) {
00918
goto ResendPacket;
00919 }
00920 }
while (ReturnCode ==
KDP_PACKET_TIMEOUT);
00921
00922
00923
00924
00925
00926
switch (ManipulateState.ApiNumber) {
00927
00928
case DbgKdReadVirtualMemoryApi:
00929
KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
00930
break;
00931
#if 0
00932
case DbgKdReadVirtualMemory64Api:
00933
KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
00934
break;
00935
#endif
00936
case DbgKdWriteVirtualMemoryApi:
00937
KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
00938
break;
00939
#if 0
00940
case DbgKdWriteVirtualMemory64Api:
00941
KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
00942
break;
00943
#endif
00944
00945
case DbgKdCheckLowMemoryApi:
00946
KdpCheckLowMemory (&ManipulateState);
00947
break;
00948
00949
case DbgKdReadPhysicalMemoryApi:
00950
KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
00951
break;
00952
00953
case DbgKdWritePhysicalMemoryApi:
00954
KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
00955
break;
00956
00957
case DbgKdGetContextApi:
00958
KdpGetContext(&ManipulateState,&MessageData,ContextRecord);
00959
break;
00960
00961
case DbgKdSetContextApi:
00962
KdpSetContext(&ManipulateState,&MessageData,ContextRecord);
00963
break;
00964
00965
case DbgKdWriteBreakPointApi:
00966
KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord);
00967
break;
00968
00969
case DbgKdRestoreBreakPointApi:
00970
KdpRestoreBreakpoint(&ManipulateState,&MessageData,ContextRecord);
00971
break;
00972
00973
case DbgKdReadControlSpaceApi:
00974
KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord);
00975
break;
00976
00977
case DbgKdWriteControlSpaceApi:
00978
KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord);
00979
break;
00980
00981
case DbgKdReadIoSpaceApi:
00982
KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord);
00983
break;
00984
00985
case DbgKdWriteIoSpaceApi:
00986
KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord);
00987
break;
00988
00989
#ifdef _ALPHA_
00990
00991
case DbgKdReadIoSpaceExtendedApi:
00992
KdpReadIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord);
00993
break;
00994
00995
case DbgKdWriteIoSpaceExtendedApi:
00996
KdpWriteIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord);
00997
break;
00998
00999
case DbgKdGetBusDataApi:
01000
KdpGetBusData(&ManipulateState,&MessageData,ContextRecord);
01001
break;
01002
01003
case DbgKdSetBusDataApi:
01004
KdpSetBusData(&ManipulateState,&MessageData,ContextRecord);
01005
break;
01006
01007
#endif // _ALPHA_
01008
01009
case DbgKdContinueApi:
01010
if (
NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) !=
FALSE) {
01011
return ContinueSuccess;
01012 }
else {
01013
return ContinueError;
01014 }
01015
break;
01016
01017
case DbgKdContinueApi2:
01018
if (
NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) !=
FALSE) {
01019
KdpGetStateChange(&ManipulateState,ContextRecord);
01020
return ContinueSuccess;
01021 }
else {
01022
return ContinueError;
01023 }
01024
break;
01025
01026
case DbgKdRebootApi:
01027
KdpReboot();
01028
break;
01029
01030
#if i386
01031
case DbgKdReadMachineSpecificRegister:
01032
KdpReadMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord);
01033
break;
01034
01035
case DbgKdWriteMachineSpecificRegister:
01036
KdpWriteMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord);
01037
break;
01038
01039
case DbgKdSetSpecialCallApi:
01040
KdSetSpecialCall(&ManipulateState,ContextRecord);
01041
break;
01042
01043
case DbgKdClearSpecialCallsApi:
01044
KdClearSpecialCalls();
01045
break;
01046
01047
case DbgKdSetInternalBreakPointApi:
01048 KdSetInternalBreakpoint(&ManipulateState);
01049
break;
01050
01051
case DbgKdGetInternalBreakPointApi:
01052 KdGetInternalBreakpoint(&ManipulateState);
01053
break;
01054
#endif
01055
01056
case DbgKdGetVersionApi:
01057
KdpGetVersion(&ManipulateState);
01058
break;
01059
01060
case DbgKdCauseBugCheckApi:
01061
KdpCauseBugCheck(&ManipulateState);
01062
break;
01063
01064
case DbgKdPageInApi:
01065
KdpNotSupported(&ManipulateState);
01066
break;
01067
01068
case DbgKdWriteBreakPointExApi:
01069
Status =
KdpWriteBreakPointEx(&ManipulateState,
01070 &MessageData,
01071 ContextRecord);
01072
if (
Status) {
01073 ManipulateState.ApiNumber = DbgKdContinueApi;
01074 ManipulateState.u.Continue.ContinueStatus =
Status;
01075
return ContinueError;
01076 }
01077
break;
01078
01079
case DbgKdRestoreBreakPointExApi:
01080
KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord);
01081
break;
01082
01083
case DbgKdSwitchProcessor:
01084
KdPortRestore ();
01085 ContinueStatus =
KeSwitchFrozenProcessor(ManipulateState.Processor);
01086
KdPortSave ();
01087
return ContinueStatus;
01088
01089
case DbgKdSearchMemoryApi:
01090
KdpSearchMemory(&ManipulateState, &MessageData, ContextRecord);
01091
break;
01092
01093
01094
01095
01096
01097
default:
01098 MessageData.Length = 0;
01099 ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
01100
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, &MessageData);
01101
break;
01102 }
01103
01104
#ifdef _ALPHA_
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
#if defined(_MSC_VER)
01115
__PAL_IMB();
01116
#else
01117
asm(
"call_pal 0x86" );
01118
#endif
01119
01120
#endif
01121
01122 }
01123 }
01124
01125
VOID
01126 KdpReadVirtualMemory(
01127 IN PDBGKD_MANIPULATE_STATE64 m,
01128 IN PSTRING AdditionalData,
01129 IN PCONTEXT Context
01130 )
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 {
01155 ULONG Length;
01156 STRING MessageHeader;
01157
#if defined(_ALPHA_) && !defined(_AXP64_)
01158
UCHAR * POINTER_64 Address;
01159 PUCHAR Destination;
01160 UCHAR * POINTER_64 Source;
01161 PUCHAR Source32;
01162
#endif
01163
01164
01165
01166
01167
01168 Length = m->u.ReadMemory.TransferCount;
01169
if (Length > (PACKET_MAX_SIZE -
sizeof(DBGKD_MANIPULATE_STATE64))) {
01170 Length = PACKET_MAX_SIZE -
sizeof(DBGKD_MANIPULATE_STATE64);
01171 }
01172
01173
01174
01175
01176
01177
#if defined(_ALPHA_) && !defined(_AXP64_)
01178
01179 AdditionalData->Length = (
USHORT)Length;
01180
01181 Destination = AdditionalData->Buffer;
01182 Source = (UCHAR * POINTER_64)m->u.ReadMemory.TargetBaseAddress;
01183 Source32 = (PUCHAR)m->u.ReadMemory.TargetBaseAddress;
01184
while (Length > 0) {
01185
if ((LONGLONG)Source != (LONGLONG)((LONG)Source)) {
01186
if ((Address =
MmDbgReadCheck64(Source)) == NULL64) {
01187
break;
01188 }
01189 }
else {
01190
if ((Address =
MmDbgReadCheck(Source32)) == NULL64) {
01191
break;
01192 }
01193 }
01194
01195 *Destination++ = *Address;
01196 Source += 1;
01197 Source32 += 1;
01198 Length -= 1;
01199 }
01200
01201
01202
01203
01204
01205
01206 m->ReturnStatus = STATUS_SUCCESS;
01207
if (Length != 0) {
01208 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01209 }
01210
01211
01212
01213
01214
01215
01216 m->u.ReadMemory.ActualBytesRead = AdditionalData->Length - Length;
01217
#else
01218
AdditionalData->Length = (
USHORT)
KdpMoveMemory(AdditionalData->Buffer,
01219 (PVOID)m->u.ReadMemory.TargetBaseAddress,
01220 Length);
01221
01222
01223
01224
01225
01226
01227 m->ReturnStatus = STATUS_SUCCESS;
01228
if (Length != AdditionalData->Length) {
01229 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01230 }
01231
01232
01233
01234
01235
01236
01237 m->u.ReadMemory.ActualBytesRead = AdditionalData->Length;
01238
#endif
01239
01240 MessageHeader.Length =
sizeof(DBGKD_MANIPULATE_STATE64);
01241 MessageHeader.Buffer = (PCHAR)m;
01242
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01243 &MessageHeader,
01244 AdditionalData);
01245
01246
return;
01247 }
01248
01249
#if 0
01250
VOID
01251
KdpReadVirtualMemory64(
01252 IN PDBGKD_MANIPULATE_STATE64 m,
01253 IN PSTRING AdditionalData,
01254 IN PCONTEXT Context
01255 )
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279 {
01280
01281 UCHAR * POINTER_64 Address;
01282 PUCHAR Destination;
01283 ULONG Length;
01284 STRING MessageHeader;
01285 UCHAR * POINTER_64 Source;
01286
01287
01288
01289
01290
01291 Length = m->u.ReadMemory64.TransferCount;
01292
if (Length > (PACKET_MAX_SIZE -
sizeof(DBGKD_MANIPULATE_STATE64))) {
01293 Length = PACKET_MAX_SIZE -
sizeof(DBGKD_MANIPULATE_STATE64);
01294 }
01295
01296
01297
01298
01299
01300 AdditionalData->Length = (
USHORT)Length;
01301
01302
#if defined(_MIPS_) || defined(_ALPHA_)
01303
01304 Destination = AdditionalData->Buffer;
01305 Source = (UCHAR * POINTER_64)m->u.ReadMemory64.TargetBaseAddress;
01306
while (Length > 0) {
01307
if ((Address =
MmDbgReadCheck64(Source)) == NULL64) {
01308
break;
01309 }
01310
01311 *Destination++ = *Address;
01312 Source += 1;
01313 Length -= 1;
01314 }
01315
01316
#endif
01317
01318
01319
01320
01321
01322
01323 m->ReturnStatus = STATUS_SUCCESS;
01324
if (Length != 0) {
01325 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01326 }
01327
01328
01329
01330
01331
01332
01333 m->u.ReadMemory64.ActualBytesRead = AdditionalData->Length - Length;
01334 MessageHeader.Length =
sizeof(DBGKD_MANIPULATE_STATE64);
01335 MessageHeader.Buffer = (PCHAR)m;
01336
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01337 &MessageHeader,
01338 AdditionalData);
01339
01340
return;
01341 }
01342
#endif
01343
01344
VOID
01345 KdpWriteVirtualMemory(
01346 IN PDBGKD_MANIPULATE_STATE64 m,
01347 IN PSTRING AdditionalData,
01348 IN PCONTEXT Context
01349 )
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373 {
01374
01375 ULONG Length;
01376 STRING MessageHeader;
01377 HARDWARE_PTE Opaque;
01378
01379
#if defined(_ALPHA_) && !defined(_AXP64_)
01380
UCHAR * POINTER_64 Address;
01381 UCHAR * POINTER_64 Destination;
01382 PUCHAR Address32;
01383 PUCHAR Source;
01384 PUCHAR Destination32;
01385
01386
01387
01388
01389
01390
01391 Length = AdditionalData->Length;
01392
01393 Destination = (UCHAR * POINTER_64)m->u.WriteMemory.TargetBaseAddress;
01394 Destination32 = (PUCHAR)m->u.WriteMemory.TargetBaseAddress;
01395 Source = AdditionalData->Buffer;
01396
while (Length > 0) {
01397 Address=Destination;
01398 Address32 =
NULL;
01399
if ((LONGLONG)Destination != (LONGLONG)((LONG)Destination)) {
01400
if ((Address =
MmDbgWriteCheck64(Destination)) == NULL64) {
01401
break;
01402 }
01403 }
else {
01404
if ((Address32 =
MmDbgWriteCheck(Destination32, &Opaque)) ==
NULL) {
01405
break;
01406 }
01407 }
01408
01409
if (Address32 !=
NULL) {
01410 *Address32 = *Source++;
01411
MmDbgReleaseAddress(Address32, &Opaque);
01412 }
01413
else {
01414 *Address = *Source++;
01415 }
01416 Destination += 1;
01417 Destination32 += 1;
01418 Length -= 1;
01419 }
01420
01421
01422
01423
01424
01425
01426 m->ReturnStatus = STATUS_SUCCESS;
01427
if (Length != 0) {
01428 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01429 }
01430
01431
01432
01433
01434
01435
01436 m->u.WriteMemory.ActualBytesWritten = AdditionalData->Length - Length;
01437 MessageHeader.Length =
sizeof(DBGKD_MANIPULATE_STATE64);
01438 MessageHeader.Buffer = (PCHAR)m;
01439
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01440 &MessageHeader,
01441
NULL);
01442
01443
return;
01444
#else
01445
01446
01447
01448
01449
01450 Length =
KdpMoveMemory((PVOID)m->u.WriteMemory.TargetBaseAddress,
01451 AdditionalData->Buffer,
01452 AdditionalData->Length);
01453
01454
01455
01456
01457
01458
01459 m->ReturnStatus = STATUS_SUCCESS;
01460
if (Length != AdditionalData->Length) {
01461 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01462 }
01463
01464
01465
01466
01467
01468
01469 m->u.WriteMemory.ActualBytesWritten = Length;
01470 MessageHeader.Length =
sizeof(DBGKD_MANIPULATE_STATE64);
01471 MessageHeader.Buffer = (PCHAR)m;
01472
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01473 &MessageHeader,
01474
NULL);
01475
01476
return;
01477
#endif
01478
}
01479
01480
#if 0
01481
VOID
01482
KdpWriteVirtualMemory64(
01483 IN PDBGKD_MANIPULATE_STATE64 m,
01484 IN PSTRING AdditionalData,
01485 IN PCONTEXT Context
01486 )
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 {
01511
01512 UCHAR * POINTER_64 Address;
01513 UCHAR * POINTER_64 Destination;
01514 ULONG Length;
01515 STRING MessageHeader;
01516 PUCHAR Source;
01517 ULONG_PTR Opaque;
01518
01519
01520
01521
01522
01523 Length = AdditionalData->Length;
01524
01525
#if defined(_MIPS_) || defined(_ALPHA_)
01526
01527 Destination = (UCHAR * POINTER_64)m->u.WriteMemory64.TargetBaseAddress;
01528 Source = AdditionalData->Buffer;
01529
while (Length > 0) {
01530
if ((Address =
MmDbgWriteCheck64(Destination, &Opaque)) == NULL64) {
01531
break;
01532 }
01533
01534 *Address = *Source++;
01535 Destination += 1;
01536 Length -= 1;
01537 }
01538
01539
#endif
01540
01541
01542
01543
01544
01545
01546 m->ReturnStatus = STATUS_SUCCESS;
01547
if (Length != 0) {
01548 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01549 }
01550
01551
01552
01553
01554
01555
01556 m->u.WriteMemory64.ActualBytesWritten = AdditionalData->Length - Length;
01557 MessageHeader.Length =
sizeof(DBGKD_MANIPULATE_STATE64);
01558 MessageHeader.Buffer = (PCHAR)m;
01559
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01560 &MessageHeader,
01561 NULL);
01562
01563
return;
01564 }
01565
#endif
01566
01567
01568
VOID
01569 KdpGetContext(
01570 IN PDBGKD_MANIPULATE_STATE64 m,
01571 IN PSTRING AdditionalData,
01572 IN PCONTEXT Context
01573 )
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597 {
01598 PDBGKD_GET_CONTEXT a = &m->u.GetContext;
01599 STRING MessageHeader;
01600
01601 MessageHeader.Length =
sizeof(*m);
01602 MessageHeader.Buffer = (PCHAR)m;
01603
01604
ASSERT(AdditionalData->Length == 0);
01605
01606
if (m->Processor >= (
USHORT)
KeNumberProcessors) {
01607 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01608 }
else {
01609 m->ReturnStatus = STATUS_SUCCESS;
01610 AdditionalData->Length =
sizeof(CONTEXT);
01611
if (m->Processor == (
USHORT)
KeGetCurrentPrcb()->Number) {
01612
KdpQuickMoveMemory(AdditionalData->Buffer, (PCHAR)Context,
sizeof(CONTEXT));
01613 }
else {
01614
KdpQuickMoveMemory(AdditionalData->Buffer,
01615 (PCHAR)&
KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame,
01616
sizeof(CONTEXT)
01617 );
01618 }
01619 }
01620
01621
KdpSendPacket(
01622 PACKET_TYPE_KD_STATE_MANIPULATE,
01623 &MessageHeader,
01624 AdditionalData
01625 );
01626 }
01627
01628
VOID
01629 KdpSetContext(
01630 IN PDBGKD_MANIPULATE_STATE64 m,
01631 IN PSTRING AdditionalData,
01632 IN PCONTEXT Context
01633 )
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657 {
01658 PDBGKD_SET_CONTEXT a = &m->u.SetContext;
01659 STRING MessageHeader;
01660
01661 MessageHeader.Length =
sizeof(*m);
01662 MessageHeader.Buffer = (PCHAR)m;
01663
01664
ASSERT(AdditionalData->Length ==
sizeof(CONTEXT));
01665
01666
if (m->Processor >= (
USHORT)
KeNumberProcessors) {
01667 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01668 }
else {
01669 m->ReturnStatus = STATUS_SUCCESS;
01670
if (m->Processor == (
USHORT)
KeGetCurrentPrcb()->Number) {
01671
KdpQuickMoveMemory((PCHAR)Context, AdditionalData->Buffer,
sizeof(CONTEXT));
01672 }
else {
01673
KdpQuickMoveMemory((PCHAR)&
KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame,
01674 AdditionalData->Buffer,
01675
sizeof(CONTEXT)
01676 );
01677 }
01678 }
01679
01680
KdpSendPacket(
01681 PACKET_TYPE_KD_STATE_MANIPULATE,
01682 &MessageHeader,
01683
NULL
01684 );
01685 }
01686
01687
VOID
01688 KdpWriteBreakpoint(
01689 IN PDBGKD_MANIPULATE_STATE64 m,
01690 IN PSTRING AdditionalData,
01691 IN PCONTEXT Context
01692 )
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716 {
01717 PDBGKD_WRITE_BREAKPOINT64 a = &m->u.WriteBreakPoint;
01718 STRING MessageHeader;
01719
01720 MessageHeader.Length =
sizeof(*m);
01721 MessageHeader.Buffer = (PCHAR)m;
01722
01723
ASSERT(AdditionalData->Length == 0);
01724
01725 a->BreakPointHandle =
KdpAddBreakpoint((PVOID)a->BreakPointAddress);
01726
if (a->BreakPointHandle != 0) {
01727 m->ReturnStatus = STATUS_SUCCESS;
01728 }
else {
01729 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01730 }
01731
KdpSendPacket(
01732 PACKET_TYPE_KD_STATE_MANIPULATE,
01733 &MessageHeader,
01734
NULL
01735 );
01736 UNREFERENCED_PARAMETER(Context);
01737 }
01738
01739
VOID
01740 KdpRestoreBreakpoint(
01741 IN PDBGKD_MANIPULATE_STATE64 m,
01742 IN PSTRING AdditionalData,
01743 IN PCONTEXT Context
01744 )
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 {
01769 PDBGKD_RESTORE_BREAKPOINT a = &m->u.RestoreBreakPoint;
01770 STRING MessageHeader;
01771
01772 MessageHeader.Length =
sizeof(*m);
01773 MessageHeader.Buffer = (PCHAR)m;
01774
01775
ASSERT(AdditionalData->Length == 0);
01776
if (
KdpDeleteBreakpoint(a->BreakPointHandle)) {
01777 m->ReturnStatus = STATUS_SUCCESS;
01778 }
else {
01779 m->ReturnStatus = STATUS_UNSUCCESSFUL;
01780 }
01781
KdpSendPacket(
01782 PACKET_TYPE_KD_STATE_MANIPULATE,
01783 &MessageHeader,
01784
NULL
01785 );
01786 UNREFERENCED_PARAMETER(Context);
01787 }
01788
01789
#if i386
01790
long
01791 SymNumFor(
01792 ULONG pc
01793 )
01794 {
01795 ULONG index;
01796
01797
for (index = 0; index <
NumTraceDataSyms; index++) {
01798
if ((
TraceDataSyms[index].
SymMin <= pc) &&
01799 (
TraceDataSyms[index].
SymMax > pc))
return(index);
01800 }
01801
return(-1);
01802 }
01803
01804 BOOLEAN TraceDataBufferFilled =
FALSE;
01805
01806
void PotentialNewSymbol (ULONG pc)
01807 {
01808
if (!TraceDataBufferFilled &&
01809 -1 != SymNumFor(pc)) {
01810
return;
01811 }
01812
01813 TraceDataBufferFilled =
FALSE;
01814
01815
01816
TraceDataBuffer[
TraceDataBufferPosition].s.LevelChange = 0;
01817
01818
if (-1 != SymNumFor(pc)) {
01819
int sym = SymNumFor(pc);
01820
TraceDataBuffer[
TraceDataBufferPosition].s.SymbolNumber = (UCHAR) sym;
01821
KdpCurrentSymbolStart =
TraceDataSyms[sym].
SymMin;
01822
KdpCurrentSymbolEnd =
TraceDataSyms[sym].
SymMax;
01823
01824
return;
01825 }
01826
01827
TraceDataSyms[
NextTraceDataSym].
SymMin =
KdpCurrentSymbolStart;
01828
TraceDataSyms[
NextTraceDataSym].
SymMax =
KdpCurrentSymbolEnd;
01829
01830
TraceDataBuffer[
TraceDataBufferPosition].s.SymbolNumber =
NextTraceDataSym;
01831
01832
01833
01834
NextTraceDataSym = (
NextTraceDataSym + 1) % 256;
01835
if (
NumTraceDataSyms <
NextTraceDataSym) {
01836
NumTraceDataSyms =
NextTraceDataSym;
01837 }
01838
01839 }
01840
01841
void DumpTraceData(PSTRING MessageData)
01842 {
01843
01844
TraceDataBuffer[0].LongNumber =
TraceDataBufferPosition;
01845 MessageData->Length =
sizeof(
TraceDataBuffer[0]) *
TraceDataBufferPosition;
01846 MessageData->Buffer = (PVOID)
TraceDataBuffer;
01847
TraceDataBufferPosition = 1;
01848 }
01849
01850 BOOLEAN
01851 TraceDataRecordCallInfo(
01852 ULONG InstructionsTraced,
01853 LONG CallLevelChange,
01854 ULONG pc
01855 )
01856 {
01857
01858
01859
01860
01861
long SymNum = SymNumFor(pc);
01862
01863
if (
KdpNextCallLevelChange != 0) {
01864
TraceDataBuffer[
TraceDataBufferPosition].s.LevelChange =
01865 (
char)
KdpNextCallLevelChange;
01866
KdpNextCallLevelChange = 0;
01867 }
01868
01869
01870
if (
InstructionsTraced >= TRACE_DATA_INSTRUCTIONS_BIG) {
01871
TraceDataBuffer[
TraceDataBufferPosition].s.Instructions =
01872 TRACE_DATA_INSTRUCTIONS_BIG;
01873
TraceDataBuffer[
TraceDataBufferPosition+1].LongNumber =
01874
InstructionsTraced;
01875
TraceDataBufferPosition += 2;
01876 }
else {
01877
TraceDataBuffer[
TraceDataBufferPosition].s.Instructions =
01878 (
unsigned short)
InstructionsTraced;
01879
TraceDataBufferPosition++;
01880 }
01881
01882
if ((
TraceDataBufferPosition + 2 >= TRACE_DATA_BUFFER_MAX_SIZE) ||
01883 (-1 == SymNum)) {
01884
if (
TraceDataBufferPosition +2 >= TRACE_DATA_BUFFER_MAX_SIZE) {
01885 TraceDataBufferFilled =
TRUE;
01886 }
01887
KdpNextCallLevelChange =
CallLevelChange;
01888
return FALSE;
01889 }
01890
01891
TraceDataBuffer[
TraceDataBufferPosition].s.LevelChange =(
char)
CallLevelChange;
01892
TraceDataBuffer[
TraceDataBufferPosition].s.SymbolNumber = (UCHAR) SymNum;
01893
KdpCurrentSymbolStart =
TraceDataSyms[SymNum].
SymMin;
01894
KdpCurrentSymbolEnd =
TraceDataSyms[SymNum].
SymMax;
01895
01896
return TRUE;
01897 }
01898
01899 BOOLEAN
01900 SkippingWhichBP (
01901 PVOID thread,
01902 PULONG BPNum
01903 )
01904
01905
01906
01907
01908
01909
01910
01911 {
01912 ULONG index;
01913
01914
if (!
IntBPsSkipping)
return FALSE;
01915
01916
for (index = 0; index <
KdpNumInternalBreakpoints; index++) {
01917
if (!(
KdpInternalBPs[index].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) &&
01918 (
KdpInternalBPs[index].
Thread == thread)) {
01919 *BPNum = index;
01920
return TRUE;
01921 }
01922 }
01923
return FALSE;
01924 }
01925
01926
01927
NTSTATUS
01928
KdQuerySpecialCalls (
01929 IN PDBGKD_MANIPULATE_STATE64 m,
01930 ULONG Length,
01931 PULONG RequiredLength
01932 )
01933 {
01934 *RequiredLength =
sizeof(DBGKD_MANIPULATE_STATE64) +
01935 (
sizeof(ULONG) *
KdNumberOfSpecialCalls);
01936
01937
if ( Length < *RequiredLength ) {
01938
return STATUS_INFO_LENGTH_MISMATCH;
01939 }
01940
01941 m->u.QuerySpecialCalls.NumberOfSpecialCalls =
KdNumberOfSpecialCalls;
01942 RtlCopyMemory(
01943 m + 1,
01944 KdSpecialCalls,
01945
sizeof(ULONG) * KdNumberOfSpecialCalls
01946 );
01947
01948
return STATUS_SUCCESS;
01949
01950 }
01951
01952
01953
VOID
01954
KdSetSpecialCall (
01955 IN PDBGKD_MANIPULATE_STATE64 m,
01956 IN PCONTEXT ContextRecord
01957 )
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 {
01977
if (
KdNumberOfSpecialCalls >=
DBGKD_MAX_SPECIAL_CALLS ) {
01978
return;
01979 }
01980
01981
KdSpecialCalls[
KdNumberOfSpecialCalls++] = (ULONG_PTR)m->u.SetSpecialCall.SpecialCall;
01982
01983
NextTraceDataSym = 0;
01984
NumTraceDataSyms = 0;
01985
KdpNextCallLevelChange = 0;
01986
if (ContextRecord && !
InstrCountInternal) {
01987
InitialSP = ContextRecord->Esp;
01988 }
01989
01990 }
01991
01992
01993
VOID
01994
KdClearSpecialCalls (
01995 VOID
01996 )
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016 {
02017
KdNumberOfSpecialCalls = 0;
02018
return;
02019
02020 }
02021
02022
02023 BOOLEAN
02024
KdpCheckTracePoint(
02025 IN PEXCEPTION_RECORD ExceptionRecord,
02026 IN OUT PCONTEXT ContextRecord
02027 )
02028 {
02029 ULONG pc = (ULONG)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
02030 LONG BpNum;
02031 ULONG SkippedBPNum;
02032 BOOLEAN AfterSC =
FALSE;
02033
02034
if (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) {
02035
if (
WatchStepOverSuspended) {
02036
02037
02038
02039
02040
02041
02042
02043
WatchStepOverHandle =
KdpAddBreakpoint((PVOID)WatchStepOverBreakAddr);
02044
WatchStepOverSuspended =
FALSE;
02045 ContextRecord->EFlags &= ~0x100
L;
02046
return TRUE;
02047 }
02048
02049
if ((!
SymbolRecorded) && (
KdpCurrentSymbolStart != 0) && (
KdpCurrentSymbolEnd != 0)) {
02050
02051
02052
02053
02054
02055
02056
02057
02058 PotentialNewSymbol(oldpc);
02059
SymbolRecorded =
TRUE;
02060 }
02061
02062
if (!
InstrCountInternal &&
02063 SkippingWhichBP((PVOID)
KeGetCurrentThread(),&SkippedBPNum)) {
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
if (
KdpInternalBPs[SkippedBPNum].
Flags &
02074 DBGKD_INTERNAL_BP_FLAG_COUNTONLY) {
02075
02076
IntBPsSkipping --;
02077
02078
KdpRestoreAllBreakpoints();
02079
02080 ContextRecord->EFlags &= ~0x100
L;
02081
KdpInternalBPs[SkippedBPNum].
Thread = 0;
02082
02083
if (
KdpInternalBPs[SkippedBPNum].
Flags &
02084 DBGKD_INTERNAL_BP_FLAG_DYING) {
02085
KdpDeleteBreakpoint(KdpInternalBPs[SkippedBPNum].Handle);
02086
KdpInternalBPs[SkippedBPNum].
Flags |=
02087 DBGKD_INTERNAL_BP_FLAG_INVALID;
02088 }
02089
02090
return TRUE;
02091 }
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
KdpCurrentSymbolEnd = 0;
02103
KdpCurrentSymbolStart = (ULONG_PTR)
KdpInternalBPs[SkippedBPNum].
ReturnAddress;
02104
02105 ContextRecord->EFlags |= 0x100
L;
02106
InitialSP = ContextRecord->Esp;
02107
02108
InstructionsTraced = 1;
02109
InstrCountInternal =
TRUE;
02110 }
02111
02112 }
02113
else if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) {
02114
if (
WatchStepOver && pc ==
WatchStepOverBreakAddr) {
02115
02116
02117
02118
02119
if ((
WSOThread != (PVOID)
KeGetCurrentThread()) ||
02120 (
WSOEsp + 0x20 < ContextRecord->Esp) ||
02121 (ContextRecord->Esp + 0x20 <
WSOEsp)) {
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
WatchStepOverSuspended =
TRUE;
02148
KdpDeleteBreakpoint(WatchStepOverHandle);
02149 ContextRecord->EFlags |= 0x100
L;
02150
return TRUE;
02151 }
02152
02153
02154
02155
02156
02157
02158
WatchStepOver =
FALSE;
02159
KdpDeleteBreakpoint(WatchStepOverHandle);
02160 ContextRecord->EFlags |= 0x100
L;
02161 AfterSC =
TRUE;
02162
02163 }
else {
02164
02165
for ( BpNum = 0; BpNum < (LONG)
KdpNumInternalBreakpoints; BpNum++ ) {
02166
if ( !(
KdpInternalBPs[BpNum].
Flags &
02167 (DBGKD_INTERNAL_BP_FLAG_INVALID |
02168 DBGKD_INTERNAL_BP_FLAG_SUSPENDED) ) &&
02169 (
KdpInternalBPs[BpNum].
Addr == pc) ) {
02170
break;
02171 }
02172 }
02173
02174
if ( BpNum < (LONG)
KdpNumInternalBreakpoints ) {
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
KdpProcessInternalBreakpoint( BpNum );
02185
KdpInternalBPs[BpNum].
Thread = (PVOID)
KeGetCurrentThread();
02186
IntBPsSkipping ++;
02187
02188
KdpSuspendAllBreakpoints();
02189
02190 ContextRecord->EFlags |= 0x100
L;
02191
if (!(
KdpInternalBPs[BpNum].
Flags &
02192 DBGKD_INTERNAL_BP_FLAG_COUNTONLY)) {
02193
KdpInternalBPs[BpNum].
ReturnAddress =
02194
KdpGetReturnAddress( ContextRecord );
02195 }
02196
return TRUE;
02197 }
02198 }
02199 }
02200
02201
02202
02203
02204
02205
if ((AfterSC || ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) &&
02206
KdpCurrentSymbolStart != 0 &&
02207 ((
KdpCurrentSymbolEnd == 0 && ContextRecord->Esp <=
InitialSP) ||
02208 (
KdpCurrentSymbolStart <= pc && pc <
KdpCurrentSymbolEnd))) {
02209 ULONG lc;
02210 BOOLEAN IsSpecialCall;
02211
02212
02213
02214
02215
02216
02217
02218 lc =
KdpLevelChange( pc, ContextRecord, &IsSpecialCall );
02219
InstructionsTraced++;
02220
CallLevelChange += lc;
02221
02222
02223
02224
02225
02226
02227
if (IsSpecialCall) {
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
if (lc != -1) {
02245
CallLevelChange -= lc;
02246 }
02247
02248
02249
02250
02251
02252
WatchStepOver =
TRUE;
02253
WatchStepOverBreakAddr =
KdpGetCallNextOffset( pc, ContextRecord );
02254
WSOThread = (PVOID)
KeGetCurrentThread( );
02255
WSOEsp = ContextRecord->Esp;
02256
02257
02258
02259
02260
02261
WatchStepOverHandle =
KdpAddBreakpoint( (PVOID)WatchStepOverBreakAddr );
02262
02263
02264
02265
02266
02267
02268
02269
02270 ContextRecord->EFlags &= ~0x100
L;
02271
return TRUE;
02272 }
02273
02274
02275
02276
02277
02278
02279 ContextRecord->EFlags |= 0x100
L;
02280
02281
return TRUE;
02282 }
02283
02284
if ((AfterSC || (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)) &&
02285 (
KdpCurrentSymbolStart != 0)) {
02286
02287
02288
02289
02290
02291
02292
int lc;
02293 BOOLEAN IsSpecialCall;
02294
02295
InstructionsTraced++;
02296
02297
02298
02299
02300
02301
if (
InstrCountInternal) {
02302
02303
02304
02305
02306 SkippingWhichBP((PVOID)
KeGetCurrentThread(),&SkippedBPNum);
02307
02308
KdpInternalBPs[SkippedBPNum].
Calls++;
02309
02310
02311
if (
KdpInternalBPs[SkippedBPNum].
MinInstructions >
InstructionsTraced) {
02312
KdpInternalBPs[SkippedBPNum].
MinInstructions =
InstructionsTraced;
02313 }
02314
if (
KdpInternalBPs[SkippedBPNum].
MaxInstructions <
InstructionsTraced) {
02315
KdpInternalBPs[SkippedBPNum].
MaxInstructions =
InstructionsTraced;
02316 }
02317
KdpInternalBPs[SkippedBPNum].
TotalInstructions +=
InstructionsTraced;
02318
02319
KdpInternalBPs[SkippedBPNum].
Thread = 0;
02320
02321
IntBPsSkipping--;
02322
InstrCountInternal =
FALSE;
02323
KdpCurrentSymbolStart = 0;
02324
KdpRestoreAllBreakpoints();
02325
02326
if (
KdpInternalBPs[SkippedBPNum].
Flags &
02327 DBGKD_INTERNAL_BP_FLAG_DYING) {
02328
KdpDeleteBreakpoint(KdpInternalBPs[SkippedBPNum].Handle);
02329
KdpInternalBPs[SkippedBPNum].
Flags |=
02330 DBGKD_INTERNAL_BP_FLAG_INVALID;
02331 }
02332
02333 ContextRecord->EFlags &= ~0x100
L;
02334
return TRUE;
02335 }
02336
02337
if (TraceDataRecordCallInfo( InstructionsTraced, CallLevelChange, pc)) {
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349 lc =
KdpLevelChange( pc, ContextRecord, &IsSpecialCall );
02350
InstructionsTraced = 0;
02351
CallLevelChange = lc;
02352
02353
02354
02355
02356
02357
02358
if (IsSpecialCall) {
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
if (lc != -1) {
02376
CallLevelChange -= lc;
02377 }
02378
02379
02380
02381
02382
02383
WatchStepOver =
TRUE;
02384
WSOThread = (PVOID)
KeGetCurrentThread();
02385
02386
02387
02388
02389
02390
WatchStepOverHandle =
02391
KdpAddBreakpoint( (PVOID)
KdpGetCallNextOffset( pc, ContextRecord ));
02392
02393
02394
02395
02396
02397
02398 ContextRecord->EFlags &= ~0x100
L;
02399
return TRUE;
02400 }
02401
02402 ContextRecord->EFlags |= 0x100
L;
02403
return TRUE;
02404 }
02405
02406 lc =
KdpLevelChange( pc, ContextRecord, &IsSpecialCall );
02407
InstructionsTraced = 0;
02408
CallLevelChange = lc;
02409
02410
02411
02412
if ((lc != 0) && IsSpecialCall) {
02413
02414
DPRINT((
"Special call on first entry to symbol scope @ %x\n", pc ));
02415 }
02416 }
02417
02418
SymbolRecorded =
FALSE;
02419
oldpc = pc;
02420
02421
return FALSE;
02422 }
02423
#endif // i386
02424
02425 BOOLEAN
02426 KdpSwitchProcessor (
02427 IN PEXCEPTION_RECORD ExceptionRecord,
02428 IN OUT PCONTEXT ContextRecord,
02429 IN BOOLEAN SecondChance
02430 )
02431 {
02432 BOOLEAN
Status;
02433
02434
02435
02436
02437
02438
KdPortSave ();
02439
02440
02441
02442
02443
02444
Status =
KdpReportExceptionStateChange (
02445 ExceptionRecord,
02446 ContextRecord,
02447 SecondChance
02448 );
02449
02450
02451
02452
02453
02454
KdPortRestore ();
02455
return Status;
02456 }
02457
02458 BOOLEAN
02459 KdpReportExceptionStateChange (
02460 IN PEXCEPTION_RECORD ExceptionRecord,
02461 IN OUT PCONTEXT ContextRecord,
02462 IN BOOLEAN SecondChance
02463 )
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488 {
02489 STRING MessageData;
02490 STRING MessageHeader;
02491 DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
02492
KCONTINUE_STATUS Status;
02493
02494
#if i386
02495
if (
KdpCheckTracePoint(ExceptionRecord,ContextRecord))
return TRUE;
02496
#endif
02497
02498
do {
02499
02500
02501
02502
02503
02504
KdpSetStateChange(&WaitStateChange,
02505 ExceptionRecord,
02506 ContextRecord,
02507 SecondChance
02508 );
02509
02510 MessageHeader.Length =
sizeof(DBGKD_WAIT_STATE_CHANGE64);
02511 MessageHeader.Buffer = (PCHAR)&WaitStateChange;
02512
02513
#if i386
02514
02515
02516
02517
02518 DumpTraceData(&MessageData);
02519
#else
02520
MessageData.Length = 0;
02521
#endif
02522
02523
02524
02525
02526
02527
02528
Status =
KdpSendWaitContinue(
02529 PACKET_TYPE_KD_STATE_CHANGE64,
02530 &MessageHeader,
02531 &MessageData,
02532 ContextRecord
02533 );
02534
02535 }
while (
Status ==
ContinueProcessorReselected) ;
02536
02537
return (BOOLEAN)
Status;
02538 }
02539
02540
02541 BOOLEAN
02542 KdpReportLoadSymbolsStateChange (
02543 IN PSTRING PathName,
02544 IN
PKD_SYMBOLS_INFO SymbolInfo,
02545 IN BOOLEAN UnloadSymbols,
02546 IN OUT PCONTEXT ContextRecord
02547 )
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578 {
02579
02580 PSTRING AdditionalData;
02581 STRING MessageData;
02582 STRING MessageHeader;
02583 DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
02584
KCONTINUE_STATUS Status;
02585
02586
do {
02587
02588
02589
02590
02591
02592 WaitStateChange.NewState = DbgKdLoadSymbolsStateChange;
02593 WaitStateChange.ProcessorLevel =
KeProcessorLevel;
02594 WaitStateChange.Processor = (
USHORT)
KeGetCurrentPrcb()->Number;
02595 WaitStateChange.NumberProcessors = (ULONG)
KeNumberProcessors;
02596 WaitStateChange.Thread = (ULONG64)(LONG64)(LONG_PTR)
KeGetCurrentThread();
02597 WaitStateChange.ProgramCounter = (ULONG64)(LONG64)(LONG_PTR) CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
02598
KdpSetLoadState(&WaitStateChange, ContextRecord);
02599 WaitStateChange.u.LoadSymbols.UnloadSymbols = UnloadSymbols;
02600 WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG64)SymbolInfo->BaseOfDll;
02601 WaitStateChange.u.LoadSymbols.ProcessId = (ULONG) SymbolInfo->ProcessId;
02602 WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
02603 WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
02604
if (ARGUMENT_PRESENT( PathName )) {
02605 WaitStateChange.u.LoadSymbols.PathNameLength =
02606
KdpMoveMemory(
02607 (PCHAR)
KdpPathBuffer,
02608 (PCHAR)PathName->Buffer,
02609 PathName->Length
02610 ) + 1;
02611
02612 MessageData.Buffer =
KdpPathBuffer;
02613 MessageData.Length = (
USHORT)WaitStateChange.u.LoadSymbols.PathNameLength;
02614 MessageData.Buffer[MessageData.Length-1] =
'\0';
02615 AdditionalData = &MessageData;
02616 }
else {
02617 WaitStateChange.u.LoadSymbols.PathNameLength = 0;
02618 AdditionalData =
NULL;
02619 }
02620
02621 MessageHeader.Length =
sizeof(DBGKD_WAIT_STATE_CHANGE64);
02622 MessageHeader.Buffer = (PCHAR)&WaitStateChange;
02623
02624
02625
02626
02627
02628
02629
Status =
KdpSendWaitContinue(
02630 PACKET_TYPE_KD_STATE_CHANGE64,
02631 &MessageHeader,
02632 AdditionalData,
02633 ContextRecord
02634 );
02635
02636 }
while (
Status ==
ContinueProcessorReselected);
02637
02638
return (BOOLEAN)
Status;
02639 }
02640
02641
02642
VOID
02643 KdpReadPhysicalMemory(
02644 IN PDBGKD_MANIPULATE_STATE64 m,
02645 IN PSTRING AdditionalData,
02646 IN PCONTEXT Context
02647 )
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671 {
02672 PDBGKD_READ_MEMORY64 a = &m->u.ReadMemory;
02673 ULONG Length;
02674 STRING MessageHeader;
02675 PVOID64 VirtualAddress;
02676 PHYSICAL_ADDRESS Source;
02677 UCHAR UNALIGNED *Destination;
02678 ULONG NumberBytes;
02679 ULONG BytesLeft;
02680
02681 MessageHeader.Length =
sizeof(*m);
02682 MessageHeader.Buffer = (PCHAR)m;
02683
02684
02685
02686
02687
02688
ASSERT(AdditionalData->Length == 0);
02689
02690
02691
02692
02693
02694
if (a->TransferCount > (PACKET_MAX_SIZE -
sizeof(DBGKD_MANIPULATE_STATE64))) {
02695 Length = PACKET_MAX_SIZE -
sizeof(DBGKD_MANIPULATE_STATE64);
02696 }
else {
02697 Length = a->TransferCount;
02698 }
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710 Source.QuadPart = a->TargetBaseAddress;
02711 Destination = AdditionalData->Buffer;
02712
while (Length > 0) {
02713 VirtualAddress =
MmDbgTranslatePhysicalAddress64(Source);
02714
if (VirtualAddress == NULL64) {
02715
break;
02716 }
02717 NumberBytes =
PAGE_SIZE -
BYTE_OFFSET(Source.LowPart);
02718
if (NumberBytes > Length) {
02719 NumberBytes = Length;
02720 }
02721
02722
#ifdef _ALPHA_
02723
BytesLeft = NumberBytes;
02724
while (BytesLeft > 0) {
02725 __MB();
02726
02727
if (((ULONG64)VirtualAddress & 7) == 0 && BytesLeft > 7) {
02728 *((ULONGLONG UNALIGNED *)Destination)++ =
02729 *((ULONGLONG * POINTER_64)VirtualAddress)++;
02730 BytesLeft -= 8;
02731 }
else {
02732
if (((ULONG64)VirtualAddress & 3) == 0 && BytesLeft > 3) {
02733 *((ULONG UNALIGNED *)Destination)++ =
02734 *((ULONG * POINTER_64)VirtualAddress)++;
02735 BytesLeft -= 4;
02736 }
else {
02737
if (((ULONG64)VirtualAddress & 1) == 0 && BytesLeft > 1) {
02738 *((
USHORT UNALIGNED *)Destination)++ =
02739 *((
USHORT * POINTER_64)VirtualAddress)++;
02740 BytesLeft -= 2;
02741 }
else {
02742 *Destination++ =
02743 *((UCHAR * POINTER_64)VirtualAddress)++;
02744 BytesLeft -= 1;
02745 }
02746 }
02747 }
02748 }
02749
#else
02750
KdpMoveMemory(Destination, VirtualAddress, NumberBytes);
02751 Destination += NumberBytes;
02752
02753
#endif
02754
Source.QuadPart += NumberBytes;
02755 Length -= NumberBytes;
02756 AdditionalData->Length += (
USHORT)NumberBytes;
02757 }
02758
02759
if (Length == 0) {
02760 m->ReturnStatus = STATUS_SUCCESS;
02761 }
else {
02762 m->ReturnStatus = STATUS_UNSUCCESSFUL;
02763 }
02764
02765 a->ActualBytesRead = AdditionalData->Length;
02766
02767
KdpSendPacket(
02768 PACKET_TYPE_KD_STATE_MANIPULATE,
02769 &MessageHeader,
02770 AdditionalData
02771 );
02772 UNREFERENCED_PARAMETER(Context);
02773
02774 }
02775
02776
02777
02778
VOID
02779 KdpWritePhysicalMemory(
02780 IN PDBGKD_MANIPULATE_STATE64 m,
02781 IN PSTRING AdditionalData,
02782 IN PCONTEXT Context
02783 )
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807 {
02808 PDBGKD_WRITE_MEMORY64 a = &m->u.WriteMemory;
02809 STRING MessageHeader;
02810 ULONG Length;
02811 PVOID64 VirtualAddress;
02812 PHYSICAL_ADDRESS Destination;
02813 UCHAR UNALIGNED *Source;
02814 ULONG NumberBytes;
02815 ULONG BytesLeft;
02816
02817 MessageHeader.Length =
sizeof(*m);
02818 MessageHeader.Buffer = (PCHAR)m;
02819
02820
02821 Length = a->TransferCount;
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838 Source = AdditionalData->Buffer;
02839 Destination.QuadPart = a->TargetBaseAddress;
02840
while (Length > 0) {
02841 VirtualAddress =
MmDbgTranslatePhysicalAddress64(Destination);
02842
if (VirtualAddress == NULL64) {
02843
break;
02844 }
02845 NumberBytes =
PAGE_SIZE -
BYTE_OFFSET(Destination.LowPart);
02846
if (NumberBytes > Length) {
02847 NumberBytes = Length;
02848 }
02849
#ifdef _ALPHA_
02850
BytesLeft = NumberBytes;
02851
while (BytesLeft > 0) {
02852
if (((ULONG64)VirtualAddress & 7) == 0 && BytesLeft > 7) {
02853 *((ULONGLONG * POINTER_64)VirtualAddress)++ =
02854 *((ULONGLONG UNALIGNED *)Source)++;
02855 BytesLeft -= 8;
02856 }
else {
02857
if (((ULONG64)VirtualAddress & 3) == 0 && BytesLeft > 3) {
02858 *((ULONG * POINTER_64)VirtualAddress)++ =
02859 *((ULONG UNALIGNED *)Source)++;
02860 BytesLeft -= 4;
02861 }
else {
02862
if (((ULONG64)VirtualAddress & 1) == 0 && BytesLeft > 1) {
02863 *((
USHORT * POINTER_64)VirtualAddress)++ =
02864 *((
USHORT UNALIGNED *)Source)++;
02865 BytesLeft -= 2;
02866 }
else {
02867 *((UCHAR * POINTER_64)VirtualAddress)++ =
02868 *(UCHAR UNALIGNED *)Source++;
02869 BytesLeft -= 1;
02870 }
02871 }
02872 }
02873
02874 __MB();
02875 }
02876
#else
02877
KdpMoveMemory(VirtualAddress, Source, NumberBytes);
02878 Source += NumberBytes;
02879
02880
#endif
02881
Destination.QuadPart += NumberBytes;
02882 Length -= NumberBytes;
02883 a->ActualBytesWritten += NumberBytes;
02884 }
02885
02886
if (Length == 0) {
02887 m->ReturnStatus = STATUS_SUCCESS;
02888 }
else {
02889 m->ReturnStatus = STATUS_UNSUCCESSFUL;
02890 }
02891
02892
KdpSendPacket(
02893 PACKET_TYPE_KD_STATE_MANIPULATE,
02894 &MessageHeader,
02895
NULL
02896 );
02897 UNREFERENCED_PARAMETER(Context);
02898 }
02899
02900
02901
02902
#if i386
02903
VOID
02904
KdpProcessInternalBreakpoint (
02905 ULONG BreakpointNumber
02906 )
02907 {
02908
static BOOLEAN timerStarted =
FALSE;
02909 LARGE_INTEGER dueTime;
02910
02911
if ( !(
KdpInternalBPs[BreakpointNumber].
Flags &
02912 DBGKD_INTERNAL_BP_FLAG_COUNTONLY) ) {
02913
return;
02914 }
02915
02916
02917
02918
02919
02920
02921
if ( !timerStarted ) {
02922 dueTime.LowPart = (ULONG)(-1 * 10 * 1000 * 1000);
02923 dueTime.HighPart = -1;
02924
KeInitializeDpc(
02925 &InternalBreakpointCheckDpc,
02926 &InternalBreakpointCheck,
02927 NULL
02928 );
02929
KeInitializeTimer( &InternalBreakpointTimer );
02930
KeSetTimer(
02931 &InternalBreakpointTimer,
02932 dueTime,
02933 &InternalBreakpointCheckDpc
02934 );
02935 timerStarted =
TRUE;
02936 }
02937
02938
KdpInternalBPs[BreakpointNumber].
Calls++;
02939
02940 }
02941
#endif
02942
02943
02944
VOID
02945 KdpGetVersion(
02946 IN PDBGKD_MANIPULATE_STATE64 m
02947 )
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968 {
02969 STRING messageHeader;
02970
02971
02972 messageHeader.Length =
sizeof(*m);
02973 messageHeader.Buffer = (PCHAR)m;
02974
02975 RtlZeroMemory(&m->u.GetVersion64,
sizeof(m->u.GetVersion64));
02976
02977
02978
02979 m->u.GetVersion64.MinorVersion = (
short)
NtBuildNumber;
02980 m->u.GetVersion64.MajorVersion = (
short)((
NtBuildNumber >> 28) & 0xFFFFFFF);
02981
02982
02983
02984
02985
02986 m->u.GetVersion64.ProtocolVersion = 5;
02987 m->u.GetVersion64.Flags = DBGKD_VERS_FLAG_DATA;
02988
02989
#if !defined(NT_UP)
02990
m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_MP;
02991
#endif
02992
02993
#if defined(_M_IX86)
02994
m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_I386;
02995
#elif defined(_M_MRX000)
02996
m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_R4000;
02997
#elif defined(_M_ALPHA)
02998
m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_ALPHA;
02999
#if defined(_AXP64_)
03000
m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_PTR64;
03001
#endif
03002
#elif defined(_M_PPC)
03003
m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_POWERPC;
03004
#elif defined(_M_IA64)
03005
m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_IA64;
03006 m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_PTR64;
03007
#else
03008
#error( "unknown target machine" );
03009
#endif
03010
03011
03012
03013
03014 m->u.GetVersion64.PsLoadedModuleList = (ULONG64)(LONG64)(LONG_PTR)&
PsLoadedModuleList;
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
if (
KdpNtosImageBase) {
03026 m->u.GetVersion64.KernBase = (ULONG64)(LONG64)(LONG_PTR)
KdpNtosImageBase;
03027 }
else {
03028 m->u.GetVersion64.KernBase = (ULONG64)(LONG64)(LONG_PTR)
PsNtosImageBase;
03029 }
03030
03031 m->u.GetVersion64.DebuggerDataList = (ULONG64)(LONG64)(LONG_PTR)&
KdpDebuggerDataListHead;
03032
03033
03034
03035
03036 m->ReturnStatus = STATUS_SUCCESS;
03037 m->ApiNumber = DbgKdGetVersionApi;
03038
03039
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
03040 &messageHeader,
03041
NULL
03042 );
03043
03044
return;
03045 }
03046
03047
03048
NTSTATUS
03049 KdpNotSupported(
03050 IN PDBGKD_MANIPULATE_STATE64 m
03051 )
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069 {
03070 STRING MessageHeader;
03071
03072
03073
03074
03075 MessageHeader.Length =
sizeof(*m);
03076 MessageHeader.Buffer = (PCHAR)m;
03077 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03078
03079
03080
03081
03082
KdpSendPacket(
03083 PACKET_TYPE_KD_STATE_MANIPULATE,
03084 &MessageHeader,
03085
NULL
03086 );
03087
03088
03089
03090
03091
03092
return 0;
03093 }
03094
03095
03096
VOID
03097 KdpCauseBugCheck(
03098 IN PDBGKD_MANIPULATE_STATE64 m
03099 )
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117 {
03118
03119
KeBugCheckEx( MANUALLY_INITIATED_CRASH, 0, 0, 0, 0 );
03120
03121 }
03122
03123
03124
NTSTATUS
03125 KdpWriteBreakPointEx(
03126 IN PDBGKD_MANIPULATE_STATE64 m,
03127 IN PSTRING AdditionalData,
03128 IN PCONTEXT Context
03129 )
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162 {
03163 PDBGKD_BREAKPOINTEX a = &m->u.BreakPointEx;
03164 PDBGKD_WRITE_BREAKPOINT64 b;
03165 STRING MessageHeader;
03166 ULONG i;
03167 DBGKD_WRITE_BREAKPOINT64 BpBuf[BREAKPOINT_TABLE_SIZE];
03168
03169
03170 MessageHeader.Length =
sizeof(*m);
03171 MessageHeader.Buffer = (PCHAR)m;
03172
03173
03174
03175
03176
if (AdditionalData->Length !=
03177 a->BreakPointCount*
sizeof(DBGKD_WRITE_BREAKPOINT64)) {
03178 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03179
KdpSendPacket(
03180 PACKET_TYPE_KD_STATE_MANIPULATE,
03181 &MessageHeader,
03182 AdditionalData
03183 );
03184
return m->ReturnStatus;
03185 }
03186
03187
KdpMoveMemory((PUCHAR)BpBuf,
03188 AdditionalData->Buffer,
03189 a->BreakPointCount*
sizeof(DBGKD_WRITE_BREAKPOINT64));
03190
03191
03192
03193
03194 m->ReturnStatus = STATUS_SUCCESS;
03195
03196
03197
03198
03199
03200 b = BpBuf;
03201
for (i=0; i<a->BreakPointCount; i++,b++) {
03202
if (b->BreakPointHandle) {
03203
if (!
KdpDeleteBreakpoint(b->BreakPointHandle)) {
03204 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03205 }
03206 b->BreakPointHandle = 0;
03207 }
03208 }
03209
03210
03211
03212
03213
03214 b = BpBuf;
03215
for (i=0; i<a->BreakPointCount; i++,b++) {
03216
if (b->BreakPointAddress) {
03217 b->BreakPointHandle =
KdpAddBreakpoint( (PVOID)b->BreakPointAddress );
03218
if (!b->BreakPointHandle) {
03219 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03220 }
03221 }
03222 }
03223
03224
03225
03226
03227
03228
KdpMoveMemory(AdditionalData->Buffer,
03229 (PUCHAR)BpBuf,
03230 a->BreakPointCount*
sizeof(DBGKD_WRITE_BREAKPOINT64));
03231
03232
KdpSendPacket(
03233 PACKET_TYPE_KD_STATE_MANIPULATE,
03234 &MessageHeader,
03235 AdditionalData
03236 );
03237
03238
03239
03240
03241
03242
return a->ContinueStatus;
03243 }
03244
03245
03246
VOID
03247 KdpRestoreBreakPointEx(
03248 IN PDBGKD_MANIPULATE_STATE64 m,
03249 IN PSTRING AdditionalData,
03250 IN PCONTEXT Context
03251 )
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274 {
03275 PDBGKD_BREAKPOINTEX a = &m->u.BreakPointEx;
03276 PDBGKD_RESTORE_BREAKPOINT b;
03277 STRING MessageHeader;
03278 ULONG i;
03279 DBGKD_RESTORE_BREAKPOINT BpBuf[BREAKPOINT_TABLE_SIZE];
03280
03281
03282 MessageHeader.Length =
sizeof(*m);
03283 MessageHeader.Buffer = (PCHAR)m;
03284
03285
03286
03287
03288
if (AdditionalData->Length !=
03289 a->BreakPointCount*
sizeof(DBGKD_RESTORE_BREAKPOINT)) {
03290 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03291
KdpSendPacket(
03292 PACKET_TYPE_KD_STATE_MANIPULATE,
03293 &MessageHeader,
03294 AdditionalData
03295 );
03296
return;
03297 }
03298
03299
KdpMoveMemory((PUCHAR)BpBuf,
03300 AdditionalData->Buffer,
03301 a->BreakPointCount*
sizeof(DBGKD_RESTORE_BREAKPOINT));
03302
03303
03304
03305
03306 m->ReturnStatus = STATUS_SUCCESS;
03307
03308
03309
03310
03311
03312 b = BpBuf;
03313
for (i=0; i<a->BreakPointCount; i++,b++) {
03314
if (!
KdpDeleteBreakpoint(b->BreakPointHandle)) {
03315 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03316 }
03317 }
03318
03319
03320
03321
03322
KdpSendPacket(
03323 PACKET_TYPE_KD_STATE_MANIPULATE,
03324 &MessageHeader,
03325 AdditionalData
03326 );
03327 }
03328
03329
VOID
03330 KdDisableDebugger(
03331 VOID
03332 )
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349 {
03350 KIRQL oldIrql ;
03351
03352
KeRaiseIrql(
DISPATCH_LEVEL, &oldIrql) ;
03353
KdpPortLock();
03354
03355
if (!
KdDisableCount) {
03356
03357
KdPreviouslyEnabled =
KdDebuggerEnabled && (!
KdPitchDebugger) ;
03358
if (
KdDebuggerEnabled) {
03359
03360
KdpSuspendAllBreakpoints() ;
03361
KiDebugRoutine =
KdpStub;
03362
KdDebuggerEnabled =
FALSE ;
03363 }
03364 }
03365
KdDisableCount++ ;
03366
KdpPortUnlock();
03367
KeLowerIrql(oldIrql);
03368 }
03369
03370
VOID
03371 KdEnableDebugger(
03372 VOID
03373 )
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390 {
03391 KIRQL oldIrql ;
03392
03393
KeRaiseIrql(
DISPATCH_LEVEL, &oldIrql) ;
03394
KdpPortLock();
03395
03396
ASSERT(
KdDisableCount > 0) ;
03397
KdDisableCount-- ;
03398
03399
if (!
KdDisableCount) {
03400
if (
KdPreviouslyEnabled) {
03401
03402
03403
03404
03405
PoHiberInProgress =
TRUE ;
03406
KdInitSystem(
NULL,
FALSE) ;
03407
KdpRestoreAllBreakpoints();
03408
PoHiberInProgress =
FALSE ;
03409 }
03410 }
03411
KdpPortUnlock();
03412
KeLowerIrql(oldIrql);
03413 }
03414
03415
03416
VOID
03417 KdpSearchMemory(
03418 IN PDBGKD_MANIPULATE_STATE64 m,
03419 IN PSTRING AdditionalData,
03420 IN PCONTEXT Context
03421 )
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446 {
03447 PUCHAR
Pattern = AdditionalData->Buffer;
03448 ULONG_PTR StartAddress = (ULONG_PTR)m->u.SearchMemory.SearchAddress;
03449 ULONG_PTR EndAddress = (ULONG_PTR)(StartAddress + m->u.SearchMemory.SearchLength);
03450 ULONG PatternLength = m->u.SearchMemory.PatternLength;
03451
03452 STRING MessageHeader;
03453 ULONG MaskIndex;
03454 PUCHAR PatternTail;
03455 PUCHAR DataTail;
03456 ULONG TailLength;
03457 ULONG Data;
03458 ULONG FirstWordPattern[4];
03459 ULONG FirstWordMask[4];
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469 m->ReturnStatus = STATUS_NO_MORE_ENTRIES;
03470
03471
03472
03473
03474
03475
if (PatternLength > 3) {
03476 FirstWordMask[0] = 0xffffffff;
03477 }
else {
03478 FirstWordMask[0] = 0xffffffff >> (8*(4-PatternLength));
03479 }
03480
03481 FirstWordMask[1] = FirstWordMask[0] << 8;
03482 FirstWordMask[2] = FirstWordMask[1] << 8;
03483 FirstWordMask[3] = FirstWordMask[2] << 8;
03484
03485 FirstWordPattern[0] = 0;
03486
KdpQuickMoveMemory((PVOID)FirstWordPattern,
03487
Pattern,
03488 PatternLength < 5 ? PatternLength : 4);
03489
03490 FirstWordPattern[1] = FirstWordPattern[0] << 8;
03491 FirstWordPattern[2] = FirstWordPattern[1] << 8;
03492 FirstWordPattern[3] = FirstWordPattern[2] << 8;
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513 MaskIndex = (ULONG) (StartAddress & 3);
03514 StartAddress = StartAddress & ~3;
03515
03516
03517
03518
03519
03520
if (
MmDbgReadCheck((PVOID)StartAddress) ==
NULL) {
03521 StartAddress = (StartAddress +
PAGE_SIZE) & ~(
PAGE_SIZE-1);
03522 MaskIndex = 0;
03523 }
03524
03525
while (StartAddress < EndAddress) {
03526
03527
03528
03529
03530
if ((StartAddress & (
PAGE_SIZE-1)) == 0) {
03531
if (
MmDbgReadCheck((PVOID)StartAddress) ==
NULL) {
03532 StartAddress = StartAddress +
PAGE_SIZE;
03533
continue;
03534 }
03535 }
03536
03537
03538
03539
03540
03541 Data = *(ULONG*)StartAddress;
03542
03543
03544
for ( ; MaskIndex < 4; MaskIndex++) {
03545
03546
03547
if ( (Data & FirstWordMask[MaskIndex]) == FirstWordPattern[MaskIndex]) {
03548
03549
03550
03551
03552
03553
if ( (4-MaskIndex) >= PatternLength ) {
03554
03555
03556
03557
03558
03559
03560 m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex;
03561 m->ReturnStatus = STATUS_SUCCESS;
03562
goto done;
03563
03564 }
else {
03565
03566
03567
03568
03569
03570
03571 PatternTail =
Pattern + 4 - MaskIndex;
03572 DataTail = (PUCHAR)StartAddress + 4;
03573 TailLength = PatternLength - 4 + MaskIndex;
03574
03575
03576
03577
03578
03579
while (TailLength) {
03580
if ( ((ULONG_PTR)DataTail & (
PAGE_SIZE-1)) == 0 &&
03581
MmDbgReadCheck(DataTail) ==
FALSE) {
03582
03583
break;
03584 }
else
03585 {
03586
03587
03588
if (*DataTail != *PatternTail) {
03589
03590
break;
03591 }
else {
03592 DataTail++;
03593 PatternTail++;
03594 TailLength--;
03595 }
03596 }
03597 }
03598
03599
if (TailLength == 0) {
03600
03601
03602
03603
03604
03605 m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex;
03606 m->ReturnStatus = STATUS_SUCCESS;
03607
goto done;
03608
03609 }
03610 }
03611 }
03612 }
03613
03614 StartAddress += 4;
03615 MaskIndex = 0;
03616 }
03617
03618 done:
03619
03620 MessageHeader.Length =
sizeof(*m);
03621 MessageHeader.Buffer = (PCHAR)m;
03622
03623
KdpSendPacket(
03624 PACKET_TYPE_KD_STATE_MANIPULATE,
03625 &MessageHeader,
03626
NULL
03627 );
03628
03629 }
03630
03631
03632
VOID
03633 KdpCheckLowMemory(
03634 IN PDBGKD_MANIPULATE_STATE64 Message
03635 )
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657 {
03658
03659
#if defined (_X86PAE_)
03660
LOGICAL
03661 MiCheckPhysicalPagePattern (
03662 PFN_NUMBER Page,
03663 PULONG CorruptionOffset
03664 );
03665
03666
extern PFN_NUMBER
MmLowestPhysicalPage;
03667
extern PFN_NUMBER
MmHighestPhysicalPage;
03668
extern LOGICAL
MiNoLowMemory;
03669
#endif // #if defined (_X86PAE_)
03670
03671
03672 STRING MessageHeader;
03673 PFN_NUMBER Page;
03674 PHYSICAL_ADDRESS P;
03675 PVOID64 VirtualAddress;
03676 ULONG CorruptionOffset;
03677
03678 Message->ReturnStatus = STATUS_SUCCESS;
03679 MessageHeader.Length =
sizeof(*Message);
03680 MessageHeader.Buffer = (PCHAR)Message;
03681
03682
if (
KdpSearchPhysicalMemoryRequested()) {
03683
03684
03685
03686
03687
03688
KdpSearchPhysicalPageRange();
03689 }
03690
else {
03691
03692
03693
03694
03695
03696
#if defined (_X86PAE_)
03697
03698
if (
MiNoLowMemory) {
03699
03700
for (Page =
MmLowestPhysicalPage;
03701 Page <
MmHighestPhysicalPage && Page < 1024 * 1024;
03702 Page += 1) {
03703
03704
03705
if (! MiCheckPhysicalPagePattern (Page, &CorruptionOffset)) {
03706 Message->ReturnStatus = Page;
03707
break;
03708 }
03709 }
03710 }
03711
03712
#endif // #if defined (_X86PAE_)
03713
}
03714
03715
03716
03717
03718
03719
KdpSendPacket (
03720 PACKET_TYPE_KD_STATE_MANIPULATE,
03721 &MessageHeader,
03722
NULL
03723 );
03724 }
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734 ULONG
03735 KdpSearchHammingDistance (
03736 ULONG_PTR Left,
03737 ULONG_PTR Right
03738 )
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763 {
03764 ULONG_PTR Value;
03765 ULONG
Index;
03766 ULONG Distance;
03767
03768 Value = Left ^ Right;
03769 Distance = 0;
03770
03771
for (
Index = 0;
Index < 8 *
sizeof(ULONG_PTR);
Index++) {
03772
03773
if ((Value & (ULONG_PTR)0x01)) {
03774
03775 Distance += 1;
03776 }
03777
03778 Value >>= 1;
03779 }
03780
03781
return Distance;
03782 }
03783
03784
03785
03786 LOGICAL
03787 KdpSearchPhysicalPage (
03788 IN PFN_NUMBER PageFrameIndex,
03789 ULONG_PTR RangeStart,
03790 ULONG_PTR RangeEnd,
03791 ULONG Flags
03792 )
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823 {
03824 PCHAR Va;
03825 ULONG
Index;
03826 PHYSICAL_ADDRESS Pa;
03827 ULONG_PTR Value;
03828
03829
03830
03831
03832
03833 Pa.QuadPart = ((ULONGLONG)PageFrameIndex) <<
PAGE_SHIFT;
03834
03835 Va = (PCHAR)
MmDbgTranslatePhysicalAddress64 (Pa);
03836
03837
for (
Index = 0;
Index <
PAGE_SIZE -
sizeof(ULONG_PTR);
Index += 1, Va += 1) {
03838
03839 Value = *((PULONG_PTR)Va);
03840
03841
if ((Value >= RangeStart && Value <= RangeEnd)
03842 ||
KdpSearchHammingDistance(Value, RangeStart) == 1) {
03843
03844
if (
KdpSearchPageHitIndex <
SEARCH_PAGE_HIT_DATABASE_SIZE) {
03845
03846
KdpSearchPageHits[
KdpSearchPageHitIndex] = PageFrameIndex;
03847
KdpSearchPageHitOffsets[
KdpSearchPageHitIndex] =
Index;
03848
03849
KdpSearchPageHitIndex += 1;
03850 }
03851
03852
if ((Flags &
KDP_SEARCH_ALL_OFFSETS_IN_PAGE)) {
03853
03854
continue;
03855 }
03856
else {
03857
03858
return TRUE;
03859 }
03860 }
03861 }
03862
03863
return FALSE;
03864 }
03865
03866
03867
03868 LOGICAL
03869 KdpSearchPhysicalMemoryRequested (
03870 VOID
03871 )
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894 {
03895
if (
KdpSearchInProgress) {
03896
03897
return TRUE;
03898 }
03899
else {
03900
03901
return FALSE;
03902 }
03903
03904 }
03905
03906
03907
03908 LOGICAL
03909 KdpSearchPhysicalPageRange (
03910 VOID
03911 )
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942 {
03943 PFN_NUMBER CurrentFrame;
03944 ULONG Flags;
03945
03946
03947
03948
03949
03950
03951
if (!
KdpSearchInProgress) {
03952
03953
return FALSE;
03954 }
03955
03956
03957 Flags = 0;
03958
03959
03960
03961
03962
03963
03964
03965
if (
KdpSearchEndPageFrame ==
KdpSearchStartPageFrame) {
03966
03967
KdpSearchEndPageFrame += 1;
03968
03969 Flags |=
KDP_SEARCH_ALL_OFFSETS_IN_PAGE;
03970 }
03971
03972
for (CurrentFrame =
KdpSearchStartPageFrame;
03973 CurrentFrame <
KdpSearchEndPageFrame;
03974 CurrentFrame += 1) {
03975
03976
KdpSearchPhysicalPage (CurrentFrame,
03977
KdpSearchAddressRangeStart,
03978
KdpSearchAddressRangeEnd,
03979 Flags);
03980
03981 }
03982
03983
return TRUE;
03984 }
03985
03986