/** @file
  UEFI driver that implements a GDB stub

  Note: Any code in the path of the Serial IO output can not call DEBUG as will
  will blow out the stack. Serial IO calls DEBUG, debug calls Serail IO, ...


  Copyright (c) 2008 - 2009, Apple Inc. 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 <GdbStubInternal.h>
#include <Protocol/DebugPort.h>


UINTN     gMaxProcessorIndex = 0;

//
// Buffers for basic gdb communication
//
CHAR8 gInBuffer[MAX_BUF_SIZE];
CHAR8 gOutBuffer[MAX_BUF_SIZE];

// Assume gdb does a "qXfer:libraries:read::offset,length" when it connects so we can default
// this value to FALSE. Since gdb can reconnect its self a global default is not good enough
BOOLEAN   gSymbolTableUpdate = FALSE;
EFI_EVENT gEvent;
VOID      *gGdbSymbolEventHandlerRegistration = NULL;

//
// Globals for returning XML from qXfer:libraries:read packet
//
UINTN                             gPacketqXferLibraryOffset = 0;
UINTN                             gEfiDebugImageTableEntry = 0;
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
EFI_DEBUG_IMAGE_INFO              *gDebugTable = NULL;
CHAR8                             gXferLibraryBuffer[2000];

GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};


VOID
EFIAPI
GdbSymbolEventHandler (
  IN  EFI_EVENT       Event,
  IN  VOID            *Context
  )
{
}


/**
  The user Entry Point for Application. The user code starts with this function
  as the real entry point for the image goes into a library that calls this
  function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
GdbStubEntry (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                  Status;
  EFI_DEBUG_SUPPORT_PROTOCOL  *DebugSupport;
  UINTN                       HandleCount;
  EFI_HANDLE                  *Handles;
  UINTN                       Index;
  UINTN                       Processor;
  BOOLEAN                     IsaSupported;

  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
  if (EFI_ERROR (Status)) {
    gDebugImageTableHeader = NULL;
  }

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDebugSupportProtocolGuid,
                  NULL,
                  &HandleCount,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Debug Support Protocol not found\n"));

    return Status;
  }

  DebugSupport = NULL;
  IsaSupported = FALSE;
  do {
    HandleCount--;
    Status = gBS->HandleProtocol (
                    Handles[HandleCount],
                    &gEfiDebugSupportProtocolGuid,
                    (VOID **) &DebugSupport
                    );
    if (!EFI_ERROR (Status)) {
      if (CheckIsa (DebugSupport->Isa)) {
        // We found what we are looking for so break out of the loop
        IsaSupported = TRUE;
        break;
      }
    }
  } while (HandleCount > 0);
  FreePool (Handles);

  if (!IsaSupported) {
    DEBUG ((EFI_D_ERROR, "Debug Support Protocol does not support our ISA\n"));

    return EFI_NOT_FOUND;
  }

  Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);
  ASSERT_EFI_ERROR (Status);

  DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));
  DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));

  // Call processor-specific init routine
  InitializeProcessor ();

  for (Processor = 0; Processor <= gMaxProcessorIndex; Processor++) {
    for (Index = 0; Index < MaxEfiException (); Index++) {
      Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor,  GdbExceptionHandler, gExceptionType[Index].Exception);
      ASSERT_EFI_ERROR (Status);
    }
    //
    // Current edk2 DebugPort is not interrupt context safe so we can not use it
    //
    Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // This even fires every time an image is added. This allows the stub to know when gdb needs
  // to update the symbol table.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  GdbSymbolEventHandler,
                  NULL,
                  &gEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for protocol notifications on this event
  //
  Status = gBS->RegisterProtocolNotify (
                  &gEfiLoadedImageProtocolGuid,
                  gEvent,
                  &gGdbSymbolEventHandlerRegistration
                  );
  ASSERT_EFI_ERROR (Status);


 if (PcdGetBool (PcdGdbSerial)) {
   GdbInitializeSerialConsole ();
 }

  return EFI_SUCCESS;
}

/**
 Transfer length bytes of input buffer, starting at Address, to memory.

 @param     length                  the number of the bytes to be transferred/written
 @param     *address                the start address of the transferring/writing the memory
 @param     *new_data               the new data to be written to memory
 **/

