summaryrefslogtreecommitdiffstats
path: root/libunwindstack/ElfInterfaceArm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/ElfInterfaceArm.cpp')
-rw-r--r--libunwindstack/ElfInterfaceArm.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp
index 66bc51fb2..17364d0c5 100644
--- a/libunwindstack/ElfInterfaceArm.cpp
+++ b/libunwindstack/ElfInterfaceArm.cpp
@@ -99,22 +99,25 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) {
return true;
}
-bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory) {
+bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
// Dwarf unwind information is precise about whether a pc is covered or not,
// but arm unwind information only has ranges of pc. In order to avoid
// incorrectly doing a bad unwind using arm unwind information for a
// different function, always try and unwind with the dwarf information first.
- return ElfInterface32::Step(pc, regs, process_memory) || StepExidx(pc, regs, process_memory);
+ return ElfInterface32::Step(pc, regs, process_memory, finished) ||
+ StepExidx(pc, regs, process_memory, finished);
}
-bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory) {
+bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
RegsArm* regs_arm = reinterpret_cast<RegsArm*>(regs);
uint64_t entry_offset;
if (!FindEntry(pc, &entry_offset)) {
return false;
}
+
ArmExidx arm(regs_arm, memory_, process_memory);
arm.set_cfa(regs_arm->sp());
+ bool return_value = false;
if (arm.ExtractEntryData(entry_offset) && arm.Eval()) {
// If the pc was not set, then use the LR registers for the PC.
if (!arm.pc_set()) {
@@ -125,9 +128,15 @@ bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory)
}
regs_arm->set_sp(arm.cfa());
(*regs_arm)[ARM_REG_SP] = regs_arm->sp();
+ *finished = false;
+ return_value = true;
+ }
+
+ if (arm.status() == ARM_STATUS_NO_UNWIND) {
+ *finished = true;
return true;
}
- return false;
+ return return_value;
}
} // namespace unwindstack