From 416b2d009157870c4b8ca32b9f3ba5ebce24b270 Mon Sep 17 00:00:00 2001 From: emoose Date: Sun, 6 Oct 2024 06:22:52 +0100 Subject: [PATCH] [GDBStub] Add memory map, MSR/FPSCR, handle Kill request IDA seems to ignore the map though, sad! --- src/xenia/debug/gdb/gdbstub.cc | 35 +++++++++++++++++++++++++++++----- src/xenia/debug/gdb/gdbstub.h | 1 + 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/xenia/debug/gdb/gdbstub.cc b/src/xenia/debug/gdb/gdbstub.cc index 7ee83fea49..55fc849aec 100644 --- a/src/xenia/debug/gdb/gdbstub.cc +++ b/src/xenia/debug/gdb/gdbstub.cc @@ -52,6 +52,20 @@ constexpr const char* kGdbReplyError = "E01"; constexpr int kSignalSigtrap = 5; +constexpr char memory_map[] = + R"(l + + + + + + + + + + +)"; + // must start with l for debugger to accept it // TODO: add power-altivec.xml (and update ReadRegister to support it) constexpr char target_xml[] = @@ -228,9 +242,8 @@ std::string GDBStub::ReadRegister(xe::cpu::ThreadDebugInfo* thread, } return u32_to_padded_hex(0); } - // msr? case 65: - return std::string(8, 'x'); + return u32_to_padded_hex((uint32_t)thread->guest_context.msr); case 66: return u32_to_padded_hex((uint32_t)thread->guest_context.cr()); case 67: @@ -242,7 +255,7 @@ std::string GDBStub::ReadRegister(xe::cpu::ThreadDebugInfo* thread, return std::string(8, 'x'); // fpscr case 70: - return std::string(8, 'x'); + return u32_to_padded_hex(thread->guest_context.fpscr.value); default: if (rid > 70) return ""; return (rid > 31) ? u64_to_padded_hex(*(uint64_t*)&( @@ -298,7 +311,7 @@ void GDBStub::Listen(std::unique_ptr& client) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - // Check if we need to notify client about anything... + // Check if we need to notify client about anything { std::unique_lock lock(mtx_); if (cache_.notify_stopped) { @@ -349,6 +362,7 @@ std::string GetPacketFriendlyName(const std::string& packetCommand) { {"qfThreadInfo", "qfThreadInfo"}, {"qC", "GetThreadId"}, {"D", "Detach"}, + {"k", "KillRequest"}, {"\03", "Break"}, }; @@ -557,6 +571,9 @@ std::string GDBStub::ExecutionPause() { #ifdef DEBUG debugging::DebugPrint("GDBStub: ExecutionPause\n"); #endif + if (processor_->execution_state() != cpu::ExecutionState::kRunning) { + return kGdbReplyError; + } processor_->Pause(); return kGdbReplyOK; } @@ -612,6 +629,8 @@ std::string GDBStub::ReadMemory(const std::string& data) { return result; } +std::string GDBStub::BuildMemoryMap() { return memory_map; } + std::string GDBStub::BuildTargetXml() { return target_xml; } std::string GDBStub::BuildThreadList() { @@ -804,6 +823,9 @@ std::string GDBStub::HandleGDBCommand(const GDBCommand& command) { // Detach {"D", [&](const GDBCommand& cmd) { return DebuggerDetached(); }}, + // Kill request (just treat as detach for now) + {"k", [&](const GDBCommand& cmd) { return DebuggerDetached(); }}, + // Enable extended mode {"!", [&](const GDBCommand& cmd) { return kGdbReplyOK; }}, @@ -887,6 +909,8 @@ std::string GDBStub::HandleGDBCommand(const GDBCommand& command) { auto sub_cmd = param.substr(0, param.find(':')); if (sub_cmd == "features") { return BuildTargetXml(); + } else if (sub_cmd == "memory-map") { + return BuildMemoryMap(); } else if (sub_cmd == "threads") { return BuildThreadList(); } @@ -895,7 +919,8 @@ std::string GDBStub::HandleGDBCommand(const GDBCommand& command) { // Supported features (TODO: memory map) {"qSupported", [&](const GDBCommand& cmd) { - return "PacketSize=1024;qXfer:features:read+;qXfer:threads:read+"; + return "PacketSize=1024;qXfer:features:read+;qXfer:threads:read+;" + "qXfer:memory-map:read+"; }}, // Thread list (IDA requests this but ignores in favor of qXfer?) {"qfThreadInfo", diff --git a/src/xenia/debug/gdb/gdbstub.h b/src/xenia/debug/gdb/gdbstub.h index ca598f2682..cf35c6ea61 100644 --- a/src/xenia/debug/gdb/gdbstub.h +++ b/src/xenia/debug/gdb/gdbstub.h @@ -69,6 +69,7 @@ class GDBStub : public cpu::DebugListener { std::string ExecutionContinue(); std::string ExecutionStep(); std::string ReadMemory(const std::string& data); + std::string BuildMemoryMap(); std::string BuildTargetXml(); std::string BuildThreadList();