/** @file

Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "Edb.h"

/**

  Load single symbol entry.

  @param  Object          - Symbol file object
  @param  Name            - Symbol name
  @param  ObjName         - Object name
  @param  Address         - Symbol address
  @param  Type            - Symbol type

  @retval EFI_SUCCESS - add single symbol entry successfully

**/
EFI_STATUS
EdbLoadSymbolSingleEntry (
  IN EFI_DEBUGGER_SYMBOL_OBJECT  *Object,
  IN CHAR8                       *Name,
  IN CHAR8                       *ObjName,
  IN UINTN                       Address,
  IN EFI_DEBUGGER_SYMBOL_TYPE    Type
  )
{
  EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;

  //
  // Check Count VS MaxCount
  //
  if (Object->EntryCount >= Object->MaxEntryCount) {
    //
    // reallocate (for codebuffer too)
    // TBD
    //
    return EFI_OUT_OF_RESOURCES;
  }

  Entry = &Object->Entry[Object->EntryCount];

  //
  // Print Debug info
  //
  if (sizeof (UINTN) == sizeof (UINT64)) {
    DEBUG ((DEBUG_ERROR, "  Symbol: %a, Address: 0x%016lx (%d)\n", Name, (UINT64)Address, (UINTN)Type));
  } else {
    DEBUG ((DEBUG_ERROR, "  Symbol: %a, Address: 0x%08x (%d)\n", Name, Address, (UINTN)Type));
  }

  //
  // Fill the entry - name, RVA, type
  //
  AsciiStrnCpyS (Entry->Name, sizeof (Entry->Name), Name, sizeof (Entry->Name) - 1);
  if (ObjName != NULL) {
    AsciiStrnCpyS (Entry->ObjName, sizeof (Entry->ObjName), ObjName, sizeof (Entry->ObjName) - 1);
  }

  Entry->Rva  = Address % EFI_DEBUGGER_DEFAULT_LINK_IMAGEBASE;
  Entry->Type = Type;

  //
  // Increase Count
  //
  Object->EntryCount++;

  //
  // Done
  //
  return EFI_SUCCESS;
}

typedef enum {
  EdbEbcMapParseStateUninitialized,
  EdbEbcMapParseStateSymbolStart,
  EdbEbcMapParseStateSeHandlerSymbol,
  EdbEbcMapParseStateFunctionSymbol,
  EdbEbcMapParseStateVarbssInitSymbol,
  EdbEbcMapParseStateCrtSymbol,
  EdbEbcMapParseStateVariableSymbol,
  EdbEbcMapParseStateStaticFunctionSymbol,
  EdbEbcMapParseStateMax,
} EDB_EBC_MAP_PARSE_STATE;

typedef enum {
  EdbEbcSymbolParseStateUninitialized,
  EdbEbcSymbolParseStateReadyForName,
  EdbEbcSymbolParseStateReadyForRVA,
  EdbEbcSymbolParseStateReadyForType,
  EdbEbcSymbolParseStateReadyForObject,
  EdbEbcSymbolParseStateMax,
} EDB_EBC_SYMBOL_PARSE_STATE;

/**

  The following code depends on the MAP file generated by IEC compiler (actually Microsoft linker).

  Sample as follows: EbcTest.map
===============================================================================
  EbcTest

 Timestamp is 45b02718 (Fri Jan 19 10:04:08 2007)

 Preferred load address is 10000000

 Start         Length     Name                   Class
 0001:00000000 00000370H .text                   CODE
 0002:00000000 00000030H _VARBSS_INIT            CODE
 0003:00000000 00000004H .CRT$TSA                DATA
 0003:00000004 00000004H .CRT$TSC                DATA
 0003:00000008 00000004H .CRT$X                  DATA
 0003:0000000c 00000008H .CRT$XCU                DATA
 0003:00000014 00000004H .CRT$Z                  DATA
 0003:00000020 0000001cH .rdata                  DATA
 0003:0000003c 00000000H .edata                  DATA
 0003:0000003c 00000056H .rdata$debug            DATA
 0004:00000000 00000070H .data                   DATA
 0004:00000070 00000020H .bss                    DATA

  Address         Publics by Value              Rva+Base     Lib:Object

 0000:00000000       ___safe_se_handler_table   00000000     <absolute>
 0000:00000000       ___safe_se_handler_count   00000000     <absolute>
 0001:00000042       TestSubRoutine             10000442 f   EbcTest.obj
 0001:0000011a       EfiMain                    1000051a f   EbcTest.obj
 0001:00000200       TestSubRoutineSub          10000600 f   EbcTestSub.obj
 0001:00000220       EfiStart                   10000620 f   EbcLib:EbcLib.obj
 0002:00000000       varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTest$c45b02717 10000800 f   EbcTest.obj
 0002:00000020       varbss_init_C:\efi_src\TIANO\Edk\Sample\Universal\Ebc\Dxe\EbcTest\EbcTestSub$c45af77f3 10000820 f   EbcTestSub.obj
 0003:00000000       CrtThunkBegin              10000a00     EbcLib:EbcLib.obj
 0003:00000004       CrtThunkEnd                10000a04     EbcLib:EbcLib.obj
 0003:00000008       CrtBegin                   10000a08     EbcLib:EbcLib.obj
 0003:00000014       CrtEnd                     10000a14     EbcLib:EbcLib.obj
 0004:00000070       TestStr                    10000c70     EbcTest.obj
 0004:00000078       TestVariable1              10000c78     EbcTest.obj
 0004:00000080       TestSubVariableSub         10000c80     EbcTestSub.obj

 entry point at        0001:00000220

 Static symbols

 0001:00000000       TestSubRoutine2            10000400 f   EbcTest.obj
===============================================================================

**/

