[clang] [llvm] [llvm][tools] Exted llvm-objdump to support nested OffloadBinaries (PR #185425)

Alex Duran via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 9 07:42:19 PDT 2026


https://github.com/adurang updated https://github.com/llvm/llvm-project/pull/185425

>From 30ed5e4f34339bbb7fd7e3c454f4fa109e1d893b Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Mon, 9 Mar 2026 07:09:28 -0700
Subject: [PATCH 1/4] [llvm][tools] Exted llvm-objdump to support nested
 OffloadBinaries

---
 llvm/tools/llvm-objdump/OffloadDump.cpp | 61 +++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 5 deletions(-)

diff --git a/llvm/tools/llvm-objdump/OffloadDump.cpp b/llvm/tools/llvm-objdump/OffloadDump.cpp
index cd2727069c2e9..1d48d44dcafc9 100644
--- a/llvm/tools/llvm-objdump/OffloadDump.cpp
+++ b/llvm/tools/llvm-objdump/OffloadDump.cpp
@@ -13,6 +13,7 @@
 
 #include "OffloadDump.h"
 #include "llvm-objdump.h"
+#include "llvm/BinaryFormat/Magic.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/OffloadBinary.h"
 #include "llvm/Object/OffloadBundle.h"
@@ -43,13 +44,63 @@ static StringRef getImageName(const OffloadBinary &OB) {
   }
 }
 
+static void printOffloadBinaryMetadata(const OffloadBinary &OB,
+                                       uint64_t justifaction) {
+  outs() << left_justify("kind", justifaction) << getImageName(OB) << "\n";
+  outs() << left_justify("arch", justifaction) << OB.getArch() << "\n";
+  outs() << left_justify("triple", justifaction) << OB.getTriple() << "\n";
+  outs() << left_justify("producer", justifaction)
+         << getOffloadKindName(OB.getOffloadKind()) << "\n";
+
+  StringRef InnerImage = OB.getImage();
+  outs() << left_justify("    image size", justifaction) << InnerImage.size()
+         << " bytes\n";
+}
+
+/// Print information about nested OffloadBinary (inner layer)
+static void printNestedOffloadBinary(const OffloadBinary &OuterOB,
+                                     uint64_t Index) {
+  StringRef ImageData = OuterOB.getImage();
+
+  // Parse inner OffloadBinary
+  MemoryBufferRef InnerBuffer(ImageData, "inner-offload-binary");
+  auto InnerBinariesOrErr = OffloadBinary::create(InnerBuffer);
+  if (!InnerBinariesOrErr) {
+    reportWarning("Failed to parse nested OffloadBinary: " +
+                      toString(InnerBinariesOrErr.takeError()),
+                  OuterOB.getFileName());
+    return;
+  }
+
+  auto &InnerBinaries = *InnerBinariesOrErr;
+  if (InnerBinaries.empty()) {
+    reportWarning("Nested OffloadBinary contains no entries",
+                  OuterOB.getFileName());
+    return;
+  }
+
+  outs() << "  [Nested OffloadBinary format detected]\n";
+  outs() << "  Number of inner images: " << InnerBinaries.size() << "\n";
+
+  // Display information for each inner image
+  for (uint64_t I = 0, E = InnerBinaries.size(); I != E; ++I) {
+    const OffloadBinary *InnerOB = InnerBinaries[I].get();
+
+    if (InnerBinaries.size() > 1)
+      outs() << "  Inner image [" << I << "]:\n";
+
+    printOffloadBinaryMetadata(*InnerOB, 20);
+  }
+}
+
 static void printBinary(const OffloadBinary &OB, uint64_t Index) {
   outs() << "\nOFFLOADING IMAGE [" << Index << "]:\n";
-  outs() << left_justify("kind", 16) << getImageName(OB) << "\n";
-  outs() << left_justify("arch", 16) << OB.getArch() << "\n";
-  outs() << left_justify("triple", 16) << OB.getTriple() << "\n";
-  outs() << left_justify("producer", 16)
-         << getOffloadKindName(OB.getOffloadKind()) << "\n";
+  printOffloadBinaryMetadata(OB, 16);
+
+  StringRef ImageData = OB.getImage();
+  // Check for nested OffloadBinary format
+  if (identify_magic(ImageData) == file_magic::offload_binary)
+    printNestedOffloadBinary(OB, Index);
 }
 
 /// Print the embedded offloading contents of an ObjectFile \p O.

>From c16e95113ef5c183939e7cc89bcc438539487dfc Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Mon, 9 Mar 2026 07:29:09 -0700
Subject: [PATCH 2/4] Add test

---
 clang/test/Tooling/clang-linker-wrapper-spirv.cpp | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 clang/test/Tooling/clang-linker-wrapper-spirv.cpp

