test: ppc/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_MASK 0xffff

## 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 0xffff

| Definition at line 30 of file ppc/kdtrap.c.

## Function Documentation

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

Definition at line 323 of file ppc/kdtrap.c.

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

    00331                    :
    00332
    00333     This routine is called whenever a user-mode exception occurs and
    00334     it might be a kernel debugger exception (Like DbgPrint/DbgPrompt ).
    00335
    00336 Arguments:
    00337
    00338     ExceptionRecord - Supplies a pointer to an exception record that
    00339         describes the exception.
    00340
    00341     ContextRecord - Supplies the context at the time of the exception.
    00342
    00343     PreviousMode - Supplies the previous processor mode.
    00344
    00345 Return Value:
    00346
    00347     A value of TRUE is returned if this is for the kernel debugger.
    00348     Otherwise, a value of FALSE is returned.
    00349
    00350 --*/
    00351
    00352 {
    00353
    00354     ULONG BreakpointCode;
    00355
    00356     //
    00357     // Determine if this is hardware debug register breakpoint
    00358     //
    00359
    00360     if (ContextRecord->Dr6 !=0) {      // Debug Register Breakpoint
    00361         if ((PreviousMode == KernelMode) ||
    00362             (KeGetCurrentThread()->DebugActive == 0)) { // No DR set for thread
    00363             return TRUE;
    00364         } else {                       // User mode and DR set for thread
    00365             return FALSE;
    00366         }
    00367     }
    00368
    00369     //
    00370     // Isolate the breakpoint code from the breakpoint instruction which
    00371     // is stored by the exception dispatch code in the information field
    00372     // of the exception record.
    00373     //
    00374
    00375     BreakpointCode = ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK;
    00376
    00377     //
    00378     // Switch on the breakpoint code.
    00379     //
    00380
    00381     switch (BreakpointCode) {
    00382
    00383         //
    00384         // Kernel breakpoint codes.
    00385         //
    00386
    00387     case BREAKIN_BREAKPOINT:
    00388     case KERNEL_BREAKPOINT:
    00389
    00390 #if DEVL
    00391
    00392         return TRUE;
    00393
    00394 #else
    00395
    00396         if (PreviousMode == KernelMode) {
    00397             return TRUE;
    00398
    00399         } else {
    00400             return FALSE;
    00401         }
    00402
    00403 #endif
    00404
    00405         //
    00406         // Debug print code.
    00407         //
    00408
    00409     case DEBUG_PRINT_BREAKPOINT:
    00410         return TRUE;
    00411
    00412         //
    00413         // Debug prompt code.
    00414         //
    00415
    00416     case DEBUG_PROMPT_BREAKPOINT:
    00417         return TRUE;
    00418
    00419         //
    00420         // Debug stop code.
    00421         //
    00422
    00423     case SINGLE_STEP_BREAKPOINT:
    00424     case DEBUG_STOP_BREAKPOINT:
    00425
    00426 #if DEVL
    00427
    00428         return TRUE;
    00429
    00430 #else
    00431
    00432         if (PreviousMode == KernelMode) {
    00433             return TRUE;
    00434
    00435         } else {
    00436             return FALSE;
    00437         }
    00438
    00439 #endif
    00440
    00441         //
    00442         // Debug load symbols code.
    00443         //
    00444
    00445     case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
    00446         if (PreviousMode == KernelMode) {
    00447             return TRUE;
    00448
    00449         } else {
    00450             return FALSE;
    00451         }
    00452
    00453         //
    00454         // Debug unload symbols code.
    00455         //
    00456
    00457     case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
    00458         if (PreviousMode == KernelMode) {
    00459             return TRUE;
    00460
    00461         } else {
    00462             return FALSE;
    00463         }
    00464
    00465         //
    00466         // All other codes.
    00467         //
    00468
    00469     default:
    00470         return FALSE;
    00471     }
    00472 }

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

Definition at line 47 of file ppc/kdtrap.c.

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

Referenced by KdpTrap().

    00053                    :
    00054
    00055     This routine is called to page in data at the supplied address.
    00056     It is called either directly from KdpTrap() or from a worker
    00057     thread that is queued by KdpTrap().
    00058
    00059 Arguments:
    00060
    00061     DataAddress - Supplies a pointer to the data to be paged in.
    00062
    00063 Return Value:
    00064
    00065     None.
    00066
    00067 --*/
    00068
    00069 {
    00070     if (MmIsSystemAddressAccessable(DataAddress)) {
    00071         UCHAR c = *DataAddress;
    00072         DataAddress = &c;
    00073     }
    00074     KdpControlCPending = TRUE;
    00075 }
    #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 475 of file ppc/kdtrap.c.