/**

  Load symbol entry by Iec.

  @param  Object          - Symbol file object
  @param  BufferSize      - Symbol file buffer size
  @param  Buffer          - Symbol file buffer

  @retval EFI_SUCCESS - add symbol entry successfully

**/
EFI_STATUS
EdbLoadSymbolEntryByIec (
  IN EFI_DEBUGGER_SYMBOL_OBJECT  *Object,
  IN UINTN                       BufferSize,
  IN VOID                        *Buffer
  )
{
  CHAR8                       *LineBuffer;
  CHAR8                       *FieldBuffer;
  EDB_EBC_MAP_PARSE_STATE     MapParseState;
  EDB_EBC_SYMBOL_PARSE_STATE  SymbolParseState;
  CHAR8                       *Name;
  CHAR8                       *ObjName;
  UINTN                       Address;
  EFI_DEBUGGER_SYMBOL_TYPE    Type;

  //
  // Begin to parse the Buffer
  //
  LineBuffer    = AsciiStrGetNewTokenLine (Buffer, "\n\r");
  MapParseState = EdbEbcMapParseStateUninitialized;
  //
  // Check each line
  //
  while (LineBuffer != NULL) {
    FieldBuffer      = AsciiStrGetNewTokenField (LineBuffer, " ");
    SymbolParseState = EdbEbcSymbolParseStateUninitialized;
    //
    // Init entry value
    //
    Name    = NULL;
    ObjName = NULL;
    Address = 0;
    Type    = EfiDebuggerSymbolTypeMax;
    //
    // Check each field
    //
    while (FieldBuffer != NULL) {
      if (AsciiStrCmp (FieldBuffer, "") == 0) {
        FieldBuffer = AsciiStrGetNextTokenField (" ");
        continue;
      }

      //
      // check "Address"
      //
      if (AsciiStrCmp (FieldBuffer, "Address") == 0) {
        MapParseState = EdbEbcMapParseStateSymbolStart;
        break;
      }

      //
      // check "Static"
      //
      if (AsciiStrCmp (FieldBuffer, "Static") == 0) {
        MapParseState = EdbEbcMapParseStateStaticFunctionSymbol;
        break;
      }

      if (MapParseState == EdbEbcMapParseStateUninitialized) {
        //
        // Do not parse anything until get "Address" or "Static"
        //
        break;
      }

      if (AsciiStrCmp (FieldBuffer, "entry") == 0) {
        //
        // Skip entry point
        //
        break;
      }

      //
      // Now we start to parse this line for Name, Address, and Object
      //
      switch (SymbolParseState) {
        case EdbEbcSymbolParseStateUninitialized:
          //
          // Get the Address
          //
          SymbolParseState = EdbEbcSymbolParseStateReadyForName;
          break;
        case EdbEbcSymbolParseStateReadyForName:
          //
          // Get the Name
          //
          if (AsciiStrnCmp (FieldBuffer, "___safe_se_handler", AsciiStrLen ("___safe_se_handler")) == 0) {
            //
            // skip SeHandler
            //
            MapParseState = EdbEbcMapParseStateSeHandlerSymbol;
            goto ExitFieldParse;
          } else if (AsciiStrnCmp (FieldBuffer, "varbss_init", AsciiStrLen ("varbss_init")) == 0) {
            //
            // check VarbssInit
            //
            MapParseState = EdbEbcMapParseStateVarbssInitSymbol;
            //          goto ExitFieldParse;
            Name             = FieldBuffer;
            SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;
          } else if (AsciiStrnCmp (FieldBuffer, "Crt", AsciiStrLen ("Crt")) == 0) {
            //
            // check Crt
            //
            MapParseState = EdbEbcMapParseStateCrtSymbol;
            //          goto ExitFieldParse;
            Name             = FieldBuffer;
            SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;
          } else {
            //
            // Now, it is normal function
            //
            switch (MapParseState) {
              case EdbEbcMapParseStateSeHandlerSymbol:
                MapParseState = EdbEbcMapParseStateFunctionSymbol;
                break;
              case EdbEbcMapParseStateCrtSymbol:
                MapParseState = EdbEbcMapParseStateVariableSymbol;
                break;
              case EdbEbcMapParseStateFunctionSymbol:
              case EdbEbcMapParseStateVariableSymbol:
              case EdbEbcMapParseStateStaticFunctionSymbol:
                break;
              default:
                ASSERT (FALSE);
                break;
            }

            Name             = FieldBuffer;
            SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;
          }

          break;
        case EdbEbcSymbolParseStateReadyForRVA:
          //
          // Get the RVA
          //
          Address          = AsciiXtoi (FieldBuffer);
          SymbolParseState = EdbEbcSymbolParseStateReadyForType;
          break;
        case EdbEbcSymbolParseStateReadyForType:
          //
          // Get the Type. This is optional, only for "f".
          //
          if (AsciiStrCmp (FieldBuffer, "f") == 0) {
            SymbolParseState = EdbEbcSymbolParseStateReadyForObject;
            switch (MapParseState) {
              case EdbEbcMapParseStateFunctionSymbol:
              case EdbEbcMapParseStateVarbssInitSymbol:
                Type = EfiDebuggerSymbolFunction;
                break;
              case EdbEbcMapParseStateStaticFunctionSymbol:
                Type = EfiDebuggerSymbolStaticFunction;
                break;
              default:
                ASSERT (FALSE);
                break;
            }

            break;
          }

        //
        // Else it should be Object.
        // let it bypass here
        //
        case EdbEbcSymbolParseStateReadyForObject:
          switch (Type) {
            case EfiDebuggerSymbolTypeMax:
              switch (MapParseState) {
                case EdbEbcMapParseStateVariableSymbol:
                case EdbEbcMapParseStateCrtSymbol:
                  Type = EfiDebuggerSymbolGlobalVariable;
                  break;
                case EdbEbcMapParseStateSeHandlerSymbol:
                  //
                  // do nothing here
                  //
                  break;
                default:
                  ASSERT (FALSE);
                  break;
              }

              break;
            case EfiDebuggerSymbolFunction:
            case EfiDebuggerSymbolStaticFunction:
              break;
            default:
              ASSERT (FALSE);
              break;
          }

          //
          // Get the Object
          //
          ObjName          = FieldBuffer;
          SymbolParseState = EdbEbcSymbolParseStateUninitialized;
          break;
        default:
          ASSERT (FALSE);
          break;
      }

      //
      // Get the next field
      //
      FieldBuffer = AsciiStrGetNextTokenField (" ");
    }

    //
    // Add the entry if we get everything.
    //
    if ((Name != NULL) && (Type != EfiDebuggerSymbolTypeMax)) {
      EdbLoadSymbolSingleEntry (Object, Name, ObjName, Address, Type);
    }

ExitFieldParse:
    //
    // Get the next line
    //
    LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**

  Load symbol entry.

  @param  Object          - Symbol file object
  @param  BufferSize      - Symbol file buffer size
  @param  Buffer          - Symbol file buffer

  @retval EFI_SUCCESS - add symbol entry successfully

**/
EFI_STATUS
EdbLoadSymbolEntry (
  IN EFI_DEBUGGER_SYMBOL_OBJECT  *Object,
  IN UINTN                       BufferSize,
  IN VOID                        *Buffer
  )
{
  //
  // MAP file format depends on the compiler (actually linker).
  //
  // It is possible to check the different MAP file format in this routine.
  // Now only IEC is supported.
  //
  return EdbLoadSymbolEntryByIec (Object, BufferSize, Buffer);
}

/**

  Find symbol file by name.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  FileName        - Symbol file name
  @param  Index           - Symbol file index

  @return Object

**/
EFI_DEBUGGER_SYMBOL_OBJECT *
EdbFindSymbolFile (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN CHAR16                     *FileName,
  IN OUT UINTN                  *Index OPTIONAL
  )
{
  UINTN  ObjectIndex;

  //
  // Check each Object
  //
  for (ObjectIndex = 0; ObjectIndex < DebuggerPrivate->DebuggerSymbolContext.ObjectCount; ObjectIndex++) {
    if (StrCmp (FileName, DebuggerPrivate->DebuggerSymbolContext.Object[ObjectIndex].Name) == 0) {
      //
      // Name match, found it
      //
      if (Index != NULL) {
        *Index = ObjectIndex;
      }

      return &DebuggerPrivate->DebuggerSymbolContext.Object[ObjectIndex];
    }
  }

  //
  // Not found
  //
  return NULL;
}

/**

  Find symbol by address.

  @param  Address         - Symbol address
  @param  Type            - Search type
  @param  RetObject       - Symbol object
  @param  RetEntry        - Symbol entry

  @return Nearest symbol address

**/
UINTN
EbdFindSymbolAddress (
  IN UINTN                        Address,
  IN EDB_MATCH_SYMBOL_TYPE        Type,
  OUT EFI_DEBUGGER_SYMBOL_OBJECT  **RetObject,
  OUT EFI_DEBUGGER_SYMBOL_ENTRY   **RetEntry
  )
{
  UINTN                       Index;
  UINTN                       SubIndex;
  UINTN                       CandidateLowerAddress;
  UINTN                       CandidateUpperAddress;
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  EFI_DEBUGGER_SYMBOL_ENTRY   *Entry;
  EFI_DEBUGGER_SYMBOL_ENTRY   *LowEntry;
  EFI_DEBUGGER_SYMBOL_ENTRY   *UpperEntry;
  EFI_DEBUGGER_SYMBOL_OBJECT  *LowObject;
  EFI_DEBUGGER_SYMBOL_OBJECT  *UpperObject;

  if ((Type < 0) || (Type >= EdbMatchSymbolTypeMax)) {
    return 0;
  }

  //
  // Init
  //
  CandidateLowerAddress = 0;
  CandidateUpperAddress = (UINTN)-1;
  LowEntry              = NULL;
  UpperEntry            = NULL;
  LowObject             = NULL;
  UpperObject           = NULL;

  //
  // Go through each object
  //
  Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
  for (Index = 0; Index < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; Index++, Object++) {
    if (Object->EntryCount == 0) {
      continue;
    }

    //
    // Go through each entry
    //
    Entry = Object->Entry;
    for (SubIndex = 0; SubIndex < Object->EntryCount; SubIndex++, Entry++) {
      if (Address != Entry->Rva + Object->BaseAddress) {
        //
        // Check for nearest address
        //
        if (Address > Entry->Rva + Object->BaseAddress) {
          //
          // Record it if Current RVA < Address
          //
          if (CandidateLowerAddress < Entry->Rva + Object->BaseAddress) {
            CandidateLowerAddress = Entry->Rva + Object->BaseAddress;
            LowEntry              = Entry;
            LowObject             = Object;
          }
        } else {
          //
          // Record it if Current RVA > Address
          //
          if (CandidateUpperAddress > Entry->Rva + Object->BaseAddress) {
            CandidateUpperAddress = Entry->Rva + Object->BaseAddress;
            UpperEntry            = Entry;
            UpperObject           = Object;
          }
        }

        continue;
      }

      //
      // address match, return directly
      //
      *RetEntry  = Entry;
      *RetObject = Object;
      return Address;
    }
  }

  //
  // No Match, provide latest symbol
  //

  if ((Address - CandidateLowerAddress) < EFI_DEBUGGER_MAX_SYMBOL_ADDRESS_DELTA_VALUE) {
    //
    // Check for lower address
    //
    if (((Type == EdbMatchSymbolTypeNearestAddress) &&
         ((CandidateUpperAddress - Address) > (Address - CandidateLowerAddress))) ||
        (Type == EdbMatchSymbolTypeLowerAddress))
    {
      //
      // return nearest lower address
      //
      *RetEntry  = LowEntry;
      *RetObject = LowObject;
      return CandidateLowerAddress;
    }
  }

  if ((CandidateUpperAddress - Address) < EFI_DEBUGGER_MAX_SYMBOL_ADDRESS_DELTA_VALUE) {
    //
    // Check for upper address
    //
    if (((Type == EdbMatchSymbolTypeNearestAddress) &&
         ((CandidateUpperAddress - Address) < (Address - CandidateLowerAddress))) ||
        (Type == EdbMatchSymbolTypeUpperAddress))
    {
      //
      // return nearest upper address
      //
      *RetEntry  = UpperEntry;
      *RetObject = UpperObject;
      return CandidateUpperAddress;
    }
  }

  //
  // No match and nearest one, return NULL
  //
  return 0;
}

/**

  Unload symbol file by name.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  FileName        - Symbol file name

  @retval EFI_SUCCESS - unload symbol successfully

**/
EFI_STATUS
EdbUnloadSymbol (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN CHAR16                     *FileName
  )
{
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  UINTN                       ObjectIndex;
  UINTN                       Index;
  EFI_DEBUGGER_SYMBOL_ENTRY   *OldEntry;
  UINTN                       OldEntryCount;
  UINTN                       MaxEntryCount;
  VOID                        **OldSourceBuffer;

  //
  // Find Symbol
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, FileName, &ObjectIndex);
  if (Object == NULL) {
    EDBPrint (L"SymbolFile is not loaded!\n");
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Record old data
  //
  Object          = DebuggerPrivate->DebuggerSymbolContext.Object;
  OldEntry        = Object->Entry;
  OldSourceBuffer = Object->SourceBuffer;
  MaxEntryCount   = Object->MaxEntryCount;
  OldEntryCount   = Object->EntryCount;

  //
  // Remove the matched Object
  //
  for (Index = ObjectIndex; Index < DebuggerPrivate->DebuggerSymbolContext.ObjectCount - 1; Index++) {
    CopyMem (&Object[Index], &Object[Index + 1], sizeof (EFI_DEBUGGER_SYMBOL_OBJECT));
  }

  ZeroMem (&Object[Index], sizeof (Object[Index]));

  //
  // Move old data to new place
  //
  Object[Index].Entry         = OldEntry;
  Object[Index].SourceBuffer  = OldSourceBuffer;
  Object[Index].MaxEntryCount = MaxEntryCount;
  DebuggerPrivate->DebuggerSymbolContext.ObjectCount--;

  //
  // Clean old entry data
  //
  for (Index = 0; Index < OldEntryCount; Index++) {
    ZeroMem (&OldEntry[Index], sizeof (OldEntry[Index]));
  }

  //
  // Free OldSourceBuffer
  //
  for (Index = 0; OldSourceBuffer[Index] != NULL; Index++) {
    gBS->FreePool (OldSourceBuffer[Index]);
    OldSourceBuffer[Index] = NULL;
  }

  return EFI_SUCCESS;
}

/**

  Load symbol file by name.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  FileName        - Symbol file name
  @param  BufferSize      - Symbol file buffer size
  @param  Buffer          - Symbol file buffer

  @retval EFI_SUCCESS - load symbol successfully

**/
EFI_STATUS
EdbLoadSymbol (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN CHAR16                     *FileName,
  IN UINTN                      BufferSize,
  IN VOID                       *Buffer
  )
{
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  EFI_STATUS                  Status;

  //
  // Check duplicated File
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, FileName, NULL);
  if (Object != NULL) {
    Status = EdbUnloadSymbol (DebuggerPrivate, FileName);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Unload Duplicated Symbol File Error!\n"));
      return Status;
    }
  }

  //
  // Check Count VS MaxCount
  //
  if (DebuggerPrivate->DebuggerSymbolContext.ObjectCount >= DebuggerPrivate->DebuggerSymbolContext.MaxObjectCount) {
    //
    // reallocate
    // TBD
    //
    return EFI_OUT_OF_RESOURCES;
  }

  Object = &DebuggerPrivate->DebuggerSymbolContext.Object[DebuggerPrivate->DebuggerSymbolContext.ObjectCount];

  //
  // Init Object
  //
  Object->EntryCount    = 0;
  Object->MaxEntryCount = EFI_DEBUGGER_SYMBOL_ENTRY_MAX;

  //
  // Load SymbolEntry
  //
  DEBUG ((DEBUG_ERROR, "Symbol File: %s\n", FileName));
  Status = EdbLoadSymbolEntry (Object, BufferSize, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Fill Object value
  //
  StrnCpyS (
    Object->Name,
    sizeof (Object->Name) / sizeof (CHAR16),
    FileName,
    (sizeof (Object->Name) / sizeof (CHAR16)) - 1
    );
  Object->BaseAddress = 0;

  //
  // Increase the object count
  //
  DebuggerPrivate->DebuggerSymbolContext.ObjectCount++;

  return EFI_SUCCESS;
}

/**

  Located PDB path name in PE image.

  @param  ImageBase - base of PE to search

  @return Pointer into image at offset of PDB file name if PDB file name is found,
  Otherwise a pointer to an empty string.

**/
CHAR8 *
GetPdbPath (
  VOID  *ImageBase
  )
{
  CHAR8                            *PdbPath;
  UINT32                           DirCount;
  EFI_IMAGE_DOS_HEADER             *DosHdr;
  EFI_IMAGE_OPTIONAL_HEADER_UNION  *NtHdr;
  EFI_IMAGE_OPTIONAL_HEADER32      *OptionalHdr32;
  EFI_IMAGE_OPTIONAL_HEADER64      *OptionalHdr64;
  EFI_IMAGE_DATA_DIRECTORY         *DirectoryEntry;
  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY  *DebugEntry;
  VOID                             *CodeViewEntryPointer;

  //
  // Init value
  //
  CodeViewEntryPointer = NULL;
  PdbPath              = NULL;
  DosHdr               = ImageBase;

  //
  // Check magic
  //
  if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
    return NULL;
  }

  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINT8 *)DosHdr + DosHdr->e_lfanew);
  //
  // Check Machine, filter for EBC
  //
  if (NtHdr->Pe32.FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {
    //
    // If not EBC, return NULL
    //
    return NULL;
  }

  //
  // Get DirectoryEntry
  // EBC spec says PE32+, but implementation uses PE32. So check dynamically here.
  //
  if (NtHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    OptionalHdr32  = (VOID *)&NtHdr->Pe32.OptionalHeader;
    DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
  } else if (NtHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    OptionalHdr64  = (VOID *)&NtHdr->Pe32Plus.OptionalHeader;
    DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
  } else {
    return NULL;
  }

  if (DirectoryEntry->VirtualAddress == 0) {
    return NULL;
  }

  //
  // Go through DirectoryEntry
  //
  for (DirCount = 0;
       (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;
       DirCount++
       )
  {
    DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(DirectoryEntry->VirtualAddress + (UINTN)ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
    if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
      //
      // Match DebugEntry, only CODEVIEW_SIGNATURE_NB10 and CODEVIEW_SIGNATURE_RSDS are supported.
      //
      CodeViewEntryPointer = (VOID *)((UINTN)DebugEntry->RVA + (UINTN)ImageBase);
      switch (*(UINT32 *)CodeViewEntryPointer) {
        case CODEVIEW_SIGNATURE_NB10:
          PdbPath = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
          break;
        case CODEVIEW_SIGNATURE_RSDS:
          PdbPath = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
          break;
        default:
          break;
      }
    }
  }

  //
  // Done successfully
  //
  return PdbPath;
}

/**

  Check whether PDB file and MAP file have same name.

  @param  PdbFileName - PDB file name
  @param  MapFileName - MAP file name

  @retval TRUE  - PDB and MAP file name match
  @retval FALSE - PDB and MAP file name not match

**/
BOOLEAN
MatchPdbAndMap (
  IN CHAR8   *PdbFileName,
  IN CHAR16  *MapFileName
  )
{
  UINTN  PdbNameSize;
  UINTN  MapNameSize;
  CHAR8  *PurePdbFileName;
  UINTN  Index;

  //
  // remove dir name
  //
  PurePdbFileName = PdbFileName;
  for (Index = 0; PdbFileName[Index] != 0; Index++) {
    if (PdbFileName[Index] == '\\') {
      PurePdbFileName = &PdbFileName[Index + 1];
    }
  }

  PdbFileName = PurePdbFileName;

  //
  // get size
  //
  PdbNameSize = AsciiStrLen (PdbFileName);
  MapNameSize = StrLen (MapFileName);

  if (PdbNameSize != MapNameSize) {
    return FALSE;
  }

  //
  // check the name
  //
  for (Index = 0; Index < MapNameSize - 4; Index++) {
    if ((PdbFileName[Index] | 0x20) != (MapFileName[Index] | 0x20)) {
      return FALSE;
    }
  }

  return TRUE;
}

//
// BUGBUG: work-around start
//
typedef struct {
  EFI_DEBUG_IMAGE_INFO    *EfiDebugImageInfoTable;
  volatile UINT32         UpdateStatus;
  UINT32                  TableSize;
} EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD;

EFI_DEBUG_IMAGE_INFO_TABLE_HEADER  mDebugImageInfoTableHeader;

/**
For compatibility consideration, we handle 2 cases:

1) IA32:
  Old:                          New:
  +------------------------+    +------------------------+
  | EfiDebugImageInfoTable |    | UpdateStatus           |
  +------------------------+    +------------------------+
  | UpdateStatus           |    | TableSize              |
  +------------------------+    +------------------------+
  | TableSize              |    | EfiDebugImageInfoTable |
  +------------------------+    +------------------------+

2) X64 and IPF:
  Old:                          New:
  +------------------------+    +------------------------+
  | EfiDebugImageInfoTable |    | UpdateStatus           |
  |                        |    +------------------------+
  |                        |    | TableSize              |
  +------------------------+    +------------------------+
  | UpdateStatus           |    | EfiDebugImageInfoTable |
  +------------------------+    |                        |
  | TableSize              |    |                        |
  +------------------------+    +------------------------+

  @param DebugImageInfoTableHeader  Point to the EFI_DEBUG_IMAGE_INFO_TABLE_HEADER structure.

**/
VOID
EdbFixDebugImageInfoTable (
  IN OUT EFI_DEBUG_IMAGE_INFO_TABLE_HEADER  **DebugImageInfoTableHeader
  )
{
  mDebugImageInfoTableHeader.EfiDebugImageInfoTable = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->EfiDebugImageInfoTable;
  mDebugImageInfoTableHeader.UpdateStatus           = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->UpdateStatus;
  mDebugImageInfoTableHeader.TableSize              = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->TableSize;

  if ((*DebugImageInfoTableHeader)->UpdateStatus > 3) {
    *DebugImageInfoTableHeader = &mDebugImageInfoTableHeader;
    return;
  }

  if ((*DebugImageInfoTableHeader)->TableSize % (EFI_PAGE_SIZE / (sizeof (VOID *))) != 0) {
    *DebugImageInfoTableHeader = &mDebugImageInfoTableHeader;
    return;
  }

  return;
}

//
// BUGBUG: work-around end
//

/**

  Patch symbol RVA.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  FileName        - Symbol file name
  @param  SearchType      - Search type for Object

  @retval EFI_SUCCESS   - Patch symbol RVA successfully
  @retval EFI_NOT_FOUND - Symbol RVA base not found

**/
EFI_STATUS
EdbPatchSymbolRVA (
  IN EFI_DEBUGGER_PRIVATE_DATA      *DebuggerPrivate,
  IN CHAR16                         *FileName,
  IN EDB_EBC_IMAGE_RVA_SEARCH_TYPE  SearchType
  )
{
  EFI_STATUS                  Status;
  UINTN                       ImageNumber;
  EFI_DEBUG_IMAGE_INFO        *ImageTable;
  CHAR8                       *PdbPath;
  VOID                        *ImageBase;
  VOID                        *CandidateImageBase;
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;

  if ((SearchType < 0) || (SearchType >= EdbEbcImageRvaSearchTypeMax)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the related object
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, FileName, NULL);
  if (Object == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Try again to get DebugImageInfoTable
  //
  if (mDebuggerPrivate.DebugImageInfoTableHeader == NULL) {
    Status = EfiGetSystemConfigurationTable (
               &gEfiDebugImageInfoTableGuid,
               (VOID **)&mDebuggerPrivate.DebugImageInfoTableHeader
               );
    if (EFI_ERROR (Status)) {
      EDBPrint (L"DebugImageInfoTable not found!\n");
      return Status;
    }
  }

  DEBUG ((DEBUG_ERROR, "DebugImageInfoTableHeader: %x\n", mDebuggerPrivate.DebugImageInfoTableHeader));

  //
  // BUGBUG: work-around start
  //
  EdbFixDebugImageInfoTable (&mDebuggerPrivate.DebugImageInfoTableHeader);
  //
  // BUGBUG: work-around end
  //

  //
  // Go through DebugImageInfoTable for each Image
  //
  CandidateImageBase = NULL;
  ImageTable         = mDebuggerPrivate.DebugImageInfoTableHeader->EfiDebugImageInfoTable;
  for (ImageNumber = 0; ImageNumber < mDebuggerPrivate.DebugImageInfoTableHeader->TableSize; ImageNumber++) {
    if (ImageTable[ImageNumber].NormalImage == NULL) {
      continue;
    }

    ImageBase = ImageTable[ImageNumber].NormalImage->LoadedImageProtocolInstance->ImageBase;
    //
    // Get PDB path
    //
    PdbPath = GetPdbPath (ImageBase);
    if (PdbPath == NULL) {
      continue;
    }

    //
    // Check PDB name
    //
    if (!MatchPdbAndMap (PdbPath, FileName)) {
      continue;
    }

    DEBUG ((DEBUG_ERROR, "ImageBase: %x\n", ImageBase));

    //
    // Check SearchType
    //
    if ((SearchType == EdbEbcImageRvaSearchTypeAny) || (SearchType == EdbEbcImageRvaSearchTypeFirst)) {
      //
      // Assign base address and return
      //
      Object->BaseAddress = (UINTN)ImageBase;
      return EFI_SUCCESS;
    }

    //
    // Get CandidateImageBase for EdbEbcImageRvaSearchTypeLast
    //
    CandidateImageBase = ImageBase;
  }

  //
  // Check EdbEbcImageRvaSearchTypeLast
  //
  if (SearchType == EdbEbcImageRvaSearchTypeLast) {
    if (CandidateImageBase == NULL) {
      return EFI_NOT_FOUND;
    }

    //
    // Assign base address and return
    //
    Object->BaseAddress = (UINTN)CandidateImageBase;
    return EFI_SUCCESS;
  }

  //
  // No match
  //
  return EFI_NOT_FOUND;
}

/**

  Check whether OBJ file and COD file have same name.

  @param  ObjFileName - OBJ file name
  @param  CodFileName - COD file name

  @retval TRUE  - OBJ and COD file name match
  @retval FALSE - OBJ and COD file name not match

**/
BOOLEAN
MatchObjAndCod (
  IN CHAR8   *ObjFileName,
  IN CHAR16  *CodFileName
  )
{
  UINTN  ObjNameSize;
  UINTN  CodNameSize;
  CHAR8  *PureObjFileName;
  UINTN  Index;

  //
  // remove library name
  //
  PureObjFileName = ObjFileName;
  for (Index = 0; ObjFileName[Index] != 0; Index++) {
    if (ObjFileName[Index] == ':') {
      PureObjFileName = &ObjFileName[Index + 1];
      break;
    }
  }

  ObjFileName = PureObjFileName;

  //
  // get size
  //
  ObjNameSize = AsciiStrLen (ObjFileName);
  CodNameSize = StrLen (CodFileName);

  if (ObjNameSize != CodNameSize) {
    return FALSE;
  }

  //
  // check the name
  //
  for (Index = 0; Index < CodNameSize - 4; Index++) {
    if ((ObjFileName[Index] | 0x20) != (CodFileName[Index] | 0x20)) {
      return FALSE;
    }
  }

  return TRUE;
}

typedef enum {
  EdbEbcCodParseStateUninitialized,
  EdbEbcCodParseStateSymbolInitialized,
  EdbEbcCodParseStateSymbolStart,
  EdbEbcCodParseStateSymbolEnd,
  EdbEbcCodParseStateMax,
} EDB_EBC_COD_PARSE_STATE;

/**

  The following code depends on the COD file generated by IEC compiler.

**/

/**

  Load code by symbol by Iec.

  @param  Name            - Symbol file name
  @param  Buffer          - Symbol file buffer
  @param  BufferSize      - Symbol file buffer size
  @param  CodeBufferSize  - Code buffer size
  @param  FuncOffset      - Code funcion offset

  @return CodeBuffer

**/
CHAR8 *
EdbLoadCodBySymbolByIec (
  IN CHAR8   *Name,
  IN VOID    *Buffer,
  IN UINTN   BufferSize,
  OUT UINTN  *CodeBufferSize,
  OUT UINTN  *FuncOffset
  )
{
  CHAR8                    *LineBuffer;
  CHAR8                    *FieldBuffer;
  VOID                     *BufferStart;
  VOID                     *BufferEnd;
  UINTN                    Offset;
  EDB_EBC_COD_PARSE_STATE  CodParseState;
  CHAR8                    Char[2];

  //
  // Init
  //
  Char[0]       = 9;
  Char[1]       = 0;
  LineBuffer    = AsciiStrGetNewTokenLine (Buffer, "\n\r");
  Offset        = (UINTN)-1;
  BufferStart   = NULL;
  BufferEnd     = NULL;
  CodParseState = EdbEbcCodParseStateUninitialized;

  //
  // Check each line
  //
  while (LineBuffer != NULL) {
    switch (CodParseState) {
      case EdbEbcCodParseStateUninitialized:
        //
        // check mark_begin, begin to check line after this match
        //
        if (AsciiStrCmp (LineBuffer, "; mark_begin;") == 0) {
          CodParseState = EdbEbcCodParseStateSymbolInitialized;
        }

        LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
        PatchForAsciiStrTokenBefore (LineBuffer, '\n');
        break;

      case EdbEbcCodParseStateSymbolInitialized:
        //
        // check mark_end, not check line after this match
        //
        if (AsciiStrCmp (LineBuffer, "; mark_end;") == 0) {
          CodParseState = EdbEbcCodParseStateUninitialized;
          LineBuffer    = AsciiStrGetNextTokenLine ("\n\r");
          PatchForAsciiStrTokenBefore (LineBuffer, '\n');
          break;
        }

        //
        // not check this line if the first char is as follows
        //
        if ((*LineBuffer == 0)   ||
            (*LineBuffer == '$') ||
            (*LineBuffer == ';') ||
            (*LineBuffer == '_') ||
            (*LineBuffer == ' '))
        {
          LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
          PatchForAsciiStrTokenBefore (LineBuffer, '\n');
          break;
        }

        //
        // get function name, function name is followed by char 0x09.
        //
        FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, Char);
        ASSERT (FieldBuffer != NULL);
        if (AsciiStriCmp (FieldBuffer, Name) == 0) {
          BufferStart   = FieldBuffer;
          CodParseState = EdbEbcCodParseStateSymbolStart;
        }

        PatchForAsciiStrTokenAfter (FieldBuffer, 0x9);

        //
        // Get next line
        //
        LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
        PatchForAsciiStrTokenBefore (LineBuffer, '\n');
        break;

      case EdbEbcCodParseStateSymbolStart:
        //
        // check mark_end, if this match, means the function is found successfully.
        //
        if (AsciiStrCmp (LineBuffer, "; mark_end;") == 0) {
          CodParseState = EdbEbcCodParseStateSymbolEnd;
          //
          // prepare CodeBufferSize, FuncOffset, and FuncStart to return
          //
          BufferEnd       = LineBuffer + sizeof ("; mark_end;") - 1;
          *CodeBufferSize = (UINTN)BufferEnd - (UINTN)BufferStart;
          *FuncOffset     = Offset;
          PatchForAsciiStrTokenAfter (LineBuffer, '\n');
          return BufferStart;
        }

        //
        // Get function offset
        //
        if ((Offset == (UINTN)-1) &&
            (*LineBuffer == ' '))
        {
          FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 2, " ");
          Offset      = AsciiXtoi (FieldBuffer);
          PatchForAsciiStrTokenAfter (FieldBuffer, ' ');
        }

        //
        // Get next line
        //
        LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
        PatchForAsciiStrTokenBefore (LineBuffer, '\n');
        break;

      case EdbEbcCodParseStateSymbolEnd:
        break;

      default:
        break;
    }
  }

  //
  // no function found
  //
  return NULL;
}

