test: mips/kdtrap.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# kdtrap.c File Reference

`#include "kdp.h"`

Go to the source code of this file.

## Defines

#define | BREAKPOINT_CODE_SHIFT 16
#define | BREAKPOINT_CODE_MASK (0xfffff << 6)

## Functions

VOID | KdpPageInData (IN PUCHAR volatile DataAddress)
BOOLEAN | KdpTrap (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
BOOLEAN | KdIsThisAKdTrap (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode)
BOOLEAN | KdpStub (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)

## Variables

ULONG | KdpPageInAddress
WORK_QUEUE_ITEM | KdpPageInWorkItem
BOOLEAN | KdpControlCPressed

## Define Documentation

#define BREAKPOINT_CODE_MASK (0xfffff << 6)

| Definition at line 29 of file mips/kdtrap.c. Referenced by KdIsThisAKdTrap(), KdpStub(), and KdpTrap().

#define BREAKPOINT_CODE_SHIFT 16

| Definition at line 28 of file mips/kdtrap.c. Referenced by KdIsThisAKdTrap(), KdpStub(), and KdpTrap().

## Function Documentation

BOOLEAN KdIsThisAKdTrap | ( | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | PreviousMode
| ) |

Definition at line 319 of file mips/kdtrap.c.

References BREAKIN_BREAKPOINT, BREAKPOINT_CODE_MASK, BREAKPOINT_CODE_SHIFT, FALSE, KERNEL_BREAKPOINT, KernelMode, and TRUE.

    00327                    :
    00328
    00329     This routine is called whenever a user-mode exception occurs and
    00330     it might be a kernel debugger exception (Like DbgPrint/DbgPrompt ).
    00331
    00332 Arguments:
    00333
    00334     ExceptionRecord - Supplies a pointer to an exception record that
    00335         describes the exception.
    00336
    00337     ContextRecord - Supplies the context at the time of the exception.
    00338
    00339     PreviousMode - Supplies the previous processor mode.
    00340
    00341 Return Value:
    00342
    00343     A value of TRUE is returned if this is for the kernel debugger.
    00344     Otherwise, a value of FALSE is returned.
    00345
    00346 --*/
    00347
    00348 {
    00349
    00350     ULONG BreakpointCode;
    00351
    00352     //
    00353     // Isolate the breakpoint code from the breakpoint instruction which
    00354     // is stored by the exception dispatch code in the information field
    00355     // of the exception record.
    00356     //
    00357
    00358     BreakpointCode = (ExceptionRecord->ExceptionInformation[0] &
    00359                                 BREAKPOINT_CODE_MASK) >> BREAKPOINT_CODE_SHIFT;
    00360
    00361     //
    00362     // Switch on the breakpoint code.
    00363     //
    00364
    00365     switch (BreakpointCode) {
    00366
    00367         //
    00368         // Kernel breakpoint codes.
    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         // Debug print code.
    00391         //
    00392
    00393     case DEBUG_PRINT_BREAKPOINT:
    00394         return TRUE;
    00395
    00396         //
    00397         // Debug prompt code.
    00398         //
    00399
    00400     case DEBUG_PROMPT_BREAKPOINT:
    00401         return TRUE;
    00402
    00403         //
    00404         // Debug stop code.
    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         // Debug load symbols code.
    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         // Debug unload symbols code.
    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         // All other codes.
    00450         //
    00451
    00452     default:
    00453         return FALSE;
    00454     }
    00455 }

VOID KdpPageInData | ( | IN PUCHAR volatile | DataAddress | ) |

Definition at line 46 of file mips/kdtrap.c.

References c, KdpControlCPending, MmIsSystemAddressAccessable(), and TRUE.

Referenced by KdpTrap().

    00052                    :
    00053
    00054     This routine is called to page in data at the supplied address.
    00055     It is called either directly from KdpTrap() or from a worker
    00056     thread that is queued by KdpTrap().
    00057
    00058 Arguments:
    00059
    00060     DataAddress - Supplies a pointer to the data to be paged in.
    00061
    00062 Return Value:
    00063
    00064     None.
    00065
    00066 --*/
    00067
    00068 {
    00069     if (MmIsSystemAddressAccessable(DataAddress)) {
    00070         UCHAR c = *DataAddress;
    00071         DataAddress = &c;
    00072     }
    00073     KdpControlCPending = TRUE;
    00074 }
    #pragma optimize( "", on )

BOOLEAN KdpStub | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | PreviousMode,
|  | IN BOOLEAN | SecondChance
| ) |

