Skip to content

Instantly share code, notes, and snippets.

@zeroomega
Created January 14, 2022 00:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeroomega/9552161efca45ad8af17a3f312582753 to your computer and use it in GitHub Desktop.
Save zeroomega/9552161efca45ad8af17a3f312582753 to your computer and use it in GitHub Desktop.
template <class ELFT>
Expected<const uint8_t *> getDataFromDynsym(
const ELFFile<ELFT> &ElfFile, uint64_t DynAddr, StringRef Name,
function_ref<Expected<const uint8_t *>(const typename ELFT::Shdr &,
const typename ELFT::ShdrRange &)>
OnFound) {
using Elf_Shdr_Range = typename ELFT::ShdrRange;
using Elf_Shdr = typename ELFT::Shdr;
Expected<Elf_Shdr_Range> Shdrs = ElfFile.sections();
if (!Shdrs)
return Shdrs.takeError();
if (Shdrs.get().size()) {
for (const Elf_Shdr &Sec : *Shdrs) {
if (Sec.sh_type == ELF::SHT_DYNSYM) {
// If multiple .dynsym are present, use the first one.
// This behavior aligns with llvm::object::ELFFile::getDynSymtabSize().
return OnFound(Sec, *Shdrs);
}
}
} // Fallback to use offsets from .dynamic as .dynsym was not found.
Expected<const uint8_t *> PtrOrErr = ElfFile.toMappedAddr(DynAddr);
if (!PtrOrErr)
return appendToError(
PtrOrErr.takeError(),
StringRef("when locating " + Name.str() + " section contents"));
return *PtrOrErr;
}
template <class ELFT>
static Expected<const uint8_t *> getDynSymPtr(const ELFFile<ELFT> &ElfFile,
const DynamicEntries &DynEnt) {
return getDataFromDynsym(ElfFile, DynEnt.DynSymAddr, ".dynsym",
[&ElfFile](const typename ELFT::Shdr &Sec,
const typename ELFT::ShdrRange &Shdrs) {
return ElfFile.base() + Sec.sh_offset;
});
}
template <class ELFT>
static Expected<StringRef> getDynStr(const ELFFile<ELFT> &ElfFile,
const DynamicEntries &DynEnt) {
Expected<const uint8_t *> ResultOrErr = getDataFromDynsym(
ElfFile, DynEnt.StrTabAddr, ".dynstr",
[&ElfFile](
const typename ELFT::Shdr &Sec,
const typename ELFT::ShdrRange &Shdrs) -> Expected<const uint8_t *> {
Expected<StringRef> DynStrRef =
ElfFile.getStringTableForSymtab(Sec, Shdrs);
if (!DynStrRef)
return DynStrRef.takeError();
return DynStrRef.get().bytes_begin();
});
if (!ResultOrErr)
return ResultOrErr.takeError();
return StringRef(reinterpret_cast<const char *>(*ResultOrErr),
DynEnt.StrSize);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment