summaryrefslogtreecommitdiffstats
path: root/src/core/arm/dynarmic/arm_dynarmic_64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/dynarmic/arm_dynarmic_64.cpp')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp38
1 files changed, 38 insertions, 0 deletions
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