VOID
TransferFromInBufToMem (
  IN    UINTN                       Length,
  IN    unsigned char               *Address,
  IN    CHAR8                       *NewData
  )
{
  CHAR8 c1;
  CHAR8 c2;

  while (Length-- > 0) {
    c1 = (CHAR8)HexCharToInt (*NewData++);
    c2 = (CHAR8)HexCharToInt (*NewData++);

    if ((c1 < 0) || (c2 < 0)) {
      Print ((CHAR16 *)L"Bad message from write to memory..\n");
      SendError (GDB_EBADMEMDATA);
      return;
    }
    *Address++ = (UINT8)((c1 << 4) + c2);
  }

  SendSuccess();
}


/**
 Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer
 as a packet.

 @param     Length                  the number of the bytes to be transferred/read
 @param     *address                pointer to the start address of the transferring/reading the memory
 **/

VOID
TransferFromMemToOutBufAndSend (
  IN    UINTN                       Length,
  IN    unsigned char               *Address
  )
{
  // there are Length bytes and every byte is represented as 2 hex chars
  CHAR8   OutBuffer[MAX_BUF_SIZE];
  CHAR8   *OutBufPtr;             // pointer to the output buffer
  CHAR8   Char;

  if (ValidateAddress(Address) == FALSE) {
    SendError(14);
    return;
  }

  OutBufPtr = OutBuffer;
  while (Length > 0) {

    Char = mHexToStr[*Address >> 4];
    if ((Char >= 'A') && (Char <= 'F')) {
      Char = Char - 'A' + 'a';
    }
    *OutBufPtr++ = Char;

    Char = mHexToStr[*Address & 0x0f];
    if ((Char >= 'A') && (Char <= 'F')) {
      Char = Char - 'A' + 'a';
    }
    *OutBufPtr++ = Char;

    Address++;
    Length--;
  }

  *OutBufPtr = '\0' ;  // the end of the buffer
  SendPacket (OutBuffer);
}



/**
  Send a GDB Remote Serial Protocol Packet

  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
  the packet teminating character '#' and the two digit checksum.

  If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
  in an infinit loop. This is so if you unplug the debugger code just keeps running

  @param PacketData   Payload data for the packet


  @retval             Number of bytes of packet data sent.

**/
UINTN
SendPacket (
  IN  CHAR8 *PacketData
  )
{
  UINT8 CheckSum;
  UINTN Timeout;
  CHAR8 *Ptr;
  CHAR8 TestChar;
  UINTN Count;

  Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount);

  Count = 0;
  do {

    Ptr = PacketData;

    if (Timeout-- == 0) {
      // Only try a finite number of times so we don't get stuck in the loop
      return Count;
    }

    // Packet prefix
    GdbPutChar ('$');

    for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {
      GdbPutChar (*Ptr);
      CheckSum = CheckSum + *Ptr;
    }

    // Packet terminating character and checksum
    GdbPutChar ('#');
    GdbPutChar (mHexToStr[CheckSum >> 4]);
    GdbPutChar (mHexToStr[CheckSum & 0x0F]);

    TestChar =  GdbGetChar ();
  } while (TestChar != '+');

  return Count;
}

