Home | History | Annotate | Download | only in EbcDebugger
      1 /** @file
      2 
      3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 
     13 **/
     14 
     15 #include "Edb.h"
     16 
     17 CHAR16 *mBranchTypeStr[] = {
     18   L"(CALL)",
     19   L"(CALLEX)",
     20   L"(RET)",
     21   L"(JMP)",
     22   L"(JMP8)",
     23 };
     24 
     25 /**
     26 
     27   Comvert Branch Type to string.
     28 
     29   @param Type        Branch Type
     30 
     31   @retval String     string of Branch Type.
     32 
     33 **/
     34 CHAR16 *
     35 EdbBranchTypeToStr (
     36   IN EFI_DEBUGGER_BRANCH_TYPE  Type
     37   )
     38 {
     39   if (Type < 0 || Type >= EfiDebuggerBranchTypeEbcMax) {
     40     return L"(Unknown Type)";
     41   }
     42 
     43   return mBranchTypeStr [Type];
     44 }
     45 
     46 /**
     47 
     48   DebuggerCommand - CallStack.
     49 
     50   @param  CommandArg         The argument for this command
     51   @param  DebuggerPrivate    EBC Debugger private data structure
     52   @param  ExceptionType      Exception type.
     53   @param  SystemContext      EBC system context.
     54 
     55   @retval EFI_DEBUG_CONTINUE   formal return value
     56 
     57 **/
     58 EFI_DEBUG_STATUS
     59 DebuggerCallStack (
     60   IN     CHAR16                    *CommandArg,
     61   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
     62   IN     EFI_EXCEPTION_TYPE        ExceptionType,
     63   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
     64   )
     65 {
     66   INTN                           Index;
     67   UINTN                          SubIndex;
     68   CHAR8                          *FuncName;
     69   EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry;
     70   BOOLEAN                        ShowParameter;
     71   UINTN                          ParameterNumber;
     72 
     73   ShowParameter = FALSE;
     74   ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER;
     75 
     76   //
     77   // Check argument
     78   //
     79   if (CommandArg != NULL) {
     80     if (StriCmp (CommandArg, L"c") == 0) {
     81       //
     82       // Clear Call-Stack
     83       //
     84       DebuggerPrivate->CallStackEntryCount = 0;
     85       ZeroMem (DebuggerPrivate->CallStackEntry, sizeof(DebuggerPrivate->CallStackEntry));
     86       EDBPrint (L"Call-Stack is cleared\n");
     87       return EFI_DEBUG_CONTINUE;
     88     } else if (StriCmp (CommandArg, L"p") == 0) {
     89       //
     90       // Print Call-Stack with parameter
     91       //
     92       ShowParameter = TRUE;
     93       CommandArg = StrGetNextTokenLine (L" ");
     94       if (CommandArg != NULL) {
     95         //
     96         // Try to get the parameter number
     97         //
     98         ParameterNumber = Atoi (CommandArg);
     99         if (ParameterNumber > 16) {
    100           EDBPrint (L"Call-Stack argument Invalid\n");
    101           return EFI_DEBUG_CONTINUE;
    102         }
    103       }
    104     } else {
    105       EDBPrint (L"Call-Stack argument Invalid\n");
    106       return EFI_DEBUG_CONTINUE;
    107     }
    108   }
    109 
    110   //
    111   // Check CallStack Entry Count
    112   //
    113   if (DebuggerPrivate->CallStackEntryCount == 0) {
    114     EDBPrint (L"No Call-Stack\n");
    115     return EFI_DEBUG_CONTINUE;
    116   } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
    117     EDBPrint (L"Call-Stack Crash, re-initialize!\n");
    118     DebuggerPrivate->CallStackEntryCount = 0;
    119     return EFI_DEBUG_CONTINUE;
    120   }
    121 
    122   //
    123   // Go through each CallStack entry and print
    124   //
    125   EDBPrint (L"Call-Stack (TOP):\n");
    126   EDBPrint (L"         Caller             Callee        Name\n");
    127   EDBPrint (L"  ================== ================== ========\n");
    128 //EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n");
    129   for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) {
    130     //
    131     // Get CallStack and print
    132     //
    133     CallStackEntry = &DebuggerPrivate->CallStackEntry[Index];
    134     EDBPrint (
    135       L"  0x%016lx 0x%016lx",
    136       CallStackEntry->SourceAddress,
    137       CallStackEntry->DestAddress
    138       );
    139     FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress);
    140     if (FuncName != NULL) {
    141       EDBPrint (L" %a()", FuncName);
    142     }
    143     EDBPrint (L"\n");
    144 
    145     if (ShowParameter) {
    146       //
    147       // Print parameter
    148       //
    149       if (sizeof(UINTN) == sizeof(UINT64)) {
    150         EDBPrint (
    151           L"    Parameter Address (0x%016lx) (\n",
    152           CallStackEntry->ParameterAddr
    153           );
    154         if (ParameterNumber == 0) {
    155           EDBPrint (L"        )\n");
    156           continue;
    157         }
    158         //
    159         // Print each parameter
    160         //
    161         for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
    162           if (SubIndex % 2 == 0) {
    163             EDBPrint (L"        ");
    164           }
    165           EDBPrint (
    166             L"0x%016lx, ",
    167             CallStackEntry->Parameter[SubIndex]
    168             );
    169           if (SubIndex % 2 == 1) {
    170             EDBPrint (L"\n");
    171           }
    172         }
    173         if (SubIndex % 2 == 0) {
    174           EDBPrint (L"        ");
    175         }
    176         EDBPrint (
    177           L"0x%016lx\n",
    178           CallStackEntry->Parameter[SubIndex]
    179           );
    180         EDBPrint (L"        )\n");
    181         //
    182         // break only for parameter
    183         //
    184         if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
    185             (Index != 0)) {
    186           if (SetPageBreak ()) {
    187             break;
    188           }
    189         }
    190       } else {
    191         EDBPrint (
    192           L"    Parameter Address (0x%08x) (\n",
    193           CallStackEntry->ParameterAddr
    194           );
    195         if (ParameterNumber == 0) {
    196           EDBPrint (L"        )\n");
    197           continue;
    198         }
    199         //
    200         // Print each parameter
    201         //
    202         for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
    203           if (SubIndex % 4 == 0) {
    204             EDBPrint (L"        ");
    205           }
    206           EDBPrint (
    207             L"0x%08x, ",
    208             CallStackEntry->Parameter[SubIndex]
    209             );
    210           if (SubIndex % 4 == 3) {
    211             EDBPrint (L"\n");
    212           }
    213         }
    214         if (SubIndex % 4 == 0) {
    215           EDBPrint (L"        ");
    216         }
    217         EDBPrint (
    218           L"0x%08x\n",
    219           CallStackEntry->Parameter[SubIndex]
    220           );
    221         EDBPrint (L"        )\n");
    222         //
    223         // break only for parameter
    224         //
    225         if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
    226             (Index != 0)) {
    227           if (SetPageBreak ()) {
    228             break;
    229           }
    230         }
    231       }
    232     }
    233   }
    234 
    235   //
    236   // Done
    237   //
    238   return EFI_DEBUG_CONTINUE;
    239 }
    240 
    241 /**
    242 
    243   DebuggerCommand - InstructionBranch.
    244 
    245   @param  CommandArg             The argument for this command
    246   @param  DebuggerPrivate        EBC Debugger private data structure
    247   @param  ExceptionType          Exception type.
    248   @param  SystemContext          EBC system context.
    249 
    250   @retval  EFI_DEBUG_CONTINUE    formal return value
    251 
    252 **/
    253 EFI_DEBUG_STATUS
    254 DebuggerInstructionBranch (
    255   IN     CHAR16                    *CommandArg,
    256   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    257   IN     EFI_EXCEPTION_TYPE        ExceptionType,
    258   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
    259   )
    260 {
    261   UINTN  Index;
    262 
    263   //
    264   // Check argument
    265   //
    266   if (CommandArg != NULL) {
    267     if (StriCmp (CommandArg, L"c") == 0) {
    268       //
    269       // Clear Trace
    270       //
    271       DebuggerPrivate->TraceEntryCount = 0;
    272       ZeroMem (DebuggerPrivate->TraceEntry, sizeof(DebuggerPrivate->TraceEntry));
    273       EDBPrint (L"Instruction Trace is cleared\n");
    274     } else {
    275       EDBPrint (L"Trace argument Invalid\n");
    276     }
    277     return EFI_DEBUG_CONTINUE;
    278   }
    279 
    280   //
    281   // Check Trace Entry Count
    282   //
    283   if (DebuggerPrivate->TraceEntryCount == 0) {
    284     EDBPrint (L"No Instruction Trace\n");
    285     return EFI_DEBUG_CONTINUE;
    286   } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
    287     EDBPrint (L"Instruction Trace Crash, re-initialize!\n");
    288     DebuggerPrivate->TraceEntryCount = 0;
    289     return EFI_DEBUG_CONTINUE;
    290   }
    291 
    292   //
    293   // Go through each Trace entry and print
    294   //
    295   EDBPrint (L"Instruction Trace (->Latest):\n");
    296   EDBPrint (L"    Source Addr        Destination Addr   Type\n");
    297   EDBPrint (L"  ================== ================== ========\n");
    298 //EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000  (CALLEX)\n");
    299   for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) {
    300     EDBPrint (
    301       L"  0x%016lx 0x%016lx  %s\n",
    302       DebuggerPrivate->TraceEntry[Index].SourceAddress,
    303       DebuggerPrivate->TraceEntry[Index].DestAddress,
    304       EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type)
    305       );
    306   }
    307 
    308   //
    309   // Done
    310   //
    311   return EFI_DEBUG_CONTINUE;
    312 }
    313