Home | History | Annotate | Download | only in EbcDebugger
      1 /** @file
      2 
      3 Copyright (c) 2007 - 2016, 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 /**
     18 
     19   Check whether current IP is EBC BREAK3 instruction.
     20 
     21   @param  Address    EBC IP address.
     22 
     23   @retval TRUE       Current IP is EBC BREAK3 instruction
     24   @retval FALSE      Current IP is not EBC BREAK3 instruction
     25 
     26 **/
     27 BOOLEAN
     28 IsEBCBREAK3 (
     29   IN UINTN            Address
     30   )
     31 {
     32   if (GET_OPCODE(Address) != OPCODE_BREAK) {
     33     return FALSE;
     34   }
     35 
     36   if (GET_OPERANDS (Address) != 3) {
     37     return FALSE;
     38   } else {
     39     return TRUE;
     40   }
     41 }
     42 
     43 /**
     44 
     45   Check whether the Address is already set in breakpoint.
     46 
     47   @param  DebuggerPrivate   EBC Debugger private data structure
     48   @param  Address           Breakpoint Address
     49 
     50   @retval TRUE              breakpoint is found
     51   @retval FALSE             breakpoint is not found
     52 
     53 **/
     54 BOOLEAN
     55 DebuggerBreakpointIsDuplicated (
     56   IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
     57   IN UINTN                     Address
     58   )
     59 {
     60   UINTN  Index;
     61 
     62   //
     63   // Go through each breakpoint context
     64   //
     65   for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
     66     if (DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) {
     67       //
     68       // Found it
     69       //
     70       return TRUE;
     71     }
     72   }
     73 
     74   //
     75   // Not found
     76   //
     77   return FALSE;
     78 }
     79 
     80 /**
     81 
     82   Add this breakpoint.
     83 
     84   @param  DebuggerPrivate   EBC Debugger private data structure
     85   @param  Address           Breakpoint Address
     86 
     87   @retval EFI_SUCCESS            breakpoint added successfully
     88   @retval EFI_ALREADY_STARTED    breakpoint is already added
     89   @retval EFI_OUT_OF_RESOURCES   all the breakpoint entries are used
     90 
     91 **/
     92 EFI_STATUS
     93 DebuggerBreakpointAdd (
     94   IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
     95   IN UINTN                     Address
     96   )
     97 {
     98   //
     99   // Check duplicated breakpoint
    100   //
    101   if (DebuggerBreakpointIsDuplicated (DebuggerPrivate, Address)) {
    102     EDBPrint (L"Breakpoint duplicated!\n");
    103     return EFI_ALREADY_STARTED;
    104   }
    105 
    106   //
    107   // Check whether the address is a breakpoint 3 instruction
    108   //
    109   if (IsEBCBREAK3 (Address)) {
    110     EDBPrint (L"Breakpoint can not be set on BREAK 3 instruction!\n");
    111     return EFI_ALREADY_STARTED;
    112   }
    113 
    114   if (DebuggerPrivate->DebuggerBreakpointCount >= EFI_DEBUGGER_BREAKPOINT_MAX) {
    115     EDBPrint (L"Breakpoint out of resource!\n");
    116     return EFI_OUT_OF_RESOURCES;
    117   }
    118 
    119   //
    120   // Set the breakpoint
    121   //
    122   DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].BreakpointAddress = Address;
    123   DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].State = TRUE;
    124   DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction = 0;
    125   CopyMem (
    126     &DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction,
    127     (VOID *)Address,
    128     sizeof(UINT16)
    129     );
    130 
    131   DebuggerPrivate->DebuggerBreakpointCount ++;
    132 
    133   //
    134   // Done
    135   //
    136   return EFI_SUCCESS;
    137 }
    138 
    139 /**
    140 
    141   Delete this breakpoint.
    142 
    143   @param  DebuggerPrivate   EBC Debugger private data structure
    144   @param  Index             Breakpoint Index
    145 
    146   @retval EFI_SUCCESS     breakpoint deleted successfully
    147   @retval EFI_NOT_FOUND   breakpoint not found
    148 
    149 **/
    150 EFI_STATUS
    151 DebuggerBreakpointDel (
    152   IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    153   IN UINTN                     Index
    154   )
    155 {
    156   UINTN    BpIndex;
    157 
    158   if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
    159       (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
    160     return EFI_NOT_FOUND;
    161   }
    162 
    163   //
    164   // Delete this breakpoint
    165   //
    166   for (BpIndex = Index; BpIndex < DebuggerPrivate->DebuggerBreakpointCount - 1; BpIndex++) {
    167     DebuggerPrivate->DebuggerBreakpointContext[BpIndex] = DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1];
    168   }
    169   ZeroMem (
    170     &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],
    171     sizeof(DebuggerPrivate->DebuggerBreakpointContext[BpIndex])
    172     );
    173 
    174   DebuggerPrivate->DebuggerBreakpointCount --;
    175 
    176   //
    177   // Done
    178   //
    179   return EFI_SUCCESS;
    180 }
    181 
    182 /**
    183 
    184   Disable this breakpoint.
    185 
    186   @param  DebuggerPrivate   EBC Debugger private data structure
    187   @param  Index             Breakpoint Index
    188 
    189   @retval EFI_SUCCESS     breakpoint disabled successfully
    190   @retval EFI_NOT_FOUND   breakpoint not found
    191 
    192 **/
    193 EFI_STATUS
    194 DebuggerBreakpointDis (
    195   IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    196   IN UINTN                     Index
    197   )
    198 {
    199   if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
    200       (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
    201     return EFI_NOT_FOUND;
    202   }
    203 
    204   //
    205   // Disable this breakpoint
    206   //
    207   DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE;
    208 
    209   return EFI_SUCCESS;
    210 }
    211 
    212 /**
    213 
    214   Enable this breakpoint.
    215 
    216   @param  DebuggerPrivate - EBC Debugger private data structure
    217   @param  Index           - Breakpoint Index
    218 
    219   @retval EFI_SUCCESS   - breakpoint enabled successfully
    220   @retval EFI_NOT_FOUND - breakpoint not found
    221 
    222 **/
    223 EFI_STATUS
    224 DebuggerBreakpointEn (
    225   IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    226   IN UINTN                     Index
    227   )
    228 {
    229   if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
    230       (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
    231     return EFI_NOT_FOUND;
    232   }
    233 
    234   //
    235   // Enable this breakpoint
    236   //
    237   DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE;
    238 
    239   return EFI_SUCCESS;
    240 }
    241 
    242 /**
    243 
    244   DebuggerCommand - BreakpointList.
    245 
    246   @param  CommandArg      - The argument for this command
    247   @param  DebuggerPrivate - EBC Debugger private data structure
    248   @param  ExceptionType   - Exception type.
    249   @param  SystemContext   - EBC system context.
    250 
    251   @retval EFI_DEBUG_CONTINUE - formal return value
    252 
    253 **/
    254 EFI_DEBUG_STATUS
    255 DebuggerBreakpointList (
    256   IN     CHAR16                    *CommandArg,
    257   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    258   IN     EFI_EXCEPTION_TYPE        ExceptionType,
    259   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
    260   )
    261 {
    262   UINTN Index;
    263 
    264   //
    265   // Check breakpoint cound
    266   //
    267   if (DebuggerPrivate->DebuggerBreakpointCount == 0) {
    268     EDBPrint (L"No Breakpoint\n");
    269     return EFI_DEBUG_CONTINUE;
    270   } else if (DebuggerPrivate->DebuggerBreakpointCount > EFI_DEBUGGER_BREAKPOINT_MAX) {
    271     EDBPrint (L"Breakpoint too many!\n");
    272     DebuggerPrivate->DebuggerBreakpointCount = 0;
    273     return EFI_DEBUG_CONTINUE;
    274   }
    275 
    276   //
    277   // Go through each breakpoint
    278   //
    279   EDBPrint (L"Breakpoint :\n");
    280   EDBPrint (L" Index   Address            Status\n");
    281   EDBPrint (L"======= ================== ========\n");
    282 //EDBPrint (L"   1    0xFFFFFFFF00000000    *\n");
    283 //EDBPrint (L"  12    0x00000000FFFFFFFF\n");
    284   for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
    285     //
    286     // Print the breakpoint
    287     //
    288     EDBPrint (L"  %2d    0x%016lx", Index, DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress);
    289     if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) {
    290       EDBPrint (L"    *\n");
    291     } else {
    292       EDBPrint (L"\n");
    293     }
    294   }
    295 
    296   //
    297   // Done
    298   //
    299   return EFI_DEBUG_CONTINUE;
    300 }
    301 
    302 /**
    303 
    304   DebuggerCommand - BreakpointSet.
    305 
    306   @param  CommandArg        The argument for this command
    307   @param  DebuggerPrivate   EBC Debugger private data structure
    308   @param  ExceptionType     Exception type.
    309   @param  SystemContext     EBC system context.
    310 
    311   @retval EFI_DEBUG_CONTINUE - formal return value
    312 
    313 **/
    314 EFI_DEBUG_STATUS
    315 DebuggerBreakpointSet (
    316   IN     CHAR16                    *CommandArg,
    317   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    318   IN     EFI_EXCEPTION_TYPE        ExceptionType,
    319   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
    320   )
    321 {
    322   UINTN      Address;
    323   EFI_STATUS Status;
    324 
    325   if (CommandArg == NULL) {
    326     EDBPrint (L"BreakpointSet Argument error!\n");
    327     return EFI_DEBUG_CONTINUE;
    328   }
    329 
    330   //
    331   // Get breakpoint address
    332   //
    333   Status = Symboltoi (CommandArg, &Address);
    334   if (EFI_ERROR (Status)) {
    335     if (Status == EFI_NOT_FOUND) {
    336       Address = Xtoi(CommandArg);
    337     } else {
    338       //
    339       // Something wrong, let Symboltoi print error info.
    340       //
    341       EDBPrint (L"Command Argument error!\n");
    342       return EFI_DEBUG_CONTINUE;
    343     }
    344   }
    345 
    346   //
    347   // Add breakpoint
    348   //
    349   Status = DebuggerBreakpointAdd (DebuggerPrivate, Address);
    350   if (EFI_ERROR(Status)) {
    351     EDBPrint (L"BreakpointSet error!\n");
    352   }
    353 
    354   //
    355   // Done
    356   //
    357   return EFI_DEBUG_CONTINUE;
    358 }
    359 
    360 /**
    361 
    362   DebuggerCommand - BreakpointClear
    363 
    364   @param  CommandArg        The argument for this command
    365   @param  DebuggerPrivate   EBC Debugger private data structure
    366   @param  ExceptionType     Exception type.
    367   @param  SystemContext     EBC system context.
    368 
    369   @retval EFI_DEBUG_CONTINUE   formal return value
    370 
    371 **/
    372 EFI_DEBUG_STATUS
    373 DebuggerBreakpointClear (
    374   IN     CHAR16                    *CommandArg,
    375   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    376   IN     EFI_EXCEPTION_TYPE        ExceptionType,
    377   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
    378   )
    379 {
    380   UINTN      Index;
    381   EFI_STATUS Status;
    382 
    383   if (CommandArg == NULL) {
    384     EDBPrint (L"BreakpointClear Argument error!\n");
    385     return EFI_DEBUG_CONTINUE;
    386   }
    387 
    388   if (StriCmp (CommandArg, L"*") == 0) {
    389     //
    390     // delete all breakpoint
    391     //
    392     DebuggerPrivate->DebuggerBreakpointCount = 0;
    393     ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof(DebuggerPrivate->DebuggerBreakpointContext));
    394     EDBPrint (L"All the Breakpoint is cleared\n");
    395     return EFI_DEBUG_CONTINUE;
    396   }
    397 
    398   //
    399   // Get breakpoint index
    400   //
    401   Index = Atoi(CommandArg);
    402   if (Index == (UINTN) -1) {
    403     EDBPrint (L"BreakpointClear Argument error!\n");
    404     return EFI_DEBUG_CONTINUE;
    405   }
    406 
    407   if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||
    408       (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {
    409     EDBPrint (L"BreakpointClear error!\n");
    410     return EFI_DEBUG_CONTINUE;
    411   }
    412 
    413   //
    414   // Delete breakpoint
    415   //
    416   Status = DebuggerBreakpointDel (DebuggerPrivate, Index);
    417   if (EFI_ERROR(Status)) {
    418     EDBPrint (L"BreakpointClear error!\n");
    419   }
    420 
    421   //
    422   // Done
    423   //
    424   return EFI_DEBUG_CONTINUE;
    425 }
    426 
    427 /**
    428 
    429   DebuggerCommand - BreakpointDisable
    430 
    431   @param  CommandArg        The argument for this command
    432   @param  DebuggerPrivate   EBC Debugger private data structure
    433   @param  ExceptionType     Exception type.
    434   @param  SystemContext     EBC system context.
    435 
    436   @retval EFI_DEBUG_CONTINUE   formal return value
    437 
    438 **/
    439 EFI_DEBUG_STATUS
    440 DebuggerBreakpointDisable (
    441   IN     CHAR16                    *CommandArg,
    442   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    443   IN     EFI_EXCEPTION_TYPE        ExceptionType,
    444   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
    445   )
    446 {
    447   UINTN      Index;
    448   EFI_STATUS Status;
    449 
    450   if (CommandArg == NULL) {
    451     EDBPrint (L"BreakpointDisable Argument error!\n");
    452     return EFI_DEBUG_CONTINUE;
    453   }
    454 
    455   if (StriCmp (CommandArg, L"*") == 0) {
    456     //
    457     // disable all breakpoint
    458     //
    459     for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
    460       Status = DebuggerBreakpointDis (DebuggerPrivate, Index);
    461     }
    462     EDBPrint (L"All the Breakpoint is disabled\n");
    463     return EFI_DEBUG_CONTINUE;
    464   }
    465 
    466   //
    467   // Get breakpoint index
    468   //
    469   Index = Atoi(CommandArg);
    470   if (Index == (UINTN) -1) {
    471     EDBPrint (L"BreakpointDisable Argument error!\n");
    472     return EFI_DEBUG_CONTINUE;
    473   }
    474 
    475   //
    476   // Disable breakpoint
    477   //
    478   Status = DebuggerBreakpointDis (DebuggerPrivate, Index);
    479   if (EFI_ERROR(Status)) {
    480     EDBPrint (L"BreakpointDisable error!\n");
    481   }
    482 
    483   //
    484   // Done
    485   //
    486   return EFI_DEBUG_CONTINUE;
    487 }
    488 
    489 /**
    490   DebuggerCommand - BreakpointEnable.
    491 
    492   @param  CommandArg        The argument for this command
    493   @param  DebuggerPrivate   EBC Debugger private data structure
    494   @param  ExceptionType     Exception type.
    495   @param  SystemContext     EBC system context.
    496 
    497   @retval EFI_DEBUG_CONTINUE   formal return value
    498 
    499 **/
    500 EFI_DEBUG_STATUS
    501 DebuggerBreakpointEnable (
    502   IN     CHAR16                    *CommandArg,
    503   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
    504   IN     EFI_EXCEPTION_TYPE        ExceptionType,
    505   IN OUT EFI_SYSTEM_CONTEXT        SystemContext
    506   )
    507 {
    508   UINTN      Index;
    509   EFI_STATUS Status;
    510 
    511   if (CommandArg == NULL) {
    512     EDBPrint (L"BreakpointEnable Argument error!\n");
    513     return EFI_DEBUG_CONTINUE;
    514   }
    515 
    516   if (StriCmp (CommandArg, L"*") == 0) {
    517     //
    518     // enable all breakpoint
    519     //
    520     for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {
    521       Status = DebuggerBreakpointEn (DebuggerPrivate, Index);
    522     }
    523     EDBPrint (L"All the Breakpoint is enabled\n");
    524     return EFI_DEBUG_CONTINUE;
    525   }
    526 
    527   //
    528   // Get breakpoint index
    529   //
    530   Index = Atoi(CommandArg);
    531   if (Index == (UINTN) -1) {
    532     EDBPrint (L"BreakpointEnable Argument error!\n");
    533     return EFI_DEBUG_CONTINUE;
    534   }
    535 
    536   //
    537   // Enable breakpoint
    538   //
    539   Status = DebuggerBreakpointEn (DebuggerPrivate, Index);
    540   if (EFI_ERROR(Status)) {
    541     EDBPrint (L"BreakpointEnable error!\n");
    542   }
    543 
    544   //
    545   // Done
    546   //
    547   return EFI_DEBUG_CONTINUE;
    548 }
    549