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

Commit e05d6afb authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Fix issues in libunwindstack."

parents 152bcf9b e7b6624c
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