/**
  Receive a GDB Remote Serial Protocol Packet

  $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
  the packet teminating character '#' and the two digit checksum.

  If host re-starts sending a packet without ending the previous packet, only the last valid packet is processed.
  (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)

  If an ack '+' is not sent resend the packet

  @param PacketData   Payload data for the packet

  @retval             Number of bytes of packet data received.

**/
UINTN
ReceivePacket (
  OUT  CHAR8 *PacketData,
  IN   UINTN PacketDataSize
 )
{
  UINT8 CheckSum;
  UINTN Index;
  CHAR8 Char;
  CHAR8 SumString[3];
  CHAR8 TestChar;

  ZeroMem (PacketData, PacketDataSize);

  for (;;) {
      // wait for the start of a packet
    TestChar = GdbGetChar ();
    while (TestChar != '$') {
      TestChar = GdbGetChar ();
    };

  retry:
    for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {
      Char = GdbGetChar ();
      if (Char == '$') {
        goto retry;
      }
      if (Char == '#') {
        break;
      }

      PacketData[Index] = Char;
      CheckSum = CheckSum + Char;
    }
    PacketData[Index] = '\0';

    if (Index == PacketDataSize) {
      continue;
    }

    SumString[0] = GdbGetChar ();
    SumString[1] = GdbGetChar ();
    SumString[2] = '\0';

    if (AsciiStrHexToUintn (SumString) == CheckSum) {
      // Ack: Success
      GdbPutChar ('+');

      // Null terminate the callers string
      PacketData[Index] = '\0';
      return Index;
    } else {
      // Ack: Failure
      GdbPutChar ('-');
    }
  }

  //return 0;
}


/**
 Empties the given buffer
 @param   Buf          pointer to the first element in buffer to be emptied
 **/
VOID
EmptyBuffer (
  IN  CHAR8           *Buf
  )
{
  *Buf = '\0';
}


/**
 Converts an 8-bit Hex Char into a INTN.

 @param   Char the hex character to be converted into UINTN
 @retval  a INTN, from 0 to 15, that corressponds to Char
 -1 if Char is not a hex character
 **/
INTN
HexCharToInt (
  IN  CHAR8           Char
  )
{
  if ((Char >= 'A') && (Char <= 'F')) {
    return Char - 'A' + 10;
  } else if ((Char >= 'a') && (Char <= 'f')) {
    return Char - 'a' + 10;
  } else if ((Char >= '0') && (Char <= '9')) {
    return Char - '0';
  } else { // if not a hex value, return a negative value
    return -1;
  }
}

  // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end
CHAR8 *gError = "E__";

/** 'E NN'
 Send an error with the given error number after converting to hex.
 The error number is put into the buffer in hex. '255' is the biggest errno we can send.
 ex: 162 will be sent as A2.

 @param   errno           the error number that will be sent
 **/
VOID
EFIAPI
SendError (
  IN  UINT8              ErrorNum
  )
{
  //
  // Replace _, or old data, with current errno
  //
  gError[1] = mHexToStr [ErrorNum >> 4];
  gError[2] = mHexToStr [ErrorNum & 0x0f];

  SendPacket (gError); // send buffer
}



/**
 Send 'OK' when the function is done executing successfully.
 **/
VOID
EFIAPI
SendSuccess (
  VOID
  )
{
  SendPacket ("OK"); // send buffer
}


/**
 Send empty packet to specify that particular command/functionality is not supported.
 **/
VOID
EFIAPI
SendNotSupported (
  VOID
  )
{
  SendPacket ("");
}


/**
 Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints

 @param  SystemContext        Register content at time of the exception
 @param  GdbExceptionType     GDB exception type
 **/
