diff options
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 3ce7e8d..ecdd227 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -321,6 +321,11 @@ static cl::alias SymbolTableShort("t", cl::desc("Alias for --syms"), cl::NotHidden, cl::Grouping, cl::aliasopt(SymbolTable)); +static cl::opt<bool> SymbolizeOperands( + "symbolize-operands", + cl::desc("Symbolize instruction operands when disassembling"), + cl::cat(ObjdumpCat)); + static cl::opt<bool> DynamicSymbolTable( "dynamic-syms", cl::desc("Display the contents of the dynamic symbol table"), @@ -1578,6 +1583,42 @@ static SymbolInfoTy createDummySymbolInfo(const ObjectFile *Obj, return SymbolInfoTy(Addr, Name, Type); } +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 X86. + if (!STI->getTargetTriple().isX86()) + return; + + Labels.clear(); + unsigned LabelCount = 0; + Start += SectionAddr; + End += SectionAddr; + uint64_t Index = Start; + while (Index < End) { + // Disassemble a real instruction and record function-local branch labels. + MCInst Inst; + uint64_t Size; + bool Disassembled = DisAsm->getInstruction( + Inst, Size, Bytes.slice(Index - SectionAddr), Index, nulls()); + if (Size == 0) + Size = 1; + + if (Disassembled && MIA) { + uint64_t Target; + bool TargetKnown = MIA->evaluateBranch(Inst, Index, Size, Target); + if (TargetKnown && (Target >= Start && Target < End) && + !Labels.count(Target)) + Labels[Target] = ("L" + Twine(LabelCount++)).str(); + } + + Index += Size; + } +} + static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, MCContext &Ctx, MCDisassembler *PrimaryDisAsm, MCDisassembler *SecondaryDisAsm, @@ -1894,6 +1935,12 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, !DisassembleAll; bool DumpARMELFData = false; formatted_raw_ostream FOS(outs()); + + std::unordered_map<uint64_t, std::string> AllLabels; + if (SymbolizeOperands) + collectLocalBranchTargets(Bytes, MIA, DisAsm, IP, PrimarySTI, + SectionAddr, Index, End, AllLabels); + while (Index < End) { // ARM and AArch64 ELF binaries can interleave data and text in the // same section. We rely on the markers introduced to understand what @@ -1934,6 +1981,11 @@ 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"; + // Disassemble a real instruction or a data when disassemble all is // provided MCInst Inst; @@ -1967,7 +2019,9 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, Inst, SectionAddr + Index, Size)) { Target = *MaybeTarget; PrintTarget = true; - FOS << " # " << Twine::utohexstr(Target); + // Do not print real address when symbolizing. + if (!SymbolizeOperands) + FOS << " # " << Twine::utohexstr(Target); } if (PrintTarget) { // In a relocatable object, the target's section must reside in @@ -2017,17 +2071,30 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, } } + // Print the labels corresponding to the target if there's any. + bool LabelAvailable = AllLabels.count(Target); if (TargetSym != nullptr) { uint64_t TargetAddress = TargetSym->Addr; + uint64_t Disp = Target - TargetAddress; std::string TargetName = TargetSym->Name.str(); if (Demangle) TargetName = demangle(TargetName); - FOS << " <" << TargetName; - uint64_t Disp = Target - TargetAddress; - if (Disp) - FOS << "+0x" << Twine::utohexstr(Disp); - FOS << '>'; + FOS << " <"; + if (!Disp) { + // Always Print the binary symbol precisely corresponding to + // the target address. + FOS << TargetName; + } else if (!LabelAvailable) { + // Always Print the binary symbol plus an offset if there's no + // local label corresponding to the target address. + FOS << TargetName << "+0x" << Twine::utohexstr(Disp); + } else { + FOS << AllLabels[Target]; + } + FOS << ">"; + } else if (LabelAvailable) { + FOS << " <" << AllLabels[Target] << ">"; } } } @@ -2149,6 +2216,8 @@ static void disassembleObject(const ObjectFile *Obj, bool InlineRelocs) { "no instruction printer for target " + TripleName); IP->setPrintImmHex(PrintImmHex); IP->setPrintBranchImmAsAddress(true); + IP->setSymbolizeOperands(SymbolizeOperands); + IP->setMCInstrAnalysis(MIA.get()); PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName)); SourcePrinter SP(Obj, TheTarget->getName()); |