From 56669e34b72399dad62780302904b2044494bc7f Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 31 Oct 2021 23:25:35 -0700 Subject: [PATCH] dmnt2: add monitor get base, TODO responses for monitor wait * --- .../dmnt.gen2/source/dmnt2_debug_process.hpp | 3 +- .../source/dmnt2_gdb_server_impl.cpp | 60 ++++++++++++++++++- .../source/dmnt2_gdb_server_impl.hpp | 1 + 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/stratosphere/dmnt.gen2/source/dmnt2_debug_process.hpp b/stratosphere/dmnt.gen2/source/dmnt2_debug_process.hpp index f0c027e6f..4ab1e83d1 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_debug_process.hpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_debug_process.hpp @@ -80,7 +80,8 @@ namespace ams::dmnt { size_t GetModuleCount() const { return m_module_count; } size_t GetMainModuleIndex() const { return m_main_module; } const char *GetModuleName(size_t ix) const { return m_module_definitions[ix].GetName(); } - uintptr_t GetBaseAddress(size_t ix) const { return m_module_definitions[ix].GetAddress(); } + uintptr_t GetModuleBaseAddress(size_t ix) const { return m_module_definitions[ix].GetAddress(); } + uintptr_t GetModuleSize(size_t ix) const { return m_module_definitions[ix].GetSize(); } ProcessStatus GetStatus() const { return m_status; } os::ProcessId GetProcessId() const { return m_process_id; } diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp index d88c9a6e1..fd0683e34 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp @@ -1818,6 +1818,8 @@ namespace ams::dmnt { this->qAttached(); } else if (ParsePrefix(m_receive_packet, "qC")) { this->qC(); + } else if (ParsePrefix(m_receive_packet, "qRcmd,")) { + this->qRcmd(); } else if (ParsePrefix(m_receive_packet, "qSupported:")) { this->qSupported(); } else if (ParsePrefix(m_receive_packet, "qXfer:")) { @@ -1844,6 +1846,58 @@ namespace ams::dmnt { } } + void GdbServerImpl::qRcmd() { + /* Decode the command. */ + HexToMemory(m_buffer, m_receive_packet, std::strlen(m_receive_packet)); + + /* Convert our response to hex, on complete. */ + ON_SCOPE_EXIT { + /* Convert response to hex. */ + MemoryToHex(m_reply_packet, m_buffer, std::strlen(m_buffer)); + }; + + /* Parse the command. */ + char *command = reinterpret_cast(m_buffer); + if (ParsePrefix(command, "help")) { + SetReply(m_buffer, "get base\n" + "wait application\n" + "wait {program id}\n" + "wait homebrew\n"); + } else if (ParsePrefix(command, "get base") || ParsePrefix(command, "get modules")) { + SetReply(m_buffer, "Modules:\n"); + + if (!this->HasDebugProcess()) { + AppendReply(m_buffer, " [Not Attached]\n"); + return; + } + + /* Get the module list. */ + for (size_t i = 0; i < m_debug_process.GetModuleCount(); ++i) { + const char *module_name = m_debug_process.GetModuleName(i); + const auto name_len = std::strlen(module_name); + if (name_len < 5 || (std::strcmp(module_name + name_len - 4, ".elf") != 0 && std::strcmp(module_name + name_len - 4, ".nss") != 0)) { + AppendReply(m_buffer, " %p - %p %s.elf\n", reinterpret_cast(m_debug_process.GetModuleBaseAddress(i)), reinterpret_cast(m_debug_process.GetModuleBaseAddress(i) + m_debug_process.GetModuleSize(i) - 1), module_name); + } else { + AppendReply(m_buffer, " %p - %p %s\n", reinterpret_cast(m_debug_process.GetModuleBaseAddress(i)), reinterpret_cast(m_debug_process.GetModuleBaseAddress(i) + m_debug_process.GetModuleSize(i) - 1), module_name); + } + } + } else if (ParsePrefix(command, "wait application") || ParsePrefix(command, "wait app")) { + SetReply(m_buffer, "[TODO] wait for next application\n"); + } else if (ParsePrefix(command, "wait homebrew") || ParsePrefix(command, "wait hb")) { + SetReply(m_buffer, "[TODO] wait for next homebrew\n"); + } else if (ParsePrefix(command, "wait ")) { + /* Allow optional "0x" prefix. */ + ParsePrefix(command, "0x"); + + /* Decode program id. */ + const u64 program_id = DecodeHex(command); + + SetReply(m_buffer, "[TODO] wait for program id 0x%lx\n", program_id); + } else { + SetReply(m_buffer, "Unknown command `%s`\n", command); + } + } + void GdbServerImpl::qSupported() { /* Current string from devkita64-none-elf-gdb: */ /* qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+ */ @@ -1962,14 +2016,14 @@ namespace ams::dmnt { /* Get the module list. */ for (size_t i = 0; i < m_debug_process.GetModuleCount(); ++i) { - AMS_DMNT2_GDB_LOG_DEBUG("Module[%zu]: %p, %s\n", i, reinterpret_cast(m_debug_process.GetBaseAddress(i)), m_debug_process.GetModuleName(i)); + AMS_DMNT2_GDB_LOG_DEBUG("Module[%zu]: %p, %s\n", i, reinterpret_cast(m_debug_process.GetModuleBaseAddress(i)), m_debug_process.GetModuleName(i)); const char *module_name = m_debug_process.GetModuleName(i); const auto name_len = std::strlen(module_name); if (name_len < 5 || (std::strcmp(module_name + name_len - 4, ".elf") != 0 && std::strcmp(module_name + name_len - 4, ".nss") != 0)) { - AppendReply(g_annex_buffer, "", module_name, m_debug_process.GetBaseAddress(i)); + AppendReply(g_annex_buffer, "", module_name, m_debug_process.GetModuleBaseAddress(i)); } else { - AppendReply(g_annex_buffer, "", module_name, m_debug_process.GetBaseAddress(i)); + AppendReply(g_annex_buffer, "", module_name, m_debug_process.GetModuleBaseAddress(i)); } } diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp index ef467a7d1..d71cd2e0d 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp @@ -98,6 +98,7 @@ namespace ams::dmnt { void qAttached(); void qC(); + void qRcmd(); void qSupported(); void qXfer(); void qXferFeaturesRead();