summaryrefslogtreecommitdiffstats
path: root/libunwindstack/DwarfSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/DwarfSection.cpp')
-rw-r--r--libunwindstack/DwarfSection.cpp13
1 files changed, 8 insertions, 5 deletions
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index 1234eb135..8b30b768d 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -47,7 +47,7 @@ const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) {
return nullptr;
}
-bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory) {
+bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
last_error_ = DWARF_ERROR_NONE;
const DwarfFde* fde = GetFdeFromPc(pc);
if (fde == nullptr || fde->cie == nullptr) {
@@ -62,7 +62,7 @@ bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory) {
}
// Now eval the actual registers.
- return Eval(fde->cie, process_memory, loc_regs, regs);
+ return Eval(fde->cie, process_memory, loc_regs, regs, finished);
}
template <typename AddressType>
@@ -92,7 +92,8 @@ bool DwarfSectionImpl<AddressType>::EvalExpression(const DwarfLocation& loc, uin
template <typename AddressType>
bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_memory,
- const dwarf_loc_regs_t& loc_regs, Regs* regs) {
+ const dwarf_loc_regs_t& loc_regs, Regs* regs,
+ bool* finished) {
RegsImpl<AddressType>* cur_regs = reinterpret_cast<RegsImpl<AddressType>*>(regs);
if (cie->return_address_register >= cur_regs->total_regs()) {
last_error_ = DWARF_ERROR_ILLEGAL_VALUE;
@@ -224,12 +225,14 @@ bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_me
// Find the return address location.
if (return_address_undefined) {
cur_regs->set_pc(0);
+ *finished = true;
} else {
cur_regs->set_pc((*cur_regs)[cie->return_address_register]);
+ *finished = false;
}
cur_regs->set_sp(cfa);
- // Stop if the cfa and pc are the same.
- return prev_cfa != cfa || prev_pc != cur_regs->pc();
+ // Return false if the unwind is not finished or the cfa and pc didn't change.
+ return *finished || prev_cfa != cfa || prev_pc != cur_regs->pc();
}
template <typename AddressType>