/** @file

Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.


**/

#include "Edb.h"

/**

  Get file name from full path.

  @param  FullPath        - full file path

  @return  file name

**/
CHAR16 *
GetFileNameFromFullPath (
  IN CHAR16   *FullPath
  )
{
  CHAR16   *FileName;
  CHAR16   *TempFileName;

  FileName = FullPath;
  TempFileName = StrGetNewTokenLine (FullPath, L"\\");

  while (TempFileName != NULL) {
    FileName = TempFileName;
    TempFileName = StrGetNextTokenLine (L"\\");
    PatchForStrTokenBefore (TempFileName, L'\\');
  }

  return FileName;
}

/**

  Get dir name from full path.

  @param  FullPath        - full file path

  @return dir name

**/
CHAR16 *
GetDirNameFromFullPath (
  IN CHAR16   *FullPath
  )
{
  CHAR16   *FileName;

  FileName = GetFileNameFromFullPath (FullPath);
  if (FileName != FullPath) {
    *(FileName - 1) = 0;
    return FullPath;
  }

  return L"";
}

/**

  Construct full path according to dir and file path.

  @param  DirPath         - dir path
  @param  FilePath        - file path
  @param  Size            - dir max size

  @return Full file name

**/
CHAR16 *
ConstructFullPath (
  IN CHAR16   *DirPath,
  IN CHAR16   *FilePath,
  IN UINTN    Size
  )
{
  UINTN DirPathSize;

  DirPathSize = StrLen(DirPath);
  *(DirPath + DirPathSize) = L'\\';
  StrnCatS (DirPath, DirPathSize + Size + 1, FilePath, Size);

  *(DirPath + DirPathSize + Size + 1) = 0;

  return DirPath;
}

CHAR16 *mSymbolTypeStr[] = {
  L"( F)",
  L"(SF)",
  L"(GV)",
  L"(SV)",
};

/**

  Comvert Symbol Type to string.

  @param  Type            - Symbol Type

  @return String

**/
CHAR16 *
EdbSymbolTypeToStr (
  IN EFI_DEBUGGER_SYMBOL_TYPE  Type
  )
{
  if (Type < 0 || Type >= EfiDebuggerSymbolTypeMax) {
    return L"(?)";
  }

  return mSymbolTypeStr [Type];
}