/**

  Load code by symbol.

  @param  Name            - Symbol file name
  @param  Buffer          - Symbol file buffer
  @param  BufferSize      - Symbol file buffer size
  @param  CodeBufferSize  - Code buffer size
  @param  FuncOffset      - Code funcion offset

  @return CodeBuffer

**/
CHAR8 *
EdbLoadCodBySymbol (
  IN CHAR8   *Name,
  IN VOID    *Buffer,
  IN UINTN   BufferSize,
  OUT UINTN  *CodeBufferSize,
  OUT UINTN  *FuncOffset
  )
{
  //
  // COD file format depends on the compiler.
  //
  // It is possible to check the different COD file format in this routine.
  // Now only IEC is supported.
  //
  return EdbLoadCodBySymbolByIec (Name, Buffer, BufferSize, CodeBufferSize, FuncOffset);
}

/**

  Find code from object.

  @param  DebuggerPrivate    EBC Debugger private data structure
  @param  Object          - Symbol object
  @param  FileName        - File name

**/
VOID *
EdbFindCodeFromObject (
  IN EFI_DEBUGGER_PRIVATE_DATA   *DebuggerPrivate,
  IN EFI_DEBUGGER_SYMBOL_OBJECT  *Object,
  IN CHAR16                      *FileName
  )
{
  UINTN  EntryIndex;

  //
  // Go througn each Entry in this Object
  //
  for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
    //
    // This check is for Function only
    //
    if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&
        (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction))
    {
      continue;
    }

    //
    // Skip match varbss_init function, because they has no source code
    //
    if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof ("varbss_init") - 1) == 0) {
      continue;
    }

    //
    // check the name
    //
    if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {
      continue;
    }

    //
    // found it, return source buffer
    //
    if (Object->Entry[EntryIndex].CodBuffer != NULL) {
      return Object->Entry[EntryIndex].SourceBuffer;
    }
  }

  //
  // not found
  //
  return NULL;
}

