summaryrefslogtreecommitdiffstats
path: root/libunwindstack/RegsArm64.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2018-03-14 18:16:22 -0700
committerChristopher Ferris <cferris@google.com>2018-03-16 23:38:07 -0700
commit11e96fe48a74e6ab97d4de899684d3a61a9d1129 (patch)
tree6a056073b680ed6fe25fb406e5f2b316b991ee3e /libunwindstack/RegsArm64.cpp
parenta411fc65d1fc4c2c1c44d5d0860b31a018b8c9fd (diff)
downloadsystem_core-11e96fe48a74e6ab97d4de899684d3a61a9d1129.tar.gz
system_core-11e96fe48a74e6ab97d4de899684d3a61a9d1129.tar.bz2
system_core-11e96fe48a74e6ab97d4de899684d3a61a9d1129.zip
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
Diffstat (limited to 'libunwindstack/RegsArm64.cpp')
-rw-r--r--libunwindstack/RegsArm64.cpp34
1 files changed, 21 insertions, 13 deletions
diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp
index cc6f5ce87..fe24c802c 100644
--- a/libunwindstack/RegsArm64.cpp
+++ b/libunwindstack/RegsArm64.cpp
@@ -29,12 +29,28 @@
namespace unwindstack {
RegsArm64::RegsArm64()
- : RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
+ : RegsImpl<uint64_t>(ARM64_REG_LAST, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
ArchEnum RegsArm64::Arch() {
return ARCH_ARM64;
}
+uint64_t RegsArm64::pc() {
+ return regs_[ARM64_REG_PC];
+}
+
+uint64_t RegsArm64::sp() {
+ return regs_[ARM64_REG_SP];
+}
+
+void RegsArm64::set_pc(uint64_t pc) {
+ regs_[ARM64_REG_PC] = pc;
+}
+
+void RegsArm64::set_sp(uint64_t sp) {
+ regs_[ARM64_REG_SP] = sp;
+}
+
uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) {
if (!elf->valid() || rel_pc < 4) {
return 0;
@@ -42,17 +58,13 @@ uint64_t RegsArm64::GetPcAdjustment(uint64_t rel_pc, Elf* elf) {
return 4;
}
-void RegsArm64::SetFromRaw() {
- set_pc(regs_[ARM64_REG_PC]);
- set_sp(regs_[ARM64_REG_SP]);
-}
-
bool RegsArm64::SetPcFromReturnAddress(Memory*) {
- if (pc() == regs_[ARM64_REG_LR]) {
+ uint64_t lr = regs_[ARM64_REG_LR];
+ if (regs_[ARM64_REG_PC] == lr) {
return false;
}
- set_pc(regs_[ARM64_REG_LR]);
+ regs_[ARM64_REG_PC] = lr;
return true;
}
@@ -100,7 +112,6 @@ Regs* RegsArm64::Read(void* remote_data) {
uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
reg_data[ARM64_REG_PC] = user->pc;
reg_data[ARM64_REG_SP] = user->sp;
- regs->SetFromRaw();
return regs;
}
@@ -109,7 +120,6 @@ Regs* RegsArm64::CreateFromUcontext(void* ucontext) {
RegsArm64* regs = new RegsArm64();
memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t));
- regs->SetFromRaw();
return regs;
}
@@ -131,12 +141,10 @@ bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_m
}
// SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset.
- if (!process_memory->ReadFully(sp() + 0x80 + 0xb0 + 0x08, regs_.data(),
+ if (!process_memory->ReadFully(regs_[ARM64_REG_SP] + 0x80 + 0xb0 + 0x08, regs_.data(),
sizeof(uint64_t) * ARM64_REG_LAST)) {
return false;
}
-
- SetFromRaw();
return true;
}