17UINTN gMaxProcessorIndex = 0;
22CHAR8 gInBuffer[MAX_BUF_SIZE];
23CHAR8 gOutBuffer[MAX_BUF_SIZE];
27BOOLEAN gSymbolTableUpdate =
FALSE;
29VOID *gGdbSymbolEventHandlerRegistration =
NULL;
34UINTN gPacketqXferLibraryOffset = 0;
35UINTN gEfiDebugImageTableEntry = 0;
38CHAR8 gXferLibraryBuffer[2000];
40GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
44GdbSymbolEventHandler (
79 if (EFI_ERROR (Status)) {
80 gDebugImageTableHeader =
NULL;
83 Status =
gBS->LocateHandleBuffer (
85 &gEfiDebugSupportProtocolGuid,
90 if (EFI_ERROR (Status)) {
91 DEBUG ((DEBUG_ERROR,
"Debug Support Protocol not found\n"));
100 Status =
gBS->HandleProtocol (
101 Handles[HandleCount],
102 &gEfiDebugSupportProtocolGuid,
103 (VOID **)&DebugSupport
105 if (!EFI_ERROR (Status)) {
112 }
while (HandleCount > 0);
117 DEBUG ((DEBUG_ERROR,
"Debug Support Protocol does not support our ISA\n"));
119 return EFI_NOT_FOUND;
122 Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);
125 DEBUG ((DEBUG_INFO,
"Debug Support Protocol ISA %x\n", DebugSupport->
Isa));
126 DEBUG ((DEBUG_INFO,
"Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));
129 InitializeProcessor ();
131 for (Processor = 0; Processor <= gMaxProcessorIndex; Processor++) {
133 Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor,
GdbExceptionHandler, gExceptionType[Index].Exception);
140 Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor,
GdbPeriodicCallBack);
148 Status =
gBS->CreateEvent (
151 GdbSymbolEventHandler,
160 Status =
gBS->RegisterProtocolNotify (
161 &gEfiLoadedImageProtocolGuid,
163 &gGdbSymbolEventHandlerRegistration
184 IN unsigned char *Address,
191 while (Length-- > 0) {
195 if ((c1 < 0) || (c2 < 0)) {
196 Print ((CHAR16 *)L
"Bad message from write to memory..\n");
201 *Address++ = (UINT8)((c1 << 4) + c2);
217 IN unsigned char *Address
221 CHAR8 OutBuffer[MAX_BUF_SIZE];
225 if (ValidateAddress (Address) ==
FALSE) {
230 OutBufPtr = OutBuffer;
232 Char = mHexToStr[*Address >> 4];
233 if ((Char >=
'A') && (Char <=
'F')) {
234 Char = Char -
'A' +
'a';
239 Char = mHexToStr[*Address & 0x0f];
240 if ((Char >=
'A') && (Char <=
'F')) {
241 Char = Char -
'A' +
'a';
280 Timeout =
PcdGet32 (PcdGdbMaxPacketRetryCount);
286 if (Timeout-- == 0) {
294 for (CheckSum = 0, Count = 0; *Ptr !=
'\0'; Ptr++, Count++) {
296 CheckSum = CheckSum + *Ptr;
305 }
while (TestChar !=
'+');
328 OUT CHAR8 *PacketData,
338 ZeroMem (PacketData, PacketDataSize);
343 while (TestChar !=
'$') {
348 for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {
358 PacketData[Index] = Char;
359 CheckSum = CheckSum + Char;
362 PacketData[Index] =
'\0';
364 if (Index == PacketDataSize) {
377 PacketData[Index] =
'\0';
412 if ((Char >=
'A') && (Char <=
'F')) {
413 return Char -
'A' + 10;
414 }
else if ((Char >=
'a') && (Char <=
'f')) {
415 return Char -
'a' + 10;
416 }
else if ((Char >=
'0') && (Char <=
'9')) {
425CHAR8 *gError =
"E__";
443 gError[1] = mHexToStr[ErrorNum >> 4];
444 gError[2] = mHexToStr[ErrorNum & 0x0f];
482 IN UINT8 GdbExceptionType
485 CHAR8 TSignalBuffer[128];
487 UINTN BreakpointDetected;
488 BREAK_TYPE BreakType;
490 CHAR8 *WatchStrPtr =
NULL;
493 TSignalPtr = &TSignalBuffer[0];
501 *TSignalPtr++ = mHexToStr[GdbExceptionType >> 4];
502 *TSignalPtr++ = mHexToStr[GdbExceptionType & 0x0f];
504 if (GdbExceptionType == GDB_SIGTRAP) {
505 if (gSymbolTableUpdate) {
509 WatchStrPtr =
"library:;";
510 while (*WatchStrPtr !=
'\0') {
511 *TSignalPtr++ = *WatchStrPtr++;
514 gSymbolTableUpdate =
FALSE;
521 BreakpointDetected = GetBreakpointDetected (SystemContext);
524 BreakType = GetBreakpointType (SystemContext, BreakpointDetected);
527 if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {
529 DataAddress = GetBreakpointDataAddress (SystemContext, BreakpointDetected);
532 if (BreakType == DataWrite) {
533 WatchStrPtr =
"watch";
534 }
else if (BreakType == DataRead) {
535 WatchStrPtr =
"rwatch";
536 }
else if (BreakType == DataReadWrite) {
537 WatchStrPtr =
"awatch";
540 while (*WatchStrPtr !=
'\0') {
541 *TSignalPtr++ = *WatchStrPtr++;
548 while (RegSize > 0) {
550 *TSignalPtr++ = mHexToStr[(UINT8)(DataAddress >> RegSize) & 0xf];
578 if (gExceptionType[Index].Exception == EFIExceptionType) {
579 return gExceptionType[Index].SignalNo;
599 CHAR8 AddressBuffer[MAX_ADDR_SIZE];
603 AddrBufPtr = AddressBuffer;
604 InBufPtr = &PacketData[1];
605 while (*InBufPtr !=
',') {
606 *AddrBufPtr++ = *InBufPtr++;
614 if (
AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
615 Print ((CHAR16 *)L
"Address is too long\n");
622 Print ((CHAR16 *)L
"Length is too long\n");
647 CHAR8 AddressBuffer[MAX_ADDR_SIZE];
648 CHAR8 LengthBuffer[MAX_LENGTH_SIZE];
653 AddrBufPtr = AddressBuffer;
654 LengthBufPtr = LengthBuffer;
655 InBufPtr = &PacketData[1];
657 while (*InBufPtr !=
',') {
658 *AddrBufPtr++ = *InBufPtr++;
665 while (*InBufPtr !=
':') {
666 *LengthBufPtr++ = *InBufPtr++;
669 *LengthBufPtr =
'\0';
679 if (
AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
680 Print ((CHAR16 *)L
"Address too long..\n");
686 if (
AsciiStrLen (LengthBuffer) >= MAX_LENGTH_SIZE) {
687 Print ((CHAR16 *)L
"Length too long..\n");
695 if (MessageLength != (2*Length)) {
720 IN CHAR8 *PacketData,
726 CHAR8 AddressBuffer[MAX_ADDR_SIZE];
727 CHAR8 *AddressBufferPtr;
728 CHAR8 *PacketDataPtr;
730 PacketDataPtr = &PacketData[1];
731 AddressBufferPtr = AddressBuffer;
737 Print ((CHAR16 *)L
"Type is invalid\n");
742 while (*PacketDataPtr++ !=
',') {
746 while (*PacketDataPtr !=
',') {
747 *AddressBufferPtr++ = *PacketDataPtr++;
750 *AddressBufferPtr =
'\0';
753 if (
AsciiStrLen (AddressBuffer) >= MAX_ADDR_SIZE) {
754 Print ((CHAR16 *)L
"Address too long..\n");
767 Print ((CHAR16 *)L
"Length is invalid\n");
775gXferObjectReadResponse (
785 OutBufPtr = gOutBuffer;
790 OutBufPtr = gOutBuffer;
791 while (*Str !=
'\0') {
793 if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {
848 VOID *CodeViewEntryPointer;
850 UINT32 NumberOfRvaAndSizes;
854 ASSERT (Pe32Data !=
NULL);
857 DirectoryEntry =
NULL;
859 NumberOfRvaAndSizes = 0;
863 if (DosHdr->
e_magic == EFI_IMAGE_DOS_SIGNATURE) {
875 if (Hdr.Te->
Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
876 if (Hdr.Te->
DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
877 DirectoryEntry = &Hdr.Te->
DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
880 Hdr.Te->
DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
887 *DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust;
888 }
else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
889 *DebugBase = Pe32Data;
896 switch (Hdr.Pe32->FileHeader.Machine) {
914 Magic = Hdr.Pe32->OptionalHeader.
Magic;
921 SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
922 NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
923 DirectoryEntry = (
EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
929 SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
930 NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
931 DirectoryEntry = (
EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
935 if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
936 DirectoryEntry =
NULL;
943 if ((DebugEntry ==
NULL) || (DirectoryEntry ==
NULL)) {
949 if (DebugEntry->SizeOfData > 0) {
950 CodeViewEntryPointer = (VOID *)((
UINTN)DebugEntry->
RVA + ((
UINTN)Pe32Data) + (
UINTN)TEImageAdjust);
951 switch (*(UINT32 *)CodeViewEntryPointer) {
957 *DebugBase = (VOID *)(
UINTN)((
UINTN)DebugBase - SizeOfHeaders);
1013 if (Offset != gPacketqXferLibraryOffset) {
1015 Print (L
"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);
1018 gPacketqXferLibraryOffset = 0;
1024 gPacketqXferLibraryOffset += gXferObjectReadResponse (
'm',
"<library-list>\n");
1030 gEfiDebugImageTableEntry = 0;
1034 if (gDebugTable !=
NULL) {
1035 for ( ; gEfiDebugImageTableEntry < gDebugImageTableHeader->
TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
1036 if (gDebugTable->NormalImage !=
NULL) {
1037 if ((gDebugTable->NormalImage->
ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
1047 sizeof (gXferLibraryBuffer),
1048 " <library name=\"%a\"><segment address=\"0x%p\"/></library>\n",
1052 if ((Size != 0) && (Size != (
sizeof (gXferLibraryBuffer) - 1))) {
1053 gPacketqXferLibraryOffset += gXferObjectReadResponse (
'm', gXferLibraryBuffer);
1056 gEfiDebugImageTableEntry++;
1074 gXferObjectReadResponse (
'l',
"</library-list>\n");
1075 gPacketqXferLibraryOffset = 0;
1093 UINT8 GdbExceptionType;
1096 if (ValidateException (ExceptionType, SystemContext) ==
FALSE) {
1108 switch (gInBuffer[0]) {
1149 AsciiSPrint (gOutBuffer, MAX_BUF_SIZE,
"qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);
1151 }
else if (
AsciiStrnCmp (gInBuffer,
"qXfer:libraries:read::", 22) == 0) {
1154 for (Ptr = &gInBuffer[22]; *Ptr !=
','; Ptr++) {
1162 AsciiSPrint (gOutBuffer, MAX_BUF_SIZE,
"Text=1000;Data=f000;Bss=f000");
1210 if (!gCtrlCBreakFlag && !gProcessingFPacket) {
1224 gCtrlCBreakFlag =
TRUE;
1233 if (gCtrlCBreakFlag) {
1240 gCtrlCBreakFlag =
FALSE;
UINTN MaxEfiException(VOID)
VOID EFIAPI RemoveBreakPoint(IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *PacketData)
VOID EFIAPI WriteGeneralRegisters(IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *InBuffer)
VOID EFIAPI InsertBreakPoint(IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *PacketData)
BOOLEAN CheckIsa(IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa)
VOID EFIAPI ReadGeneralRegisters(IN EFI_SYSTEM_CONTEXT SystemContext)
VOID RemoveSingleStep(IN EFI_SYSTEM_CONTEXT SystemContext)
VOID AddSingleStep(IN EFI_SYSTEM_CONTEXT SystemContext)
VOID EFIAPI SingleStep(IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *PacketData)
VOID WriteNthRegister(IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *InBuffer)
VOID EFIAPI ContinueAtAddress(IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *PacketData)
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
UINTN EFIAPI AsciiStrHexToUintn(IN CONST CHAR8 *String)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
CHAR8 EFIAPI GdbGetChar(VOID)
BOOLEAN EFIAPI GdbIsCharAvailable(VOID)
VOID EFIAPI GdbPutChar(IN CHAR8 Char)
UINT8 ConvertEFItoGDBtype(IN EFI_EXCEPTION_TYPE EFIExceptionType)
VOID EFIAPI WriteToMemory(IN CHAR8 *PacketData)
VOID EFIAPI ReadFromMemory(CHAR8 *PacketData)
VOID QxferLibrary(IN UINTN Offset, IN UINTN Length)
UINTN ParseBreakpointPacket(IN CHAR8 *PacketData, OUT UINTN *Type, OUT UINTN *Address, OUT UINTN *Length)
VOID EFIAPI SendNotSupported(VOID)
VOID TransferFromMemToOutBufAndSend(IN UINTN Length, IN unsigned char *Address)
VOID EFIAPI GdbExceptionHandler(IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext)
UINTN SendPacket(IN CHAR8 *PacketData)
EFI_STATUS EFIAPI GdbStubEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID EFIAPI SendSuccess(VOID)
VOID GdbSendTSignal(IN EFI_SYSTEM_CONTEXT SystemContext, IN UINT8 GdbExceptionType)
VOID EmptyBuffer(IN CHAR8 *Buf)
UINTN ReceivePacket(OUT CHAR8 *PacketData, IN UINTN PacketDataSize)
INTN HexCharToInt(IN CHAR8 Char)
VOID *EFIAPI PeCoffLoaderGetDebuggerInfo(IN VOID *Pe32Data, OUT VOID **DebugBase)
VOID TransferFromInBufToMem(IN UINTN Length, IN unsigned char *Address, IN CHAR8 *NewData)
VOID EFIAPI SendError(IN UINT8 ErrorNum)
VOID EFIAPI GdbPeriodicCallBack(IN OUT EFI_SYSTEM_CONTEXT SystemContext)
VOID GdbInitializeSerialConsole(VOID)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
#define GLOBAL_REMOVE_IF_UNREFERENCED
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)
#define CODEVIEW_SIGNATURE_NB10
#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW
The Visual C++ debug information.
#define CODEVIEW_SIGNATURE_RSDS
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
#define CODEVIEW_SIGNATURE_MTOC
#define EFI_IMAGE_MACHINE_IA32
#define EFI_IMAGE_MACHINE_IA64
#define EFI_IMAGE_MACHINE_X64
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
EFI_INSTRUCTION_SET_ARCHITECTURE Isa
EFI_LOADED_IMAGE_PROTOCOL * LoadedImageProtocolInstance
EFI_DEBUG_IMAGE_INFO * EfiDebugImageInfoTable
UINT32 RVA
The address of the debug data when loaded, relative to the image base.
UINT32 e_lfanew
File address of new exe header.
UINT16 e_magic
Magic number.
VOID * ImageBase
The base address at which the image was loaded.
UINT16 Signature
The signature for TE format = "VZ".
UINT32 BaseOfCode
From original image – required for ITP debug.
EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]
Only base relocation and debug directory.
UINT16 StrippedSize
Number of bytes we removed from the header.