From 44d746fc92718c39629e64dbfb8555690d3af0fc Mon Sep 17 00:00:00 2001 From: polaris- Date: Wed, 6 Apr 2016 07:01:00 -0400 Subject: Adopted WinterMute's gdbstub changes This fixes the comments left on the PR (whitespace, SO_REUSEADDR, comment changes). --- src/core/gdbstub/gdbstub.cpp | 108 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 23 deletions(-) (limited to 'src/core') diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 3a2445241..c1a7ec5bf 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -60,6 +60,59 @@ const u32 R15_REGISTER = 15; const u32 CPSR_REGISTER = 25; const u32 FPSCR_REGISTER = 58; +// For sample XML files see the GDB source /gdb/features +// GDB also wants the l character at the start +// This XML defines what the registers are for this specific ARM device +static const char* target_xml = +R"(l + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)"; + namespace GDBStub { static int gdbserver_socket = -1; @@ -211,7 +264,7 @@ static u8 ReadByte() { } /// Calculate the checksum of the current command buffer. -static u8 CalculateChecksum(u8 *buffer, u32 length) { +static u8 CalculateChecksum(u8* buffer, u32 length) { return static_cast(std::accumulate(buffer, buffer + length, 0, std::plus())); } @@ -353,8 +406,15 @@ static void SendReply(const char* reply) { static void HandleQuery() { LOG_DEBUG(Debug_GDBStub, "gdb: query '%s'\n", command_buffer + 1); - if (!strcmp(reinterpret_cast(command_buffer + 1), "TStatus")) { + const char* query = reinterpret_cast(command_buffer + 1); + + if (strcmp(query, "TStatus") == 0 ) { SendReply("T0"); + } else if (strncmp(query, "Supported:", strlen("Supported:")) == 0) { + // PacketSize needs to be large enough for target xml + SendReply("PacketSize=800;qXfer:features:read+"); + } else if (strncmp(query, "Xfer:features:read:target.xml:", strlen("Xfer:features:read:target.xml:")) == 0) { + SendReply(target_xml); } else { SendReply(""); } @@ -491,29 +551,25 @@ static void ReadRegisters() { memset(buffer, 0, sizeof(buffer)); u8* bufptr = buffer; - for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) { - if (reg <= R15_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetReg(reg)); - } else if (reg == CPSR_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetCPSR()); - } else if (reg == CPSR_REGISTER - 1) { - // Dummy FPA register, ignore - IntToGdbHex(bufptr + i * CHAR_BIT, 0); - } else if (reg < CPSR_REGISTER) { - // Dummy FPA registers, ignore - IntToGdbHex(bufptr + i * CHAR_BIT, 0); - IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); - IntToGdbHex(bufptr + (i + 2) * CHAR_BIT, 0); - i += 2; - } else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPReg(reg - CPSR_REGISTER - 1)); - IntToGdbHex(bufptr + (i + 1) * CHAR_BIT, 0); - i++; - } else if (reg == FPSCR_REGISTER) { - IntToGdbHex(bufptr + i * CHAR_BIT, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); - } + + for (int reg = 0; reg <= R15_REGISTER; reg++) { + IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetReg(reg)); } + bufptr += (16 * CHAR_BIT); + + IntToGdbHex(bufptr, Core::g_app_core->GetCPSR()); + + bufptr += CHAR_BIT; + + for (int reg = 0; reg <= 31; reg++) { + IntToGdbHex(bufptr + reg * CHAR_BIT, Core::g_app_core->GetVFPReg(reg)); + } + + bufptr += (32 * CHAR_BIT); + + IntToGdbHex(bufptr, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); + SendReply(reinterpret_cast(buffer)); } @@ -885,6 +941,12 @@ void Init(u16 port) { LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket"); } + // Set socket to SO_REUSEADDR so it can always bind on the same port + int reuse_enabled = 1; + if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, sizeof(reuse_enabled)) < 0) { + LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); + } + const sockaddr* server_addr = reinterpret_cast(&saddr_server); socklen_t server_addrlen = sizeof(saddr_server); if (bind(tmpsock, server_addr, server_addrlen) < 0) { -- cgit v1.2.3