diff options
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 73 |
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] << ">"; } |