Definition at line 458 of file mips/kdtrap.c.

References BREAKPOINT_CODE_MASK, BREAKPOINT_CODE_SHIFT, FALSE, and TRUE.

    00469                    :
    00470
    00471     This routine provides a kernel debugger stub routine that catchs debug
    00472     prints in checked systems when the kernel debugger is not active.
    00473
    00474 Arguments:
    00475
    00476     TrapFrame - Supplies a pointer to a trap frame that describes the
    00477         trap.
    00478
    00479     ExceptionFrame - Supplies a pointer to a exception frame that describes
    00480         the trap.
    00481
    00482     ExceptionRecord - Supplies a pointer to an exception record that
    00483         describes the exception.
    00484
    00485     ContextRecord - Supplies the context at the time of the exception.
    00486
    00487     PreviousMode - Supplies the previous processor mode.
    00488
    00489     SecondChance - Supplies a boolean value that determines whether this is
    00490         the second chance (TRUE) that the exception has been raised.
    00491
    00492 Return Value:
    00493
    00494     A value of TRUE is returned if the exception is handled. Otherwise a
    00495     value of FALSE is returned.
    00496
    00497 --*/
    00498
    00499 {
    00500
    00501     ULONG BreakpointCode;
    00502
    00503     //
    00504     // Isolate the breakpoint code from the breakpoint instruction which
    00505     // is stored by the exception dispatch code in the information field
    00506     // of the exception record.
    00507     //
    00508
    00509     BreakpointCode = (ExceptionRecord->ExceptionInformation[0] &
    00510                                 BREAKPOINT_CODE_MASK) >> BREAKPOINT_CODE_SHIFT;
    00511
    00512
    00513     //
    00514     // If the breakpoint is a debug print, debug load symbols, or debug
    00515     // unload symbols, then return TRUE. Otherwise, return FALSE;
    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 }
    }

BOOLEAN KdpTrap | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PEXCEPTION_RECORD | ExceptionRecord,
|  | IN PCONTEXT | ContextRecord,
|  | IN KPROCESSOR_MODE | PreviousMode,
|  | IN BOOLEAN | SecondChance
| ) |

Definition at line 79 of file mips/kdtrap.c.

