Note: Any code in the path of the Serial IO output can not call DEBUG as will\r
will blow out the stack. Serial IO calls DEBUG, debug calls Serail IO, ...\r
Note: Any code in the path of the Serial IO output can not call DEBUG as will\r
will blow out the stack. Serial IO calls DEBUG, debug calls Serail IO, ...\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
// this value to FALSE. Since gdb can reconnect its self a global default is not good enough\r
BOOLEAN gSymbolTableUpdate = FALSE;\r
EFI_EVENT gEvent;\r
// this value to FALSE. Since gdb can reconnect its self a global default is not good enough\r
BOOLEAN gSymbolTableUpdate = FALSE;\r
EFI_EVENT gEvent;\r
@retval EFI_SUCCESS The entry point is executed successfully.\r
@retval other Some error occurs when executing this entry point.\r
\r
@retval EFI_SUCCESS The entry point is executed successfully.\r
@retval other Some error occurs when executing this entry point.\r
\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);\r
if (EFI_ERROR (Status)) {\r
gDebugImageTableHeader = NULL;\r
Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);\r
if (EFI_ERROR (Status)) {\r
gDebugImageTableHeader = NULL;\r
Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);\r
ASSERT_EFI_ERROR (Status);\r
Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);\r
ASSERT_EFI_ERROR (Status);\r
DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));\r
DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));\r
DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));\r
DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));\r
for (Index = 0; Index < MaxEfiException (); Index++) {\r
Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor, GdbExceptionHandler, gExceptionType[Index].Exception);\r
ASSERT_EFI_ERROR (Status);\r
for (Index = 0; Index < MaxEfiException (); Index++) {\r
Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor, GdbExceptionHandler, gExceptionType[Index].Exception);\r
ASSERT_EFI_ERROR (Status);\r
Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);\r
ASSERT_EFI_ERROR (Status);\r
}\r
Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);\r
ASSERT_EFI_ERROR (Status);\r
}\r
//\r
Status = gBS->RegisterProtocolNotify (\r
&gEfiLoadedImageProtocolGuid,\r
//\r
Status = gBS->RegisterProtocolNotify (\r
&gEfiLoadedImageProtocolGuid,\r
while (Length-- > 0) {\r
c1 = (CHAR8)HexCharToInt (*NewData++);\r
c2 = (CHAR8)HexCharToInt (*NewData++);\r
\r
if ((c1 < 0) || (c2 < 0)) {\r
Print ((CHAR16 *)L"Bad message from write to memory..\n");\r
while (Length-- > 0) {\r
c1 = (CHAR8)HexCharToInt (*NewData++);\r
c2 = (CHAR8)HexCharToInt (*NewData++);\r
\r
if ((c1 < 0) || (c2 < 0)) {\r
Print ((CHAR16 *)L"Bad message from write to memory..\n");\r
Char = mHexToStr[*Address >> 4];\r
if ((Char >= 'A') && (Char <= 'F')) {\r
Char = Char - 'A' + 'a';\r
Char = mHexToStr[*Address >> 4];\r
if ((Char >= 'A') && (Char <= 'F')) {\r
Char = Char - 'A' + 'a';\r
for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {\r
GdbPutChar (*Ptr);\r
CheckSum = CheckSum + *Ptr;\r
}\r
for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {\r
GdbPutChar (*Ptr);\r
CheckSum = CheckSum + *Ptr;\r
}\r
(In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)\r
(In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)\r
for (;;) {\r
// wait for the start of a packet\r
TestChar = GdbGetChar ();\r
while (TestChar != '$') {\r
TestChar = GdbGetChar ();\r
};\r
for (;;) {\r
// wait for the start of a packet\r
TestChar = GdbGetChar ();\r
while (TestChar != '$') {\r
TestChar = GdbGetChar ();\r
};\r
@param Char the hex character to be converted into UINTN\r
@retval a INTN, from 0 to 15, that corressponds to Char\r
-1 if Char is not a hex character\r
@param Char the hex character to be converted into UINTN\r
@retval a INTN, from 0 to 15, that corressponds to Char\r
-1 if Char is not a hex character\r
} else if ((Char >= '0') && (Char <= '9')) {\r
return Char - '0';\r
} else { // if not a hex value, return a negative value\r
} else if ((Char >= '0') && (Char <= '9')) {\r
return Char - '0';\r
} else { // if not a hex value, return a negative value\r
Send an error with the given error number after converting to hex.\r
The error number is put into the buffer in hex. '255' is the biggest errno we can send.\r
ex: 162 will be sent as A2.\r
Send an error with the given error number after converting to hex.\r
The error number is put into the buffer in hex. '255' is the biggest errno we can send.\r
ex: 162 will be sent as A2.\r
@param SystemContext Register content at time of the exception\r
@param GdbExceptionType GDB exception type\r
**/\r
@param SystemContext Register content at time of the exception\r
@param GdbExceptionType GDB exception type\r
**/\r
\r
//Retrieve the breakpoint number\r
BreakpointDetected = GetBreakpointDetected (SystemContext);\r
\r
//Figure out if the exception is happend due to watch, rwatch or awatch.\r
\r
//Retrieve the breakpoint number\r
BreakpointDetected = GetBreakpointDetected (SystemContext);\r
\r
//Figure out if the exception is happend due to watch, rwatch or awatch.\r
\r
//INFO: rwatch is not supported due to the way IA32 debug registers work\r
if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {\r
\r
//INFO: rwatch is not supported due to the way IA32 debug registers work\r
if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {\r
@param EFIExceptionType EFI Exception that is being processed\r
@retval UINTN that corresponds to EFIExceptionType's GDB exception type number\r
**/\r
UINT8\r
@param EFIExceptionType EFI Exception that is being processed\r
@retval UINTN that corresponds to EFIExceptionType's GDB exception type number\r
**/\r
UINT8\r
-{ \r
- UINTN i;\r
- \r
- for (i=0; i < MaxEfiException() ; i++) {\r
- if (gExceptionType[i].Exception == EFIExceptionType) {\r
- return gExceptionType[i].SignalNo;\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < MaxEfiException () ; Index++) {\r
+ if (gExceptionType[Index].Exception == EFIExceptionType) {\r
+ return gExceptionType[Index].SignalNo;\r
- Find the Length of the area to read and the start addres. Finally, pass them to \r
- another function, TransferFromMemToOutBufAndSend, that will read from that memory space and \r
+ Find the Length of the area to read and the start addres. Finally, pass them to\r
+ another function, TransferFromMemToOutBufAndSend, that will read from that memory space and\r
CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars\r
CHAR8 *AddrBufPtr; // pointer to the address buffer\r
CHAR8 *InBufPtr; /// pointer to the input buffer\r
CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars\r
CHAR8 *AddrBufPtr; // pointer to the address buffer\r
CHAR8 *InBufPtr; /// pointer to the input buffer\r
AddrBufPtr = AddressBuffer;\r
InBufPtr = &PacketData[1];\r
while (*InBufPtr != ',') {\r
*AddrBufPtr++ = *InBufPtr++;\r
}\r
*AddrBufPtr = '\0';\r
AddrBufPtr = AddressBuffer;\r
InBufPtr = &PacketData[1];\r
while (*InBufPtr != ',') {\r
*AddrBufPtr++ = *InBufPtr++;\r
}\r
*AddrBufPtr = '\0';\r
TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);\r
}\r
\r
\r
/** "M addr,length :XX..."\r
TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);\r
}\r
\r
\r
/** "M addr,length :XX..."\r
CHAR8 *AddrBufPtr; // pointer to the Address buffer\r
CHAR8 *LengthBufPtr; // pointer to the Length buffer\r
CHAR8 *InBufPtr; /// pointer to the input buffer\r
CHAR8 *AddrBufPtr; // pointer to the Address buffer\r
CHAR8 *LengthBufPtr; // pointer to the Length buffer\r
CHAR8 *InBufPtr; /// pointer to the input buffer\r
AddrBufPtr = AddressBuffer;\r
LengthBufPtr = LengthBuffer;\r
InBufPtr = &PacketData[1];\r
AddrBufPtr = AddressBuffer;\r
LengthBufPtr = LengthBuffer;\r
InBufPtr = &PacketData[1];\r
while (*InBufPtr != ',') {\r
*AddrBufPtr++ = *InBufPtr++;\r
}\r
*AddrBufPtr = '\0';\r
while (*InBufPtr != ',') {\r
*AddrBufPtr++ = *InBufPtr++;\r
}\r
*AddrBufPtr = '\0';\r
- Note: This should be a library function. In the Apple case you have to add \r
- the size of the PE/COFF header into the starting address to make things work \r
+ Note: This should be a library function. In the Apple case you have to add\r
+ the size of the PE/COFF header into the starting address to make things work\r
Returns a pointer to the PDB file name for a PE/COFF image that has been\r
loaded into system memory with the PE/COFF Loader Library functions.\r
\r
Returns a pointer to the PDB file name for a PE/COFF image that has been\r
loaded into system memory with the PE/COFF Loader Library functions.\r
\r
\r
@return The PDB file name for the PE/COFF image specified by Pe32Data or NULL\r
if it cannot be retrieved. DebugBase is only valid if PDB file name is\r
\r
@return The PDB file name for the PE/COFF image specified by Pe32Data or NULL\r
if it cannot be retrieved. DebugBase is only valid if PDB file name is\r
// __APPLE__ check this math...\r
*DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust;\r
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
// __APPLE__ check this math...\r
*DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust;\r
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
//\r
// NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.\r
// It is due to backward-compatibility, for some system might\r
//\r
// NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.\r
// It is due to backward-compatibility, for some system might\r
- \r
- Returns an XML document that contains loaded libraries. In our case it is \r
- infomration in the EFI Debug Inmage Table converted into an XML document.\r
- \r
- GDB will call with an arbitrary length (it can't know the real length and \r
- will reply with chunks of XML that are easy for us to deal with. Gdb will \r
+\r
+ Returns an XML document that contains loaded libraries. In our case it is\r
+ information in the EFI Debug Image Table converted into an XML document.\r
+\r
+ GDB will call with an arbitrary length (it can't know the real length and\r
+ will reply with chunks of XML that are easy for us to deal with. Gdb will\r
<library-list>\r
<library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>\r
<library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>\r
<library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>\r
</library-list>\r
<library-list>\r
<library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>\r
<library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>\r
<library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>\r
</library-list>\r
assumptions about how it will get called:\r
1) Length will generally be max remote packet size (big enough)\r
2) First Offset of an XML document read needs to be 0\r
3) This code will return back small chunks of the XML document on every read.\r
assumptions about how it will get called:\r
1) Length will generally be max remote packet size (big enough)\r
2) First Offset of an XML document read needs to be 0\r
3) This code will return back small chunks of the XML document on every read.\r
based on the file path and name of the symbol file. If the symbol file name\r
is bigger than the max gdb remote packet size we could update this code\r
to respond back in chunks.\r
\r
@param Offset offset into special data area\r
based on the file path and name of the symbol file. If the symbol file name\r
is bigger than the max gdb remote packet size we could update this code\r
to respond back in chunks.\r
\r
@param Offset offset into special data area\r
if (Offset != gPacketqXferLibraryOffset) {\r
SendError (GDB_EINVALIDARG);\r
Print (L"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);\r
if (Offset != gPacketqXferLibraryOffset) {\r
SendError (GDB_EINVALIDARG);\r
Print (L"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);\r
// returned in a tight loop. Since we are in the debugger the table should not get updated\r
gDebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;\r
gEfiDebugImageTableEntry = 0;\r
return;\r
}\r
// returned in a tight loop. Since we are in the debugger the table should not get updated\r
gDebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;\r
gEfiDebugImageTableEntry = 0;\r
return;\r
}\r
if (gDebugTable != NULL) {\r
for (; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {\r
if (gDebugTable->NormalImage != NULL) {\r
if (gDebugTable != NULL) {\r
for (; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {\r
if (gDebugTable->NormalImage != NULL) {\r
(gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {\r
Pdb = PeCoffLoaderGetDebuggerInfo (\r
(gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {\r
Pdb = PeCoffLoaderGetDebuggerInfo (\r
- gXferLibraryBuffer, \r
- sizeof (gXferLibraryBuffer), \r
- " <library name=\"%a\"><segment address=\"0x%p\"/></library>\n", \r
+ gXferLibraryBuffer,\r
+ sizeof (gXferLibraryBuffer),\r
+ " <library name=\"%a\"><segment address=\"0x%p\"/></library>\n",\r
Pdb,\r
LoadAddress\r
);\r
if ((Size != 0) && (Size != (sizeof (gXferLibraryBuffer) - 1))) {\r
gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', gXferLibraryBuffer);\r
Pdb,\r
LoadAddress\r
);\r
if ((Size != 0) && (Size != (sizeof (gXferLibraryBuffer) - 1))) {\r
gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', gXferLibraryBuffer);\r
// Update loop variables so we are in the right place when we get back\r
gEfiDebugImageTableEntry++;\r
gDebugTable++;\r
return;\r
} else {\r
// Update loop variables so we are in the right place when we get back\r
gEfiDebugImageTableEntry++;\r
gDebugTable++;\r
return;\r
} else {\r
gXferObjectReadResponse ('l', "</library-list>\n");\r
gPacketqXferLibraryOffset = 0;\r
return;\r
gXferObjectReadResponse ('l', "</library-list>\n");\r
gPacketqXferLibraryOffset = 0;\r
return;\r
/**\r
Exception Hanldler for GDB. It will be called for all exceptions\r
registered via the gExceptionType[] array.\r
/**\r
Exception Hanldler for GDB. It will be called for all exceptions\r
registered via the gExceptionType[] array.\r
-GdbExceptionHandler ( \r
- IN EFI_EXCEPTION_TYPE ExceptionType, \r
- IN OUT EFI_SYSTEM_CONTEXT SystemContext \r
+GdbExceptionHandler (\r
+ IN EFI_EXCEPTION_TYPE ExceptionType,\r
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);\r
GdbSendTSignal (SystemContext, GdbExceptionType);\r
GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);\r
GdbSendTSignal (SystemContext, GdbExceptionType);\r
switch (gInBuffer[0]) {\r
case '?':\r
GdbSendTSignal (SystemContext, GdbExceptionType);\r
break;\r
switch (gInBuffer[0]) {\r
case '?':\r
GdbSendTSignal (SystemContext, GdbExceptionType);\r
break;\r
// General Query Packets\r
if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {\r
// return what we currently support, we don't parse what gdb suports\r
// General Query Packets\r
if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {\r
// return what we currently support, we don't parse what gdb suports\r
// ‘qXfer:libraries:read::offset,length\r
// gInBuffer[22] is offset string, ++Ptr is length string’\r
for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);\r
// ‘qXfer:libraries:read::offset,length\r
// gInBuffer[22] is offset string, ++Ptr is length string’\r
for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);\r
// Not sure if multi-radix support is required. Currently only support decimal\r
QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));\r
} if (AsciiStrnCmp (gInBuffer, "qOffsets", 10) == 0) {\r
// Not sure if multi-radix support is required. Currently only support decimal\r
QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));\r
} if (AsciiStrnCmp (gInBuffer, "qOffsets", 10) == 0) {\r
- // gCtrlCBreakFlag may have been set from a previous F response package \r
- // and we set the global as we need to process it at a point where we \r
+ // gCtrlCBreakFlag may have been set from a previous F response package\r
+ // and we set the global as we need to process it at a point where we\r
// can update the system context. If we are in the middle of processing\r
// a F Packet it is not safe to read the GDB serial stream so we need\r
// to skip it on this check\r
//\r
if (!gCtrlCBreakFlag && !gProcessingFPacket) {\r
//\r
// can update the system context. If we are in the middle of processing\r
// a F Packet it is not safe to read the GDB serial stream so we need\r
// to skip it on this check\r
//\r
if (!gCtrlCBreakFlag && !gProcessingFPacket) {\r
//\r
- // Ctrl-C was not pending so grab any pending characters and see if they \r
- // are a Ctrl-c (0x03). If so set the Ctrl-C global. \r
+ // Ctrl-C was not pending so grab any pending characters and see if they\r
+ // are a Ctrl-c (0x03). If so set the Ctrl-C global.\r
// us break into the program. We don't want to break into the GDB stub.\r
//\r
AddSingleStep (SystemContext);\r
// us break into the program. We don't want to break into the GDB stub.\r
//\r
AddSingleStep (SystemContext);\r