/**

  Load code.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  MapFileName     - Symbol file name
  @param  FileName        - Code file name
  @param  BufferSize      - Code file buffer size
  @param  Buffer          - Code file buffer

  @retval EFI_SUCCESS - Code loaded successfully

**/
EFI_STATUS
EdbLoadCode (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN CHAR16                     *MapFileName,
  IN CHAR16                     *FileName,
  IN UINTN                      BufferSize,
  IN VOID                       *Buffer
  )
{
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  UINTN                       ObjectIndex;
  UINTN                       EntryIndex;
  VOID                        *SourceBuffer;
  EFI_STATUS                  Status;

  //
  // Find Symbol
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, &ObjectIndex);
  if (Object == NULL) {
    EDBPrint (L"SymbolFile is not loaded!\n");
    return EFI_NOT_FOUND;
  } else {
    //
    // Check duplicated File
    //
    SourceBuffer = EdbFindCodeFromObject (DebuggerPrivate, Object, FileName);
    if (SourceBuffer != NULL) {
      //
      // unnload duplicated code
      //
      Status = EdbUnloadCode (DebuggerPrivate, MapFileName, FileName, &SourceBuffer);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "Unload Duplicated Code File Error!\n"));
        return Status;
      }

      Status = EdbDeleteCodeBuffer (DebuggerPrivate, MapFileName, FileName, SourceBuffer);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "Delete Duplicated Code File Error!\n"));
        return Status;
      }
    }
  }

  //
  // Go through each SymbolEntry
  //
  for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
    //
    // load symbol for function only
    //
    if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&
        (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction))
    {
      continue;
    }

    //
    // skip varbss_init
    //
    if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof ("varbss_init") - 1) == 0) {
      continue;
    }

    //
    // Check the name
    //
    if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {
      continue;
    }

    //
    // load code for this symbol
    //
    Object->Entry[EntryIndex].CodBuffer = EdbLoadCodBySymbol (
                                            Object->Entry[EntryIndex].Name,
                                            Buffer,
                                            BufferSize,
                                            &Object->Entry[EntryIndex].CodBufferSize,
                                            &Object->Entry[EntryIndex].FuncOffsetBase
                                            );
    if (Object->Entry[EntryIndex].CodBuffer != NULL) {
      Object->Entry[EntryIndex].SourceBuffer = Buffer;
    }
  }

  //
  // patch end '\0' for each code buffer
  //
  for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
    if (Object->Entry[EntryIndex].CodBuffer != NULL) {
      *((UINT8 *)Object->Entry[EntryIndex].CodBuffer + Object->Entry[EntryIndex].CodBufferSize) = 0;
      DEBUG ((DEBUG_ERROR, "  CodeSymbol: %a, FuncOffset: 0x05%x\n", Object->Entry[EntryIndex].Name, Object->Entry[EntryIndex].FuncOffsetBase));
      //      DEBUG ((DEBUG_ERROR, "  [CODE]:\n%a\n", Object->Entry[EntryIndex].CodBuffer));
    }
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**

  Unload code.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  MapFileName     - Symbol file name
  @param  FileName        - Code file name
  @param  Buffer          - Code file buffer

  @retval EFI_SUCCESS - Code unloaded successfully

