aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ELFObjectFile.cpp
diff options
context:
space:
mode:
authorRahman Lavaee <rahmanl@google.com>2022-05-13 10:32:13 -0700
committerRahman Lavaee <rahmanl@google.com>2022-05-16 10:11:11 -0700
commit5f7ef65245372b9e5d2979a11b57ac8aab4306a6 (patch)
treede9e3f529af416329a99cab29a4534beced8d3b0 /llvm/lib/Object/ELFObjectFile.cpp
parent9c7c8be4a316c9cfcfd064e5dada250a99c405c7 (diff)
downloadllvm-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.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");
+}