VOID
GdbSendTSignal (
  IN  EFI_SYSTEM_CONTEXT  SystemContext,
  IN  UINT8               GdbExceptionType
  )
{
  CHAR8 TSignalBuffer[128];
  CHAR8 *TSignalPtr;
  UINTN BreakpointDetected;
  BREAK_TYPE BreakType;
  UINTN DataAddress;
  CHAR8 *WatchStrPtr = NULL;
  UINTN RegSize;

  TSignalPtr = &TSignalBuffer[0];

  //Construct TSignal packet
  *TSignalPtr++ = 'T';

  //
  // replace _, or previous value, with Exception type
  //
  *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4];
  *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f];

  if (GdbExceptionType == GDB_SIGTRAP) {
    if (gSymbolTableUpdate) {
      //
      // We can only send back on reason code. So if the flag is set it means the breakpoint is from our event handler
      //
      WatchStrPtr = "library:;";
      while (*WatchStrPtr != '\0') {
        *TSignalPtr++ = *WatchStrPtr++;
      }
      gSymbolTableUpdate = FALSE;
    } else {


      //
      // possible n:r pairs
      //

      //Retrieve the breakpoint number
      BreakpointDetected = GetBreakpointDetected (SystemContext);

      //Figure out if the exception is happend due to watch, rwatch or awatch.
      BreakType = GetBreakpointType (SystemContext, BreakpointDetected);

      //INFO: rwatch is not supported due to the way IA32 debug registers work
      if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {

        //Construct n:r pair
        DataAddress = GetBreakpointDataAddress (SystemContext, BreakpointDetected);

        //Assign appropriate buffer to print particular watchpoint type
        if (BreakType == DataWrite) {
          WatchStrPtr = "watch";
        } else if (BreakType == DataRead) {
          WatchStrPtr = "rwatch";
        } else if (BreakType == DataReadWrite) {
          WatchStrPtr = "awatch";
        }

        while (*WatchStrPtr != '\0') {
          *TSignalPtr++ = *WatchStrPtr++;
        }

        *TSignalPtr++ = ':';

        //Set up series of bytes in big-endian byte order. "awatch" won't work with little-endian byte order.
        RegSize = REG_SIZE;
        while (RegSize > 0) {
          RegSize = RegSize-4;
          *TSignalPtr++ = mHexToStr[(UINT8)(DataAddress >> RegSize) & 0xf];
        }

        //Always end n:r pair with ';'
        *TSignalPtr++ = ';';
      }
    }
  }

  *TSignalPtr = '\0';

  SendPacket (TSignalBuffer);
}


/**
 Translates the EFI mapping to GDB mapping

 @param   EFIExceptionType    EFI Exception that is being processed
 @retval  UINTN that corresponds to EFIExceptionType's GDB exception type number
 **/
UINT8
ConvertEFItoGDBtype (
  IN  EFI_EXCEPTION_TYPE      EFIExceptionType
  )
{
  UINTN Index;

  for (Index = 0; Index < MaxEfiException () ; Index++) {
    if (gExceptionType[Index].Exception == EFIExceptionType) {
      return gExceptionType[Index].SignalNo;
    }
  }
  return GDB_SIGTRAP; // this is a GDB trap
}


/** "m addr,length"
 Find the Length of the area to read and the start addres. Finally, pass them to
 another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
 send it as a packet.
 **/

VOID
EFIAPI
ReadFromMemory (
  CHAR8 *PacketData
  )
{
  UINTN Address;
  UINTN Length;
  CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars
  CHAR8 *AddrBufPtr; // pointer to the address buffer
  CHAR8 *InBufPtr; /// pointer to the input buffer

  AddrBufPtr = AddressBuffer;
  InBufPtr = &PacketData[1];
  while (*InBufPtr != ',') {
    *AddrBufPtr++ = *InBufPtr++;
  }
  *AddrBufPtr = '\0';

  InBufPtr++; // this skips ',' in the buffer

  /* Error checking */
  if (AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
    Print((CHAR16 *)L"Address is too long\n");
    SendError (GDB_EBADMEMADDRBUFSIZE);
    return;
  }

  // 2 = 'm' + ','
  if (AsciiStrLen (PacketData) - AsciiStrLen (AddressBuffer) - 2 >= MAX_LENGTH_SIZE) {
    Print((CHAR16 *)L"Length is too long\n");
    SendError (GDB_EBADMEMLENGTH);
    return;
  }

  Address = AsciiStrHexToUintn (AddressBuffer);
  Length = AsciiStrHexToUintn (InBufPtr);

  TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);
}


/** "M addr,length :XX..."
 Find the Length of the area in bytes to write and the start addres. Finally, pass them to
 another function, TransferFromInBufToMem, that will write to that memory space the info in
 the input buffer.
 **/
