summaryrefslogtreecommitdiffstats
path: root/libunwindstack/DwarfSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/DwarfSection.cpp')
-rw-r--r--libunwindstack/DwarfSection.cpp30
1 files changed, 19 insertions, 11 deletions
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index 5586e725d..65eec65b8 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -55,21 +55,29 @@ const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) {
}
bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
- last_error_.code = DWARF_ERROR_NONE;
- const DwarfFde* fde = GetFdeFromPc(pc);
- if (fde == nullptr || fde->cie == nullptr) {
- last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
- return false;
- }
+ // Lookup the pc in the cache.
+ auto it = loc_regs_.upper_bound(pc);
+ if (it == loc_regs_.end() || pc < it->second.pc_start) {
+ last_error_.code = DWARF_ERROR_NONE;
+ const DwarfFde* fde = GetFdeFromPc(pc);
+ if (fde == nullptr || fde->cie == nullptr) {
+ last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
+ return false;
+ }
- // Now get the location information for this pc.
- dwarf_loc_regs_t loc_regs;
- if (!GetCfaLocationInfo(pc, fde, &loc_regs)) {
- return false;
+ // Now get the location information for this pc.
+ dwarf_loc_regs_t loc_regs;
+ if (!GetCfaLocationInfo(pc, fde, &loc_regs)) {
+ return false;
+ }
+ loc_regs.cie = fde->cie;
+
+ // Store it in the cache.
+ it = loc_regs_.emplace(loc_regs.pc_end, std::move(loc_regs)).first;
}
// Now eval the actual registers.
- return Eval(fde->cie, process_memory, loc_regs, regs, finished);
+ return Eval(it->second.cie, process_memory, it->second, regs, finished);
}
template <typename AddressType>