summaryrefslogtreecommitdiffstats
path: root/src/core/gdbstub
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gdbstub')
-rw-r--r--src/core/gdbstub/gdbstub.cpp101
-rw-r--r--src/core/gdbstub/gdbstub.h14
2 files changed, 63 insertions, 52 deletions
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 28d403158..6d709bd15 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -16,25 +16,25 @@
#ifdef _MSC_VER
#include <WinSock2.h>
-#include <ws2tcpip.h>
#include <common/x64/abi.h>
#include <io.h>
#include <iphlpapi.h>
+#include <ws2tcpip.h>
#define SHUT_RDWR 2
#else
-#include <unistd.h>
+#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <netinet/in.h>
+#include <unistd.h>
#endif
#include "common/logging/log.h"
#include "common/string_util.h"
-#include "core/core.h"
-#include "core/memory.h"
#include "core/arm/arm_interface.h"
+#include "core/core.h"
#include "core/gdbstub/gdbstub.h"
+#include "core/memory.h"
const int GDB_BUFFER_SIZE = 10000;
@@ -64,7 +64,7 @@ const u32 FPSCR_REGISTER = 58;
// 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<?xml version="1.0"?>
+ R"(l<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<feature name="org.gnu.gdb.arm.core">
@@ -297,7 +297,8 @@ static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
auto bp = p.find(addr);
if (bp != p.end()) {
- LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n", bp->second.len, bp->second.addr, type);
+ LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n",
+ bp->second.len, bp->second.addr, type);
p.erase(addr);
}
}
@@ -342,7 +343,9 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
}
if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
- LOG_DEBUG(Debug_GDBStub, "Found breakpoint type %d @ %08x, range: %08x - %08x (%d bytes)\n", type, addr, bp->second.addr, bp->second.addr + len, len);
+ LOG_DEBUG(Debug_GDBStub,
+ "Found breakpoint type %d @ %08x, range: %08x - %08x (%d bytes)\n", type,
+ addr, bp->second.addr, bp->second.addr + len, len);
return true;
}
}
@@ -408,12 +411,13 @@ static void HandleQuery() {
const char* query = reinterpret_cast<const char*>(command_buffer + 1);
- if (strcmp(query, "TStatus") == 0 ) {
+ 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) {
+ } else if (strncmp(query, "Xfer:features:read:target.xml:",
+ strlen("Xfer:features:read:target.xml:")) == 0) {
SendReply(target_xml);
} else {
SendReply("");
@@ -422,10 +426,8 @@ static void HandleQuery() {
/// Handle set thread command from gdb client.
static void HandleSetThread() {
- if (memcmp(command_buffer, "Hg0", 3) == 0 ||
- memcmp(command_buffer, "Hc-1", 4) == 0 ||
- memcmp(command_buffer, "Hc0", 4) == 0 ||
- memcmp(command_buffer, "Hc1", 4) == 0) {
+ if (memcmp(command_buffer, "Hg0", 3) == 0 || memcmp(command_buffer, "Hc-1", 4) == 0 ||
+ memcmp(command_buffer, "Hc0", 4) == 0 || memcmp(command_buffer, "Hc1", 4) == 0) {
return SendReply("OK");
}
@@ -444,7 +446,9 @@ static void SendSignal(u32 signal) {
latest_signal = signal;
- std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15, htonl(Core::g_app_core->GetPC()), 13, htonl(Core::g_app_core->GetReg(13)));
+ std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
+ htonl(Core::g_app_core->GetPC()), 13,
+ htonl(Core::g_app_core->GetReg(13)));
LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str());
SendReply(buffer.c_str());
}
@@ -456,7 +460,7 @@ static void ReadCommand() {
u8 c = ReadByte();
if (c == '+') {
- //ignore ack
+ // ignore ack
return;
} else if (c == 0x03) {
LOG_INFO(Debug_GDBStub, "gdb: found break command\n");
@@ -483,8 +487,9 @@ static void ReadCommand() {
u8 checksum_calculated = CalculateChecksum(command_buffer, command_length);
if (checksum_received != checksum_calculated) {
- LOG_ERROR(Debug_GDBStub, "gdb: invalid checksum: calculated %02x and read %02x for $%s# (length: %d)\n",
- checksum_calculated, checksum_received, command_buffer, command_length);
+ LOG_ERROR(Debug_GDBStub,
+ "gdb: invalid checksum: calculated %02x and read %02x for $%s# (length: %d)\n",
+ checksum_calculated, checksum_received, command_buffer, command_length);
command_length = 0;
@@ -534,7 +539,9 @@ static void ReadRegister() {
} else if (id == CPSR_REGISTER) {
IntToGdbHex(reply, Core::g_app_core->GetCPSR());
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
- IntToGdbHex(reply, Core::g_app_core->GetVFPReg(id - CPSR_REGISTER - 1)); // VFP registers should start at 26, so one after CSPR_REGISTER
+ IntToGdbHex(reply, Core::g_app_core->GetVFPReg(
+ id - CPSR_REGISTER -
+ 1)); // VFP registers should start at 26, so one after CSPR_REGISTER
} else if (id == FPSCR_REGISTER) {
IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR
IntToGdbHex(reply + 8, 0);
@@ -617,7 +624,8 @@ static void WriteRegisters() {
// Dummy FPA registers, ignore
i += 2;
} else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
- Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
+ Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1,
+ GdbHexToInt(buffer_ptr + i * CHAR_BIT));
i++; // Skip padding
} else if (reg == FPSCR_REGISTER) {
Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
@@ -631,12 +639,13 @@ static void WriteRegisters() {
static void ReadMemory() {
static u8 reply[GDB_BUFFER_SIZE - 4];
- auto start_offset = command_buffer+1;
- auto addr_pos = std::find(start_offset, command_buffer+command_length, ',');
+ auto start_offset = command_buffer + 1;
+ auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
- start_offset = addr_pos+1;
- u32 len = HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
+ start_offset = addr_pos + 1;
+ u32 len =
+ HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %08x len: %08x\n", addr, len);
@@ -656,12 +665,12 @@ static void ReadMemory() {
/// Modify location in memory with data received from the gdb client.
static void WriteMemory() {
- auto start_offset = command_buffer+1;
- auto addr_pos = std::find(start_offset, command_buffer+command_length, ',');
+ auto start_offset = command_buffer + 1;
+ auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
- start_offset = addr_pos+1;
- auto len_pos = std::find(start_offset, command_buffer+command_length, ':');
+ start_offset = addr_pos + 1;
+ auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
u8* dst = Memory::GetPointer(addr);
@@ -720,9 +729,10 @@ static bool CommitBreakpoint(BreakpointType type, PAddr addr, u32 len) {
breakpoint.active = true;
breakpoint.addr = addr;
breakpoint.len = len;
- p.insert({ addr, breakpoint });
+ p.insert({addr, breakpoint});
- LOG_DEBUG(Debug_GDBStub, "gdb: added %d breakpoint: %08x bytes at %08x\n", type, breakpoint.len, breakpoint.addr);
+ LOG_DEBUG(Debug_GDBStub, "gdb: added %d breakpoint: %08x bytes at %08x\n", type, breakpoint.len,
+ breakpoint.addr);
return true;
}
@@ -750,12 +760,13 @@ static void AddBreakpoint() {
return SendReply("E01");
}
- auto start_offset = command_buffer+3;
- auto addr_pos = std::find(start_offset, command_buffer+command_length, ',');
+ auto start_offset = command_buffer + 3;
+ auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
- start_offset = addr_pos+1;
- u32 len = HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
+ start_offset = addr_pos + 1;
+ u32 len =
+ HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
if (type == BreakpointType::Access) {
// Access is made up of Read and Write types, so add both breakpoints
@@ -798,12 +809,13 @@ static void RemoveBreakpoint() {
return SendReply("E01");
}
- auto start_offset = command_buffer+3;
- auto addr_pos = std::find(start_offset, command_buffer+command_length, ',');
+ auto start_offset = command_buffer + 3;
+ auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
- start_offset = addr_pos+1;
- u32 len = HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
+ start_offset = addr_pos + 1;
+ u32 len =
+ HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
if (type == BreakpointType::Access) {
// Access is made up of Read and Write types, so add both breakpoints
@@ -896,8 +908,7 @@ void ToggleServer(bool status) {
if (!IsConnected() && Core::g_sys_core != nullptr) {
Init();
}
- }
- else {
+ } else {
// Stop server
if (IsConnected()) {
Shutdown();
@@ -943,7 +954,8 @@ static void Init(u16 port) {
// 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) {
+ 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");
}
@@ -964,13 +976,13 @@ static void Init(u16 port) {
socklen_t client_addrlen = sizeof(saddr_client);
gdbserver_socket = accept(tmpsock, client_addr, &client_addrlen);
if (gdbserver_socket < 0) {
- // In the case that we couldn't start the server for whatever reason, just start CPU execution like normal.
+ // In the case that we couldn't start the server for whatever reason, just start CPU
+ // execution like normal.
halt_loop = false;
step_loop = false;
LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
- }
- else {
+ } else {
LOG_INFO(Debug_GDBStub, "Client connected.\n");
saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr);
}
@@ -1018,5 +1030,4 @@ bool GetCpuStepFlag() {
void SetCpuStepFlag(bool is_step) {
step_loop = is_step;
}
-
};
diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h
index 4f21da23b..fddc27a3e 100644
--- a/src/core/gdbstub/gdbstub.h
+++ b/src/core/gdbstub/gdbstub.h
@@ -13,11 +13,11 @@ namespace GDBStub {
/// Breakpoint Method
enum class BreakpointType {
- None, ///< None
- Execute, ///< Execution Breakpoint
- Read, ///< Read Breakpoint
- Write, ///< Write Breakpoint
- Access ///< Access (R/W) Breakpoint
+ None, ///< None
+ Execute, ///< Execution Breakpoint
+ Read, ///< Read Breakpoint
+ Write, ///< Write Breakpoint
+ Access ///< Access (R/W) Breakpoint
};
struct BreakpointAddress {
@@ -25,7 +25,8 @@ struct BreakpointAddress {
BreakpointType type;
};
-/// If set to false, the server will never be started and no gdbstub-related functions will be executed.
+/// If set to false, the server will never be started and no gdbstub-related functions will be
+/// executed.
extern std::atomic<bool> g_server_enabled;
/**
@@ -92,5 +93,4 @@ bool GetCpuStepFlag();
* @param is_step
*/
void SetCpuStepFlag(bool is_step);
-
}