[PATCH] D132887: [objdump] [debuginfod] Fetch for very-stripped binaries.

Daniel Thornburgh via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 13:57:42 PDT 2022


mysterymath created this revision.
mysterymath added reviewers: jhenderson, MaskRay, alexander-shaposhnikov, phosek, mcgrathr.
Herald added subscribers: StephenFan, rupprecht.
Herald added a project: All.
mysterymath requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

When a binary is missing section headers or symbols, objdump can't
provide as good of a disassembly. This change makes objdump try to fetch
a better verion of the binary by its build ID.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132887

Files:
  llvm/test/tools/llvm-objdump/debuginfod.test
  llvm/tools/llvm-objdump/llvm-objdump.cpp


Index: llvm/tools/llvm-objdump/llvm-objdump.cpp
===================================================================
--- llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ 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<OwningBinary<Binary>> 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<OwningBinary<Binary>> fetchBinaryByBuildID(const ObjectFile &Obj) {
   Optional<object::BuildIDRef> BuildID = getBuildID(&Obj);
   if (!BuildID)
     return None;
@@ -1281,10 +1281,7 @@
     consumeError(DebugBinary.takeError());
     return None;
   }
-  if (ObjectFile *DbgObj = dyn_cast<ObjectFile>(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<Binary> FetchedBinary;
+  if (Obj->sections().empty() || Obj->symbols().empty()) {
+    if (Optional<OwningBinary<Binary>> FetchedBinaryOpt =
+            fetchBinaryByBuildID(*Obj)) {
+      if (auto *O = dyn_cast<ObjectFile>(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<Binary> DebugBinary;
-  if (!Obj->hasDebugInfo()) {
-    Optional<OwningBinary<Binary>> DebugBinaryOpt = fetchDebugFile(*Obj);
-    if (DebugBinaryOpt) {
-      DebugBinary = std::move(*DebugBinaryOpt);
-      DbgObj = cast<ObjectFile>(DebugBinary.getBinary());
+  if (!FetchedBinary.getBinary() && !Obj->hasDebugInfo()) {
+    if (Optional<OwningBinary<Binary>> DebugBinaryOpt =
+            fetchBinaryByBuildID(*Obj)) {
+      if (ObjectFile *FetchedObj =
+              dyn_cast<ObjectFile>(DebugBinaryOpt->getBinary());
+          FetchedObj->hasDebugInfo()) {
+        FetchedBinary = std::move(*DebugBinaryOpt);
+        DbgObj = FetchedObj;
+      }
     }
   }
   SourcePrinter SP(DbgObj, TheTarget->getName());
Index: llvm/test/tools/llvm-objdump/debuginfod.test
===================================================================
--- llvm/test/tools/llvm-objdump/debuginfod.test
+++ 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: <main>:
+
 FOUND: int main(int argc, char *argv[]) {
 NOTFOUND-NOT: int main(int argc, char *argv[]) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132887.456456.patch
Type: text/x-patch
Size: 3599 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220829/75107866/attachment.bin>


More information about the llvm-commits mailing list