aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ELFObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/ELFObjectFile.cpp')
-rw-r--r--llvm/lib/Object/ELFObjectFile.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index c402599..c325e30 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -671,6 +671,35 @@ ELFObjectFileBase::getPltAddresses() const {
}
template <class ELFT>
+Expected<std::vector<BBAddrMap>>
+readBBAddrMapImpl(const ELFFile<ELFT> &EF,
+ Optional<unsigned> TextSectionIndex) {
+ using Elf_Shdr = typename ELFT::Shdr;
+ std::vector<BBAddrMap> BBAddrMaps;
+ const auto &Sections = cantFail(EF.sections());
+ for (const Elf_Shdr &Sec : Sections) {
+ if (Sec.sh_type != ELF::SHT_LLVM_BB_ADDR_MAP)
+ continue;
+ if (TextSectionIndex) {
+ Expected<const Elf_Shdr *> TextSecOrErr = EF.getSection(Sec.sh_link);
+ if (!TextSecOrErr)
+ return createError("unable to get the linked-to section for " +
+ describe(EF, Sec) + ": " +
+ toString(TextSecOrErr.takeError()));
+ if (*TextSectionIndex != std::distance(Sections.begin(), *TextSecOrErr))
+ continue;
+ }
+ Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = EF.decodeBBAddrMap(Sec);
+ if (!BBAddrMapOrErr)
+ return createError("unable to read " + describe(EF, Sec) + ": " +
+ toString(BBAddrMapOrErr.takeError()));
+ std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),
+ std::back_inserter(BBAddrMaps));
+ }
+ return BBAddrMaps;
+}
+
+template <class ELFT>
static Expected<std::vector<VersionEntry>>
readDynsymVersionsImpl(const ELFFile<ELFT> &EF,
ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
@@ -738,3 +767,17 @@ ELFObjectFileBase::readDynsymVersions() const {
return readDynsymVersionsImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),
Symbols);
}
+
+Expected<std::vector<BBAddrMap>>
+ELFObjectFileBase::readBBAddrMap(Optional<unsigned> TextSectionIndex) const {
+ if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ if (const auto *Obj = cast<ELF64BEObjectFile>(this))
+ return readBBAddrMapImpl(Obj->getELFFile(), TextSectionIndex);
+ else
+ llvm_unreachable("Unsupported binary format");
+}