[GDBStub] Add memory map, MSR/FPSCR, handle Kill request

IDA seems to ignore the map though, sad!
This commit is contained in:
emoose 2024-10-06 06:22:52 +01:00
parent 0469ae2aee
commit 26cfa69497
2 changed files with 31 additions and 5 deletions

View File

@ -52,6 +52,20 @@ constexpr const char* kGdbReplyError = "E01";
constexpr int kSignalSigtrap = 5; constexpr int kSignalSigtrap = 5;
constexpr char memory_map[] =
R"(l<?xml version="1.0"?>
<memory-map>
<!-- Based on memory.cc Initialize() -->
<memory type="ram" start="0x10000" length="0x3FFF0000"/>
<memory type="ram" start="0x40000000" length="0x3F000000"/>
<memory type="ram" start="0x80000000" length="0x10000000"/>
<memory type="ram" start="0x90000000" length="0x10000000"/>
<memory type="ram" start="0xA0000000" length="0x20000000"/>
<memory type="ram" start="0xC0000000" length="0x20000000"/>
<memory type="ram" start="0xE0000000" length="0x1FD00000"/>
</memory-map>
)";
// must start with l for debugger to accept it // must start with l for debugger to accept it
// TODO: add power-altivec.xml (and update ReadRegister to support it) // TODO: add power-altivec.xml (and update ReadRegister to support it)
constexpr char target_xml[] = constexpr char target_xml[] =
@ -228,9 +242,8 @@ std::string GDBStub::ReadRegister(xe::cpu::ThreadDebugInfo* thread,
} }
return u32_to_padded_hex(0); return u32_to_padded_hex(0);
} }
// msr?
case 65: case 65:
return std::string(8, 'x'); return u32_to_padded_hex((uint32_t)thread->guest_context.msr);
case 66: case 66:
return u32_to_padded_hex((uint32_t)thread->guest_context.cr()); return u32_to_padded_hex((uint32_t)thread->guest_context.cr());
case 67: case 67:
@ -242,7 +255,7 @@ std::string GDBStub::ReadRegister(xe::cpu::ThreadDebugInfo* thread,
return std::string(8, 'x'); return std::string(8, 'x');
// fpscr // fpscr
case 70: case 70:
return std::string(8, 'x'); return u32_to_padded_hex(thread->guest_context.fpscr.value);
default: default:
if (rid > 70) return ""; if (rid > 70) return "";
return (rid > 31) ? u64_to_padded_hex(*(uint64_t*)&( return (rid > 31) ? u64_to_padded_hex(*(uint64_t*)&(
@ -298,7 +311,7 @@ void GDBStub::Listen(std::unique_ptr<Socket>& client) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); 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<std::mutex> lock(mtx_); std::unique_lock<std::mutex> lock(mtx_);
if (cache_.notify_stopped) { if (cache_.notify_stopped) {
@ -349,6 +362,7 @@ std::string GetPacketFriendlyName(const std::string& packetCommand) {
{"qfThreadInfo", "qfThreadInfo"}, {"qfThreadInfo", "qfThreadInfo"},
{"qC", "GetThreadId"}, {"qC", "GetThreadId"},
{"D", "Detach"}, {"D", "Detach"},
{"k", "KillRequest"},
{"\03", "Break"}, {"\03", "Break"},
}; };
@ -557,6 +571,9 @@ std::string GDBStub::ExecutionPause() {
#ifdef DEBUG #ifdef DEBUG
debugging::DebugPrint("GDBStub: ExecutionPause\n"); debugging::DebugPrint("GDBStub: ExecutionPause\n");
#endif #endif
if (processor_->execution_state() != cpu::ExecutionState::kRunning) {
return kGdbReplyError;
}
processor_->Pause(); processor_->Pause();
return kGdbReplyOK; return kGdbReplyOK;
} }
@ -612,6 +629,8 @@ std::string GDBStub::ReadMemory(const std::string& data) {
return result; return result;
} }
std::string GDBStub::BuildMemoryMap() { return memory_map; }
std::string GDBStub::BuildTargetXml() { return target_xml; } std::string GDBStub::BuildTargetXml() { return target_xml; }
std::string GDBStub::BuildThreadList() { std::string GDBStub::BuildThreadList() {
@ -804,6 +823,9 @@ std::string GDBStub::HandleGDBCommand(const GDBCommand& command) {
// Detach // Detach
{"D", [&](const GDBCommand& cmd) { return DebuggerDetached(); }}, {"D", [&](const GDBCommand& cmd) { return DebuggerDetached(); }},
// Kill request (just treat as detach for now)
{"k", [&](const GDBCommand& cmd) { return DebuggerDetached(); }},
// Enable extended mode // Enable extended mode
{"!", [&](const GDBCommand& cmd) { return kGdbReplyOK; }}, {"!", [&](const GDBCommand& cmd) { return kGdbReplyOK; }},
@ -887,6 +909,8 @@ std::string GDBStub::HandleGDBCommand(const GDBCommand& command) {
auto sub_cmd = param.substr(0, param.find(':')); auto sub_cmd = param.substr(0, param.find(':'));
if (sub_cmd == "features") { if (sub_cmd == "features") {
return BuildTargetXml(); return BuildTargetXml();
} else if (sub_cmd == "memory-map") {
return BuildMemoryMap();
} else if (sub_cmd == "threads") { } else if (sub_cmd == "threads") {
return BuildThreadList(); return BuildThreadList();
} }
@ -895,7 +919,8 @@ std::string GDBStub::HandleGDBCommand(const GDBCommand& command) {
// Supported features (TODO: memory map) // Supported features (TODO: memory map)
{"qSupported", {"qSupported",
[&](const GDBCommand& cmd) { [&](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?) // Thread list (IDA requests this but ignores in favor of qXfer?)
{"qfThreadInfo", {"qfThreadInfo",

View File

@ -69,6 +69,7 @@ class GDBStub : public cpu::DebugListener {
std::string ExecutionContinue(); std::string ExecutionContinue();
std::string ExecutionStep(); std::string ExecutionStep();
std::string ReadMemory(const std::string& data); std::string ReadMemory(const std::string& data);
std::string BuildMemoryMap();
std::string BuildTargetXml(); std::string BuildTargetXml();
std::string BuildThreadList(); std::string BuildThreadList();