VOID
EFIAPI
WriteToMemory (
  IN CHAR8 *PacketData
  )
{
  UINTN Address;
  UINTN Length;
  UINTN MessageLength;
  CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars
  CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars
  CHAR8 *AddrBufPtr; // pointer to the Address buffer
  CHAR8 *LengthBufPtr; // pointer to the Length buffer
  CHAR8 *InBufPtr; /// pointer to the input buffer

  AddrBufPtr = AddressBuffer;
  LengthBufPtr = LengthBuffer;
  InBufPtr = &PacketData[1];

  while (*InBufPtr != ',') {
    *AddrBufPtr++ = *InBufPtr++;
  }
  *AddrBufPtr = '\0';

  InBufPtr++; // this skips ',' in the buffer

  while (*InBufPtr != ':') {
    *LengthBufPtr++ = *InBufPtr++;
  }
  *LengthBufPtr = '\0';

  InBufPtr++; // this skips ':' in the buffer

  Address = AsciiStrHexToUintn (AddressBuffer);
  Length = AsciiStrHexToUintn (LengthBuffer);

  /* Error checking */

  //Check if Address is not too long.
  if (AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
    Print ((CHAR16 *)L"Address too long..\n");
    SendError (GDB_EBADMEMADDRBUFSIZE);
    return;
  }

  //Check if message length is not too long
  if (AsciiStrLen (LengthBuffer) >= MAX_LENGTH_SIZE) {
    Print ((CHAR16 *)L"Length too long..\n");
    SendError (GDB_EBADMEMLENGBUFSIZE);
    return;
  }

  // Check if Message is not too long/short.
  // 3 = 'M' + ',' + ':'
  MessageLength = (AsciiStrLen (PacketData) - AsciiStrLen (AddressBuffer) - AsciiStrLen (LengthBuffer) - 3);
  if (MessageLength != (2*Length)) {
    //Message too long/short. New data is not the right size.
    SendError (GDB_EBADMEMDATASIZE);
    return;
  }
  TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr);
}

/**
  Parses breakpoint packet data and captures Breakpoint type, Address and length.
  In case of an error, function returns particular error code. Returning 0 meaning
  no error.

  @param  PacketData  Pointer to the payload data for the packet.
  @param  Type        Breakpoint type
  @param  Address     Breakpoint address
  @param  Length      Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)

  @retval 1           Success
  @retval {other}     Particular error code

**/
UINTN
ParseBreakpointPacket (
  IN  CHAR8 *PacketData,
  OUT UINTN *Type,
  OUT UINTN *Address,
  OUT UINTN *Length
  )
{
  CHAR8 AddressBuffer[MAX_ADDR_SIZE];
  CHAR8 *AddressBufferPtr;
  CHAR8 *PacketDataPtr;

  PacketDataPtr = &PacketData[1];
  AddressBufferPtr = AddressBuffer;

  *Type = AsciiStrHexToUintn (PacketDataPtr);

  //Breakpoint/watchpoint type should be between 0 to 4
  if (*Type > 4) {
    Print ((CHAR16 *)L"Type is invalid\n");
    return 22; //EINVAL: Invalid argument.
  }

  //Skip ',' in the buffer.
  while (*PacketDataPtr++ != ',');

  //Parse Address information
  while (*PacketDataPtr != ',') {
    *AddressBufferPtr++ = *PacketDataPtr++;
  }
  *AddressBufferPtr = '\0';

  //Check if Address is not too long.
  if (AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
    Print ((CHAR16 *)L"Address too long..\n");
    return 40; //EMSGSIZE: Message size too long.
  }

  *Address = AsciiStrHexToUintn (AddressBuffer);

  PacketDataPtr++; //This skips , in the buffer

  //Parse Length information
  *Length = AsciiStrHexToUintn (PacketDataPtr);

  //Length should be 1, 2 or 4 bytes
  if (*Length > 4) {
    Print ((CHAR16 *)L"Length is invalid\n");
    return 22; //EINVAL: Invalid argument
  }

  return 0; //0 = No error
}