**/
EFI_STATUS
EdbUnloadCode (
  IN EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN CHAR16                     *MapFileName,
  IN CHAR16                     *FileName,
  OUT VOID                      **Buffer
  )
{
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  UINTN                       ObjectIndex;
  UINTN                       EntryIndex;

  //
  // Find Symbol
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, &ObjectIndex);
  if (Object == NULL) {
    EDBPrint (L"SymbolFile is not loaded!\n");
    return EFI_NOT_FOUND;
  }

  //
  // Find code
  //
  *Buffer = EdbFindCodeFromObject (DebuggerPrivate, Object, FileName);
  if (*Buffer == NULL) {
    EDBPrint (L"CodeFile is not loaded!\n");
    return EFI_NOT_FOUND;
  }

  //
  // go through each entry
  //
  for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
    if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&
        (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction))
    {
      continue;
    }

    if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof ("varbss_init") - 1) == 0) {
      continue;
    }

    if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {
      continue;
    }

    //
    // clean up the buffer
    //
    Object->Entry[EntryIndex].CodBuffer      = NULL;
    Object->Entry[EntryIndex].CodBufferSize  = 0;
    Object->Entry[EntryIndex].FuncOffsetBase = 0;
    Object->Entry[EntryIndex].SourceBuffer   = NULL;
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}