References APC_LEVEL, BREAKPOINT_CODE_MASK, BREAKPOINT_CODE_SHIFT, DelayedWorkQueue, ExInitializeWorkItem, ExQueueWorkItem(), FALSE, KdDebuggerNotPresent, KdEnterDebugger(), KdExitDebugger(), KdpControlCPending, KdpControlCPressed, KdpPageInAddress, KdpPageInData(), KdpPageInWorkItem, KdpPrintString(), KdpPromptString(), KdpReportExceptionStateChange(), KdpReportLoadSymbolsStateChange(), KeFlushCurrentTb(), KeGetCurrentPrcb, KiRestoreProcessorState(), KiSaveProcessorState(), PWORKER_THREAD_ROUTINE, TRUE, and USHORT.

    00090                    :
    00091
    00092     This routine is called whenever a exception is dispatched and the kernel
    00093     debugger is active.
    00094
    00095 Arguments:
    00096
    00097     TrapFrame - Supplies a pointer to a trap frame that describes the
    00098         trap.
    00099
    00100     ExceptionFrame - Supplies a pointer to a exception frame that describes
    00101         the trap.
    00102
    00103     ExceptionRecord - Supplies a pointer to an exception record that
    00104         describes the exception.
    00105
    00106     ContextRecord - Supplies the context at the time of the exception.
    00107
    00108     PreviousMode - Supplies the previous processor mode.
    00109
    00110     SecondChance - Supplies a boolean value that determines whether this is
    00111         the second chance (TRUE) that the exception has been raised.
    00112
    00113 Return Value:
    00114
    00115     A value of TRUE is returned if the exception is handled. Otherwise a
    00116     value of FALSE is returned.
    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     // Synchronize processor execution, save processor state, enter debugger,
    00132     // and flush the current TB.
    00133     //
    00134
    00135 re_enter_debugger:
    00136     Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    00137     Prcb = KeGetCurrentPrcb();
    00138     KiSaveProcessorState(TrapFrame, ExceptionFrame);
    00139     KeFlushCurrentTb();
    00140
    00141     //
    00142     // If this is a breakpoint instruction, then check to determine if is
    00143     // an internal command.
    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         // Switch on the breakpoint code.
    00152         //
    00153
    00154         switch ((ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK) >>
    00155                 BREAKPOINT_CODE_SHIFT) {
    00156
    00157             //
    00158             // Print a debug string.
    00159             //
    00160             // Arguments:
    00161             //
    00162             //   a0 - Supplies a pointer to an output string buffer.
    00163             //   a1 - Supplies the length of the output string buffer.
    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             // Print a debug prompt string, then input a string.
    00188             //
    00189             //   a0 - Supplies a pointer to an output string buffer.
    00190             //   a1 - Supplies the length of the output string buffer..
    00191             //   a2 - supplies a pointer to an input string buffer.
    00192             //   a3 - Supplies the length of the input string bufffer.
    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             // Load the symbolic information for an image.
    00209             //
    00210             // Arguments:
    00211             //
    00212             //    a0 - Supplies a pointer to an output string descriptor.
    00213             //    a1 - Supplies a the base address of the image.
    00214             //
    00215
    00216         case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
    00217             UnloadSymbols = TRUE;
    00218
    00219             //
    00220             // Fall through
    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             // If the kernel debugger did not update the FIR, then increment
    00242             // past the break point instruction.
    00243             //
    00244
    00245             if (ContextRecord->Fir == OldFir) {
    00246                 ContextRecord->Fir += 4;
    00247             }
    00248
    00249             return TRUE;
    00250
    00251             //
    00252             // Unknown internal command.
    00253             //
    00254
    00255         default:
    00256             break;
    00257         }
    00258     }
    00259
    00260     //
    00261     // Report state change to kernel debugger on host machine.
    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     // Check to determine if the user of the remote debugger requested memory
    00277     // to be paged in.
    00278     //
    00279
    00280     if (KdpPageInAddress) {
    00281         if (KeGetCurrentIrql() <= APC_LEVEL) {
    00282
    00283             //
    00284             // If the IQRL is below DPC level then cause the page fault to
    00285             // occur and then re-enter the debugger. This whole process is
    00286             // transparent to the user.
    00287             //
    00288
    00289             KdpPageInData((PUCHAR)KdpPageInAddress);
    00290             KdpPageInAddress = 0;
    00291             KdpControlCPending = FALSE;
    00292             goto re_enter_debugger;
    00293
    00294         } else {
    00295
    00296             //
    00297             // A page fault cannot be taken at an IRQL above APC level. Thus
    00298             // a worker item is queued to take the page fault. After the worker
    00299             // item takes the page fault it sets the contol-c flag so that the
    00300             // user re-enters the debugger just as if control-c was pressed.
    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 }

## Variable Documentation

BOOLEAN KdpControlCPressed

| Definition at line 42 of file mips/kdtrap.c.

ULONG KdpPageInAddress

| Definition at line 35 of file mips/kdtrap.c. Referenced by KdpTrap().

WORK_QUEUE_ITEM KdpPageInWorkItem

| Definition at line 36 of file mips/kdtrap.c. Referenced by KdpTrap().