diff --git a/llvm/test/tools/llvm-objdump/debuginfod.test b/llvm/test/tools/llvm-objdump/debuginfod.test --- a/llvm/test/tools/llvm-objdump/debuginfod.test +++ b/llvm/test/tools/llvm-objdump/debuginfod.test @@ -35,5 +35,13 @@ RUN: %t/stripped | \ RUN: FileCheck %s --check-prefix=FOUND +# Use debuginfod to replace very-stripped binaries entirely. +RUN: llvm-strip --strip-sections %t/stripped +RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-objdump -d --debuginfod \ +RUN: %t/stripped | \ +RUN: FileCheck %s --check-prefix=SYMBOLS + +SYMBOLS:
: + FOUND: int main(int argc, char *argv[]) { NOTFOUND-NOT: int main(int argc, char *argv[]) { diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1267,9 +1267,9 @@ llvm_unreachable("Unsupported binary format"); } -// Try to fetch a debug file for the given object file using its Build ID. -// Returns none if no additional debug information was found. -static Optional> fetchDebugFile(const ObjectFile &Obj) { +// Tries to fetch a more complete version of the given object file using its +// Build ID. Returns none if nothing was found. +static Optional> fetchBinaryByBuildID(const ObjectFile &Obj) { Optional BuildID = getBuildID(&Obj); if (!BuildID) return None; @@ -1281,10 +1281,7 @@ consumeError(DebugBinary.takeError()); return None; } - if (ObjectFile *DbgObj = dyn_cast(DebugBinary->getBinary()); - DbgObj->hasDebugInfo()) - return std::move(*DebugBinary); - return None; + return std::move(*DebugBinary); } static void disassembleObject(const Target *TheTarget, ObjectFile &Obj, @@ -1861,6 +1858,22 @@ } static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) { + // If information useful for showing the disassembly is missing, try to find a + // more complete binary and disassemble that instead. + OwningBinary FetchedBinary; + if (Obj->sections().empty() || Obj->symbols().empty()) { + if (Optional> FetchedBinaryOpt = + fetchBinaryByBuildID(*Obj)) { + if (auto *O = dyn_cast(FetchedBinaryOpt->getBinary()); + (!O->sections().empty() || !O->symbols().empty()) && + (!O->sections().empty() || Obj->sections().empty()) && + (!O->symbols().empty() || Obj->symbols().empty())) { + FetchedBinary = std::move(*FetchedBinaryOpt); + Obj = O; + } + } + } + const Target *TheTarget = getTarget(Obj); // Package up features to be passed to target/subtarget @@ -1964,12 +1977,15 @@ PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName)); ObjectFile *DbgObj = Obj; - OwningBinary DebugBinary; - if (!Obj->hasDebugInfo()) { - Optional> DebugBinaryOpt = fetchDebugFile(*Obj); - if (DebugBinaryOpt) { - DebugBinary = std::move(*DebugBinaryOpt); - DbgObj = cast(DebugBinary.getBinary()); + if (!FetchedBinary.getBinary() && !Obj->hasDebugInfo()) { + if (Optional> DebugBinaryOpt = + fetchBinaryByBuildID(*Obj)) { + if (ObjectFile *FetchedObj = + dyn_cast(DebugBinaryOpt->getBinary()); + FetchedObj->hasDebugInfo()) { + FetchedBinary = std::move(*DebugBinaryOpt); + DbgObj = FetchedObj; + } } } SourcePrinter SP(DbgObj, TheTarget->getName());