References BREAKPOINT_CODE_MASK, FALSE, and TRUE.

    00486                    :
    00487
    00488     This routine provides a kernel debugger stub routine that catchs debug
    00489     prints in checked systems when the kernel debugger is not active.
    00490
    00491 Arguments:
    00492
    00493     TrapFrame - Supplies a pointer to a trap frame that describes the
    00494         trap.
    00495
    00496     ExceptionFrame - Supplies a pointer to a exception frame that describes
    00497         the trap.
    00498
    00499     ExceptionRecord - Supplies a pointer to an exception record that
    00500         describes the exception.
    00501
    00502     ContextRecord - Supplies the context at the time of the exception.
    00503
    00504     PreviousMode - Supplies the previous processor mode.
    00505
    00506     SecondChance - Supplies a boolean value that determines whether this is
    00507         the second chance (TRUE) that the exception has been raised.
    00508
    00509 Return Value:
    00510
    00511     A value of TRUE is returned if the exception is handled. Otherwise a
    00512     value of FALSE is returned.
    00513
    00514 --*/
    00515
    00516 {
    00517
    00518     ULONG BreakpointCode;
    00519
    00520     //
    00521     // If it isn't a real breakpoint or doesn't have any params, get out.
    00522     //
    00523
    00524     if ((ExceptionRecord->ExceptionCode != STATUS_BREAKPOINT) ||
    00525         (ExceptionRecord->NumberParameters == 0)) {
    00526         return FALSE;
    00527     }
    00528
    00529     //
    00530     // Isolate the breakpoint code from the breakpoint instruction which
    00531     // is stored by the exception dispatch code in the information field
    00532     // of the exception record.
    00533     //
    00534
    00535     BreakpointCode = ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK;
    00536
    00537
    00538     //
    00539     // If the breakpoint is a debug print, debug load symbols, or debug
    00540     // unload symbols, then return TRUE. Otherwise, return FALSE;
    00541     //
    00542
    00543     if ((BreakpointCode == DEBUG_PRINT_BREAKPOINT) ||
    00544         (BreakpointCode == DEBUG_LOAD_SYMBOLS_BREAKPOINT) ||
    00545         (BreakpointCode == DEBUG_UNLOAD_SYMBOLS_BREAKPOINT)) {
    00546         ContextRecord->Iar += 4;
    00547         return TRUE;
    00548
    00549     } else {
    00550         return FALSE;
    00551     }
    00552 }
    }

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 80 of file ppc/kdtrap.c.

