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

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

Merge "Fix issues in libunwindstack." am: e05d6afb

am: 31bf0843

Change-Id: Ieca0fc29f7004d2324011e646f2e42d7ebeafe5e
parents c6e98a1a 31bf0843
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ cc_test {
    data: [
        "tests/files/elf32.xz",
        "tests/files/elf64.xz",
        "tests/files/offline/gnu_debugdata_arm32/*",
        "tests/files/offline/straddle_arm32/*",
        "tests/files/offline/straddle_arm64/*",
    ],
+2 −9
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ void Elf::InitGnuDebugdata() {
  uint64_t load_bias;
  if (gnu->Init(&load_bias)) {
    gnu->InitHeaders();
    interface_->SetGnuDebugdataInterface(gnu);
  } else {
    // Free all of the memory associated with the gnu_debugdata section.
    gnu_debugdata_memory_.reset(nullptr);
@@ -115,17 +116,9 @@ bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, R
    return true;
  }

  // Adjust the load bias to get the real relative pc.
  if (adjusted_rel_pc < load_bias_) {
    return false;
  }
  adjusted_rel_pc -= load_bias_;

  // Lock during the step which can update information in the object.
  std::lock_guard<std::mutex> guard(lock_);
  return interface_->Step(adjusted_rel_pc, regs, process_memory, finished) ||
         (gnu_debugdata_interface_ &&
          gnu_debugdata_interface_->Step(adjusted_rel_pc, regs, process_memory, finished));
  return interface_->Step(adjusted_rel_pc, load_bias_, regs, process_memory, finished);
}

bool Elf::IsValidElf(Memory* memory) {
+16 −3
Original line number Diff line number Diff line
@@ -386,16 +386,29 @@ bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias
  return false;
}

bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
bool ElfInterface::Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory,
                        bool* finished) {
  // Adjust the load bias to get the real relative pc.
  if (pc < load_bias) {
    return false;
  }
  uint64_t adjusted_pc = pc - load_bias;

  // Try the eh_frame first.
  DwarfSection* eh_frame = eh_frame_.get();
  if (eh_frame != nullptr && eh_frame->Step(pc, regs, process_memory, finished)) {
  if (eh_frame != nullptr && eh_frame->Step(adjusted_pc, regs, process_memory, finished)) {
    return true;
  }

  // Try the debug_frame next.
  DwarfSection* debug_frame = debug_frame_.get();
  if (debug_frame != nullptr && debug_frame->Step(pc, regs, process_memory, finished)) {
  if (debug_frame != nullptr && debug_frame->Step(adjusted_pc, regs, process_memory, finished)) {
    return true;
  }

  // Finally try the gnu_debugdata interface, but always use a zero load bias.
  if (gnu_debugdata_interface_ != nullptr &&
      gnu_debugdata_interface_->Step(pc, 0, regs, process_memory, finished)) {
    return true;
  }
  return false;
+12 −4
Original line number Diff line number Diff line
@@ -92,16 +92,24 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_b
  return true;
}

bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
bool ElfInterfaceArm::Step(uint64_t pc, uint64_t load_bias, 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, finished) ||
         StepExidx(pc, regs, process_memory, finished);
  return ElfInterface32::Step(pc, load_bias, regs, process_memory, finished) ||
         StepExidx(pc, load_bias, regs, process_memory, finished);
}

bool ElfInterfaceArm::StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
bool ElfInterfaceArm::StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory,
                                bool* finished) {
  // Adjust the load bias to get the real relative pc.
  if (pc < load_bias) {
    return false;
  }
  pc -= load_bias;

  RegsArm* regs_arm = reinterpret_cast<RegsArm*>(regs);
  uint64_t entry_offset;
  if (!FindEntry(pc, &entry_offset)) {
+4 −2
Original line number Diff line number Diff line
@@ -70,9 +70,11 @@ class ElfInterfaceArm : public ElfInterface32 {

  bool HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) override;

  bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) override;
  bool Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory,
            bool* finished) override;

  bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished);
  bool StepExidx(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory,
                 bool* finished);

  uint64_t start_offset() { return start_offset_; }

Loading