UINTN
gXferObjectReadResponse (
  IN  CHAR8         Type,
  IN  CHAR8         *Str
  )
{
  CHAR8   *OutBufPtr;             // pointer to the output buffer
  CHAR8   Char;
  UINTN   Count;

  // Response starts with 'm' or 'l' if it is the end
  OutBufPtr = gOutBuffer;
  *OutBufPtr++ = Type;
  Count = 1;

  // Binary data encoding
  OutBufPtr = gOutBuffer;
  while (*Str != '\0') {
    Char = *Str++;
    if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {
      // escape character
      *OutBufPtr++ = 0x7d;

      Char ^= 0x20;
    }
    *OutBufPtr++ = Char;
    Count++;
  }

  *OutBufPtr = '\0' ;  // the end of the buffer
  SendPacket (gOutBuffer);

  return Count;
}


/**
  Note: This should be a library function.  In the Apple case you have to add
  the size of the PE/COFF header into the starting address to make things work
  right as there is no way to pad the Mach-O for the size of the PE/COFF header.


  Returns a pointer to the PDB file name for a PE/COFF image that has been
  loaded into system memory with the PE/COFF Loader Library functions.

  Returns the PDB file name for the PE/COFF image specified by Pe32Data.  If
  the PE/COFF image specified by Pe32Data is not a valid, then NULL is
  returned.  If the PE/COFF image specified by Pe32Data does not contain a
  debug directory entry, then NULL is returned.  If the debug directory entry
  in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
  then NULL is returned.
  If Pe32Data is NULL, then ASSERT().

  @param  Pe32Data   Pointer to the PE/COFF image that is loaded in system
                     memory.
  @param  DebugBase  Address that the debugger would use as the base of the image

  @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
          if it cannot be retrieved. DebugBase is only valid if PDB file name is
          valid.

**/
VOID *
EFIAPI
PeCoffLoaderGetDebuggerInfo (
  IN VOID     *Pe32Data,
  OUT VOID    **DebugBase
  )
{
  EFI_IMAGE_DOS_HEADER                  *DosHdr;
  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
  UINTN                                 DirCount;
  VOID                                  *CodeViewEntryPointer;
  INTN                                  TEImageAdjust;
  UINT32                                NumberOfRvaAndSizes;
  UINT16                                Magic;
  UINTN                                 SizeOfHeaders;

  ASSERT (Pe32Data   != NULL);

  TEImageAdjust       = 0;
  DirectoryEntry      = NULL;
  DebugEntry          = NULL;
  NumberOfRvaAndSizes = 0;
  SizeOfHeaders       = 0;

  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
    //
    // DOS image header is present, so read the PE header after the DOS image header.
    //
    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
  } else {
    //
    // DOS image header is not present, so PE header is at the image base.
    //
    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
  }

  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
    if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
      DirectoryEntry  = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
      TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +
                    Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
                    TEImageAdjust);
    }
    SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;

    // __APPLE__ check this math...
    *DebugBase = ((CHAR8 *)Pe32Data) -  TEImageAdjust;
  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {

    *DebugBase = Pe32Data;


    //
    // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
    //       It is due to backward-compatibility, for some system might
    //       generate PE32+ image with PE32 Magic.
    //
    switch (Hdr.Pe32->FileHeader.Machine) {
    case EFI_IMAGE_MACHINE_IA32:
      //
      // Assume PE32 image with IA32 Machine field.
      //
      Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
      break;
    case EFI_IMAGE_MACHINE_X64:
    case EFI_IMAGE_MACHINE_IA64:
      //
      // Assume PE32+ image with X64 or IPF Machine field
      //
      Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
      break;
    default:
      //
      // For unknow Machine field, use Magic in optional Header
      //
      Magic = Hdr.Pe32->OptionalHeader.Magic;
    }

    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset get Debug Directory Entry
      //
      SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
    } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
      //
      // Use PE32+ offset get Debug Directory Entry
      //
      SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
    }

    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
      DirectoryEntry = NULL;
      DebugEntry = NULL;
    }
  } else {
    return NULL;
  }

  if (DebugEntry == NULL || DirectoryEntry == NULL) {
    return NULL;
  }

  for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
    if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
      if (DebugEntry->SizeOfData > 0) {
        CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);
        switch (* (UINT32 *) CodeViewEntryPointer) {
        case CODEVIEW_SIGNATURE_NB10:
          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));
        case CODEVIEW_SIGNATURE_RSDS:
          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));
        case CODEVIEW_SIGNATURE_MTOC:
          *DebugBase = (VOID *)(UINTN)((UINTN)DebugBase - SizeOfHeaders);
          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
        default:
          break;
        }
      }
    }
  }

  (void)SizeOfHeaders;
  return NULL;
}


