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
(cherry picked from commit 11e96fe48a74e6ab97d4de899684d3a61a9d1129)
diff --git a/libunwindstack/RegsMips.cpp b/libunwindstack/RegsMips.cpp
index 5d20bef..0b10e21 100644
--- a/libunwindstack/RegsMips.cpp
+++ b/libunwindstack/RegsMips.cpp
@@ -29,12 +29,28 @@
namespace unwindstack {
RegsMips::RegsMips()
- : RegsImpl<uint32_t>(MIPS_REG_LAST, MIPS_REG_SP, Location(LOCATION_REGISTER, MIPS_REG_RA)) {}
+ : RegsImpl<uint32_t>(MIPS_REG_LAST, Location(LOCATION_REGISTER, MIPS_REG_RA)) {}
ArchEnum RegsMips::Arch() {
return ARCH_MIPS;
}
+uint64_t RegsMips::pc() {
+ return regs_[MIPS_REG_PC];
+}
+
+uint64_t RegsMips::sp() {
+ return regs_[MIPS_REG_SP];
+}
+
+void RegsMips::set_pc(uint64_t pc) {
+ regs_[MIPS_REG_PC] = static_cast<uint32_t>(pc);
+}
+
+void RegsMips::set_sp(uint64_t sp) {
+ regs_[MIPS_REG_SP] = static_cast<uint32_t>(sp);
+}
+
uint64_t RegsMips::GetPcAdjustment(uint64_t rel_pc, Elf* elf) {
if (!elf->valid() || rel_pc < 8) {
return 0;
@@ -43,17 +59,13 @@
return 8;
}
-void RegsMips::SetFromRaw() {
- set_pc(regs_[MIPS_REG_PC]);
- set_sp(regs_[MIPS_REG_SP]);
-}
-
bool RegsMips::SetPcFromReturnAddress(Memory*) {
- if (pc() == regs_[MIPS_REG_RA]) {
+ uint32_t ra = regs_[MIPS_REG_RA];
+ if (regs_[MIPS_REG_PC] == ra) {
return false;
}
- set_pc(regs_[MIPS_REG_RA]);
+ regs_[MIPS_REG_PC] = ra;
return true;
}
@@ -101,7 +113,6 @@
memcpy(regs->RawData(), &user->regs[MIPS32_EF_R0], (MIPS_REG_R31 + 1) * sizeof(uint32_t));
reg_data[MIPS_REG_PC] = user->regs[MIPS32_EF_CP0_EPC];
- regs->SetFromRaw();
return regs;
}
@@ -114,7 +125,6 @@
(*regs)[MIPS_REG_R0 + i] = mips_ucontext->uc_mcontext.sc_regs[i];
}
(*regs)[MIPS_REG_PC] = mips_ucontext->uc_mcontext.sc_pc;
- regs->SetFromRaw();
return regs;
}
@@ -149,7 +159,7 @@
// read sc_pc and sc_regs[32] from stack
uint64_t values[MIPS_REG_LAST];
- if (!process_memory->Read(sp() + offset, values, sizeof(values))) {
+ if (!process_memory->Read(regs_[MIPS_REG_SP] + offset, values, sizeof(values))) {
return false;
}
@@ -160,8 +170,6 @@
for (int i = 0; i < 32; i++) {
regs_[MIPS_REG_R0 + i] = values[1 + i];
}
-
- SetFromRaw();
return true;
}