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