std::vector<typename ELFFile<T>::Elf_Shdr> elf_sections(const ELFFile<T> &elf) { typedef typename ELFFile<T>::Elf_Shdr hdr; auto er_hdrs = elf.sections(); if (!er_hdrs) return std::vector<hdr>(); auto hdrs = er_hdrs.get(); return std::vector<hdr>(hdrs.begin(), hdrs.end()); }
// Partially parse the shared object file so that we can call // getSoName on this object. template <class ELFT> void SharedFile<ELFT>::parseSoName() { typedef typename ELFT::Dyn Elf_Dyn; typedef typename ELFT::uint uintX_t; const Elf_Shdr *DynamicSec = nullptr; const ELFFile<ELFT> Obj = this->ELFObj; for (const Elf_Shdr &Sec : Obj.sections()) { switch (Sec.sh_type) { default: continue; case SHT_DYNSYM: this->Symtab = &Sec; break; case SHT_DYNAMIC: DynamicSec = &Sec; break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); break; case SHT_GNU_versym: this->VersymSec = &Sec; break; case SHT_GNU_verdef: this->VerdefSec = &Sec; break; } } this->initStringTable(); // DSOs are identified by soname, and they usually contain // DT_SONAME tag in their header. But if they are missing, // filenames are used as default sonames. SoName = sys::path::filename(this->getName()); if (!DynamicSec) return; ArrayRef<Elf_Dyn> Arr = check(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), getFilename(this) + ": getSectionContentsAsArray failed"); for (const Elf_Dyn &Dyn : Arr) { if (Dyn.d_tag == DT_SONAME) { uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) fatal(getFilename(this) + ": invalid DT_SONAME entry"); SoName = StringRef(this->StringTable.data() + Val); return; } } }
// Partially parse the shared object file so that we can call // getSoName on this object. template <class ELFT> void SharedFile<ELFT>::parseSoName() { const Elf_Shdr *DynamicSec = nullptr; const ELFFile<ELFT> Obj = this->getObj(); ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), toString(this)); // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d. for (const Elf_Shdr &Sec : Sections) { switch (Sec.sh_type) { default: continue; case SHT_DYNSYM: this->initSymtab(Sections, &Sec); break; case SHT_DYNAMIC: DynamicSec = &Sec; break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec, Sections), toString(this)); break; case SHT_GNU_versym: this->VersymSec = &Sec; break; case SHT_GNU_verdef: this->VerdefSec = &Sec; break; } } if (this->VersymSec && this->Symbols.empty()) error("SHT_GNU_versym should be associated with symbol table"); // Search for a DT_SONAME tag to initialize this->SoName. if (!DynamicSec) return; ArrayRef<Elf_Dyn> Arr = check(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec), toString(this)); for (const Elf_Dyn &Dyn : Arr) { if (Dyn.d_tag == DT_SONAME) { uint64_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) fatal(toString(this) + ": invalid DT_SONAME entry"); SoName = this->StringTable.data() + Val; return; } } }
template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() { typedef typename ELFT::Shdr Elf_Shdr; typedef typename ELFT::Sym Elf_Sym; typedef typename ELFT::SymRange Elf_Sym_Range; const ELFFile<ELFT> Obj = createELFObj<ELFT>(this->MB); for (const Elf_Shdr &Sec : Obj.sections()) { if (Sec.sh_type != SHT_SYMTAB) continue; Elf_Sym_Range Syms = Obj.symbols(&Sec); uint32_t FirstNonLocal = Sec.sh_info; StringRef StringTable = check(Obj.getStringTableForSymtab(Sec)); std::vector<StringRef> V; for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal)) if (Sym.st_shndx != SHN_UNDEF) V.push_back(check(Sym.getName(StringTable))); return V; } return {}; }
// Partially parse the shared object file so that we can call // getSoName on this object. template <class ELFT> void SharedFile<ELFT>::parseSoName() { typedef typename ELFT::Dyn Elf_Dyn; typedef typename ELFT::uint uintX_t; const Elf_Shdr *DynamicSec = nullptr; const ELFFile<ELFT> Obj = this->ELFObj; for (const Elf_Shdr &Sec : Obj.sections()) { switch (Sec.sh_type) { default: continue; case SHT_DYNSYM: this->Symtab = &Sec; break; case SHT_DYNAMIC: DynamicSec = &Sec; break; case SHT_SYMTAB_SHNDX: this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec)); break; } } this->initStringTable(); SoName = this->getName(); if (!DynamicSec) return; auto *Begin = reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset); const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); for (const Elf_Dyn &Dyn : make_range(Begin, End)) { if (Dyn.d_tag == DT_SONAME) { uintX_t Val = Dyn.getVal(); if (Val >= this->StringTable.size()) fatal("invalid DT_SONAME entry"); SoName = StringRef(this->StringTable.data() + Val); return; } } }
std::vector<typename ELFFile<T>::Elf_Shdr> elf_sections(const ELFFile<T> &elf) { typedef typename ELFFile<T>::Elf_Shdr hdr; auto secs = elf.sections(); return std::vector<hdr>(secs.begin(), secs.end()); }