References APC_LEVEL, BREAKPOINT_CODE_MASK, 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.

    00091                    :
    00092
    00093     This routine is called whenever a exception is dispatched and the kernel
    00094     debugger is active.
    00095
    00096 Arguments:
    00097
    00098     TrapFrame - Supplies a pointer to a trap frame that describes the
    00099         trap.
    00100
    00101     ExceptionFrame - Supplies a pointer to a exception frame that describes
    00102         the trap.
    00103
    00104     ExceptionRecord - Supplies a pointer to an exception record that
    00105         describes the exception.
    00106
    00107     ContextRecord - Supplies the context at the time of the exception.
    00108
    00109     PreviousMode - Supplies the previous processor mode.
    00110
    00111     SecondChance - Supplies a boolean value that determines whether this is
    00112         the second chance (TRUE) that the exception has been raised.
    00113
    00114 Return Value:
    00115
    00116     A value of TRUE is returned if the exception is handled. Otherwise a
    00117     value of FALSE is returned.
    00118
    00119 --*/
    00120
    00121 {
    00122
    00123     BOOLEAN Completion;
    00124     BOOLEAN Enable;
    00125     BOOLEAN UnloadSymbols = FALSE;
    00126     ULONG OldIar;
    00127     STRING Input;
    00128     STRING Output;
    00129     PKPRCB Prcb;
    00130
    00131     //
    00132     // Synchronize processor execution, save processor state, enter debugger,
    00133     // and flush the current TB.
    00134     //
    00135
    00136 re_enter_debugger:
    00137     Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
    00138     Prcb = KeGetCurrentPrcb();
    00139     KiSaveProcessorState(TrapFrame, ExceptionFrame);
    00140     KeFlushCurrentTb();
    00141
    00142     //
    00143     // If this is a breakpoint instruction, then check to determine if is
    00144     // an internal command.
    00145     //
    00146
    00147     if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
    00148        ((ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK)
    00149                               >= DEBUG_PRINT_BREAKPOINT)) {
    00150
    00151         //
    00152         // Switch on the breakpoint code.
    00153         //
    00154
    00155         switch (ExceptionRecord->ExceptionInformation[0] & BREAKPOINT_CODE_MASK) {
    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             ContextRecord->Iar += 4;
    00168             Output.Buffer = (PCHAR)ContextRecord->Gpr3;
    00169             Output.Length = (USHORT)ContextRecord->Gpr4;
    00170             if (KdDebuggerNotPresent == FALSE) {
    00171                 if (KdpPrintString(&Output)) {
    00172                     ContextRecord->Gpr3 = (ULONG)STATUS_BREAKPOINT;
    00173
    00174                 } else {
    00175                     ContextRecord->Gpr3 = (ULONG)STATUS_SUCCESS;
    00176                 }
    00177
    00178             } else {
    00179                 ContextRecord->Gpr3 = (ULONG)STATUS_DEVICE_NOT_CONNECTED;
    00180             }
    00181
    00182             KiRestoreProcessorState(TrapFrame, ExceptionFrame);
    00183             KdExitDebugger(Enable);
    00184             return TRUE;
    00185
    00186             //
    00187             // Print a debug prompt string, then input a string.
    00188             //
    00189             //   r.3 - Supplies a pointer to an output string buffer.
    00190             //   r.4 - Supplies the length of the output string buffer..
    00191             //   r.5 - supplies a pointer to an input string buffer.
    00192             //   r.6 - Supplies the length of the input string bufffer.
    00193             //
    00194
    00195         case DEBUG_PROMPT_BREAKPOINT:
    00196             ContextRecord->Iar += 4;
    00197             Output.Buffer = (PCHAR)ContextRecord->Gpr3;
    00198             Output.Length = (USHORT)ContextRecord->Gpr4;
    00199             Input.Buffer = (PCHAR)ContextRecord->Gpr5;
    00200             Input.MaximumLength = (USHORT)ContextRecord->Gpr6;
    00201             KdpPromptString(&Output, &Input);
    00202             ContextRecord->Gpr3 = Input.Length;
    00203             KiRestoreProcessorState(TrapFrame, ExceptionFrame);
    00204             KdExitDebugger(Enable);
    00205             return TRUE;
    00206
    00207             //
    00208             // Load the symbolic information for an image.
    00209             //
    00210             // Arguments:
    00211             //
    00212             //    r.3 - Supplies a pointer to an output string descriptor.
    00213             //    r.4 - 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             OldIar = ContextRecord->Iar;
    00225             if (KdDebuggerNotPresent == FALSE) {
    00226                 KdpReportLoadSymbolsStateChange((PSTRING)ContextRecord->Gpr3,
    00227                                                 (PKD_SYMBOLS_INFO) ContextRecord->Gpr4,
    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 IAR, then increment
    00242             // past the breakpoint instruction.
    00243             //
    00244
    00245             if (ContextRecord->Iar == OldIar) {
    00246                 ContextRecord->Iar += 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(
    00265                     ExceptionRecord,
    00266                     &Prcb->ProcessorState.ContextFrame,
    00267                     SecondChance);
    00268
    00269     RtlCopyMemory(ContextRecord,
    00270                   &Prcb->ProcessorState.ContextFrame,
    00271                   sizeof(CONTEXT));
    00272
    00273     KiRestoreProcessorState(TrapFrame, ExceptionFrame);
    00274     KdExitDebugger(Enable);
    00275
    00276     //
    00277     // check to see if the user of the remote debugger
    00278     // requested memory to be paged in
    00279     //
    00280     if (KdpPageInAddress) {
    00281
    00282         if (KeGetCurrentIrql() <= APC_LEVEL) {
    00283
    00284             //
    00285             // if the IQRL is below DPC level then cause
    00286             // the page fault to occur and then re-enter
    00287             // the debugger.  this whole process is transparent
    00288             // to the user.
    00289             //
    00290             KdpPageInData( (PUCHAR)KdpPageInAddress );
    00291             KdpPageInAddress = 0;
    00292             KdpControlCPending = FALSE;
    00293             goto re_enter_debugger;
    00294
    00295         } else {
    00296
    00297             //
    00298             // we cannot take a page fault
    00299             // here so a worker item is queued to take the
    00300             // page fault.  after the worker item takes the
    00301             // page fault it sets the contol-c flag so that
    00302             // the user re-enters the debugger just as if
    00303             // control-c was pressed.
    00304             //
    00305             if (KdpControlCPressed) {
    00306                 ExInitializeWorkItem(
    00307                     &KdpPageInWorkItem,
    00308                     (PWORKER_THREAD_ROUTINE) KdpPageInData,
    00309                     (PVOID) KdpPageInAddress
    00310                     );
    00311                 ExQueueWorkItem( &KdpPageInWorkItem, DelayedWorkQueue );
    00312                 KdpPageInAddress = 0;
    00313             }
    00314         }
    00315     }
    00316
    00317     KdpControlCPressed = FALSE;
    00318
    00319     return Completion;
    00320 }

## Variable Documentation

BOOLEAN KdpControlCPressed

| Definition at line 41 of file ppc/kdtrap.c.

ULONG KdpPageInAddress

| Definition at line 35 of file ppc/kdtrap.c.

WORK_QUEUE_ITEM KdpPageInWorkItem

| Definition at line 36 of file ppc/kdtrap.c.