Always set the sp reg to the cfa for DWARF.
There are a few places where it is assumed that this register is
set to the cfa value when interpreting DWARF information.
Add a testcase for unwinding art_quick_osr_stub on ARM.
Bug: 73954823
Test: Ran libunwindstack/libbacktrace unit tests.
Test: Random debuggerd -b of process on a hikey.
Test: Ran the 137 art test on host.
Change-Id: Ida6ccdc38c3cfeea6b57fe861a0cc127b150b790
diff --git a/libunwindstack/RegsMips64.cpp b/libunwindstack/RegsMips64.cpp
index 4a03538..8848e3b 100644
--- a/libunwindstack/RegsMips64.cpp
+++ b/libunwindstack/RegsMips64.cpp
@@ -29,13 +29,28 @@
namespace unwindstack {
RegsMips64::RegsMips64()
- : RegsImpl<uint64_t>(MIPS64_REG_LAST, MIPS64_REG_SP,
- Location(LOCATION_REGISTER, MIPS64_REG_RA)) {}
+ : RegsImpl<uint64_t>(MIPS64_REG_LAST, Location(LOCATION_REGISTER, MIPS64_REG_RA)) {}
ArchEnum RegsMips64::Arch() {
return ARCH_MIPS64;
}
+uint64_t RegsMips64::pc() {
+ return regs_[MIPS64_REG_PC];
+}
+
+uint64_t RegsMips64::sp() {
+ return regs_[MIPS64_REG_SP];
+}
+
+void RegsMips64::set_pc(uint64_t pc) {
+ regs_[MIPS64_REG_PC] = pc;
+}
+
+void RegsMips64::set_sp(uint64_t sp) {
+ regs_[MIPS64_REG_SP] = sp;
+}
+
uint64_t RegsMips64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) {
if (!elf->valid() || rel_pc < 8) {
return 0;
@@ -44,17 +59,13 @@
return 8;
}
-void RegsMips64::SetFromRaw() {
- set_pc(regs_[MIPS64_REG_PC]);
- set_sp(regs_[MIPS64_REG_SP]);
-}
-
bool RegsMips64::SetPcFromReturnAddress(Memory*) {
- if (pc() == regs_[MIPS64_REG_RA]) {
+ uint64_t ra = regs_[MIPS64_REG_RA];
+ if (regs_[MIPS64_REG_PC] == ra) {
return false;
}
- set_pc(regs_[MIPS64_REG_RA]);
+ regs_[MIPS64_REG_PC] = ra;
return true;
}
@@ -102,7 +113,6 @@
memcpy(regs->RawData(), &user->regs[MIPS64_EF_R0], (MIPS64_REG_R31 + 1) * sizeof(uint64_t));
reg_data[MIPS64_REG_PC] = user->regs[MIPS64_EF_CP0_EPC];
- regs->SetFromRaw();
return regs;
}
@@ -113,7 +123,6 @@
// Copy 64 bit sc_regs over to 64 bit regs
memcpy(regs->RawData(), &mips64_ucontext->uc_mcontext.sc_regs[0], 32 * sizeof(uint64_t));
(*regs)[MIPS64_REG_PC] = mips64_ucontext->uc_mcontext.sc_pc;
- regs->SetFromRaw();
return regs;
}
@@ -137,19 +146,17 @@
// vdso_rt_sigreturn => read rt_sigframe
// offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset
// read 64 bit sc_regs[32] from stack into 64 bit regs_
- if (!process_memory->Read(sp() + 24 + 128 + 40, regs_.data(),
+ uint64_t sp = regs_[MIPS64_REG_SP];
+ if (!process_memory->Read(sp + 24 + 128 + 40, regs_.data(),
sizeof(uint64_t) * (MIPS64_REG_LAST - 1))) {
return false;
}
// offset = siginfo offset + sizeof(siginfo) + uc_mcontext offset + sc_pc offset
// read 64 bit sc_pc from stack into 64 bit regs_[MIPS64_REG_PC]
- if (!process_memory->Read(sp() + 24 + 128 + 40 + 576, ®s_[MIPS64_REG_PC],
- sizeof(uint64_t))) {
+ if (!process_memory->Read(sp + 24 + 128 + 40 + 576, ®s_[MIPS64_REG_PC], sizeof(uint64_t))) {
return false;
}
-
- SetFromRaw();
return true;
}