Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b9e1866 authored by Christopher Ferris's avatar Christopher Ferris Committed by android-build-merger
Browse files

Merge "Cache DWARF location rules for a given pc."

am: 95a52446

Change-Id: I8374f20b4e20b01347023ea2703d5d8cf522fe26
parents 80e8231a 95a52446
Loading
Loading
Loading
Loading
+11 −2
Original line number Original line Diff line number Diff line
@@ -50,7 +50,17 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
  memory_->set_cur_offset(start_offset);
  memory_->set_cur_offset(start_offset);
  uint64_t cfa_offset;
  uint64_t cfa_offset;
  cur_pc_ = fde_->pc_start;
  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();
    operands_.clear();
    // Read the cfa information.
    // Read the cfa information.
    uint8_t cfa_value;
    uint8_t cfa_value;
@@ -129,7 +139,6 @@ bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset,
      }
      }
    }
    }
  }
  }
  return true;
}
}


template <typename AddressType>
template <typename AddressType>
+19 −11
Original line number Original line Diff line number Diff line
@@ -55,6 +55,9 @@ const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) {
}
}


bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
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;
    last_error_.code = DWARF_ERROR_NONE;
    const DwarfFde* fde = GetFdeFromPc(pc);
    const DwarfFde* fde = GetFdeFromPc(pc);
    if (fde == nullptr || fde->cie == nullptr) {
    if (fde == nullptr || fde->cie == nullptr) {
@@ -67,9 +70,14 @@ bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* f
    if (!GetCfaLocationInfo(pc, fde, &loc_regs)) {
    if (!GetCfaLocationInfo(pc, fde, &loc_regs)) {
      return false;
      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.
  // 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>
template <typename AddressType>
+9 −1
Original line number Original line Diff line number Diff line
@@ -23,6 +23,8 @@


namespace unwindstack {
namespace unwindstack {


struct DwarfCie;

enum DwarfLocationEnum : uint8_t {
enum DwarfLocationEnum : uint8_t {
  DWARF_LOCATION_INVALID = 0,
  DWARF_LOCATION_INVALID = 0,
  DWARF_LOCATION_UNDEFINED,
  DWARF_LOCATION_UNDEFINED,
@@ -38,7 +40,13 @@ struct DwarfLocation {
  uint64_t values[2];
  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
}  // namespace unwindstack


+2 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdint.h>


#include <iterator>
#include <iterator>
#include <map>
#include <unordered_map>
#include <unordered_map>


#include <unwindstack/DwarfError.h>
#include <unwindstack/DwarfError.h>
@@ -112,6 +113,7 @@ class DwarfSection {
  std::unordered_map<uint64_t, DwarfFde> fde_entries_;
  std::unordered_map<uint64_t, DwarfFde> fde_entries_;
  std::unordered_map<uint64_t, DwarfCie> cie_entries_;
  std::unordered_map<uint64_t, DwarfCie> cie_entries_;
  std::unordered_map<uint64_t, dwarf_loc_regs_t> cie_loc_regs_;
  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>
template <typename AddressType>
+2 −1
Original line number Original line Diff line number Diff line
@@ -853,7 +853,8 @@ TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_cached) {
  fde.cfa_instructions_offset = 0x6000;
  fde.cfa_instructions_offset = 0x6000;
  fde.cfa_instructions_end = 0x6002;
  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->section_->TestSetCachedCieLocRegs(0x8000, cie_loc_regs);
  this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});
  this->memory_.SetMemory(0x6000, std::vector<uint8_t>{0x09, 0x04, 0x03});


Loading