Loading libunwindstack/DwarfCfa.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -50,7 +50,17 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset, memory_->set_cur_offset(start_offset); uint64_t cfa_offset; cur_pc_ = fde_->pc_start; while ((cfa_offset = memory_->cur_offset()) < end_offset && cur_pc_ <= pc) { loc_regs->pc_start = cur_pc_; while (true) { if (cur_pc_ > pc) { loc_regs->pc_end = cur_pc_; return true; } if ((cfa_offset = memory_->cur_offset()) >= end_offset) { loc_regs->pc_end = fde_->pc_end; return true; } loc_regs->pc_start = cur_pc_; operands_.clear(); // Read the cfa information. uint8_t cfa_value; Loading Loading @@ -129,7 +139,6 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset, } } } return true; } template <typename AddressType> Loading libunwindstack/DwarfSection.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) { } bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { // 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) { Loading @@ -67,9 +70,14 @@ bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* f 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> Loading libunwindstack/include/unwindstack/DwarfLocation.h +9 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ namespace unwindstack { struct DwarfCie; enum DwarfLocationEnum : uint8_t { DWARF_LOCATION_INVALID = 0, DWARF_LOCATION_UNDEFINED, Loading @@ -38,7 +40,13 @@ struct DwarfLocation { uint64_t values[2]; }; typedef std::unordered_map<uint32_t, DwarfLocation> dwarf_loc_regs_t; struct DwarfLocations : public std::unordered_map<uint32_t, DwarfLocation> { const DwarfCie* cie; // The range of PCs where the locations are valid (end is exclusive). uint64_t pc_start = 0; uint64_t pc_end = 0; }; typedef DwarfLocations dwarf_loc_regs_t; } // namespace unwindstack Loading libunwindstack/include/unwindstack/DwarfSection.h +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <stdint.h> #include <iterator> #include <map> #include <unordered_map> #include <unwindstack/DwarfError.h> Loading Loading @@ -112,6 +113,7 @@ class DwarfSection { std::unordered_map<uint64_t, DwarfFde> fde_entries_; std::unordered_map<uint64_t, DwarfCie> cie_entries_; std::unordered_map<uint64_t, dwarf_loc_regs_t> cie_loc_regs_; std::map<uint64_t, dwarf_loc_regs_t> loc_regs_; // Single row indexed by pc_end. }; template <typename AddressType> Loading libunwindstack/tests/DwarfSectionImplTest.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -853,7 +853,8 @@ TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) { fde.cfa_instructions_offset = 0x6000; fde.cfa_instructions_end = 0x6002; dwarf_loc_regs_t cie_loc_regs{{6, {DWARF_LOCATION_REGISTER, {4, 0}}}}; dwarf_loc_regs_t cie_loc_regs; cie_loc_regs[6] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 0}}; this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs); this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03}); Loading Loading
libunwindstack/DwarfCfa.cpp +11 −2 Original line number Diff line number Diff line Loading @@ -50,7 +50,17 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset, memory_->set_cur_offset(start_offset); uint64_t cfa_offset; cur_pc_ = fde_->pc_start; while ((cfa_offset = memory_->cur_offset()) < end_offset && cur_pc_ <= pc) { loc_regs->pc_start = cur_pc_; while (true) { if (cur_pc_ > pc) { loc_regs->pc_end = cur_pc_; return true; } if ((cfa_offset = memory_->cur_offset()) >= end_offset) { loc_regs->pc_end = fde_->pc_end; return true; } loc_regs->pc_start = cur_pc_; operands_.clear(); // Read the cfa information. uint8_t cfa_value; Loading Loading @@ -129,7 +139,6 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset, } } } return true; } template <typename AddressType> Loading
libunwindstack/DwarfSection.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) { } bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { // 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) { Loading @@ -67,9 +70,14 @@ bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* f 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> Loading
libunwindstack/include/unwindstack/DwarfLocation.h +9 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ namespace unwindstack { struct DwarfCie; enum DwarfLocationEnum : uint8_t { DWARF_LOCATION_INVALID = 0, DWARF_LOCATION_UNDEFINED, Loading @@ -38,7 +40,13 @@ struct DwarfLocation { uint64_t values[2]; }; typedef std::unordered_map<uint32_t, DwarfLocation> dwarf_loc_regs_t; struct DwarfLocations : public std::unordered_map<uint32_t, DwarfLocation> { const DwarfCie* cie; // The range of PCs where the locations are valid (end is exclusive). uint64_t pc_start = 0; uint64_t pc_end = 0; }; typedef DwarfLocations dwarf_loc_regs_t; } // namespace unwindstack Loading
libunwindstack/include/unwindstack/DwarfSection.h +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <stdint.h> #include <iterator> #include <map> #include <unordered_map> #include <unwindstack/DwarfError.h> Loading Loading @@ -112,6 +113,7 @@ class DwarfSection { std::unordered_map<uint64_t, DwarfFde> fde_entries_; std::unordered_map<uint64_t, DwarfCie> cie_entries_; std::unordered_map<uint64_t, dwarf_loc_regs_t> cie_loc_regs_; std::map<uint64_t, dwarf_loc_regs_t> loc_regs_; // Single row indexed by pc_end. }; template <typename AddressType> Loading
libunwindstack/tests/DwarfSectionImplTest.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -853,7 +853,8 @@ TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) { fde.cfa_instructions_offset = 0x6000; fde.cfa_instructions_end = 0x6002; dwarf_loc_regs_t cie_loc_regs{{6, {DWARF_LOCATION_REGISTER, {4, 0}}}}; dwarf_loc_regs_t cie_loc_regs; cie_loc_regs[6] = DwarfLocation{DWARF_LOCATION_REGISTER, {4, 0}}; this->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs); this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03}); Loading