/**
  Process "qXfer:object:read:annex:offset,length" request.

  Returns an XML document that contains loaded libraries. In our case it is
  information in the EFI Debug Image Table converted into an XML document.

  GDB will call with an arbitrary length (it can't know the real length and
  will reply with chunks of XML that are easy for us to deal with. Gdb will
  keep calling until we say we are done. XML doc looks like:

  <library-list>
    <library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>
    <library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>
    <library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>
  </library-list>

  Since we can not allocate memory in interrupt context this module has
  assumptions about how it will get called:
  1) Length will generally be max remote packet size (big enough)
  2) First Offset of an XML document read needs to be 0
  3) This code will return back small chunks of the XML document on every read.
     Each subsequent call will ask for the next available part of the document.

  Note: The only variable size element in the XML is:
  "  <library name=\"%s\"><segment address=\"%p\"/></library>\n" and it is
  based on the file path and name of the symbol file. If the symbol file name
  is bigger than the max gdb remote packet size we could update this code
  to respond back in chunks.

 @param Offset  offset into special data area
 @param Length  number of bytes to read starting at Offset

 **/
VOID
QxferLibrary (
  IN  UINTN   Offset,
  IN  UINTN   Length
  )
{
  VOID                              *LoadAddress;
  CHAR8                             *Pdb;
  UINTN                             Size;

  if (Offset != gPacketqXferLibraryOffset) {
    SendError (GDB_EINVALIDARG);
    Print (L"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);

    // Force a retry from the beginning
    gPacketqXferLibraryOffset = 0;

    return;
  }

  if (Offset == 0) {
    gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "<library-list>\n");

    // The owner of the table may have had to ralloc it so grab a fresh copy every time
    // we assume qXferLibrary will get called over and over again until the entire XML table is
    // returned in a tight loop. Since we are in the debugger the table should not get updated
    gDebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
    gEfiDebugImageTableEntry = 0;
    return;
  }

  if (gDebugTable != NULL) {
    for (; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
      if (gDebugTable->NormalImage != NULL) {
        if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
            (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
          Pdb = PeCoffLoaderGetDebuggerInfo (
                 gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase,
                 &LoadAddress
                 );
          if (Pdb != NULL) {
            Size = AsciiSPrint (
                    gXferLibraryBuffer,
                    sizeof (gXferLibraryBuffer),
                    "  <library name=\"%a\"><segment address=\"0x%p\"/></library>\n",
                    Pdb,
                    LoadAddress
                    );
            if ((Size != 0) && (Size != (sizeof (gXferLibraryBuffer) - 1))) {
              gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', gXferLibraryBuffer);

              // Update loop variables so we are in the right place when we get back
              gEfiDebugImageTableEntry++;
              gDebugTable++;
              return;
            } else {
              // We could handle <library> entires larger than sizeof (gXferLibraryBuffer) here if
              // needed by breaking up into N packets
              // "<library name=\"%s
              // the rest of the string (as many packets as required
              // \"><segment address=\"%d\"/></library> (fixed size)
              //
              // But right now we just skip any entry that is too big
            }
          }
        }
      }
    }
  }


  gXferObjectReadResponse ('l', "</library-list>\n");
  gPacketqXferLibraryOffset = 0;
  return;
}


