diff options
Diffstat (limited to 'llvm/lib/Object/ELFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 43 |
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"); +} |