diff options
author | Liam <byteslice@airmail.cc> | 2022-04-21 02:17:48 +0200 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2022-04-21 03:39:42 +0200 |
commit | 0ca4dff62c61570828ec563d6200ca47b3d02569 (patch) | |
tree | 506ade8f6772141c95261168f8ae8f3b71ffbf3a /src/core/arm/dynarmic | |
parent | Update dynarmic (diff) | |
download | yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.gz yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.bz2 yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.lz yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.xz yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.zst yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.zip |
Diffstat (limited to '')
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 19 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.h | 8 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 38 | ||||
-rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 8 |
4 files changed, 73 insertions, 0 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 5de4384db..da5659046 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -268,6 +268,10 @@ u64 ARM_Dynarmic_32::GetPC() const { return jit.load()->Regs()[15]; } +u64 ARM_Dynarmic_32::GetSP() const { + return jit.load()->Regs()[13]; +} + u64 ARM_Dynarmic_32::GetReg(int index) const { return jit.load()->Regs()[index]; } @@ -362,4 +366,19 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, jit_cache.emplace(key, std::move(new_jit)); } +std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system, + u64 sp, u64 lr) { + // No way to get accurate stack traces in A32 yet + return {}; +} + +std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktraceFromContext( + System& system, const ThreadContext32& ctx) { + return GetBacktrace(system, ctx.cpu_registers[13], ctx.cpu_registers[14]); +} + +std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace() const { + return GetBacktrace(system, GetReg(13), GetReg(14)); +} + } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 684937353..1b628f94d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h @@ -35,6 +35,7 @@ public: void SetPC(u64 pc) override; u64 GetPC() const override; + u64 GetSP() const override; u64 GetReg(int index) const override; void SetReg(int index, u64 value) override; u128 GetVectorReg(int index) const override; @@ -66,9 +67,16 @@ public: void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; + static std::vector<BacktraceEntry> GetBacktraceFromContext(System& system, + const ThreadContext32& ctx); + + std::vector<BacktraceEntry> GetBacktrace() const override; + private: std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; + static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 sp, u64 lr); + using JitCacheKey = std::pair<Common::PageTable*, std::size_t>; using JitCacheType = std::unordered_map<JitCacheKey, std::shared_ptr<Dynarmic::A32::Jit>, Common::PairHash>; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index ae0b158c2..871d9d10e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -328,6 +328,10 @@ u64 ARM_Dynarmic_64::GetPC() const { return jit.load()->GetPC(); } +u64 ARM_Dynarmic_64::GetSP() const { + return jit.load()->GetSP(); +} + u64 ARM_Dynarmic_64::GetReg(int index) const { return jit.load()->GetRegister(index); } @@ -430,4 +434,38 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table, jit_cache.emplace(key, std::move(new_jit)); } +std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system, + u64 fp, u64 lr) { + std::vector<BacktraceEntry> 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 + // 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) { + break; + } + lr = memory.Read64(fp + 8) - 4; + fp = memory.Read64(fp); + } + + SymbolicateBacktrace(system, out); + + return out; +} + +std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktraceFromContext( + System& system, const ThreadContext64& ctx) { + return GetBacktrace(system, ctx.cpu_registers[29], ctx.cpu_registers[30]); +} + +std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace() const { + return GetBacktrace(system, GetReg(29), GetReg(30)); +} + } // namespace Core diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 86018f196..78773e293 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h @@ -33,6 +33,7 @@ public: void SetPC(u64 pc) override; u64 GetPC() const override; + u64 GetSP() const override; u64 GetReg(int index) const override; void SetReg(int index, u64 value) override; u128 GetVectorReg(int index) const override; @@ -60,10 +61,17 @@ public: void PageTableChanged(Common::PageTable& new_page_table, std::size_t new_address_space_size_in_bits) override; + static std::vector<BacktraceEntry> GetBacktraceFromContext(System& system, + const ThreadContext64& ctx); + + std::vector<BacktraceEntry> GetBacktrace() const override; + private: std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, std::size_t address_space_bits) const; + static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 fp, u64 lr); + using JitCacheKey = std::pair<Common::PageTable*, std::size_t>; using JitCacheType = std::unordered_map<JitCacheKey, std::shared_ptr<Dynarmic::A64::Jit>, Common::PairHash>; |