From 117546c7c81dcc182ab1a5b0ae96cc8c79b8bbaf Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 25 Jul 2025 02:49:06 +0100 Subject: [PATCH] [dynarmic] separate abi functors (win/nix) and impl aliases for gdb commands & document them --- docs/Development.md | 14 ++-- .../dynarmic/src/dynarmic/backend/x64/abi.cpp | 28 ++++--- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 9 +-- src/core/debugger/gdbstub.cpp | 79 ++++++++----------- 4 files changed, 59 insertions(+), 71 deletions(-) diff --git a/docs/Development.md b/docs/Development.md index 4f17bf6977..61391364f1 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -1,11 +1,11 @@ # Development -* **Windows**: [Windows Building Guide](./docs/build/Windows.md) -* **Linux**: [Linux Building Guide](./docs/build/Linux.md) -* **Android**: [Android Building Guide](./docs/build/Android.md) -* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./docs/build/macOS.md) +* **Windows**: [Windows Building Guide](./build/Windows.md) +* **Linux**: [Linux Building Guide](./build/Linux.md) +* **Android**: [Android Building Guide](./build/Android.md) +* **Solaris**: [Solaris Building Guide](./build/Solaris.md) +* **FreeBSD**: [FreeBSD Building Guide](./build/FreeBSD.md) +* **macOS**: [macOS Building Guide](./build/macOS.md) # Building speedup @@ -31,7 +31,7 @@ Then type `target remote localhost:1234` and type `c` (for continue) - and then ### gdb cheatsheet -- `mo `: Monitor commands, `get info`, `get fastmem` and `get mappings` are available. +- `mo `: Monitor commands, `get info`, `get fastmem` and `get mappings` are available. Type `mo help` for more info. - `detach`: Detach from remote (i.e restarting the emulator). - `c`: Continue - `p `: Print variable, `p/x ` for hexadecimal. diff --git a/externals/dynarmic/src/dynarmic/backend/x64/abi.cpp b/externals/dynarmic/src/dynarmic/backend/x64/abi.cpp index e8eaddcbac..235e2e227d 100644 --- a/externals/dynarmic/src/dynarmic/backend/x64/abi.cpp +++ b/externals/dynarmic/src/dynarmic/backend/x64/abi.cpp @@ -119,6 +119,20 @@ void ABI_PopCallerSaveRegistersAndAdjustStack(BlockOfCode& code, const std::size ABI_PopRegistersAndAdjustStack(code, frame_size, ABI_ALL_CALLER_SAVE); } +// Windows ABI registers are not in the same allocation algorithm as unix's +#ifdef _MSC_VER +void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { + std::vector regs; + std::remove_copy(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end(), std::back_inserter(regs), exception); + ABI_PushRegistersAndAdjustStack(code, 0, regs); +} + +void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { + std::vector regs; + std::remove_copy(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end(), std::back_inserter(regs), exception); + ABI_PopRegistersAndAdjustStack(code, 0, regs); +} +#else static consteval size_t ABI_AllCallerSaveSize() noexcept { return ABI_ALL_CALLER_SAVE.max_size(); } @@ -166,24 +180,14 @@ alignas(64) static constinit std::array AB }; void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { -#ifdef _MSC_VER - std::vector regs; - std::remove_copy(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end(), std::back_inserter(regs), exception); - ABI_PushRegistersAndAdjustStack(code, 0, regs); -#else ASSUME(size_t(exception) < 32); ABI_PushRegistersAndAdjustStack(code, 0, ABI_CALLER_SAVED_EXCEPT_TABLE[size_t(exception)]); -#endif } void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, const HostLoc exception) { -#ifdef _MSC_VER - std::vector regs; - std::remove_copy(ABI_ALL_CALLER_SAVE.begin(), ABI_ALL_CALLER_SAVE.end(), std::back_inserter(regs), exception); - ABI_PopRegistersAndAdjustStack(code, 0, regs); -#else ASSUME(size_t(exception) < 32); ABI_PopRegistersAndAdjustStack(code, 0, ABI_CALLER_SAVED_EXCEPT_TABLE[size_t(exception)]); -#endif } +#endif + } // namespace Dynarmic::Backend::X64 diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 99a80644ad..2a388d4cd9 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -136,6 +136,7 @@ public: case Dynarmic::A64::Exception::SendEvent: case Dynarmic::A64::Exception::SendEventLocal: case Dynarmic::A64::Exception::Yield: + LOG_TRACE(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", static_cast(exception), pc, m_memory.Read32(pc)); return; case Dynarmic::A64::Exception::NoExecuteFault: LOG_CRITICAL(Core_ARM, "Cannot execute instruction at unmapped address {:#016x}", pc); @@ -144,12 +145,10 @@ public: default: if (m_debugger_enabled) { ReturnException(pc, InstructionBreakpoint); - return; + } else { + m_parent.LogBacktrace(m_process); + LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", static_cast(exception), pc, m_memory.Read32(pc)); } - - m_parent.LogBacktrace(m_process); - LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", - static_cast(exception), pc, m_memory.Read32(pc)); } } diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 80091cc7e0..fcb5787147 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -554,32 +554,31 @@ void GDBStub::HandleVCont(std::string_view command, std::vector& } } -constexpr std::array, 22> MemoryStateNames{{ - {"----- Free ------", Kernel::Svc::MemoryState::Free}, - {"Io ", Kernel::Svc::MemoryState::Io}, - {"Static ", Kernel::Svc::MemoryState::Static}, - {"Code ", Kernel::Svc::MemoryState::Code}, - {"CodeData ", Kernel::Svc::MemoryState::CodeData}, - {"Normal ", Kernel::Svc::MemoryState::Normal}, - {"Shared ", Kernel::Svc::MemoryState::Shared}, - {"AliasCode ", Kernel::Svc::MemoryState::AliasCode}, - {"AliasCodeData ", Kernel::Svc::MemoryState::AliasCodeData}, - {"Ipc ", Kernel::Svc::MemoryState::Ipc}, - {"Stack ", Kernel::Svc::MemoryState::Stack}, - {"ThreadLocal ", Kernel::Svc::MemoryState::ThreadLocal}, - {"Transferred ", Kernel::Svc::MemoryState::Transferred}, - {"SharedTransferred", Kernel::Svc::MemoryState::SharedTransferred}, - {"SharedCode ", Kernel::Svc::MemoryState::SharedCode}, - {"Inaccessible ", Kernel::Svc::MemoryState::Inaccessible}, - {"NonSecureIpc ", Kernel::Svc::MemoryState::NonSecureIpc}, - {"NonDeviceIpc ", Kernel::Svc::MemoryState::NonDeviceIpc}, - {"Kernel ", Kernel::Svc::MemoryState::Kernel}, - {"GeneratedCode ", Kernel::Svc::MemoryState::GeneratedCode}, - {"CodeOut ", Kernel::Svc::MemoryState::CodeOut}, - {"Coverage ", Kernel::Svc::MemoryState::Coverage}, -}}; - static constexpr const char* GetMemoryStateName(Kernel::Svc::MemoryState state) { + constexpr std::array, 22> MemoryStateNames{{ + {"----- Free ------", Kernel::Svc::MemoryState::Free}, + {"Io ", Kernel::Svc::MemoryState::Io}, + {"Static ", Kernel::Svc::MemoryState::Static}, + {"Code ", Kernel::Svc::MemoryState::Code}, + {"CodeData ", Kernel::Svc::MemoryState::CodeData}, + {"Normal ", Kernel::Svc::MemoryState::Normal}, + {"Shared ", Kernel::Svc::MemoryState::Shared}, + {"AliasCode ", Kernel::Svc::MemoryState::AliasCode}, + {"AliasCodeData ", Kernel::Svc::MemoryState::AliasCodeData}, + {"Ipc ", Kernel::Svc::MemoryState::Ipc}, + {"Stack ", Kernel::Svc::MemoryState::Stack}, + {"ThreadLocal ", Kernel::Svc::MemoryState::ThreadLocal}, + {"Transferred ", Kernel::Svc::MemoryState::Transferred}, + {"SharedTransferred", Kernel::Svc::MemoryState::SharedTransferred}, + {"SharedCode ", Kernel::Svc::MemoryState::SharedCode}, + {"Inaccessible ", Kernel::Svc::MemoryState::Inaccessible}, + {"NonSecureIpc ", Kernel::Svc::MemoryState::NonSecureIpc}, + {"NonDeviceIpc ", Kernel::Svc::MemoryState::NonDeviceIpc}, + {"Kernel ", Kernel::Svc::MemoryState::Kernel}, + {"GeneratedCode ", Kernel::Svc::MemoryState::GeneratedCode}, + {"CodeOut ", Kernel::Svc::MemoryState::CodeOut}, + {"Coverage ", Kernel::Svc::MemoryState::Coverage}, + }}; for (size_t i = 0; i < MemoryStateNames.size(); i++) { if (std::get<1>(MemoryStateNames[i]) == state) { return std::get<0>(MemoryStateNames[i]); @@ -611,13 +610,7 @@ void GDBStub::HandleRcmd(const std::vector& command) { auto* process = GetProcess(); auto& page_table = process->GetPageTable(); - - const char* commands = "Commands:\n" - " get fastmem\n" - " get info\n" - " get mappings\n"; - - if (command_str == "get fastmem") { + if (command_str == "fastmem" || command_str == "get fastmem") { if (Settings::IsFastmemEnabled()) { const auto& impl = page_table.GetImpl(); const auto region = reinterpret_cast(impl.fastmem_arena); @@ -630,7 +623,7 @@ void GDBStub::HandleRcmd(const std::vector& command) { } else { reply = "Fastmem is not enabled.\n"; } - } else if (command_str == "get info") { + } else if (command_str == "info" || command_str == "get info") { auto modules = Core::FindModules(process); reply = fmt::format("Process: {:#x} ({})\n" @@ -648,8 +641,7 @@ void GDBStub::HandleRcmd(const std::vector& command) { GetInteger(page_table.GetHeapRegionStart()), GetInteger(page_table.GetHeapRegionStart()) + page_table.GetHeapRegionSize() - 1, GetInteger(page_table.GetAliasCodeRegionStart()), - GetInteger(page_table.GetAliasCodeRegionStart()) + page_table.GetAliasCodeRegionSize() - - 1, + GetInteger(page_table.GetAliasCodeRegionStart()) + page_table.GetAliasCodeRegionSize() - 1, GetInteger(page_table.GetStackRegionStart()), GetInteger(page_table.GetStackRegionStart()) + page_table.GetStackRegionSize() - 1); @@ -657,7 +649,7 @@ void GDBStub::HandleRcmd(const std::vector& command) { reply += fmt::format(" {:#012x} - {:#012x} {}\n", vaddr, GetInteger(Core::GetModuleEnd(process, vaddr)), name); } - } else if (command_str == "get mappings") { + } else if (command_str == "mappings" || command_str == "get mappings") { reply = "Mappings:\n"; VAddr cur_addr = 0; @@ -675,15 +667,11 @@ void GDBStub::HandleRcmd(const std::vector& command) { std::numeric_limits::max()) { const char* state = GetMemoryStateName(svc_mem_info.state); const char* perm = GetMemoryPermissionString(svc_mem_info); - const char l = True(svc_mem_info.attribute & MemoryAttribute::Locked) ? 'L' : '-'; - const char i = - True(svc_mem_info.attribute & MemoryAttribute::IpcLocked) ? 'I' : '-'; - const char d = - True(svc_mem_info.attribute & MemoryAttribute::DeviceShared) ? 'D' : '-'; + const char i = True(svc_mem_info.attribute & MemoryAttribute::IpcLocked) ? 'I' : '-'; + const char d = True(svc_mem_info.attribute & MemoryAttribute::DeviceShared) ? 'D' : '-'; const char u = True(svc_mem_info.attribute & MemoryAttribute::Uncached) ? 'U' : '-'; - const char p = - True(svc_mem_info.attribute & MemoryAttribute::PermissionLocked) ? 'P' : '-'; + const char p =True(svc_mem_info.attribute & MemoryAttribute::PermissionLocked) ? 'P' : '-'; reply += fmt::format( " {:#012x} - {:#012x} {} {} {}{}{}{}{} [{}, {}]\n", svc_mem_info.base_address, @@ -698,11 +686,8 @@ void GDBStub::HandleRcmd(const std::vector& command) { cur_addr = next_address; } - } else if (command_str == "help") { - reply = commands; } else { - reply = "Unknown command.\n"; - reply += commands; + reply += "Commands: fastmem, info, mappings\n"; } std::span reply_span{reinterpret_cast(&reply.front()), reply.size()};