+++ /dev/null
-/** @file\r
- Debug Agent library implementition with empty functions.\r
-\r
- Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\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
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "GdbDebugAgent.h"\r
-\r
-\r
-UINTN gMaxProcessorIndex = 0;\r
-\r
-//\r
-// Buffers for basic gdb communication\r
-//\r
-CHAR8 gInBuffer[MAX_BUF_SIZE];\r
-CHAR8 gOutBuffer[MAX_BUF_SIZE];\r
-\r
-\r
-//\r
-// Globals for returning XML from qXfer:libraries:read packet\r
-//\r
-UINTN gPacketqXferLibraryOffset = 0;\r
-UINTN gEfiDebugImageTableEntry = 0;\r
-CHAR8 gXferLibraryBuffer[2000];\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};\r
-\r
-\r
-// add-symbol-file c:/work/edk2/Build/BeagleBoard/DEBUG_GCC48/ARM/BeagleBoardPkg/Sec/Sec/DEBUG/BeagleBoardSec.dll 0x80008360\r
-CHAR8 *qXferHack = "<library name=\"c:/work/edk2/Build/BeagleBoard/DEBUG_GCC48/ARM/BeagleBoardPkg/Sec/Sec/DEBUG/BeagleBoardSec.dll\"><segment address=\"0x80008360\"/></library>";\r
-\r
-UINTN\r
-gXferObjectReadResponse (\r
- IN CHAR8 Type,\r
- IN CHAR8 *Str\r
- )\r
-{\r
- CHAR8 *OutBufPtr; // pointer to the output buffer\r
- CHAR8 Char;\r
- UINTN Count;\r
-\r
- // responce starts with 'm' or 'l' if it is the end\r
- OutBufPtr = gOutBuffer;\r
- *OutBufPtr++ = Type;\r
- Count = 1;\r
-\r
- // Binary data encoding\r
- OutBufPtr = gOutBuffer;\r
- while (*Str != '\0') {\r
- Char = *Str++;\r
- if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {\r
- // escape character\r
- *OutBufPtr++ = 0x7d;\r
-\r
- Char ^= 0x20;\r
- }\r
- *OutBufPtr++ = Char;\r
- Count++;\r
- }\r
-\r
- *OutBufPtr = '\0' ; // the end of the buffer\r
- SendPacket (gOutBuffer);\r
-\r
- return Count;\r
-}\r
-\r
-/**\r
- Process "qXfer:object:read:annex:offset,length" request.\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
- keep calling until we say we are done. XML doc looks like:\r
-\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
-\r
- Since we can not allocate memory in interupt context this module has\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
- Each subseqent call will ask for the next available part of the document.\r
-\r
- Note: The only variable size element in the XML is:\r
- " <library name=\"%s\"><segment address=\"%p\"/></library>\n" and it is\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
- @param Length number of bytes to read starting at Offset\r
-\r
- **/\r
-VOID\r
-QxferLibrary (\r
- IN UINTN Offset,\r
- IN UINTN Length\r
- )\r
-{\r
- gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "<library-list>\n");\r
- gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', qXferHack);\r
- gXferObjectReadResponse ('l', "</library-list>\n");\r
- gPacketqXferLibraryOffset = 0;\r
-}\r
-\r
-/**\r
- Transfer length bytes of input buffer, starting at Address, to memory.\r
-\r
- @param length the number of the bytes to be transferred/written\r
- @param *address the start address of the transferring/writing the memory\r
- @param *new_data the new data to be written to memory\r
- **/\r
-\r
-VOID\r
-TransferFromInBufToMem (\r
- IN UINTN Length,\r
- IN unsigned char *Address,\r
- IN CHAR8 *NewData\r
- )\r
-{\r
- CHAR8 c1;\r
- CHAR8 c2;\r
-\r
- while (Length-- > 0) {\r
- c1 = (CHAR8)HexCharToInt (*NewData++);\r
- c2 = (CHAR8)HexCharToInt (*NewData++);\r
-\r
- if ((c1 < 0) || (c2 < 0)) {\r
- SendError (GDB_EBADMEMDATA);\r
- return;\r
- }\r
- *Address++ = (UINT8)((c1 << 4) + c2);\r
- }\r
-\r
- SendSuccess();\r
-}\r
-\r
-\r
-/**\r
- Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer\r
- as a packet.\r
-\r
- @param Length the number of the bytes to be transferred/read\r
- @param *address pointer to the start address of the transferring/reading the memory\r
- **/\r
-\r
-VOID\r
-TransferFromMemToOutBufAndSend (\r
- IN UINTN Length,\r
- IN unsigned char *Address\r
- )\r
-{\r
- // there are Length bytes and every byte is represented as 2 hex chars\r
- CHAR8 OutBuffer[MAX_BUF_SIZE];\r
- CHAR8 *OutBufPtr; // pointer to the output buffer\r
- CHAR8 Char;\r
-\r
- OutBufPtr = OutBuffer;\r
- while (Length > 0) {\r
-\r
- Char = mHexToStr[*Address >> 4];\r
- if ((Char >= 'A') && (Char <= 'F')) {\r
- Char = Char - 'A' + 'a';\r
- }\r
- *OutBufPtr++ = Char;\r
-\r
- Char = mHexToStr[*Address & 0x0f];\r
- if ((Char >= 'A') && (Char <= 'F')) {\r
- Char = Char - 'A' + 'a';\r
- }\r
- *OutBufPtr++ = Char;\r
-\r
- Address++;\r
- Length--;\r
- }\r
-\r
- *OutBufPtr = '\0' ; // the end of the buffer\r
- SendPacket (OutBuffer);\r
-}\r
-\r
-\r
-\r
-/**\r
- Send a GDB Remote Serial Protocol Packet\r
-\r
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',\r
- the packet teminating character '#' and the two digit checksum.\r
-\r
- If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up\r
- in an infinit loop. This is so if you unplug the debugger code just keeps running\r
-\r
- @param PacketData Payload data for the packet\r
-\r
-\r
- @retval Number of bytes of packet data sent.\r
-\r
-**/\r
-UINTN\r
-SendPacket (\r
- IN CHAR8 *PacketData\r
- )\r
-{\r
- UINT8 CheckSum;\r
- UINTN Timeout;\r
- CHAR8 *Ptr;\r
- CHAR8 TestChar;\r
- UINTN Count;\r
-\r
- Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount);\r
-\r
- Count = 0;\r
- do {\r
-\r
- Ptr = PacketData;\r
-\r
- if (Timeout-- == 0) {\r
- // Only try a finite number of times so we don't get stuck in the loop\r
- return Count;\r
- }\r
-\r
- // Packet prefix\r
- GdbPutChar ('$');\r
-\r
- for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {\r
- GdbPutChar (*Ptr);\r
- CheckSum = CheckSum + *Ptr;\r
- }\r
-\r
- // Packet terminating character and checksum\r
- GdbPutChar ('#');\r
- GdbPutChar (mHexToStr[CheckSum >> 4]);\r
- GdbPutChar (mHexToStr[CheckSum & 0x0F]);\r
-\r
- TestChar = GdbGetChar ();\r
- } while (TestChar != '+');\r
-\r
- return Count;\r
-}\r
-\r
-/**\r
- Receive a GDB Remote Serial Protocol Packet\r
-\r
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',\r
- the packet teminating character '#' and the two digit checksum.\r
-\r
- If host re-starts sending a packet without ending the previous packet, only the last valid packet is processed.\r
- (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)\r
-\r
- If an ack '+' is not sent resend the packet\r
-\r
- @param PacketData Payload data for the packet\r
-\r
- @retval Number of bytes of packet data received.\r
-\r
-**/\r
-UINTN\r
-ReceivePacket (\r
- OUT CHAR8 *PacketData,\r
- IN UINTN PacketDataSize\r
- )\r
-{\r
- UINT8 CheckSum;\r
- UINTN Index;\r
- CHAR8 Char;\r
- CHAR8 SumString[3];\r
- CHAR8 TestChar;\r
-\r
- ZeroMem (PacketData, PacketDataSize);\r
-\r
- for (;;) {\r
- // wait for the start of a packet\r
- TestChar = GdbGetChar ();\r
- while (TestChar != '$') {\r
- TestChar = GdbGetChar ();\r
- };\r
-\r
- retry:\r
- for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {\r
- Char = GdbGetChar ();\r
- if (Char == '$') {\r
- goto retry;\r
- }\r
- if (Char == '#') {\r
- break;\r
- }\r
-\r
- PacketData[Index] = Char;\r
- CheckSum = CheckSum + Char;\r
- }\r
- PacketData[Index] = '\0';\r
-\r
- if (Index == PacketDataSize) {\r
- continue;\r
- }\r
-\r
- SumString[0] = GdbGetChar ();\r
- SumString[1] = GdbGetChar ();\r
- SumString[2] = '\0';\r
-\r
- if (AsciiStrHexToUintn (SumString) == CheckSum) {\r
- // Ack: Success\r
- GdbPutChar ('+');\r
-\r
- // Null terminate the callers string\r
- PacketData[Index] = '\0';\r
- return Index;\r
- } else {\r
- // Ack: Failure\r
- GdbPutChar ('-');\r
- }\r
- }\r
-\r
- //return 0;\r
-}\r
-\r
-\r
-/**\r
- Empties the given buffer\r
- @param Buf pointer to the first element in buffer to be emptied\r
- **/\r
-VOID\r
-EmptyBuffer (\r
- IN CHAR8 *Buf\r
- )\r
-{\r
- *Buf = '\0';\r
-}\r
-\r
-\r
-/**\r
- Converts an 8-bit Hex Char into a INTN.\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
- **/\r
-INTN\r
-HexCharToInt (\r
- IN CHAR8 Char\r
- )\r
-{\r
- if ((Char >= 'A') && (Char <= 'F')) {\r
- return Char - 'A' + 10;\r
- } else if ((Char >= 'a') && (Char <= 'f')) {\r
- return Char - 'a' + 10;\r
- } else if ((Char >= '0') && (Char <= '9')) {\r
- return Char - '0';\r
- } else { // if not a hex value, return a negative value\r
- return -1;\r
- }\r
-}\r
-\r
- // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end\r
-CHAR8 *gError = "E__";\r
-\r
-/** 'E NN'\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
-\r
- @param errno the error number that will be sent\r
- **/\r
-VOID\r
-EFIAPI\r
-SendError (\r
- IN UINT8 ErrorNum\r
- )\r
-{\r
- //\r
- // Replace _, or old data, with current errno\r
- //\r
- gError[1] = mHexToStr [ErrorNum >> 4];\r
- gError[2] = mHexToStr [ErrorNum & 0x0f];\r
-\r
- SendPacket (gError); // send buffer\r
-}\r
-\r
-\r
-\r
-/**\r
- Send 'OK' when the function is done executing successfully.\r
- **/\r
-VOID\r
-EFIAPI\r
-SendSuccess (\r
- VOID\r
- )\r
-{\r
- SendPacket ("OK"); // send buffer\r
-}\r
-\r
-\r
-/**\r
- Send empty packet to specify that particular command/functionality is not supported.\r
- **/\r
-VOID\r
-EFIAPI\r
-SendNotSupported (\r
- VOID\r
- )\r
-{\r
- SendPacket ("");\r
-}\r
-\r
-\r
-\r
-\r
-\r
-/**\r
- Translates the EFI mapping to GDB mapping\r
-\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
-ConvertEFItoGDBtype (\r
- IN EFI_EXCEPTION_TYPE EFIExceptionType\r
- )\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
- }\r
- return GDB_SIGTRAP; // this is a GDB trap\r
-}\r
-\r
-\r
-/** "m addr,length"\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
- send it as a packet.\r
- **/\r
-\r
-VOID\r
-EFIAPI\r
-ReadFromMemory (\r
- CHAR8 *PacketData\r
- )\r
-{\r
- UINTN Address;\r
- UINTN Length;\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
-\r
- AddrBufPtr = AddressBuffer;\r
- InBufPtr = &PacketData[1];\r
- while (*InBufPtr != ',') {\r
- *AddrBufPtr++ = *InBufPtr++;\r
- }\r
- *AddrBufPtr = '\0';\r
-\r
- InBufPtr++; // this skips ',' in the buffer\r
-\r
- /* Error checking */\r
- if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {\r
- SendError (GDB_EBADMEMADDRBUFSIZE);\r
- return;\r
- }\r
-\r
- // 2 = 'm' + ','\r
- if (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - 2 >= MAX_LENGTH_SIZE) {\r
- SendError (GDB_EBADMEMLENGTH);\r
- return;\r
- }\r
-\r
- Address = AsciiStrHexToUintn (AddressBuffer);\r
- Length = AsciiStrHexToUintn (InBufPtr);\r
-\r
- TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);\r
-}\r
-\r
-\r
-/** "M addr,length :XX..."\r
- Find the Length of the area in bytes to write and the start addres. Finally, pass them to\r
- another function, TransferFromInBufToMem, that will write to that memory space the info in\r
- the input buffer.\r
- **/\r
-VOID\r
-EFIAPI\r
-WriteToMemory (\r
- IN CHAR8 *PacketData\r
- )\r
-{\r
- UINTN Address;\r
- UINTN Length;\r
- UINTN MessageLength;\r
- CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars\r
- CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars\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
-\r
- AddrBufPtr = AddressBuffer;\r
- LengthBufPtr = LengthBuffer;\r
- InBufPtr = &PacketData[1];\r
-\r
- while (*InBufPtr != ',') {\r
- *AddrBufPtr++ = *InBufPtr++;\r
- }\r
- *AddrBufPtr = '\0';\r
-\r
- InBufPtr++; // this skips ',' in the buffer\r
-\r
- while (*InBufPtr != ':') {\r
- *LengthBufPtr++ = *InBufPtr++;\r
- }\r
- *LengthBufPtr = '\0';\r
-\r
- InBufPtr++; // this skips ':' in the buffer\r
-\r
- Address = AsciiStrHexToUintn (AddressBuffer);\r
- Length = AsciiStrHexToUintn (LengthBuffer);\r
-\r
- /* Error checking */\r
-\r
- //Check if Address is not too long.\r
- if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {\r
- SendError (GDB_EBADMEMADDRBUFSIZE);\r
- return;\r
- }\r
-\r
- //Check if message length is not too long\r
- if (AsciiStrLen(LengthBuffer) >= MAX_LENGTH_SIZE) {\r
- SendError (GDB_EBADMEMLENGBUFSIZE);\r
- return;\r
- }\r
-\r
- // Check if Message is not too long/short.\r
- // 3 = 'M' + ',' + ':'\r
- MessageLength = (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - AsciiStrLen(LengthBuffer) - 3);\r
- if (MessageLength != (2*Length)) {\r
- //Message too long/short. New data is not the right size.\r
- SendError (GDB_EBADMEMDATASIZE);\r
- return;\r
- }\r
- TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr);\r
-}\r
-\r
-/**\r
- Parses breakpoint packet data and captures Breakpoint type, Address and length.\r
- In case of an error, function returns particular error code. Returning 0 meaning\r
- no error.\r
-\r
- @param PacketData Pointer to the payload data for the packet.\r
- @param Type Breakpoint type\r
- @param Address Breakpoint address\r
- @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)\r
-\r
- @retval 1 Success\r
- @retval {other} Particular error code\r
-\r
-**/\r
-UINTN\r
-ParseBreakpointPacket (\r
- IN CHAR8 *PacketData,\r
- OUT UINTN *Type,\r
- OUT UINTN *Address,\r
- OUT UINTN *Length\r
- )\r
-{\r
- CHAR8 AddressBuffer[MAX_ADDR_SIZE];\r
- CHAR8 *AddressBufferPtr;\r
- CHAR8 *PacketDataPtr;\r
-\r
- PacketDataPtr = &PacketData[1];\r
- AddressBufferPtr = AddressBuffer;\r
-\r
- *Type = AsciiStrHexToUintn (PacketDataPtr);\r
-\r
- //Breakpoint/watchpoint type should be between 0 to 4\r
- if (*Type > 4) {\r
- return 22; //EINVAL: Invalid argument.\r
- }\r
-\r
- //Skip ',' in the buffer.\r
- while (*PacketDataPtr++ != ',');\r
-\r
- //Parse Address information\r
- while (*PacketDataPtr != ',') {\r
- *AddressBufferPtr++ = *PacketDataPtr++;\r
- }\r
- *AddressBufferPtr = '\0';\r
-\r
- //Check if Address is not too long.\r
- if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {\r
- return 40; //EMSGSIZE: Message size too long.\r
- }\r
-\r
- *Address = AsciiStrHexToUintn (AddressBuffer);\r
-\r
- PacketDataPtr++; //This skips , in the buffer\r
-\r
- //Parse Length information\r
- *Length = AsciiStrHexToUintn (PacketDataPtr);\r
-\r
- //Length should be 1, 2 or 4 bytes\r
- if (*Length > 4) {\r
- return 22; //EINVAL: Invalid argument\r
- }\r
-\r
- return 0; //0 = No error\r
-}\r
-\r
-\r
-\r
-/**\r
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints\r
-\r
- @param SystemContext Register content at time of the exception\r
- @param GdbExceptionType GDB exception type\r
- **/\r
-VOID\r
-GdbSendTSignal (\r
- IN EFI_SYSTEM_CONTEXT SystemContext,\r
- IN UINT8 GdbExceptionType\r
- )\r
-{\r
- CHAR8 TSignalBuffer[128];\r
- CHAR8 *TSignalPtr;\r
-\r
- TSignalPtr = &TSignalBuffer[0];\r
-\r
- //Construct TSignal packet\r
- *TSignalPtr++ = 'T';\r
-\r
- //\r
- // replace _, or previous value, with Exception type\r
- //\r
- *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4];\r
- *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f];\r
-\r
- ProcessorSendTSignal (SystemContext, GdbExceptionType, TSignalPtr, sizeof (TSignalBuffer) - 2);\r
-\r
- SendPacket (TSignalBuffer);\r
-}\r
-\r
-VOID\r
-GdbFWrite (\r
- IN UINTN Fd,\r
- IN CHAR8 *Data,\r
- IN UINTN DataSize\r
- )\r
-{\r
- CHAR8 Buffer[128];\r
-\r
- AsciiSPrint (Buffer, sizeof (Buffer), "Fwrite,%x,%x,%x", Fd, Data, DataSize);\r
- SendPacket (Buffer);\r
-\r
- for( ; ; ) {\r
- ReceivePacket (gInBuffer, MAX_BUF_SIZE);\r
-\r
- switch (gInBuffer[0]) {\r
- case 'm':\r
- ReadFromMemory (gInBuffer);\r
- break;\r
-\r
- case 'M':\r
- WriteToMemory (gInBuffer);\r
- break;\r
-\r
- case 'F':\r
- return;\r
- }\r
- }\r
-}\r
-\r
-\r
-VOID\r
-GdbFPutString (\r
- IN CHAR8 *String\r
- )\r
-{\r
- UINTN Len = AsciiStrSize (String);\r
-\r
- GdbFWrite (2, String, Len);\r
-}\r
-\r
-\r
-/**\r
- Exception Hanldler for GDB. It will be called for all exceptions\r
- registered via the gExceptionType[] array.\r
-\r
- @param ExceptionType Exception that is being processed\r
- @param SystemContext Register content at time of the exception\r
- **/\r
-VOID\r
-EFIAPI\r
-GdbExceptionHandler (\r
- IN EFI_EXCEPTION_TYPE ExceptionType,\r
- IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
- )\r
-{\r
- UINT8 GdbExceptionType;\r
- CHAR8 *Ptr;\r
-\r
- if (ProcessorControlC (ExceptionType, SystemContext)) {\r
- // We tried to process a control C handler and there is nothing to do\r
- return;\r
- }\r
-\r
- GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);\r
- GdbSendTSignal (SystemContext, GdbExceptionType);\r
-\r
- for( ; ; ) {\r
- ReceivePacket (gInBuffer, MAX_BUF_SIZE);\r
-\r
- switch (gInBuffer[0]) {\r
- case '?':\r
- GdbSendTSignal (SystemContext, GdbExceptionType);\r
- break;\r
-\r
- case 'c':\r
- ContinueAtAddress (SystemContext, gInBuffer);\r
- return;\r
-\r
- case 'D':\r
- // gdb wants to disconnect so return "OK" packet since.\r
- SendSuccess ();\r
- return;\r
-\r
- case 'g':\r
- ReadGeneralRegisters (SystemContext);\r
- break;\r
-\r
- case 'G':\r
- WriteGeneralRegisters (SystemContext, gInBuffer);\r
- break;\r
-\r
- case 'H':\r
- //Return "OK" packet since we don't have more than one thread.\r
- SendSuccess ();\r
- break;\r
-\r
- case 'm':\r
- ReadFromMemory (gInBuffer);\r
- break;\r
-\r
- case 'M':\r
- WriteToMemory (gInBuffer);\r
- break;\r
-\r
- case 'P':\r
- WriteNthRegister (SystemContext, gInBuffer);\r
- break;\r
-\r
- //\r
- // Still debugging this code. Not used in Darwin\r
- //\r
- case 'q':\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
- AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);\r
- SendPacket (gOutBuffer);\r
- } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) {\r
- // \91qXfer:libraries:read::offset,length\r
- // gInBuffer[22] is offset string, ++Ptr is length string\92\r
- for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);\r
-\r
- // Not sure if multi-radix support is required. Currently only support decimal\r
- QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));\r
- } else if (AsciiStrnCmp (gInBuffer, "qOffsets", 8) == 0) {\r
- AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000");\r
- SendPacket (gOutBuffer);\r
- } else if (AsciiStrnCmp (gInBuffer, "qAttached", 9) == 0) {\r
- // remote server attached to an existing process\r
- SendPacket ("1");\r
- } else {\r
- //Send empty packet\r
- SendNotSupported ();\r
- }\r
- break;\r
-\r
- case 's':\r
- SingleStep (SystemContext, gInBuffer);\r
- return;\r
-\r
- case 'z':\r
- RemoveBreakPoint (SystemContext, gInBuffer);\r
- break;\r
-\r
- case 'Z':\r
- InsertBreakPoint (SystemContext, gInBuffer);\r
- break;\r
-\r
- default:\r
- //Send empty packet\r
- SendNotSupported ();\r
- break;\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-\r