From 705afe3c2a01d2559bc65e4e8d18b7d0ed9f6786 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Fri, 8 Jul 2022 06:57:27 +0200 Subject: [PATCH] early-access version 2822 --- README.md | 2 +- src/core/arm/arm_interface.cpp | 15 ++++++++++++ src/core/arm/dynarmic/arm_dynarmic_32.cpp | 30 +++++++++++++++++++---- src/core/arm/dynarmic/arm_dynarmic_32.h | 2 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 17 +++++++------ src/core/arm/dynarmic/arm_dynarmic_64.h | 2 +- 6 files changed, 52 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index bc5639317..34f51656a 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2821. +This is the source code for early-access 2822. ## Legal Notice diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 0efc3732f..cef79b245 100755 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -1,6 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#ifndef _MSC_VER +#include +#endif + #include #include #include "common/bit_field.h" @@ -68,8 +72,19 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vectorsecond, entry.offset); if (symbol.has_value()) { +#ifdef _MSC_VER // TODO(DarkLordZach): Add demangling of symbol names. entry.name = *symbol; +#else + int status{-1}; + char* demangled{abi::__cxa_demangle(symbol->c_str(), nullptr, nullptr, &status)}; + if (status == 0 && demangled != nullptr) { + entry.name = demangled; + std::free(demangled); + } else { + entry.name = *symbol; + } +#endif } } } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 9e31ff652..4dd4a6b43 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -434,18 +434,38 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, } std::vector ARM_Dynarmic_32::GetBacktrace(Core::System& system, - u64 sp, u64 lr) { - // No way to get accurate stack traces in A32 yet - return {}; + u64 fp, u64 lr, u64 pc) { + std::vector out; + auto& memory = system.Memory(); + + out.push_back({"", 0, pc, 0, ""}); + + // fp (= r11) points to the last frame record. + // Frame records are two words long: + // fp+0 : pointer to previous frame record + // fp+4 : value of lr for frame + while (true) { + out.push_back({"", 0, lr, 0, ""}); + if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) { + break; + } + lr = memory.Read32(fp + 4); + fp = memory.Read32(fp); + } + + SymbolicateBacktrace(system, out); + + return out; } std::vector ARM_Dynarmic_32::GetBacktraceFromContext( System& system, const ThreadContext32& ctx) { - return GetBacktrace(system, ctx.cpu_registers[13], ctx.cpu_registers[14]); + const auto& reg = ctx.cpu_registers; + return GetBacktrace(system, reg[11], reg[14], reg[15]); } std::vector ARM_Dynarmic_32::GetBacktrace() const { - return GetBacktrace(system, GetReg(13), GetReg(14)); + return GetBacktrace(system, GetReg(11), GetReg(14), GetReg(15)); } } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index fcbe24f0c..346e9abf8 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -78,7 +78,7 @@ protected: private: std::shared_ptr MakeJit(Common::PageTable* page_table) const; - static std::vector GetBacktrace(Core::System& system, u64 sp, u64 lr); + static std::vector GetBacktrace(Core::System& system, u64 fp, u64 lr, u64 pc); using JitCacheKey = std::pair; using JitCacheType = diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 680aa24e9..3bdccea74 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -501,22 +501,22 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table, } std::vector ARM_Dynarmic_64::GetBacktrace(Core::System& system, - u64 fp, u64 lr) { + u64 fp, u64 lr, u64 pc) { std::vector out; auto& memory = system.Memory(); - // fp (= r29) points to the last frame record. - // Note that this is the frame record for the *previous* frame, not the current one. - // Note we need to subtract 4 from our last read to get the proper address + out.push_back({"", 0, pc, 0, ""}); + + // fp (= x29) points to the previous frame record. // Frame records are two words long: // fp+0 : pointer to previous frame record // fp+8 : value of lr for frame while (true) { out.push_back({"", 0, lr, 0, ""}); - if (!fp) { + if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) { break; } - lr = memory.Read64(fp + 8) - 4; + lr = memory.Read64(fp + 8); fp = memory.Read64(fp); } @@ -527,11 +527,12 @@ std::vector ARM_Dynarmic_64::GetBacktrace(Core::S std::vector ARM_Dynarmic_64::GetBacktraceFromContext( System& system, const ThreadContext64& ctx) { - return GetBacktrace(system, ctx.cpu_registers[29], ctx.cpu_registers[30]); + const auto& reg = ctx.cpu_registers; + return GetBacktrace(system, reg[29], reg[30], ctx.pc); } std::vector ARM_Dynarmic_64::GetBacktrace() const { - return GetBacktrace(system, GetReg(29), GetReg(30)); + return GetBacktrace(system, GetReg(29), GetReg(30), GetPC()); } } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 71dbaac5e..c77a83ad7 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -73,7 +73,7 @@ private: std::shared_ptr MakeJit(Common::PageTable* page_table, std::size_t address_space_bits) const; - static std::vector GetBacktrace(Core::System& system, u64 fp, u64 lr); + static std::vector GetBacktrace(Core::System& system, u64 fp, u64 lr, u64 pc); using JitCacheKey = std::pair; using JitCacheType =