diff options
author | Rahman Lavaee <rahmanl@google.com> | 2022-05-13 10:32:13 -0700 |
---|---|---|
committer | Rahman Lavaee <rahmanl@google.com> | 2022-05-16 10:11:11 -0700 |
commit | 5f7ef65245372b9e5d2979a11b57ac8aab4306a6 (patch) | |
tree | de9e3f529af416329a99cab29a4534beced8d3b0 /llvm/lib/Object/ELFObjectFile.cpp | |
parent | 9c7c8be4a316c9cfcfd064e5dada250a99c405c7 (diff) | |
download | llvm-5f7ef65245372b9e5d2979a11b57ac8aab4306a6.zip llvm-5f7ef65245372b9e5d2979a11b57ac8aab4306a6.tar.gz llvm-5f7ef65245372b9e5d2979a11b57ac8aab4306a6.tar.bz2 |
[llvm-objdump] Let --symbolize-operands symbolize basic block addresses based on the SHT_LLVM_BB_ADDR_MAP section.
`--symbolize-operands` already symbolizes branch targets based on the disassembly. When the object file is created with `-fbasic-block-sections=labels` (ELF-only) it will include a SHT_LLVM_BB_ADDR_MAP section which maps basic blocks to their addresses. In such case `llvm-objdump` can annotate the disassembly based on labels inferred on this section.
In contrast to the current labels, SHT_LLVM_BB_ADDR_MAP-based labels are created for every machine basic block including empty blocks and those which are not branched into (fallthrough blocks).
The old logic is still executed even when the SHT_LLVM_BB_ADDR_MAP section is present to handle functions which have not been received an entry in this section.
Reviewed By: jhenderson, MaskRay
Differential Revision: https://reviews.llvm.org/D124560
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"); +} |