/**

  Add code buffer.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  MapFileName     - Symbol file name
  @param  CodeFileName    - Code file name
  @param  SourceBufferSize- Code buffer size
  @param  SourceBuffer    - Code buffer

  @retval EFI_SUCCESS - CodeBuffer added successfully

**/
EFI_STATUS
EdbAddCodeBuffer (
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     CHAR16                     *MapFileName,
  IN     CHAR16                     *CodeFileName,
  IN     UINTN                      SourceBufferSize,
  IN     VOID                       *SourceBuffer
  )
{
  UINTN                       Index;
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;

  //
  // Find Symbol
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, NULL);
  if (Object == NULL) {
    EDBPrint (L"SymbolFile is not loaded!\n");
    return EFI_NOT_FOUND;
  }

  //
  // Add it to last entry
  //
  for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {
  }

  Object->SourceBuffer[Index] = SourceBuffer;

  return EFI_SUCCESS;
}

/**

  Delete code buffer.

  @param  DebuggerPrivate - EBC Debugger private data structure
  @param  MapFileName     - Symbol file name
  @param  CodeFileName    - Code file name
  @param  SourceBuffer    - Code buffer

  @retval EFI_SUCCESS - CodeBuffer deleted successfully

**/
EFI_STATUS
EdbDeleteCodeBuffer (
  IN     EFI_DEBUGGER_PRIVATE_DATA  *DebuggerPrivate,
  IN     CHAR16                     *MapFileName,
  IN     CHAR16                     *CodeFileName,
  IN     VOID                       *SourceBuffer
  )
{
  UINTN                       Index;
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;

  //
  // Find Symbol
  //
  Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, NULL);
  if (Object == NULL) {
    EDBPrint (L"SymbolFile is not loaded!\n");
    return EFI_NOT_FOUND;
  }

  for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {
    //
    // free the buffer if match
    //
    if (Object->SourceBuffer[Index] == SourceBuffer) {
      gBS->FreePool (SourceBuffer);
      break;
    }
  }

  if (Object->SourceBuffer[Index] == NULL) {
    //
    // not return NOT_FOUND
    //
    return EFI_SUCCESS;
  }

  //
  // remove the entry
  //
  Object->SourceBuffer[Index] = NULL;
  for (Index = Index + 1; Object->SourceBuffer[Index] != NULL; Index++) {
    Object->SourceBuffer[Index - 1] = Object->SourceBuffer[Index];
  }

  Object->SourceBuffer[Index - 1] = NULL;

  return EFI_SUCCESS;
}

