From 31dee93e849d79a91f280faf16941806e3cb3c6b Mon Sep 17 00:00:00 2001 From: polaris- Date: Wed, 2 Sep 2015 08:56:38 -0400 Subject: Implement gdbstub --- src/citra_qt/config.cpp | 10 ++++++++++ src/citra_qt/main.cpp | 12 ++++++++++++ src/citra_qt/main.h | 1 + src/citra_qt/main.ui | 9 +++++++++ 4 files changed, 32 insertions(+) (limited to 'src/citra_qt') diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp index 1f4981ce1..8e247ff5c 100644 --- a/src/citra_qt/config.cpp +++ b/src/citra_qt/config.cpp @@ -62,6 +62,11 @@ void Config::ReadValues() { qt_config->beginGroup("Miscellaneous"); Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString(); qt_config->endGroup(); + + qt_config->beginGroup("Debugging"); + Settings::values.use_gdbstub = qt_config->value("use_gdbstub", false).toBool(); + Settings::values.gdbstub_port = qt_config->value("gdbstub_port", 24689).toInt(); + qt_config->endGroup(); } void Config::SaveValues() { @@ -97,6 +102,11 @@ void Config::SaveValues() { qt_config->beginGroup("Miscellaneous"); qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter)); qt_config->endGroup(); + + qt_config->beginGroup("Debugging"); + qt_config->setValue("use_gdbstub", Settings::values.use_gdbstub); + qt_config->setValue("gdbstub_port", Settings::values.gdbstub_port); + qt_config->endGroup(); } void Config::Reload() { diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 298649aaf..d8d17f466 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -48,6 +48,8 @@ #include "video_core/video_core.h" +#include "core/gdbstub/gdbstub.h" + GMainWindow::GMainWindow() : emu_thread(nullptr) { Pica::g_debug_context = Pica::DebugContext::Construct(); @@ -143,6 +145,11 @@ GMainWindow::GMainWindow() : emu_thread(nullptr) game_list->LoadInterfaceLayout(settings); + ui.action_Use_Gdbstub->setChecked(Settings::values.use_gdbstub); + SetGdbstubEnabled(ui.action_Use_Gdbstub->isChecked()); + + GDBStub::SetServerPort(static_cast(Settings::values.gdbstub_port)); + ui.action_Use_Hardware_Renderer->setChecked(Settings::values.use_hw_renderer); SetHardwareRendererEnabled(ui.action_Use_Hardware_Renderer->isChecked()); @@ -175,6 +182,7 @@ GMainWindow::GMainWindow() : emu_thread(nullptr) connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame())); connect(ui.action_Use_Hardware_Renderer, SIGNAL(triggered(bool)), this, SLOT(SetHardwareRendererEnabled(bool))); connect(ui.action_Use_Shader_JIT, SIGNAL(triggered(bool)), this, SLOT(SetShaderJITEnabled(bool))); + connect(ui.action_Use_Gdbstub, SIGNAL(triggered(bool)), this, SLOT(SetGdbstubEnabled(bool))); connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode())); connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog())); @@ -445,6 +453,10 @@ void GMainWindow::SetHardwareRendererEnabled(bool enabled) { VideoCore::g_hw_renderer_enabled = enabled; } +void GMainWindow::SetGdbstubEnabled(bool enabled) { + GDBStub::ToggleServer(enabled); +} + void GMainWindow::SetShaderJITEnabled(bool enabled) { VideoCore::g_shader_jit_enabled = enabled; } diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 6d27ce6a9..f6d429cd9 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -99,6 +99,7 @@ private slots: void OnConfigure(); void OnDisplayTitleBars(bool); void SetHardwareRendererEnabled(bool); + void SetGdbstubEnabled(bool); void SetShaderJITEnabled(bool); void ToggleWindowMode(); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index 997597642..1e8a07cfb 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -75,6 +75,7 @@ + @@ -170,6 +171,14 @@ Use Shader JIT + + + true + + + Use Gdbstub + + Configure ... -- cgit v1.2.3 From a5ab8accc21e73be9564bebde4d3b20b38d85b6e Mon Sep 17 00:00:00 2001 From: polaris- Date: Wed, 21 Oct 2015 22:19:55 -0400 Subject: Handle changes pointed out in comments on PR --- src/citra/citra.cpp | 3 +- src/citra_qt/main.cpp | 3 +- src/core/gdbstub/gdbstub.cpp | 95 ++++++++++++++++---------------------------- 3 files changed, 36 insertions(+), 65 deletions(-) (limited to 'src/citra_qt') diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index bfbb21199..c96fc1374 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -23,6 +23,7 @@ #include "core/settings.h" #include "core/system.h" #include "core/core.h" +#include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" #include "citra/config.h" @@ -30,8 +31,6 @@ #include "video_core/video_core.h" -#include "core/gdbstub/gdbstub.h" - static void PrintHelp() { diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index d8d17f466..e5ed01a11 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -44,12 +44,11 @@ #include "core/settings.h" #include "core/system.h" #include "core/arm/disassembler/load_symbol_map.h" +#include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" #include "video_core/video_core.h" -#include "core/gdbstub/gdbstub.h" - GMainWindow::GMainWindow() : emu_thread(nullptr) { Pica::g_debug_context = Pica::DebugContext::Construct(); diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 6c21b5998..6f9c8fa29 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -20,18 +20,18 @@ #include #define SHUT_RDWR 2 #else +#include #include #include #include #include -#include #endif #include "common/logging/log.h" #include "common/string_util.h" -#include #include "core/core.h" #include "core/memory.h" +#include "core/arm/arm_interface.h" #include "gdbstub.h" const int GDB_BUFFER_SIZE = 10000; @@ -67,8 +67,7 @@ static u8 command_buffer[GDB_BUFFER_SIZE]; static u32 command_length; static u32 latest_signal = 0; -static u32 send_signal = 0; -static u32 step_break = 0; +static bool step_break = false; static bool memory_break = false; // Binding to a port within the reserved ports range (0-1023) requires root permissions, @@ -356,33 +355,21 @@ static void HandleSetThread() { SendReply("E01"); } -/// Create and send signal packet. -static void HandleSignal() { - 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()); -} - /** - * Set signal and send packet to client through HandleSignal if signal flag is set using SendSignal. + * Send signal packet to client. * * @param signal Signal to be sent to client. */ -int SendSignal(u32 signal) { +void SendSignal(u32 signal) { if (gdbserver_socket == -1) { - return 1; + return; } latest_signal = signal; - if (send_signal) { - HandleSignal(); - send_signal = 0; - } - - return 0; + 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()); } /// Read command from gdb client. @@ -397,7 +384,6 @@ static void ReadCommand() { } else if (c == 0x03) { LOG_INFO(Debug_GDBStub, "gdb: found break command\n"); halt_loop = true; - send_signal = 1; SendSignal(SIGTRAP); return; } else if (c != GDB_STUB_START) { @@ -566,17 +552,14 @@ static void WriteRegisters() { static void ReadMemory() { static u8 reply[GDB_BUFFER_SIZE - 4]; - int i = 1; + auto start_offset = command_buffer+1; + auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); PAddr addr = 0; - while (command_buffer[i] != ',') { - addr = (addr << 4) | HexCharToValue(command_buffer[i++]); - } - i++; + HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + start_offset = addr_pos+1; u32 len = 0; - while (i < command_length) { - len = (len << 4) | HexCharToValue(command_buffer[i++]); - } + HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); if (len * 2 > sizeof(reply)) { SendReply("E01"); @@ -594,31 +577,28 @@ static void ReadMemory() { /// Modify location in memory with data received from the gdb client. static void WriteMemory() { - int i = 1; + auto start_offset = command_buffer+1; + auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); PAddr addr = 0; - while (command_buffer[i] != ',') { - addr = (addr << 4) | HexCharToValue(command_buffer[i++]); - } - i++; + HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + start_offset = addr_pos+1; + auto len_pos = std::find(start_offset, command_buffer+command_length, ':'); u32 len = 0; - while (command_buffer[i] != ':') { - len = (len << 4) | HexCharToValue(command_buffer[i++]); - } + HexToMem((u8*)&len, start_offset, (len_pos - start_offset) / 2); u8* dst = Memory::GetPointer(addr); if (!dst) { return SendReply("E00"); } - HexToMem(dst, command_buffer + i + 1, len); + HexToMem(dst, len_pos + 1, len); SendReply("OK"); } void Break(bool is_memory_break) { if (!halt_loop) { halt_loop = true; - send_signal = 1; SendSignal(SIGTRAP); } @@ -629,8 +609,7 @@ void Break(bool is_memory_break) { static void Step() { step_loop = true; halt_loop = true; - send_signal = 1; - step_break = 1; + step_break = true; SendSignal(SIGTRAP); } @@ -645,7 +624,7 @@ bool IsMemoryBreak() { /// Tell the CPU to continue executing. static void Continue() { memory_break = false; - step_break = 0; + step_break = false; step_loop = false; halt_loop = false; } @@ -694,17 +673,14 @@ static void AddBreakpoint() { return SendReply("E01"); } - int i = 3; + auto start_offset = command_buffer+3; + auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); PAddr addr = 0; - while (command_buffer[i] != ',') { - addr = addr << 4 | HexCharToValue(command_buffer[i++]); - } - i++; + HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + start_offset = addr_pos+1; u32 len = 0; - while (i < command_length) { - len = len << 4 | HexCharToValue(command_buffer[i++]); - } + HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints @@ -747,17 +723,14 @@ static void RemoveBreakpoint() { return SendReply("E01"); } - int i = 3; + auto start_offset = command_buffer+3; + auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); PAddr addr = 0; - while (command_buffer[i] != ',') { - addr = (addr << 4) | HexCharToValue(command_buffer[i++]); - } - i++; + HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); + start_offset = addr_pos+1; u32 len = 0; - while (i < command_length) { - len = (len << 4) | HexCharToValue(command_buffer[i++]); - } + HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints @@ -795,7 +768,7 @@ void HandlePacket() { HandleSetThread(); break; case '?': - HandleSignal(); + SendSignal(latest_signal); break; case 'k': Shutdown(); -- cgit v1.2.3