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

Commit 02a6c448 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Add support for displaying soname in an apk.

Changes:
- Change GetSoname to always returns a std::string.
- Added new unit tests for the soname printing.
- Modify the GetElf() function to save the same elf when we see rosegment
  linkers that split the read-only and read-write across a map. This
  avoids creating multiple elf objects for each map.
- Fixed a few offline unwind tests.

Bug: 29218999

Test: Unit tests pass.
Change-Id: Iad7c38b5c2957a8c5fd4ba94ebec335bafcad57d
parent 9a00f596
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -93,9 +93,12 @@ void Elf::Invalidate() {
  valid_ = false;
}

bool Elf::GetSoname(std::string* name) {
std::string Elf::GetSoname() {
  std::lock_guard<std::mutex> guard(lock_);
  return valid_ && interface_->GetSoname(name);
  if (!valid_) {
    return "";
  }
  return interface_->GetSoname();
}

uint64_t Elf::GetRelPc(uint64_t pc, const MapInfo* map_info) {
+10 −12
Original line number Diff line number Diff line
@@ -374,13 +374,12 @@ void ElfInterface::ReadSectionHeaders(const EhdrType& ehdr) {
}

template <typename DynType>
bool ElfInterface::GetSonameWithTemplate(std::string* soname) {
std::string ElfInterface::GetSonameWithTemplate() {
  if (soname_type_ == SONAME_INVALID) {
    return false;
    return "";
  }
  if (soname_type_ == SONAME_VALID) {
    *soname = soname_;
    return true;
    return soname_;
  }

  soname_type_ = SONAME_INVALID;
@@ -397,7 +396,7 @@ bool ElfInterface::GetSonameWithTemplate(std::string* soname) {
    if (!memory_->ReadFully(offset, &dyn, sizeof(dyn))) {
      last_error_.code = ERROR_MEMORY_INVALID;
      last_error_.address = offset;
      return false;
      return "";
    }

    if (dyn.d_tag == DT_STRTAB) {
@@ -416,17 +415,16 @@ bool ElfInterface::GetSonameWithTemplate(std::string* soname) {
    if (entry.first == strtab_addr) {
      soname_offset = entry.second + soname_offset;
      if (soname_offset >= entry.second + strtab_size) {
        return false;
        return "";
      }
      if (!memory_->ReadString(soname_offset, &soname_)) {
        return false;
        return "";
      }
      soname_type_ = SONAME_VALID;
      *soname = soname_;
      return true;
      return soname_;
    }
  }
  return false;
  return "";
}

template <typename SymType>
@@ -653,8 +651,8 @@ template void ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf
template std::string ElfInterface::ReadBuildID<Elf32_Nhdr>();
template std::string ElfInterface::ReadBuildID<Elf64_Nhdr>();

template bool ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(std::string*);
template bool ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(std::string*);
template std::string ElfInterface::GetSonameWithTemplate<Elf32_Dyn>();
template std::string ElfInterface::GetSonameWithTemplate<Elf64_Dyn>();

template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, std::string*,
                                                                   uint64_t*);
+42 −29
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
}

Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch) {
  {
    // Make sure no other thread is trying to add the elf to this map.
    std::lock_guard<std::mutex> guard(mutex_);

@@ -226,6 +227,18 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum exp
      Elf::CacheAdd(this);
      Elf::CacheUnlock();
    }
  }

  // If there is a read-only map then a read-execute map that represents the
  // same elf object, make sure the previous map is using the same elf
  // object if it hasn't already been set.
  if (prev_map != nullptr && elf_start_offset != offset && prev_map->offset == elf_start_offset &&
      prev_map->name == name) {
    std::lock_guard<std::mutex> guard(prev_map->mutex_);
    if (prev_map->elf.get() == nullptr) {
      prev_map->elf = elf;
    }
  }
  return elf.get();
}

+6 −0
Original line number Diff line number Diff line
@@ -105,6 +105,12 @@ void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_

  if (resolve_names_) {
    frame->map_name = map_info->name;
    if (embedded_soname_ && map_info->elf_start_offset != 0 && !frame->map_name.empty()) {
      std::string soname = elf->GetSoname();
      if (!soname.empty()) {
        frame->map_name += '!' + soname;
      }
    }
  }
  frame->map_elf_start_offset = map_info->elf_start_offset;
  frame->map_exact_offset = map_info->offset;
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ class Elf {

  void Invalidate();

  bool GetSoname(std::string* name);
  std::string GetSoname();

  bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset);

Loading