/**
 Exception Hanldler for GDB. It will be called for all exceptions
 registered via the gExceptionType[] array.

 @param ExceptionType     Exception that is being processed
 @param SystemContext     Register content at time of the exception
 **/
VOID
EFIAPI
GdbExceptionHandler (
  IN  EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT     SystemContext
  )
{
  UINT8   GdbExceptionType;
  CHAR8   *Ptr;


  if (ValidateException (ExceptionType, SystemContext) == FALSE) {
    return;
  }

  RemoveSingleStep (SystemContext);

  GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);
  GdbSendTSignal (SystemContext, GdbExceptionType);

  for( ; ; ) {
    ReceivePacket (gInBuffer, MAX_BUF_SIZE);

    switch (gInBuffer[0]) {
      case '?':
        GdbSendTSignal (SystemContext, GdbExceptionType);
        break;

      case 'c':
        ContinueAtAddress (SystemContext, gInBuffer);
        return;

      case 'g':
        ReadGeneralRegisters (SystemContext);
        break;

      case 'G':
        WriteGeneralRegisters (SystemContext, gInBuffer);
        break;

      case 'H':
        //Return "OK" packet since we don't have more than one thread.
        SendSuccess ();
        break;

      case 'm':
        ReadFromMemory (gInBuffer);
        break;

      case 'M':
        WriteToMemory (gInBuffer);
        break;

      case 'P':
        WriteNthRegister (SystemContext, gInBuffer);
        break;

      //
      // Still debugging this code. Not used in Darwin
      //
      case 'q':
        // General Query Packets
        if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {
          // return what we currently support, we don't parse what gdb suports
          AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);
          SendPacket (gOutBuffer);
        } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) {
          // ‘qXfer:libraries:read::offset,length
          // gInBuffer[22] is offset string, ++Ptr is length string’
          for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);

          // Not sure if multi-radix support is required. Currently only support decimal
          QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));
        } if (AsciiStrnCmp (gInBuffer, "qOffsets", 10) == 0) {
          AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000");
          SendPacket (gOutBuffer);
        } else {
          //Send empty packet
          SendNotSupported ();
        }
        break;

      case 's':
        SingleStep (SystemContext, gInBuffer);
        return;

      case 'z':
        RemoveBreakPoint (SystemContext, gInBuffer);
        break;

      case 'Z':
        InsertBreakPoint (SystemContext, gInBuffer);
        break;

      default:
        //Send empty packet
        SendNotSupported ();
        break;
    }
  }
}


/**
 Periodic callback for GDB. This function is used to catch a ctrl-c or other
 break in type command from GDB.

 @param SystemContext     Register content at time of the call
 **/
VOID
EFIAPI
GdbPeriodicCallBack (
  IN OUT EFI_SYSTEM_CONTEXT     SystemContext
  )
{
  //
  // gCtrlCBreakFlag may have been set from a previous F response package
  // and we set the global as we need to process it at a point where we
  // can update the system context. If we are in the middle of processing
  // a F Packet it is not safe to read the GDB serial stream so we need
  // to skip it on this check
  //
  if (!gCtrlCBreakFlag && !gProcessingFPacket) {
    //
    // Ctrl-C was not pending so grab any pending characters and see if they
    // are a Ctrl-c (0x03). If so set the Ctrl-C global.
    //
    while (TRUE) {
      if (!GdbIsCharAvailable ()) {
        //
        // No characters are pending so exit the loop
        //
        break;
      }

      if (GdbGetChar () == 0x03) {
        gCtrlCBreakFlag = TRUE;
        //
        // We have a ctrl-c so exit the loop
        //
        break;
      }
    }
  }

  if (gCtrlCBreakFlag) {
    //
    // Update the context to force a single step trap when we exit the GDB
    // stub. This will transfer control to GdbExceptionHandler () and let
    // us break into the program. We don't want to break into the GDB stub.
    //
    AddSingleStep (SystemContext);
    gCtrlCBreakFlag = FALSE;
  }
}
