/** @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"

/**

  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) {
    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;
}
