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

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

Merge "Multiple bugfixes, small restructuring."

am: 26b614dd

Change-Id: I7a44bbfe9f43981031fc6cc84de08cef79d78e78
parents a909e5e2 26b614dd
Loading
Loading
Loading
Loading
+30 −19
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@

namespace unwindstack {

bool Elf::Init() {
bool Elf::Init(bool init_gnu_debugdata) {
  load_bias_ = 0;
  if (!memory_) {
    return false;
  }
@@ -45,9 +46,14 @@ bool Elf::Init() {
    return false;
  }

  valid_ = interface_->Init();
  valid_ = interface_->Init(&load_bias_);
  if (valid_) {
    interface_->InitHeaders();
    if (init_gnu_debugdata) {
      InitGnuDebugdata();
    } else {
      gnu_debugdata_interface_.reset(nullptr);
    }
  } else {
    interface_.reset(nullptr);
  }
@@ -67,7 +73,11 @@ void Elf::InitGnuDebugdata() {
  if (gnu == nullptr) {
    return;
  }
  if (gnu->Init()) {

  // Ignore the load_bias from the compressed section, the correct load bias
  // is in the uncompressed data.
  uint64_t load_bias;
  if (gnu->Init(&load_bias)) {
    gnu->InitHeaders();
  } else {
    // Free all of the memory associated with the gnu_debugdata section.
@@ -81,38 +91,39 @@ bool Elf::GetSoname(std::string* name) {
}

uint64_t Elf::GetRelPc(uint64_t pc, const MapInfo* map_info) {
  uint64_t load_bias = 0;
  if (valid()) {
    load_bias = interface_->load_bias();
  }

  return pc - map_info->start + load_bias + map_info->elf_offset;
  return pc - map_info->start + load_bias_ + map_info->elf_offset;
}

bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) {
  return valid_ && (interface_->GetFunctionName(addr, name, func_offset) ||
                    (gnu_debugdata_interface_ &&
                     gnu_debugdata_interface_->GetFunctionName(addr, name, func_offset)));
  return valid_ && (interface_->GetFunctionName(addr, load_bias_, name, func_offset) ||
                    (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName(
                                                     addr, load_bias_, name, func_offset)));
}

bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) {
// The relative pc is always relative to the start of the map from which it comes.
bool Elf::Step(uint64_t rel_pc, uint64_t elf_offset, Regs* regs, Memory* process_memory,
               bool* finished) {
  if (!valid_) {
    return false;
  }
  if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) {

  // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf.
  if (regs->StepIfSignalHandler(rel_pc + elf_offset, this, process_memory)) {
    *finished = false;
    return true;
  }

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

  return interface_->Step(rel_pc, regs, process_memory, finished) ||
         (gnu_debugdata_interface_ &&
          gnu_debugdata_interface_->Step(rel_pc, regs, process_memory, finished));
}

uint64_t Elf::GetLoadBias() {
  if (!valid_) return 0;
  return interface_->load_bias();
}

bool Elf::IsValidElf(Memory* memory) {
  if (memory == nullptr) {
    return false;
+13 −19
Original line number Diff line number Diff line
@@ -118,13 +118,13 @@ void ElfInterface::InitHeadersWithTemplate() {
}

template <typename EhdrType, typename PhdrType, typename ShdrType>
bool ElfInterface::ReadAllHeaders() {
bool ElfInterface::ReadAllHeaders(uint64_t* load_bias) {
  EhdrType ehdr;
  if (!memory_->Read(0, &ehdr, sizeof(ehdr))) {
    return false;
  }

  if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr)) {
  if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr, load_bias)) {
    return false;
  }

@@ -137,7 +137,7 @@ bool ElfInterface::ReadAllHeaders() {
}

template <typename EhdrType, typename PhdrType>
bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) {
bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias) {
  uint64_t offset = ehdr.e_phoff;
  for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) {
    PhdrType phdr;
@@ -145,7 +145,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) {
      return false;
    }

    if (HandleType(offset, phdr.p_type)) {
    if (HandleType(offset, phdr.p_type, *load_bias)) {
      continue;
    }

@@ -172,7 +172,7 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) {
      pt_loads_[phdr.p_offset] = LoadInfo{phdr.p_offset, phdr.p_vaddr,
                                          static_cast<size_t>(phdr.p_memsz)};
      if (phdr.p_offset == 0) {
        load_bias_ = phdr.p_vaddr;
        *load_bias = phdr.p_vaddr;
      }
      break;
    }
@@ -334,14 +334,14 @@ bool ElfInterface::GetSonameWithTemplate(std::string* soname) {
}

template <typename SymType>
bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name,
bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias, std::string* name,
                                               uint64_t* func_offset) {
  if (symbols_.empty()) {
    return false;
  }

  for (const auto symbol : symbols_) {
    if (symbol->GetName<SymType>(addr, load_bias_, memory_, name, func_offset)) {
    if (symbol->GetName<SymType>(addr, load_bias, memory_, name, func_offset)) {
      return true;
    }
  }
@@ -349,12 +349,6 @@ bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name,
}

bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
  // Need to subtract off the load_bias to get the correct pc.
  if (pc < load_bias_) {
    return false;
  }
  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)) {
@@ -389,11 +383,11 @@ void ElfInterface::GetMaxSizeWithTemplate(Memory* memory, uint64_t* size) {
template void ElfInterface::InitHeadersWithTemplate<uint32_t>();
template void ElfInterface::InitHeadersWithTemplate<uint64_t>();

template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>();
template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>();
template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(uint64_t*);
template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(uint64_t*);

template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&);
template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&);
template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&, uint64_t*);
template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&, uint64_t*);

template bool ElfInterface::ReadSectionHeaders<Elf32_Ehdr, Elf32_Shdr>(const Elf32_Ehdr&);
template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf64_Ehdr&);
@@ -401,9 +395,9 @@ template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf
template bool ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(std::string*);
template bool ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(std::string*);