/**

  Find the symbol according to address and display symbol.

  @param  Address         - SymbolAddress
  @param  DebuggerPrivate - EBC Debugger private data structure

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerDisplaySymbolAccrodingToAddress (
  IN     UINTN                      Address,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate
  )
{
  EFI_DEBUGGER_SYMBOL_OBJECT *Object;
  EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;
  UINTN                      CandidateAddress;

  //
  // Find the nearest symbol address
  //
  CandidateAddress = EbdFindSymbolAddress (Address, EdbMatchSymbolTypeNearestAddress, &Object, &Entry);
  if (CandidateAddress == 0 || CandidateAddress == (UINTN) -1) {
    EDBPrint (L"Symbole at Address not found!\n");
    return EFI_DEBUG_CONTINUE;
  } else if (Address != CandidateAddress) {
    EDBPrint (L"Symbole at Address not found, print nearest one!\n");
  }

  //
  // Display symbol
  //
  EDBPrint (L"Symbol File Name: %s\n", Object->Name);
  if (sizeof(UINTN) == sizeof(UINT64)) {
    EDBPrint (L"        Address      Type  Symbol\n");
    EDBPrint (L"  ================== ==== ========\n");
//  EDBPrint (L"  0xFFFFFFFF00000000 ( F) TestMain\n");
    EDBPrint (
      L"  0x%016lx %s %a\n",
      (UINT64)Entry->Rva + Object->BaseAddress,
      EdbSymbolTypeToStr (Entry->Type),
      Entry->Name
      );
  } else {
    EDBPrint (L"   Address   Type  Symbol\n");
    EDBPrint (L"  ========== ==== ========\n");
//  EDBPrint (L"  0xFFFF0000 ( F) TestMain\n");
    EDBPrint (
      L"  0x%08x %s %a\n",
      Entry->Rva + Object->BaseAddress,
      EdbSymbolTypeToStr (Entry->Type),
      Entry->Name
      );
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  Find the symbol according to name and display symbol.

  @param  SymbolFileName  - The Symbol File Name, NULL means for all
  @param  SymbolName      - The Symbol Name, NULL means for all
  @param  DebuggerPrivate - EBC Debugger private data structure

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerDisplaySymbolAccrodingToName (
  IN     CHAR16                     *SymbolFileName,
  IN     CHAR16                     *SymbolName,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate
  )
{
  UINTN                      Index;
  UINTN                      SubIndex;
  EFI_DEBUGGER_SYMBOL_OBJECT *Object;
  EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;

  if (DebuggerPrivate->DebuggerSymbolContext.ObjectCount == 0) {
    EDBPrint (L"No Symbol File!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Go throuth each symbol file
  //
  Object = DebuggerPrivate->DebuggerSymbolContext.Object;
  for (Index = 0; Index < DebuggerPrivate->DebuggerSymbolContext.ObjectCount; Index++, Object++) {
    if ((SymbolFileName != NULL) &&
        (StriCmp (SymbolFileName, Object->Name) != 0)) {
      continue;
    }

    //
    // Break each symbol file
    //
    if (Index != 0) {
      if (SetPageBreak ()) {
        break;
      }
    }

    EDBPrint (L"Symbol File Name: %s\n", Object->Name);
    if (Object->EntryCount == 0) {
      EDBPrint (L"No Symbol!\n");
      continue;
    }
    Entry = Object->Entry;
    if (sizeof(UINTN) == sizeof(UINT64)) {
      EDBPrint (L"        Address      Type  Symbol\n");
      EDBPrint (L"  ================== ==== ========\n");
//    EDBPrint (L"  0xFFFFFFFF00000000 ( F) TestMain (EbcTest.obj)\n");
    } else {
      EDBPrint (L"   Address   Type  Symbol\n");
      EDBPrint (L"  ========== ==== ========\n");
//    EDBPrint (L"  0xFFFF0000 ( F) TestMain (EbcTest.obj)\n");
    }

    //
    // Go through each symbol name
    //
    for (SubIndex = 0; SubIndex < Object->EntryCount; SubIndex++, Entry++) {
      if ((SymbolName != NULL) &&
          (StrCmpUnicodeAndAscii (SymbolName, Entry->Name) != 0)) {
        continue;
      }

      //
      // Break symbol
      //
      if (((SubIndex % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) &&
          (SubIndex != 0)) {
        if (SetPageBreak ()) {
          break;
        }
      }

      if (sizeof(UINTN) == sizeof(UINT64)) {
        EDBPrint (
          L"  0x%016lx %s %a (%a)\n",
          (UINT64)Entry->Rva + Object->BaseAddress,
          EdbSymbolTypeToStr (Entry->Type),
          Entry->Name,
          Entry->ObjName
          );
      } else {
        EDBPrint (
          L"  0x%08x %s %a (%a)\n",
          Entry->Rva + Object->BaseAddress,
          EdbSymbolTypeToStr (Entry->Type),
          Entry->Name,
          Entry->ObjName
          );
      }
    }
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - ListSymbol.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerListSymbol (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  CHAR16                     *SymbolFileName;
  CHAR16                     *SymbolName;
  CHAR16                     *CommandStr;
  UINTN                      Address;

  SymbolFileName = NULL;
  SymbolName = NULL;
  CommandStr = CommandArg;

  //
  // display symbol according to address
  //
  if (CommandStr != NULL) {
    if ((StriCmp (CommandStr, L"F") != 0) &&
        (StriCmp (CommandStr, L"S") != 0)) {
      Address = Xtoi (CommandStr);
      return DebuggerDisplaySymbolAccrodingToAddress (Address, DebuggerPrivate);
    }
  }

  //
  // Get SymbolFileName
  //
  if (CommandStr != NULL) {
    if (StriCmp (CommandStr, L"F") == 0) {
      CommandStr = StrGetNextTokenLine (L" ");
      if (CommandStr == NULL) {
        EDBPrint (L"Symbol File Name missing!\n");
        return EFI_DEBUG_CONTINUE;
      } else {
        SymbolFileName = CommandStr;
        CommandStr = StrGetNextTokenLine (L" ");
      }
    }
  }
  //
  // Get SymbolName
  //
  if (CommandStr != NULL) {
    if (StriCmp (CommandStr, L"S") == 0) {
      CommandStr = StrGetNextTokenLine (L" ");
      if (CommandStr == NULL) {
        EDBPrint (L"Symbol Name missing!\n");
        return EFI_DEBUG_CONTINUE;
      } else {
        SymbolName = CommandStr;
        CommandStr = StrGetNextTokenLine (L" ");
      }
    }
  }
  if (CommandStr != NULL) {
    EDBPrint (L"Argument error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // display symbol according to name
  //
  return DebuggerDisplaySymbolAccrodingToName (SymbolFileName, SymbolName, DebuggerPrivate);
}

/**

  DebuggerCommand - LoadSymbol.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerLoadSymbol (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  UINTN      BufferSize;
  VOID       *Buffer;
  EFI_STATUS Status;
  CHAR16     *FileName;
  CHAR16     *CommandArg2;
  BOOLEAN    IsLoadCode;
  CHAR16     *DirName;
  CHAR16     CodFile[EFI_DEBUGGER_SYMBOL_NAME_MAX];
  CHAR16     *CodFileName;
  UINTN      Index;

  //
  // Check the argument
  //
  if (CommandArg == NULL) {
    EDBPrint (L"SymbolFile not found!\n");
    return EFI_DEBUG_CONTINUE;
  }
  IsLoadCode = FALSE;
  CommandArg2 = StrGetNextTokenLine (L" ");
  if (CommandArg2 != NULL) {
    if (StriCmp (CommandArg2, L"a") == 0) {
      IsLoadCode = TRUE;
    } else {
      EDBPrint (L"Argument error!\n");
      return EFI_DEBUG_CONTINUE;
    }
  }

  if (StrLen (CommandArg) <= 4) {
    EDBPrint (L"SymbolFile name error!\n");
    return EFI_DEBUG_CONTINUE;
  }
  if (StriCmp (CommandArg + (StrLen (CommandArg) - 4), L".map") != 0) {
    EDBPrint (L"SymbolFile name error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Read MAP file to memory
  //
  Status = ReadFileToBuffer (DebuggerPrivate, CommandArg, &BufferSize, &Buffer, TRUE);
  if (EFI_ERROR(Status)) {
    EDBPrint (L"SymbolFile read error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  FileName = GetFileNameFromFullPath (CommandArg);
  //
  // Load Symbol
  //
  Status = EdbLoadSymbol (DebuggerPrivate, FileName, BufferSize, Buffer);
  if (EFI_ERROR(Status)) {
    EDBPrint (L"LoadSymbol error!\n");
    gBS->FreePool (Buffer);
    return EFI_DEBUG_CONTINUE;
  }
  gBS->FreePool (Buffer);

  //
  // Patch Symbol for RVA
  //
  Status = EdbPatchSymbolRVA (DebuggerPrivate, FileName, EdbEbcImageRvaSearchTypeLast);
  if (EFI_ERROR(Status)) {
    EDBPrint (L"PatchSymbol RVA  - %r! Using the RVA in symbol file.\n", Status);
  } else {
    DEBUG ((DEBUG_ERROR, "PatchSymbol RVA successfully!\n"));
  }

  if (!IsLoadCode) {
    return EFI_DEBUG_CONTINUE;
  }

  //
  // load each cod file
  //
  DirName = GetDirNameFromFullPath (CommandArg);
  ZeroMem (CodFile, sizeof(CodFile));
  if (StrCmp (DirName, L"") != 0) {
    StrCpyS (CodFile, sizeof(CodFile), DirName);
  } else {
    DirName = L"\\";
  }

  //
  // Go throuth each file under this dir
  //
  Index = 0;
  CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
  while (CodFileName != NULL) {
    ZeroMem (CodFile, sizeof(CodFile));
    if (StrCmp (DirName, L"\\") != 0) {
      StrCpyS (CodFile, sizeof(CodFile), DirName);
    }

    //
    // read cod file to memory
    //
    Status = ReadFileToBuffer (DebuggerPrivate, ConstructFullPath (CodFile, CodFileName, EFI_DEBUGGER_SYMBOL_NAME_MAX - StrLen (CodFile) - 2), &BufferSize, &Buffer, FALSE);
    if (EFI_ERROR(Status)) {
      EDBPrint (L"CodeFile read error!\n");
      CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
      continue;
    }

    //
    // Load Code
    //
    Status = EdbLoadCode (DebuggerPrivate, FileName, CodFileName, BufferSize, Buffer);
    if (EFI_ERROR (Status)) {
      EDBPrint (L"LoadCode error!\n");
      gBS->FreePool (Buffer);
      CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
      continue;
    }

    //
    // Record the buffer
    //
    Status = EdbAddCodeBuffer (DebuggerPrivate, FileName, CodFileName, BufferSize, Buffer);
    if (EFI_ERROR (Status)) {
      EDBPrint (L"AddCodeBuffer error!\n");
      gBS->FreePool (Buffer);
      CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
      continue;
    }

    //
    // Get next file
    //
    CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - UnloadSymbol

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerUnloadSymbol (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  EFI_STATUS Status;
  CHAR16     *FileName;
  CHAR16     *DirName;
  CHAR16     CodFile[EFI_DEBUGGER_SYMBOL_NAME_MAX];
  CHAR16     *CodFileName;
  UINTN      Index;
  VOID       *BufferPtr;

  //
  // Check the argument
  //
  if (CommandArg == NULL) {
    EDBPrint (L"SymbolFile not found!\n");
    return EFI_DEBUG_CONTINUE;
  }

  FileName = GetFileNameFromFullPath (CommandArg);

  //
  // Unload Code
  //
  DirName = GetDirNameFromFullPath (CommandArg);
  ZeroMem (CodFile, sizeof(CodFile));
  if (StrCmp (DirName, L"") != 0) {
    StrCpyS (CodFile, sizeof(CodFile), DirName);
  } else {
    DirName = L"\\";
  }

  //
  // Go through each file under this dir
  //
  Index = 0;
  CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
  while (CodFileName != NULL) {
    ZeroMem (CodFile, sizeof(CodFile));
    if (StrCmp (DirName, L"\\") != 0) {
      StrCpyS (CodFile, sizeof(CodFile), DirName);
    }

    //
    // Unload Code
    //
    Status = EdbUnloadCode (DebuggerPrivate, FileName, CodFileName, &BufferPtr);
    if (EFI_ERROR (Status)) {
      EDBPrint (L"UnloadCode error!\n");
      CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
      continue;
    }

    //
    // Delete the code buffer
    //
    Status = EdbDeleteCodeBuffer (DebuggerPrivate, FileName, CodFileName, BufferPtr);
    if (EFI_ERROR (Status)) {
      EDBPrint (L"DeleteCodeBuffer error!\n");
      CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
      continue;
    }

    //
    // Get next file
    //
    CodFileName = GetFileNameUnderDir (DebuggerPrivate, DirName, L".cod", &Index);
  }

  //
  // Unload Symbol
  //
  Status = EdbUnloadSymbol (DebuggerPrivate, FileName);
  if (EFI_ERROR(Status)) {
    EDBPrint (L"UnloadSymbol error!\n");
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - DisplaySymbol.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerDisplaySymbol (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  if (CommandArg == NULL) {
    DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = !DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol;
    EdbShowDisasm (DebuggerPrivate, SystemContext);
  } else if (StriCmp (CommandArg, L"on") == 0) {
    DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = TRUE;
    EdbShowDisasm (DebuggerPrivate, SystemContext);
  } else if (StriCmp (CommandArg, L"off") == 0) {
    DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = FALSE;
    EdbShowDisasm (DebuggerPrivate, SystemContext);
  } else {
    EDBPrint (L"DisplaySymbol - argument error\n");
  }

  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - LoadCode.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerLoadCode (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  UINTN      BufferSize;
  VOID       *Buffer;
  EFI_STATUS Status;
  CHAR16     *CommandArg2;
  CHAR16     *FileName;
  CHAR16     *MapFileName;

  //
  // Check the argument
  //
  if (CommandArg == NULL) {
    EDBPrint (L"CodeFile not found!\n");
    return EFI_DEBUG_CONTINUE;
  }
  CommandArg2 = StrGetNextTokenLine (L" ");
  if (CommandArg2 == NULL) {
    EDBPrint (L"SymbolFile not found!\n");
    return EFI_DEBUG_CONTINUE;
  }

  if (StrLen (CommandArg) <= 4) {
    EDBPrint (L"CodeFile name error!\n");
    return EFI_DEBUG_CONTINUE;
  }
  if (StriCmp (CommandArg + (StrLen (CommandArg) - 4), L".cod") != 0) {
    EDBPrint (L"CodeFile name error!\n");
    return EFI_DEBUG_CONTINUE;
  }
  if (StrLen (CommandArg2) <= 4) {
    EDBPrint (L"SymbolFile name error!\n");
    return EFI_DEBUG_CONTINUE;
  }
  if (StriCmp (CommandArg2 + (StrLen (CommandArg2) - 4), L".map") != 0) {
    EDBPrint (L"SymbolFile name error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // read cod file to memory
  //
  Status = ReadFileToBuffer (DebuggerPrivate, CommandArg, &BufferSize, &Buffer, TRUE);
  if (EFI_ERROR(Status)) {
    EDBPrint (L"CodeFile read error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  FileName = GetFileNameFromFullPath (CommandArg);
  MapFileName = GetFileNameFromFullPath (CommandArg2);
  //
  // Load Code
  //
  Status = EdbLoadCode (DebuggerPrivate, MapFileName, FileName, BufferSize, Buffer);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"LoadCode error!\n");
    gBS->FreePool (Buffer);
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Record the buffer
  //
  Status = EdbAddCodeBuffer (DebuggerPrivate, MapFileName, FileName, BufferSize, Buffer);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"AddCodeBuffer error!\n");
    gBS->FreePool (Buffer);
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - UnloadCode.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerUnloadCode (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  CHAR16     *CommandArg2;
  CHAR16     *FileName;
  CHAR16     *MapFileName;
  EFI_STATUS Status;
  VOID       *BufferPtr;

  //
  // Check the argument
  //
  if (CommandArg == NULL) {
    EDBPrint (L"CodeFile not found!\n");
    return EFI_DEBUG_CONTINUE;
  }
  CommandArg2 = StrGetNextTokenLine (L" ");
  if (CommandArg2 == NULL) {
    EDBPrint (L"SymbolFile not found!\n");
    return EFI_DEBUG_CONTINUE;
  }

  FileName = GetFileNameFromFullPath (CommandArg);
  MapFileName = GetFileNameFromFullPath (CommandArg2);

  //
  // Unload Code
  //
  Status = EdbUnloadCode (DebuggerPrivate, MapFileName, FileName, &BufferPtr);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"UnloadCode error!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Delete Code buffer
  //
  Status = EdbDeleteCodeBuffer (DebuggerPrivate, MapFileName, FileName, BufferPtr);
  if (EFI_ERROR (Status)) {
    EDBPrint (L"DeleteCodeBuffer error!\n");
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}

/**

  DebuggerCommand - DisplayCode.

  @param  CommandArg      - The argument for this command
  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  ExceptionType   - Exception type.
  @param  SystemContext   - EBC system context.

  @retval EFI_DEBUG_CONTINUE - formal return value

**/
EFI_DEBUG_STATUS
DebuggerDisplayCode (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
{
  if (CommandArg == NULL) {
    DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = !DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly;
    EdbShowDisasm (DebuggerPrivate, SystemContext);
  } else if (StriCmp (CommandArg, L"on") == 0) {
    DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = TRUE;
    EdbShowDisasm (DebuggerPrivate, SystemContext);
  } else if (StriCmp (CommandArg, L"off") == 0) {
    DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = FALSE;
    EdbShowDisasm (DebuggerPrivate, SystemContext);
  } else {
    EDBPrint (L"DisplayCode - argument error\n");
  }

  return EFI_DEBUG_CONTINUE;
}
