diff options
| author | 2022-04-20 20:17:48 -0400 | |
|---|---|---|
| committer | 2022-04-20 21:39:42 -0400 | |
| commit | 0ca4dff62c61570828ec563d6200ca47b3d02569 (patch) | |
| tree | 506ade8f6772141c95261168f8ae8f3b71ffbf3a /src/core/arm/dynarmic | |
| parent | Update dynarmic (diff) | |
| download | yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.gz yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.tar.xz yuzu-0ca4dff62c61570828ec563d6200ca47b3d02569.zip | |
core/arm: separate backtrace collection
Diffstat (limited to 'src/core/arm/dynarmic')
| -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 { | |||
| 268 | return jit.load()->Regs()[15]; | 268 | return jit.load()->Regs()[15]; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | u64 ARM_Dynarmic_32::GetSP() const { | ||
| 272 | return jit.load()->Regs()[13]; | ||
| 273 | } | ||
| 274 | |||
| 271 | u64 ARM_Dynarmic_32::GetReg(int index) const { | 275 | u64 ARM_Dynarmic_32::GetReg(int index) const { |
| 272 | return jit.load()->Regs()[index]; | 276 | return jit.load()->Regs()[index]; |
| 273 | } | 277 | } |
| @@ -362,4 +366,19 @@ void ARM_Dynarmic_32::PageTableChanged(Common::PageTable& page_table, | |||
| 362 | jit_cache.emplace(key, std::move(new_jit)); | 366 | jit_cache.emplace(key, std::move(new_jit)); |
| 363 | } | 367 | } |
| 364 | 368 | ||
| 369 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::System& system, | ||
| 370 | u64 sp, u64 lr) { | ||
| 371 | // No way to get accurate stack traces in A32 yet | ||
| 372 | return {}; | ||
| 373 | } | ||
| 374 | |||
| 375 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktraceFromContext( | ||
| 376 | System& system, const ThreadContext32& ctx) { | ||
| 377 | return GetBacktrace(system, ctx.cpu_registers[13], ctx.cpu_registers[14]); | ||
| 378 | } | ||
| 379 | |||
| 380 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace() const { | ||
| 381 | return GetBacktrace(system, GetReg(13), GetReg(14)); | ||
| 382 | } | ||
| 383 | |||
| 365 | } // namespace Core | 384 | } // 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: | |||
| 35 | 35 | ||
| 36 | void SetPC(u64 pc) override; | 36 | void SetPC(u64 pc) override; |
| 37 | u64 GetPC() const override; | 37 | u64 GetPC() const override; |
| 38 | u64 GetSP() const override; | ||
| 38 | u64 GetReg(int index) const override; | 39 | u64 GetReg(int index) const override; |
| 39 | void SetReg(int index, u64 value) override; | 40 | void SetReg(int index, u64 value) override; |
| 40 | u128 GetVectorReg(int index) const override; | 41 | u128 GetVectorReg(int index) const override; |
| @@ -66,9 +67,16 @@ public: | |||
| 66 | void PageTableChanged(Common::PageTable& new_page_table, | 67 | void PageTableChanged(Common::PageTable& new_page_table, |
| 67 | std::size_t new_address_space_size_in_bits) override; | 68 | std::size_t new_address_space_size_in_bits) override; |
| 68 | 69 | ||
| 70 | static std::vector<BacktraceEntry> GetBacktraceFromContext(System& system, | ||
| 71 | const ThreadContext32& ctx); | ||
| 72 | |||
| 73 | std::vector<BacktraceEntry> GetBacktrace() const override; | ||
| 74 | |||
| 69 | private: | 75 | private: |
| 70 | std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; | 76 | std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; |
| 71 | 77 | ||
| 78 | static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 sp, u64 lr); | ||
| 79 | |||
| 72 | using JitCacheKey = std::pair<Common::PageTable*, std::size_t>; | 80 | using JitCacheKey = std::pair<Common::PageTable*, std::size_t>; |
| 73 | using JitCacheType = | 81 | using JitCacheType = |
| 74 | std::unordered_map<JitCacheKey, std::shared_ptr<Dynarmic::A32::Jit>, Common::PairHash>; | 82 | 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 { | |||
| 328 | return jit.load()->GetPC(); | 328 | return jit.load()->GetPC(); |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | u64 ARM_Dynarmic_64::GetSP() const { | ||
| 332 | return jit.load()->GetSP(); | ||
| 333 | } | ||
| 334 | |||
| 331 | u64 ARM_Dynarmic_64::GetReg(int index) const { | 335 | u64 ARM_Dynarmic_64::GetReg(int index) const { |
| 332 | return jit.load()->GetRegister(index); | 336 | return jit.load()->GetRegister(index); |
| 333 | } | 337 | } |
| @@ -430,4 +434,38 @@ void ARM_Dynarmic_64::PageTableChanged(Common::PageTable& page_table, | |||
| 430 | jit_cache.emplace(key, std::move(new_jit)); | 434 | jit_cache.emplace(key, std::move(new_jit)); |
| 431 | } | 435 | } |
| 432 | 436 | ||
| 437 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::System& system, | ||
| 438 | u64 fp, u64 lr) { | ||
| 439 | std::vector<BacktraceEntry> out; | ||
| 440 | auto& memory = system.Memory(); | ||
| 441 | |||
| 442 | // fp (= r29) points to the last frame record. | ||
| 443 | // Note that this is the frame record for the *previous* frame, not the current one. | ||
| 444 | // Note we need to subtract 4 from our last read to get the proper address | ||
| 445 | // Frame records are two words long: | ||
| 446 | // fp+0 : pointer to previous frame record | ||
| 447 | // fp+8 : value of lr for frame | ||
| 448 | while (true) { | ||
| 449 | out.push_back({"", 0, lr, 0, ""}); | ||
| 450 | if (!fp) { | ||
| 451 | break; | ||
| 452 | } | ||
| 453 | lr = memory.Read64(fp + 8) - 4; | ||
| 454 | fp = memory.Read64(fp); | ||
| 455 | } | ||
| 456 | |||
| 457 | SymbolicateBacktrace(system, out); | ||
| 458 | |||
| 459 | return out; | ||
| 460 | } | ||
| 461 | |||
| 462 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktraceFromContext( | ||
| 463 | System& system, const ThreadContext64& ctx) { | ||
| 464 | return GetBacktrace(system, ctx.cpu_registers[29], ctx.cpu_registers[30]); | ||
| 465 | } | ||
| 466 | |||
| 467 | std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace() const { | ||
| 468 | return GetBacktrace(system, GetReg(29), GetReg(30)); | ||
| 469 | } | ||
| 470 | |||
| 433 | } // namespace Core | 471 | } // 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: | |||
| 33 | 33 | ||
| 34 | void SetPC(u64 pc) override; | 34 | void SetPC(u64 pc) override; |
| 35 | u64 GetPC() const override; | 35 | u64 GetPC() const override; |
| 36 | u64 GetSP() const override; | ||
| 36 | u64 GetReg(int index) const override; | 37 | u64 GetReg(int index) const override; |
| 37 | void SetReg(int index, u64 value) override; | 38 | void SetReg(int index, u64 value) override; |
| 38 | u128 GetVectorReg(int index) const override; | 39 | u128 GetVectorReg(int index) const override; |
| @@ -60,10 +61,17 @@ public: | |||
| 60 | void PageTableChanged(Common::PageTable& new_page_table, | 61 | void PageTableChanged(Common::PageTable& new_page_table, |
| 61 | std::size_t new_address_space_size_in_bits) override; | 62 | std::size_t new_address_space_size_in_bits) override; |
| 62 | 63 | ||
| 64 | static std::vector<BacktraceEntry> GetBacktraceFromContext(System& system, | ||
| 65 | const ThreadContext64& ctx); | ||
| 66 | |||
| 67 | std::vector<BacktraceEntry> GetBacktrace() const override; | ||
| 68 | |||
| 63 | private: | 69 | private: |
| 64 | std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, | 70 | std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, |
| 65 | std::size_t address_space_bits) const; | 71 | std::size_t address_space_bits) const; |
| 66 | 72 | ||
| 73 | static std::vector<BacktraceEntry> GetBacktrace(Core::System& system, u64 fp, u64 lr); | ||
| 74 | |||
| 67 | using JitCacheKey = std::pair<Common::PageTable*, std::size_t>; | 75 | using JitCacheKey = std::pair<Common::PageTable*, std::size_t>; |
| 68 | using JitCacheType = | 76 | using JitCacheType = |
| 69 | std::unordered_map<JitCacheKey, std::shared_ptr<Dynarmic::A64::Jit>, Common::PairHash>; | 77 | std::unordered_map<JitCacheKey, std::shared_ptr<Dynarmic::A64::Jit>, Common::PairHash>; |