template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, std::string*,
template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, uint64_t, std::string*,
                                                                   uint64_t*);
template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, std::string*,
template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, uint64_t, std::string*,
                                                                   uint64_t*);

template void ElfInterface::GetMaxSizeWithTemplate<Elf32_Ehdr>(Memory*, uint64_t*);
+2 −9
Original line number Diff line number Diff line
@@ -31,12 +31,6 @@ bool ElfInterfaceArm::FindEntry(uint32_t pc, uint64_t* entry_offset) {
    return false;
  }

  // Need to subtract the load_bias from the pc.
  if (pc < load_bias_) {
    return false;
  }
  pc -= load_bias_;

  size_t first = 0;
  size_t last = total_entries_;
  while (first < last) {
@@ -81,7 +75,7 @@ bool ElfInterfaceArm::GetPrel31Addr(uint32_t offset, uint32_t* addr) {
#define PT_ARM_EXIDX 0x70000001
#endif

bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) {
bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type, uint64_t load_bias) {
  if (type != PT_ARM_EXIDX) {
    return false;
  }
@@ -93,8 +87,7 @@ bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) {
  if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
    return true;
  }
  // The load_bias_ should always be set by this time.
  start_offset_ = phdr.p_vaddr - load_bias_;
  start_offset_ = phdr.p_vaddr - load_bias;
  total_entries_ = phdr.p_memsz / 8;
  return true;
}
+2 −6
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ class ElfInterfaceArm : public ElfInterface32 {

  bool FindEntry(uint32_t pc, uint64_t* entry_offset);

  bool HandleType(uint64_t offset, uint32_t type) override;
  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;

@@ -76,13 +76,9 @@ class ElfInterfaceArm : public ElfInterface32 {

  uint64_t start_offset() { return start_offset_; }

  void set_start_offset(uint64_t start_offset) { start_offset_ = start_offset; }

  size_t total_entries() { return total_entries_; }

  void set_total_entries(size_t total_entries) { total_entries_ = total_entries; }

 private:
 protected:
  uint64_t start_offset_ = 0;
  size_t total_entries_ = 0;

+2 −3
Original line number Diff line number Diff line
@@ -110,9 +110,8 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gn
  }

  elf = new Elf(CreateMemory(process_memory));
  if (elf->Init() && init_gnu_debugdata) {
    elf->InitGnuDebugdata();
  }
  elf->Init(init_gnu_debugdata);

  // If the init fails, keep the elf around as an invalid object so we
  // don't try to reinit the object.
  return elf;
Loading