-
-
Save zeroomega/9552161efca45ad8af17a3f312582753 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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