summaryrefslogtreecommitdiff
path: root/src/core/arm/dynarmic
diff options
context:
space:
mode:
authorGravatar Liam2022-04-20 20:17:48 -0400
committerGravatar Liam2022-04-20 21:39:42 -0400
commit0ca4dff62c61570828ec563d6200ca47b3d02569 (patch)
tree506ade8f6772141c95261168f8ae8f3b71ffbf3a /src/core/arm/dynarmic
parentUpdate dynarmic (diff)
downloadyuzu-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.cpp19
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp38
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h8
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
271u64 ARM_Dynarmic_32::GetSP() const {
272 return jit.load()->Regs()[13];
273}
274
271u64 ARM_Dynarmic_32::GetReg(int index) const { 275u64 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
369std::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
375std::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
380std::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
69private: 75private:
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
331u64 ARM_Dynarmic_64::GetSP() const {
332 return jit.load()->GetSP();
333}
334
331u64 ARM_Dynarmic_64::GetReg(int index) const { 335u64 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
437std::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
462std::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
467std::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
63private: 69private:
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>;