/**

  Find the symbol string according to address.

  @param  Address         - Symbol address

  @return Symbol string

**/
CHAR8 *
FindSymbolStr (
  IN UINTN  Address
  )
{
  UINTN                       ObjectIndex;
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  UINTN                       EntryIndex;
  EFI_DEBUGGER_SYMBOL_ENTRY   *Entry;

  //
  // need we display symbol
  //
  if (!mDebuggerPrivate.DebuggerSymbolContext.DisplaySymbol) {
    return NULL;
  }

  //
  // Go through each object and entry
  //
  Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
  for (ObjectIndex = 0; ObjectIndex < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; ObjectIndex++) {
    Entry = Object[ObjectIndex].Entry;
    for (EntryIndex = 0; EntryIndex < Object[ObjectIndex].EntryCount; EntryIndex++) {
      //
      // if Address match, return Name
      //
      if (Address == (Entry[EntryIndex].Rva + Object[ObjectIndex].BaseAddress)) {
        return Entry[EntryIndex].Name;
      }
    }
  }

  //
  // not found
  //
  return NULL;
}

/**

  Get line number and offset from this line in code file.

  @param  Line            - Line buffer in code file
  @param  Offset          - Offset to functin entry

  @return Line number

**/
UINTN
EdbGetLineNumberAndOffsetFromThisLine (
  IN VOID    *Line,
  OUT UINTN  *Offset
  )
{
  UINTN  LineNumber;
  CHAR8  *LineBuffer;
  CHAR8  *FieldBuffer;

  LineNumber = (UINTN)-1;
  LineBuffer = Line;
  *Offset    = (UINTN)-1;

  while (LineBuffer != NULL) {
    //
    // Check candidate
    //
    if (*LineBuffer != ' ') {
      return (UINTN)-1;
    }

    //
    // Get Offset
    //
    if (*(LineBuffer + 2) != ' ') {
      if (*Offset == (UINTN)-1) {
        FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 2, " ");
        *Offset     = AsciiXtoi (FieldBuffer);
        PatchForAsciiStrTokenAfter (FieldBuffer, ' ');
      }
    }

    //
    // 1. assembly instruction
    //
    FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, ":");
    //
    // 2. file path
    //
    FieldBuffer = AsciiStrGetNextTokenField (":");
    PatchForAsciiStrTokenBefore (FieldBuffer, ':');
    if (FieldBuffer == NULL) {
      //
      // candidate found
      //
      LineNumber = 0;
      LineBuffer = AsciiStrGetNextTokenLine ("\n");
      PatchForAsciiStrTokenBefore (LineBuffer, '\n');
      continue;
    }

    //
    // 3. line number
    //
    FieldBuffer = AsciiStrGetNextTokenField (":");
    PatchForAsciiStrTokenBefore (FieldBuffer, ':');
    if (FieldBuffer == NULL) {
      //
      // impossible, TBD?
      //
      LineBuffer = AsciiStrGetNextTokenLine ("\n");
      PatchForAsciiStrTokenBefore (LineBuffer, '\n');
      continue;
    }

    LineNumber = AsciiAtoi (FieldBuffer);
    //
    // Not patch after
    //

    return LineNumber;
  }

  return (UINTN)-1;
}

typedef enum {
  EdbEbcLineSearchTypeAny,
  EdbEbcLineSearchTypeFirst,
  EdbEbcLineSearchTypeLast,
  EdbEbcLineSearchTypeMax,
} EDB_EBC_LINE_SEARCH_TYPE;

/**

  Get line number from this code file.

  @param  Entry           - Symbol entry
  @param  FuncOffset      - Offset to functin entry
  @param  SearchType      - Search type for the code

  @return Line number

**/
UINTN
EdbGetLineNumberFromCode (
  IN EFI_DEBUGGER_SYMBOL_ENTRY  *Entry,
  IN UINTN                      FuncOffset,
  IN EDB_EBC_LINE_SEARCH_TYPE   SearchType
  )
{
  CHAR8  *LineBuffer;
  UINTN  LineNumber;
  UINTN  Offset;
  UINTN  CandidateLineNumber;
  UINTN  CandidateOffset;

  if ((SearchType < 0) || (SearchType >= EdbEbcLineSearchTypeMax)) {
    return (UINTN)-1;
  }

  LineNumber          = (UINTN)-1;
  CandidateLineNumber = (UINTN)-1;
  CandidateOffset     = (UINTN)-1;
  LineBuffer          = AsciiStrGetNewTokenLine (Entry->CodBuffer, "\n");
  while (LineBuffer != NULL) {
    if (*LineBuffer != ' ') {
      LineBuffer = AsciiStrGetNextTokenLine ("\n");
      PatchForAsciiStrTokenBefore (LineBuffer, '\n');
      continue;
    }

    //
    // Get Info
    //
    LineNumber = EdbGetLineNumberAndOffsetFromThisLine (LineBuffer, &Offset);

    //
    // Check offset
    //
    if (Offset != FuncOffset) {
      //
      // Check last offset match
      //
      if (CandidateOffset == FuncOffset) {
        if (SearchType == EdbEbcLineSearchTypeLast) {
          PatchForAsciiStrTokenAfter (LineBuffer, '\n');
          if (CandidateLineNumber != LineNumber) {
            return CandidateLineNumber;
          } else {
            return (UINTN)-1;
          }
        } else {
          //
          // impossible, TBD?
          //
        }
      }

      LineBuffer = AsciiStrGetNextTokenLine ("\n");
      PatchForAsciiStrTokenBefore (LineBuffer, '\n');
      CandidateLineNumber = LineNumber;
      continue;
    }

    //
    // Offset match, more check
    //
    if (SearchType == EdbEbcLineSearchTypeAny) {
      PatchForAsciiStrTokenAfter (LineBuffer, '\n');
      return LineNumber;
    }

    if (SearchType == EdbEbcLineSearchTypeFirst) {
      //
      // Check last line
      //
      PatchForAsciiStrTokenAfter (LineBuffer, '\n');
      if (CandidateLineNumber != LineNumber) {
        return LineNumber;
      } else {
        return (UINTN)-1;
      }
    }

    CandidateLineNumber = LineNumber;
    CandidateOffset     = Offset;

    LineBuffer = AsciiStrGetNextTokenLine ("\n");
    PatchForAsciiStrTokenBefore (LineBuffer, '\n');
  }

  //
  // Check last offset match
  //
  if (CandidateOffset == FuncOffset) {
    if (SearchType == EdbEbcLineSearchTypeLast) {
      return CandidateLineNumber;
    }
  }

  return (UINTN)-1;
}

