00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "kdp.h"
00023
00024
00025
00026
00027
00028 #define BREAKPOINT_CODE_SHIFT 16
00029 #define BREAKPOINT_CODE_MASK (0xfffff << 6)
00030
00031
00032
00033
00034
00035 ULONG
KdpPageInAddress;
00036 WORK_QUEUE_ITEM KdpPageInWorkItem;
00037
00038
00039
00040
00041
00042 extern BOOLEAN
KdpControlCPressed;
00043
00044
#pragma optimize( "", off )
00045
VOID
00046 KdpPageInData (
00047 IN PUCHAR
volatile DataAddress
00048 )
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 {
00069
if (
MmIsSystemAddressAccessable(DataAddress)) {
00070 UCHAR
c = *DataAddress;
00071 DataAddress = &
c;
00072 }
00073
KdpControlCPending =
TRUE;
00074 }
00075
#pragma optimize( "", on )
00076
00077
00078 BOOLEAN
00079 KdpTrap (
00080 IN PKTRAP_FRAME TrapFrame,
00081 IN PKEXCEPTION_FRAME ExceptionFrame,
00082 IN PEXCEPTION_RECORD ExceptionRecord,
00083 IN PCONTEXT ContextRecord,
00084 IN KPROCESSOR_MODE PreviousMode,
00085 IN BOOLEAN SecondChance
00086 )
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 {
00121
00122 BOOLEAN Completion;
00123 BOOLEAN Enable;
00124 BOOLEAN UnloadSymbols =
FALSE;
00125 STRING Input;
00126 ULONG OldFir;
00127 STRING Output;
00128 PKPRCB Prcb;
00129
00130
00131
00132
00133
00134
00135 re_enter_debugger:
00136 Enable =
KdEnterDebugger(TrapFrame, ExceptionFrame);
00137 Prcb =
KeGetCurrentPrcb();
00138
KiSaveProcessorState(TrapFrame, ExceptionFrame);
00139
KeFlushCurrentTb();
00140
00141
00142
00143
00144
00145
00146
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00147 (((ExceptionRecord->ExceptionInformation[0] &
BREAKPOINT_CODE_MASK) >>
00148
BREAKPOINT_CODE_SHIFT) >= DEBUG_PRINT_BREAKPOINT)) {
00149
00150
00151
00152
00153
00154
switch ((ExceptionRecord->ExceptionInformation[0] &
BREAKPOINT_CODE_MASK) >>
00155
BREAKPOINT_CODE_SHIFT) {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
case DEBUG_PRINT_BREAKPOINT:
00167 Output.Buffer = (PCHAR)((ULONG)ContextRecord->XIntA0);
00168 Output.Length = (
USHORT)ContextRecord->XIntA1;
00169
if (
KdDebuggerNotPresent ==
FALSE) {
00170
if (
KdpPrintString(&Output)) {
00171 ContextRecord->XIntV0 = (ULONGLONG)((LONG)STATUS_BREAKPOINT);
00172
00173 }
else {
00174 ContextRecord->XIntV0 = (ULONGLONG)((LONG)STATUS_SUCCESS);
00175 }
00176
00177 }
else {
00178 ContextRecord->XIntV0 = (ULONGLONG)((LONG)STATUS_DEVICE_NOT_CONNECTED);
00179 }
00180
00181
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00182
KdExitDebugger(Enable);
00183 ContextRecord->Fir += 4;
00184
return TRUE;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
case DEBUG_PROMPT_BREAKPOINT:
00196 Output.Buffer = (PCHAR)((ULONG)ContextRecord->XIntA0);
00197 Output.Length = (
USHORT)ContextRecord->XIntA1;
00198 Input.Buffer = (PCHAR)((ULONG)ContextRecord->XIntA2);
00199 Input.MaximumLength = (
USHORT)ContextRecord->XIntA3;
00200
KdpPromptString(&Output, &Input);
00201 ContextRecord->XIntV0 = (LONG)Input.Length;
00202
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00203
KdExitDebugger(Enable);
00204 ContextRecord->Fir += 4;
00205
return TRUE;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
00217 UnloadSymbols =
TRUE;
00218
00219
00220
00221
00222
00223
case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
00224 OldFir = ContextRecord->Fir;
00225
if (
KdDebuggerNotPresent ==
FALSE) {
00226
KdpReportLoadSymbolsStateChange((PSTRING)((ULONG)ContextRecord->XIntA0),
00227 (
PKD_SYMBOLS_INFO)((ULONG)ContextRecord->XIntA1),
00228 UnloadSymbols,
00229 &Prcb->ProcessorState.ContextFrame);
00230
00231 }
00232
00233 RtlCopyMemory(ContextRecord,
00234 &Prcb->ProcessorState.ContextFrame,
00235 sizeof (CONTEXT) );
00236
00237
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00238
KdExitDebugger(Enable);
00239
00240
00241
00242
00243
00244
00245
if (ContextRecord->Fir == OldFir) {
00246 ContextRecord->Fir += 4;
00247 }
00248
00249
return TRUE;
00250
00251
00252
00253
00254
00255
default:
00256
break;
00257 }
00258 }
00259
00260
00261
00262
00263
00264 Completion =
KdpReportExceptionStateChange(ExceptionRecord,
00265 &Prcb->ProcessorState.ContextFrame,
00266 SecondChance);
00267
00268 RtlCopyMemory(ContextRecord,
00269 &Prcb->ProcessorState.ContextFrame,
00270
sizeof(CONTEXT));
00271
00272
KiRestoreProcessorState(TrapFrame, ExceptionFrame);
00273
KdExitDebugger(Enable);
00274
00275
00276
00277
00278
00279
00280
if (
KdpPageInAddress) {
00281
if (KeGetCurrentIrql() <=
APC_LEVEL) {
00282
00283
00284
00285
00286
00287
00288
00289
KdpPageInData((PUCHAR)
KdpPageInAddress);
00290
KdpPageInAddress = 0;
00291
KdpControlCPending =
FALSE;
00292
goto re_enter_debugger;
00293
00294 }
else {
00295
00296
00297
00298
00299
00300
00301
00302
00303
if (
KdpControlCPressed) {
00304
ExInitializeWorkItem(&
KdpPageInWorkItem,
00305 (
PWORKER_THREAD_ROUTINE)
KdpPageInData,
00306 (PVOID)
KdpPageInAddress);
00307
00308
ExQueueWorkItem( &
KdpPageInWorkItem,
DelayedWorkQueue );
00309
KdpPageInAddress = 0;
00310 }
00311 }
00312 }
00313
00314
KdpControlCPressed =
FALSE;
00315
return Completion;
00316 }
00317
00318 BOOLEAN
00319 KdIsThisAKdTrap (
00320 IN PEXCEPTION_RECORD ExceptionRecord,
00321 IN PCONTEXT ContextRecord,
00322 IN KPROCESSOR_MODE PreviousMode
00323 )
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 {
00349
00350 ULONG BreakpointCode;
00351
00352
00353
00354
00355
00356
00357
00358 BreakpointCode = (ExceptionRecord->ExceptionInformation[0] &
00359
BREAKPOINT_CODE_MASK) >>
BREAKPOINT_CODE_SHIFT;
00360
00361
00362
00363
00364
00365
switch (BreakpointCode) {
00366
00367
00368
00369
00370
00371
case BREAKIN_BREAKPOINT:
00372
case KERNEL_BREAKPOINT:
00373
00374
#if DEVL
00375
00376
return TRUE;
00377
00378
#else
00379
00380
if (PreviousMode ==
KernelMode) {
00381
return TRUE;
00382
00383 }
else {
00384
return FALSE;
00385 }
00386
00387
#endif
00388
00389
00390
00391
00392
00393
case DEBUG_PRINT_BREAKPOINT:
00394
return TRUE;
00395
00396
00397
00398
00399
00400
case DEBUG_PROMPT_BREAKPOINT:
00401
return TRUE;
00402
00403
00404
00405
00406
00407
case DEBUG_STOP_BREAKPOINT:
00408
00409
#if DEVL
00410
00411
return TRUE;
00412
00413
#else
00414
00415
if (PreviousMode ==
KernelMode) {
00416
return TRUE;
00417
00418 }
else {
00419
return FALSE;
00420 }
00421
00422
#endif
00423
00424
00425
00426
00427
00428
case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
00429
if (PreviousMode ==
KernelMode) {
00430
return TRUE;
00431
00432 }
else {
00433
return FALSE;
00434 }
00435
00436
00437
00438
00439
00440
case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
00441
if (PreviousMode ==
KernelMode) {
00442
return TRUE;
00443
00444 }
else {
00445
return FALSE;
00446 }
00447
00448
00449
00450
00451
00452
default:
00453
return FALSE;
00454 }
00455 }
00456
00457 BOOLEAN
00458 KdpStub (
00459 IN PKTRAP_FRAME TrapFrame,
00460 IN PKEXCEPTION_FRAME ExceptionFrame,
00461 IN PEXCEPTION_RECORD ExceptionRecord,
00462 IN PCONTEXT ContextRecord,
00463 IN KPROCESSOR_MODE PreviousMode,
00464 IN BOOLEAN SecondChance
00465 )
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 {
00500
00501 ULONG BreakpointCode;
00502
00503
00504
00505
00506
00507
00508
00509 BreakpointCode = (ExceptionRecord->ExceptionInformation[0] &
00510
BREAKPOINT_CODE_MASK) >>
BREAKPOINT_CODE_SHIFT;
00511
00512
00513
00514
00515
00516
00517
00518
if ((BreakpointCode == DEBUG_PRINT_BREAKPOINT) ||
00519 (BreakpointCode == DEBUG_LOAD_SYMBOLS_BREAKPOINT) ||
00520 (BreakpointCode == DEBUG_UNLOAD_SYMBOLS_BREAKPOINT)) {
00521 ContextRecord->Fir += 4;
00522
return TRUE;
00523
00524 }
else {
00525
return FALSE;
00526 }
00527 }