diff --git a/clang/test/Tooling/clang-linker-wrapper-spirv.cpp b/clang/test/Tooling/clang-linker-wrapper-spirv.cpp
new file mode 100644
index 0000000000000..74d1fb2c212c1
--- /dev/null
+++ b/clang/test/Tooling/clang-linker-wrapper-spirv.cpp
@@ -0,0 +1,14 @@
+// Verify the ELF packaging of OpenMP SPIR-V device images.
+// REQUIRES: system-linux
+// REQUIRES: spirv-tools
+// REQUIRES: spirv-registered-target
+// RUN: %clangxx -fopenmp -fopenmp-targets=spirv64-intel -nogpulib -o %t %s
+// RUN: llvm-objdump --offloading %t | FileCheck -check-prefix=CHECK %s
+
+// CHECK: [Nested OffloadBinary
+// CHECK: Number of inner images: 1
+// CHECK: spirv64-intel
+
+int main(int argc, char** argv) {
+  return 0;
+}

>From 7b5920b79b5fdd9ef152e245b03a13e78dda3c03 Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Mon, 9 Mar 2026 07:40:58 -0700
Subject: [PATCH 3/4] fix tool output

---
 llvm/tools/llvm-objdump/OffloadDump.cpp | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/llvm/tools/llvm-objdump/OffloadDump.cpp b/llvm/tools/llvm-objdump/OffloadDump.cpp
index 1d48d44dcafc9..50b4178495b68 100644
--- a/llvm/tools/llvm-objdump/OffloadDump.cpp
+++ b/llvm/tools/llvm-objdump/OffloadDump.cpp
@@ -45,15 +45,17 @@ static StringRef getImageName(const OffloadBinary &OB) {
 }
 
 static void printOffloadBinaryMetadata(const OffloadBinary &OB,
-                                       uint64_t justifaction) {
-  outs() << left_justify("kind", justifaction) << getImageName(OB) << "\n";
-  outs() << left_justify("arch", justifaction) << OB.getArch() << "\n";
-  outs() << left_justify("triple", justifaction) << OB.getTriple() << "\n";
-  outs() << left_justify("producer", justifaction)
+                                       uint64_t level) {
+  const std::string Indent(level * 2, ' ');
+
+  outs() << Indent << left_justify("kind", 16) << getImageName(OB) << "\n";
+  outs() << Indent << left_justify("arch", 16) << OB.getArch() << "\n";
+  outs() << Indent << left_justify("triple", 16) << OB.getTriple() << "\n";
+  outs() << Indent << left_justify("producer", 16)
          << getOffloadKindName(OB.getOffloadKind()) << "\n";
 
   StringRef InnerImage = OB.getImage();
-  outs() << left_justify("    image size", justifaction) << InnerImage.size()
+  outs() << Indent << left_justify("image size", 16) << InnerImage.size()
          << " bytes\n";
 }
 
@@ -89,13 +91,13 @@ static void printNestedOffloadBinary(const OffloadBinary &OuterOB,
     if (InnerBinaries.size() > 1)
       outs() << "  Inner image [" << I << "]:\n";
 
-    printOffloadBinaryMetadata(*InnerOB, 20);
+    printOffloadBinaryMetadata(*InnerOB, 1);
   }
 }
 
 static void printBinary(const OffloadBinary &OB, uint64_t Index) {
   outs() << "\nOFFLOADING IMAGE [" << Index << "]:\n";
-  printOffloadBinaryMetadata(OB, 16);
+  printOffloadBinaryMetadata(OB, 0);
 
   StringRef ImageData = OB.getImage();
   // Check for nested OffloadBinary format

>From 69ce34569bda1a251eedf75d5ca62f896a72145c Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Mon, 9 Mar 2026 07:42:00 -0700
Subject: [PATCH 4/4] fix messages

---
 llvm/tools/llvm-objdump/OffloadDump.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/tools/llvm-objdump/OffloadDump.cpp b/llvm/tools/llvm-objdump/OffloadDump.cpp
index 50b4178495b68..ffe4d52d30446 100644
--- a/llvm/tools/llvm-objdump/OffloadDump.cpp
+++ b/llvm/tools/llvm-objdump/OffloadDump.cpp
@@ -68,7 +68,7 @@ static void printNestedOffloadBinary(const OffloadBinary &OuterOB,
   MemoryBufferRef InnerBuffer(ImageData, "inner-offload-binary");
   auto InnerBinariesOrErr = OffloadBinary::create(InnerBuffer);
   if (!InnerBinariesOrErr) {
-    reportWarning("Failed to parse nested OffloadBinary: " +
+    reportWarning("failed to parse nested OffloadBinary: " +
                       toString(InnerBinariesOrErr.takeError()),
                   OuterOB.getFileName());
     return;
@@ -76,7 +76,7 @@ static void printNestedOffloadBinary(const OffloadBinary &OuterOB,
 
   auto &InnerBinaries = *InnerBinariesOrErr;
   if (InnerBinaries.empty()) {
-    reportWarning("Nested OffloadBinary contains no entries",
+    reportWarning("nested OffloadBinary contains no entries",
                   OuterOB.getFileName());
     return;
   }



More information about the cfe-commits mailing list