/**

  Get the source string from this code file by line.

  @param  Entry           - Symbol entry
  @param  LineNumber      - line number
  @param  FuncEnd         - Function end

  @return Funtion start

**/
VOID *
EdbGetSourceStrFromCodeByLine (
  IN EFI_DEBUGGER_SYMBOL_ENTRY  *Entry,
  IN UINTN                      LineNumber,
  IN VOID                       **FuncEnd
  )
{
  CHAR8  *LineBuffer;
  CHAR8  *FieldBuffer;
  VOID   *FuncStart;
  UINTN  Number;

  FuncStart  = NULL;
  LineBuffer = AsciiStrGetNewTokenLine (Entry->CodBuffer, "\n");
  while (LineBuffer != NULL) {
    if (*LineBuffer != ';') {
      if (FuncStart != NULL) {
        //
        // Over
        //
        *FuncEnd = LineBuffer - 1;
        PatchForAsciiStrTokenAfter (LineBuffer, '\n');
        return FuncStart;
      }

      LineBuffer = AsciiStrGetNextTokenLine ("\n");
      PatchForAsciiStrTokenBefore (LineBuffer, '\n');
      continue;
    }

    //
    // Check LineNumber
    //
    FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 1, " ");
    Number      = AsciiAtoi (FieldBuffer);
    PatchForAsciiStrTokenAfter (FieldBuffer, ' ');
    if (Number != LineNumber) {
      LineBuffer = AsciiStrGetNextTokenLine ("\n");
      PatchForAsciiStrTokenBefore (LineBuffer, '\n');
      continue;
    }

    //
    // Line match, get line number
    //
    if (FuncStart == NULL) {
      FuncStart = LineBuffer;
    }

    LineBuffer = AsciiStrGetNextTokenLine ("\n");
    PatchForAsciiStrTokenBefore (LineBuffer, '\n');
  }

  return NULL;
}

/**

  Get source string from this code file.

  @param  Entry           - Symbol entry
  @param  FuncOffset      - Offset to functin entry
  @param  FuncEnd         - Function end

  @retval Funtion start

**/
VOID *
EdbGetSourceStrFromCode (
  IN EFI_DEBUGGER_SYMBOL_ENTRY  *Entry,
  IN UINTN                      FuncOffset,
  IN VOID                       **FuncEnd
  )
{
  UINTN  LineNumber;

  //
  // Only search the last line, then display
  //
  LineNumber = EdbGetLineNumberFromCode (Entry, FuncOffset, EdbEbcLineSearchTypeLast);
  if (LineNumber == (UINTN)-1) {
    return NULL;
  }

  return EdbGetSourceStrFromCodeByLine (Entry, LineNumber, FuncEnd);
}

/**

  Print source.

  @param  Address         - Instruction address
  @param  IsPrint         - Whether need to print

  @retval 1 - find the source
  @retval 0 - not find the source

**/
UINTN
EdbPrintSource (
  IN UINTN    Address,
  IN BOOLEAN  IsPrint
  )
{
  UINTN                       SymbolAddress;
  EFI_DEBUGGER_SYMBOL_OBJECT  *RetObject;
  EFI_DEBUGGER_SYMBOL_ENTRY   *RetEntry;
  UINTN                       FuncOffset;
  UINT8                       *FuncStart;
  UINT8                       *FuncEnd;
  UINT8                       *FuncIndex;
  CHAR8                       Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];
  UINTN                       BufferSize;

  //
  // need we display symbol
  //
  if (!mDebuggerPrivate.DebuggerSymbolContext.DisplaySymbol) {
    return 0;
  }

  //
  // find the symbol address
  //
  SymbolAddress = EbdFindSymbolAddress (
                    Address,
                    EdbMatchSymbolTypeLowerAddress,
                    &RetObject,
                    &RetEntry
                    );
  if ((SymbolAddress == 0) || (RetEntry == NULL)) {
    return 0;
  }

  FuncOffset = Address - SymbolAddress + RetEntry->FuncOffsetBase;

  //
  // Get Func String
  //
  FuncStart = EdbGetSourceStrFromCode (RetEntry, FuncOffset, (VOID **)&FuncEnd);
  if (FuncStart == NULL) {
    return 0;
  }

  //
  // check whether need to real print
  //
  if (!IsPrint) {
    return 1;
  }

  *(UINT8 *)FuncEnd = 0;

  //
  // seperate buffer by \n, so that \r can be added.
  //
  FuncIndex = FuncStart;
  while (*FuncIndex != 0) {
    if (*FuncIndex == '\n') {
      if ((FuncIndex - FuncStart) < (EFI_DEBUG_MAX_PRINT_BUFFER - 3)) {
        BufferSize = FuncIndex - FuncStart;
      } else {
        BufferSize = EFI_DEBUG_MAX_PRINT_BUFFER - 3;
      }

      if (BufferSize != 0) {
        CopyMem (Buffer, FuncStart, BufferSize);
      }

      Buffer[BufferSize] = 0;
      EDBPrint (L"%a\n", Buffer);
      FuncStart = FuncIndex + 1;
      FuncIndex = FuncStart;
    } else {
      FuncIndex++;
    }
  }

  //
  // Patch the end
  //
  *(UINT8 *)FuncEnd = '\n';

  return 1;
}

/**

  Get Mapfile and SymbolName from one symbol format: [MapFileName:]SymbolName.

  @param  Symbol          - whole Symbol name
  @param  MapfileName     - the mapfile name in the symbol
  @param  SymbolName      - the symbol name in the symbol

**/
VOID
GetMapfileAndSymbol (
  IN CHAR16   *Symbol,
  OUT CHAR16  **MapfileName,
  OUT CHAR16  **SymbolName
  )
{
  CHAR16  *Ch;

  *MapfileName = NULL;
  *SymbolName  = Symbol;

  for (Ch = Symbol; *Ch != 0; Ch++) {
    //
    // Find split char
    //
    if (*Ch == L':') {
      *MapfileName = Symbol;
      *Ch          = 0;
      *SymbolName  = Ch + 1;
      break;
    }
  }

  return;
}

/**

  Convert a symbol to an address.

  @param  Symbol          - Symbol name
  @param  Address         - Symbol address

  @retval EFI_SUCCESS    - symbol found and address returned.
  @retval EFI_NOT_FOUND  - symbol not found
  @retval EFI_NO_MAPPING - duplicated symbol not found

**/
EFI_STATUS
Symboltoi (
  IN CHAR16  *Symbol,
  OUT UINTN  *Address
  )
{
  UINTN                       ObjectIndex;
  EFI_DEBUGGER_SYMBOL_OBJECT  *Object;
  UINTN                       EntryIndex;
  EFI_DEBUGGER_SYMBOL_ENTRY   *Entry;
  CHAR16                      *SymbolName;
  CHAR16                      *MapfileName;

  //
  // Split one symbol to mapfile name and symbol name
  //
  GetMapfileAndSymbol (Symbol, &MapfileName, &SymbolName);

  *Address = 0;
  //
  // Go through each object
  //
  Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
  for (ObjectIndex = 0; ObjectIndex < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; ObjectIndex++) {
    //
    // Check MapfileName
    //
    if ((MapfileName != NULL) && (StriCmp (Object[ObjectIndex].Name, MapfileName) != 0)) {
      continue;
    }

    //
    // Go through each entry
    //
    Entry = Object[ObjectIndex].Entry;
    for (EntryIndex = 0; EntryIndex < Object[ObjectIndex].EntryCount; EntryIndex++) {
      //
      // Check SymbolName (case sensitive)
      //
      if (StrCmpUnicodeAndAscii (SymbolName, Entry[EntryIndex].Name) == 0) {
        if ((*Address != 0) && (MapfileName == NULL)) {
          //
          // Find the duplicated symbol
          //
          EDBPrint (L"Duplicated Symbol found!\n");
          return EFI_NO_MAPPING;
        } else {
          //
          // record Address
          //
          *Address = (Entry[EntryIndex].Rva + Object[ObjectIndex].BaseAddress);
        }
      }
    }
  }

  if (*Address == 0) {
    //
    // Not found
    //
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}
