aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/llvm-objdump.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/tools/llvm-objdump/llvm-objdump.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/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp73
1 files changed, 60 insertions, 13 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index a9ce463..615eb87 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -53,6 +53,7 @@
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
#include "llvm/Object/FaultMapParser.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
@@ -982,11 +983,29 @@ static SymbolInfoTy createDummySymbolInfo(const ObjectFile *Obj,
}
static void
-collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, const MCInstrAnalysis *MIA,
- MCDisassembler *DisAsm, MCInstPrinter *IP,
- const MCSubtargetInfo *STI, uint64_t SectionAddr,
- uint64_t Start, uint64_t End,
- std::unordered_map<uint64_t, std::string> &Labels) {
+collectBBAddrMapLabels(const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
+ uint64_t SectionAddr, uint64_t Start, uint64_t End,
+ std::unordered_map<uint64_t, std::vector<std::string>> &Labels) {
+ if (AddrToBBAddrMap.empty())
+ return;
+ Labels.clear();
+ uint64_t StartAddress = SectionAddr + Start;
+ uint64_t EndAddress = SectionAddr + End;
+ auto Iter = AddrToBBAddrMap.find(StartAddress);
+ if (Iter == AddrToBBAddrMap.end())
+ return;
+ for (unsigned I = 0, Size = Iter->second.BBEntries.size(); I < Size; ++I) {
+ uint64_t BBAddress = Iter->second.BBEntries[I].Offset + Iter->second.Addr;
+ if (BBAddress >= EndAddress)
+ continue;
+ Labels[BBAddress].push_back(("BB" + Twine(I)).str());
+ }
+}
+
+static void collectLocalBranchTargets(
+ ArrayRef<uint8_t> Bytes, const MCInstrAnalysis *MIA, MCDisassembler *DisAsm,
+ MCInstPrinter *IP, const MCSubtargetInfo *STI, uint64_t SectionAddr,
+ uint64_t Start, uint64_t End, std::unordered_map<uint64_t, std::string> &Labels) {
// So far only supports PowerPC and X86.
if (!STI->getTargetTriple().isPPC() && !STI->getTargetTriple().isX86())
return;
@@ -1015,7 +1034,6 @@ collectLocalBranchTargets(ArrayRef<uint8_t> Bytes, const MCInstrAnalysis *MIA,
!(STI->getTargetTriple().isPPC() && Target == Index))
Labels[Target] = ("L" + Twine(LabelCount++)).str();
}
-
Index += Size;
}
}
@@ -1250,6 +1268,20 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (!SectSize)
continue;
+ std::unordered_map<uint64_t, BBAddrMap> AddrToBBAddrMap;
+ if (SymbolizeOperands) {
+ if (auto *Elf = dyn_cast<ELFObjectFileBase>(Obj)) {
+ // Read the BB-address-map corresponding to this section, if present.
+ auto SectionBBAddrMapsOrErr = Elf->readBBAddrMap(Section.getIndex());
+ if (!SectionBBAddrMapsOrErr)
+ reportWarning(toString(SectionBBAddrMapsOrErr.takeError()),
+ Obj->getFileName());
+ for (auto &FunctionBBAddrMap : *SectionBBAddrMapsOrErr)
+ AddrToBBAddrMap.emplace(FunctionBBAddrMap.Addr,
+ std::move(FunctionBBAddrMap));
+ }
+ }
+
// Get the list of all the symbols in this section.
SectionSymbolsTy &Symbols = AllSymbols[Section];
std::vector<MappingSymbolPair> MappingSymbols;
@@ -1413,9 +1445,13 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
formatted_raw_ostream FOS(outs());
std::unordered_map<uint64_t, std::string> AllLabels;
- if (SymbolizeOperands)
+ std::unordered_map<uint64_t, std::vector<std::string>> BBAddrMapLabels;
+ if (SymbolizeOperands) {
collectLocalBranchTargets(Bytes, MIA, DisAsm, IP, PrimarySTI,
SectionAddr, Index, End, AllLabels);
+ collectBBAddrMapLabels(AddrToBBAddrMap, SectionAddr, Index, End,
+ BBAddrMapLabels);
+ }
while (Index < End) {
// ARM and AArch64 ELF binaries can interleave data and text in the
@@ -1459,9 +1495,15 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
}
// Print local label if there's any.
- auto Iter = AllLabels.find(SectionAddr + Index);
- if (Iter != AllLabels.end())
- FOS << "<" << Iter->second << ">:\n";
+ auto Iter1 = BBAddrMapLabels.find(SectionAddr + Index);
+ if (Iter1 != BBAddrMapLabels.end()) {
+ for (StringRef Label : Iter1->second)
+ FOS << "<" << Label << ">:\n";
+ } else {
+ auto Iter2 = AllLabels.find(SectionAddr + Index);
+ if (Iter2 != AllLabels.end())
+ FOS << "<" << Iter2->second << ">:\n";
+ }
// Disassemble a real instruction or a data when disassemble all is
// provided
@@ -1556,6 +1598,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
}
// Print the labels corresponding to the target if there's any.
+ bool BBAddrMapLabelAvailable = BBAddrMapLabels.count(Target);
bool LabelAvailable = AllLabels.count(Target);
if (TargetSym != nullptr) {
uint64_t TargetAddress = TargetSym->Addr;
@@ -1569,14 +1612,18 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
// Always Print the binary symbol precisely corresponding to
// the target address.
*TargetOS << TargetName;
- } else if (!LabelAvailable) {
+ } else if (BBAddrMapLabelAvailable) {
+ *TargetOS << BBAddrMapLabels[Target].front();
+ } else if (LabelAvailable) {
+ *TargetOS << AllLabels[Target];
+ } else {
// Always Print the binary symbol plus an offset if there's no
// local label corresponding to the target address.
*TargetOS << TargetName << "+0x" << Twine::utohexstr(Disp);
- } else {
- *TargetOS << AllLabels[Target];
}
*TargetOS << ">";
+ } else if (BBAddrMapLabelAvailable) {
+ *TargetOS << " <" << BBAddrMapLabels[Target].front() << ">";
} else if (LabelAvailable) {
*TargetOS << " <" << AllLabels[Target] << ">";
}