diff options
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | llvm/tools/llvm-objdump/llvm-objdump.cpp | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 0977598..8daeb4e 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -36,6 +36,9 @@ #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h" #include "llvm/DebugInfo/Symbolize/Symbolize.h" +#include "llvm/Debuginfod/BuildIDFetcher.h" +#include "llvm/Debuginfod/Debuginfod.h" +#include "llvm/Debuginfod/HTTPClient.h" #include "llvm/Demangle/Demangle.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" @@ -51,6 +54,7 @@ #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/BuildID.h" #include "llvm/Object/COFF.h" #include "llvm/Object/COFFImportFile.h" #include "llvm/Object/ELFObjectFile.h" @@ -233,6 +237,9 @@ static StringSet<> DisasmSymbolSet; StringSet<> objdump::FoundSectionSet; static StringRef ToolName; +std::unique_ptr<BuildIDFetcher> BIDFetcher; +ExitOnError ExitOnErr; + namespace { struct FilterResult { // True if the section should not be skipped. @@ -1258,6 +1265,24 @@ static void createFakeELFSections(ObjectFile &Obj) { llvm_unreachable("Unsupported binary format"); } +// Tries to fetch a more complete version of the given object file using its +// Build ID. Returns None if nothing was found. +static Optional<OwningBinary<Binary>> +fetchBinaryByBuildID(const ObjectFile &Obj) { + Optional<object::BuildIDRef> BuildID = getBuildID(&Obj); + if (!BuildID) + return None; + Optional<std::string> Path = BIDFetcher->fetch(*BuildID); + if (!Path) + return None; + Expected<OwningBinary<Binary>> DebugBinary = createBinary(*Path); + if (!DebugBinary) { + reportWarning(toString(DebugBinary.takeError()), *Path); + return None; + } + return std::move(*DebugBinary); +} + static void disassembleObject(const Target *TheTarget, ObjectFile &Obj, MCContext &Ctx, MCDisassembler *PrimaryDisAsm, MCDisassembler *SecondaryDisAsm, @@ -2043,7 +2068,21 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) { IP->setMCInstrAnalysis(MIA.get()); PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName)); - SourcePrinter SP(Obj, TheTarget->getName()); + ObjectFile *DbgObj = Obj; + OwningBinary<Binary> DebugBinary; + if (!Obj->hasDebugInfo()) { + if (Optional<OwningBinary<Binary>> DebugBinaryOpt = + fetchBinaryByBuildID(*Obj)) { + if (ObjectFile *FetchedObj = + dyn_cast<ObjectFile>(DebugBinaryOpt->getBinary())) { + if (FetchedObj->hasDebugInfo()) { + DebugBinary = std::move(*DebugBinaryOpt); + DbgObj = FetchedObj; + } + } + } + } + SourcePrinter SP(DbgObj, TheTarget->getName()); for (StringRef Opt : DisassemblerOptions) if (!IP->applyTargetSpecificCLOption(Opt)) @@ -3080,6 +3119,22 @@ int main(int argc, char **argv) { return 0; } + // Initialize debuginfod. + const bool ShouldUseDebuginfodByDefault = + HTTPClient::isAvailable() && + !ExitOnErr(getDefaultDebuginfodUrls()).empty(); + std::vector<std::string> DebugFileDirectories = + InputArgs.getAllArgValues(OBJDUMP_debug_file_directory); + if (InputArgs.hasFlag(OBJDUMP_debuginfod, OBJDUMP_no_debuginfod, + ShouldUseDebuginfodByDefault)) { + HTTPClient::initialize(); + BIDFetcher = + std::make_unique<DebuginfodFetcher>(std::move(DebugFileDirectories)); + } else { + BIDFetcher = + std::make_unique<BuildIDFetcher>(std::move(DebugFileDirectories)); + } + if (Is("otool")) parseOtoolOptions(InputArgs); else |