https://github.com/YuriPlyakhin updated 
https://github.com/llvm/llvm-project/pull/169425

>From ce7ab7652cf29469a8addea8ebe67f408b4b03af Mon Sep 17 00:00:00 2001
From: "Plyakhin, Yury" <[email protected]>
Date: Tue, 25 Nov 2025 00:40:45 +0100
Subject: [PATCH 1/3] [Offloading] Extend OffloadBinary format to support
 multiple metadata entries

---
 llvm/include/llvm/Object/OffloadBinary.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Object/OffloadBinary.h 
b/llvm/include/llvm/Object/OffloadBinary.h
index f3847c1624977..cf25c02bc43fd 100644
--- a/llvm/include/llvm/Object/OffloadBinary.h
+++ b/llvm/include/llvm/Object/OffloadBinary.h
@@ -67,7 +67,7 @@ class OffloadBinary : public Binary {
   using string_iterator_range = iterator_range<string_iterator>;
 
   /// The current version of the binary used for backwards compatibility.
-  static const uint32_t Version = 1;
+  static const uint32_t Version = 2;
 
   /// The offloading metadata that will be serialized to a memory buffer.
   struct OffloadingImage {
@@ -109,9 +109,12 @@ class OffloadBinary : public Binary {
   struct Header {
     uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
     uint32_t Version = OffloadBinary::Version;   // Version identifier.
-    uint64_t Size;        // Size in bytes of this entire binary.
-    uint64_t EntryOffset; // Offset of the metadata entry in bytes.
-    uint64_t EntrySize;   // Size of the metadata entry in bytes.
+    uint64_t Size;          // Size in bytes of this entire binary.
+    uint64_t EntriesCount;  // Number of metadata entries in the binary.
+    uint64_t EntriesOffset; // Offset in bytes to the start of entries block.
+    uint64_t EntriesSize;   // Size of the entries block in bytes.
+    uint64_t StringOffset;  // Offset in bytes to the global string map
+    uint64_t NumStrings;    // Number of entries in the global string map.
   };
 
   struct Entry {
@@ -127,6 +130,7 @@ class OffloadBinary : public Binary {
   struct StringEntry {
     uint64_t KeyOffset;
     uint64_t ValueOffset;
+    uint64_t ValueSize;   // Size of the value in bytes.
   };
 
 private:

>From f66ae8cca8d7678ba900c15eef1fa5fdb83a70dc Mon Sep 17 00:00:00 2001
From: "Plyakhin, Yury" <[email protected]>
Date: Tue, 25 Nov 2025 21:04:43 +0100
Subject: [PATCH 2/3] updated offloadbinary per discussion

---
 llvm/include/llvm/Object/OffloadBinary.h | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/Object/OffloadBinary.h 
b/llvm/include/llvm/Object/OffloadBinary.h
index cf25c02bc43fd..bdcacce204966 100644
--- a/llvm/include/llvm/Object/OffloadBinary.h
+++ b/llvm/include/llvm/Object/OffloadBinary.h
@@ -52,6 +52,13 @@ enum ImageKind : uint16_t {
   IMG_LAST,
 };
 
+/// Flags associated with the Entry.
+enum OffloadEntryFlags : uint32_t {
+  OIF_None = 0,
+  // Entry doesn't contain image. Used to keep metadata only entries.
+  OIF_NoImage = (1 << 0),
+};
+
 /// A simple binary serialization of an offloading file. We use this format to
 /// embed the offloading image into the host executable so it can be extracted
 /// and used by the linker.
@@ -110,17 +117,14 @@ class OffloadBinary : public Binary {
     uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
     uint32_t Version = OffloadBinary::Version;   // Version identifier.
     uint64_t Size;          // Size in bytes of this entire binary.
-    uint64_t EntriesCount;  // Number of metadata entries in the binary.
     uint64_t EntriesOffset; // Offset in bytes to the start of entries block.
-    uint64_t EntriesSize;   // Size of the entries block in bytes.
-    uint64_t StringOffset;  // Offset in bytes to the global string map
-    uint64_t NumStrings;    // Number of entries in the global string map.
+    uint64_t EntriesCount;  // Number of metadata entries in the binary.
   };
 
   struct Entry {
     ImageKind TheImageKind;     // The kind of the image stored.
     OffloadKind TheOffloadKind; // The producer of this image.
-    uint32_t Flags;             // Additional flags associated with the image.
+    uint32_t Flags;             // Additional flags associated with the entry.
     uint64_t StringOffset;      // Offset in bytes to the string map.
     uint64_t NumStrings;        // Number of entries in the string map.
     uint64_t ImageOffset;       // Offset in bytes of the actual binary image.

>From 98ad7e9b818a68029b4f8d1b274d5165d8dd1bdf Mon Sep 17 00:00:00 2001
From: "Plyakhin, Yury" <[email protected]>
Date: Wed, 26 Nov 2025 03:16:48 +0100
Subject: [PATCH 3/3] Minimal changes to make build and lit tests pass with new
 OffloadBinary format.

---
 clang/test/Driver/linker-wrapper-image.c      |  2 +-
 llvm/include/llvm/Object/OffloadBinary.h      |  2 +-
 llvm/include/llvm/ObjectYAML/OffloadYAML.h    |  4 ++--
 .../Frontend/Offloading/OffloadWrapper.cpp    |  2 +-
 llvm/lib/Object/OffloadBinary.cpp             | 24 +++++++++++--------
 llvm/lib/ObjectYAML/OffloadEmitter.cpp        |  8 +++----
 llvm/lib/ObjectYAML/OffloadYAML.cpp           |  4 ++--
 ...size.yaml => malformed-entries-count.yaml} |  2 +-
 .../ObjectYAML/Offload/malformed-offset.yaml  |  2 +-
 .../ObjectYAML/Offload/malformed-version.yaml |  2 +-
 10 files changed, 28 insertions(+), 24 deletions(-)
 rename llvm/test/ObjectYAML/Offload/{malformed-entry-size.yaml => 
malformed-entries-count.yaml} (94%)

diff --git a/clang/test/Driver/linker-wrapper-image.c 
b/clang/test/Driver/linker-wrapper-image.c
index b9327121edcf9..2c0df8c6be925 100644
--- a/clang/test/Driver/linker-wrapper-image.c
+++ b/clang/test/Driver/linker-wrapper-image.c
@@ -25,7 +25,7 @@
 // OPENMP-REL: @.omp_offloading.device_image = internal unnamed_addr constant 
[[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section 
".llvm.offloading.relocatable", align 8
 
 //      OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant 
[[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading", align 
8
-// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr 
constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr 
([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), 
ptr getelementptr ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, 
i64 0, i64 144), ptr @__start_llvm_offload_entries, ptr 
@__stop_llvm_offload_entries }]
+// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr 
constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr 
([[[IMG_OFF:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 
[[IMG_OFF]]), ptr getelementptr ([[[IMG_OFF]] x i8], ptr 
@.omp_offloading.device_image, i64 0, i64 [[IMG_OFF]]), ptr 
@__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries }]
 // OPENMP-NEXT: @.omp_offloading.descriptor = internal constant 
%__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr 
@__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries }
 // OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] 
[{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }]
 
diff --git a/llvm/include/llvm/Object/OffloadBinary.h 
b/llvm/include/llvm/Object/OffloadBinary.h
index bdcacce204966..74dcd5cc7384b 100644
--- a/llvm/include/llvm/Object/OffloadBinary.h
+++ b/llvm/include/llvm/Object/OffloadBinary.h
@@ -134,7 +134,7 @@ class OffloadBinary : public Binary {
   struct StringEntry {
     uint64_t KeyOffset;
     uint64_t ValueOffset;
-    uint64_t ValueSize;   // Size of the value in bytes.
+    uint64_t ValueSize; // Size of the value in bytes.
   };
 
 private:
diff --git a/llvm/include/llvm/ObjectYAML/OffloadYAML.h 
b/llvm/include/llvm/ObjectYAML/OffloadYAML.h
index f897b52aa8b0e..63ff561f3fcbf 100644
--- a/llvm/include/llvm/ObjectYAML/OffloadYAML.h
+++ b/llvm/include/llvm/ObjectYAML/OffloadYAML.h
@@ -39,8 +39,8 @@ struct Binary {
 
   std::optional<uint32_t> Version;
   std::optional<uint64_t> Size;
-  std::optional<uint64_t> EntryOffset;
-  std::optional<uint64_t> EntrySize;
+  std::optional<uint64_t> EntriesOffset;
+  std::optional<uint64_t> EntriesCount;
   std::vector<Member> Members;
 };
 
diff --git a/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp 
b/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
index 288fa10fc04bb..f1602765dbaa7 100644
--- a/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
+++ b/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
@@ -161,7 +161,7 @@ GlobalVariable *createBinDesc(Module &M, 
ArrayRef<ArrayRef<char>> Bufs,
               Binary.bytes_begin());
       const auto *Entry =
           reinterpret_cast<const object::OffloadBinary::Entry *>(
-              Binary.bytes_begin() + Header->EntryOffset);
+              Binary.bytes_begin() + Header->EntriesOffset);
       BeginOffset = Entry->ImageOffset;
       EndOffset = Entry->ImageOffset + Entry->ImageSize;
     }
diff --git a/llvm/lib/Object/OffloadBinary.cpp 
b/llvm/lib/Object/OffloadBinary.cpp
index 3fff6b6a09e08..8e51b94b92951 100644
--- a/llvm/lib/Object/OffloadBinary.cpp
+++ b/llvm/lib/Object/OffloadBinary.cpp
@@ -189,19 +189,23 @@ OffloadBinary::create(MemoryBufferRef Buf) {
       TheHeader->Size < sizeof(Entry) || TheHeader->Size < sizeof(Header))
     return errorCodeToError(object_error::unexpected_eof);
 
-  if (TheHeader->EntryOffset > TheHeader->Size - sizeof(Entry) ||
-      TheHeader->EntrySize > TheHeader->Size - sizeof(Header))
+  uint64_t EntriesSize = sizeof(Entry) * TheHeader->EntriesCount;
+  if (TheHeader->EntriesOffset > TheHeader->Size - EntriesSize ||
+      EntriesSize > TheHeader->Size - sizeof(Header))
     return errorCodeToError(object_error::unexpected_eof);
 
-  const Entry *TheEntry =
-      reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);
+  const Entry *Entries =
+      reinterpret_cast<const Entry *>(&Start[TheHeader->EntriesOffset]);
+  for (uint32_t I = 0; I < TheHeader->EntriesCount; ++I) {
+    const Entry *TheEntry = &Entries[I];
 
-  if (TheEntry->ImageOffset > Buf.getBufferSize() ||
-      TheEntry->StringOffset > Buf.getBufferSize())
-    return errorCodeToError(object_error::unexpected_eof);
+    if (TheEntry->ImageOffset > Buf.getBufferSize() ||
+        TheEntry->StringOffset > Buf.getBufferSize())
+      return errorCodeToError(object_error::unexpected_eof);
+  }
 
   return std::unique_ptr<OffloadBinary>(
-      new OffloadBinary(Buf, TheHeader, TheEntry));
+      new OffloadBinary(Buf, TheHeader, Entries));
 }
 
 SmallString<0> OffloadBinary::write(const OffloadingImage &OffloadingData) {
@@ -227,8 +231,8 @@ SmallString<0> OffloadBinary::write(const OffloadingImage 
&OffloadingData) {
   Header TheHeader;
   TheHeader.Size = alignTo(
       BinaryDataSize + OffloadingData.Image->getBufferSize(), getAlignment());
-  TheHeader.EntryOffset = sizeof(Header);
-  TheHeader.EntrySize = sizeof(Entry);
+  TheHeader.EntriesOffset = sizeof(Header);
+  TheHeader.EntriesCount = 1;
 
   // Create the entry using the string table offsets. The string table will be
   // placed directly after the entry in memory, and the image after that.
diff --git a/llvm/lib/ObjectYAML/OffloadEmitter.cpp 
b/llvm/lib/ObjectYAML/OffloadEmitter.cpp
index 131da68d77506..34eca4d61a410 100644
--- a/llvm/lib/ObjectYAML/OffloadEmitter.cpp
+++ b/llvm/lib/ObjectYAML/OffloadEmitter.cpp
@@ -45,10 +45,10 @@ bool yaml2offload(Binary &Doc, raw_ostream &Out, 
ErrorHandler EH) {
       TheHeader->Version = *Doc.Version;
     if (Doc.Size)
       TheHeader->Size = *Doc.Size;
-    if (Doc.EntryOffset)
-      TheHeader->EntryOffset = *Doc.EntryOffset;
-    if (Doc.EntrySize)
-      TheHeader->EntrySize = *Doc.EntrySize;
+    if (Doc.EntriesOffset)
+      TheHeader->EntriesOffset = *Doc.EntriesOffset;
+    if (Doc.EntriesCount)
+      TheHeader->EntriesCount = *Doc.EntriesCount;
 
     Out.write(Buffer.begin(), Buffer.size());
   }
diff --git a/llvm/lib/ObjectYAML/OffloadYAML.cpp 
b/llvm/lib/ObjectYAML/OffloadYAML.cpp
index d5a0edde2179f..cab5a39741294 100644
--- a/llvm/lib/ObjectYAML/OffloadYAML.cpp
+++ b/llvm/lib/ObjectYAML/OffloadYAML.cpp
@@ -50,8 +50,8 @@ void MappingTraits<OffloadYAML::Binary>::mapping(IO &IO,
   IO.mapTag("!Offload", true);
   IO.mapOptional("Version", O.Version);
   IO.mapOptional("Size", O.Size);
-  IO.mapOptional("EntryOffset", O.EntryOffset);
-  IO.mapOptional("EntrySize", O.EntrySize);
+  IO.mapOptional("EntriesOffset", O.EntriesOffset);
+  IO.mapOptional("EntriesCount", O.EntriesCount);
   IO.mapRequired("Members", O.Members);
   IO.setContext(nullptr);
 }
diff --git a/llvm/test/ObjectYAML/Offload/malformed-entry-size.yaml 
b/llvm/test/ObjectYAML/Offload/malformed-entries-count.yaml
similarity index 94%
rename from llvm/test/ObjectYAML/Offload/malformed-entry-size.yaml
rename to llvm/test/ObjectYAML/Offload/malformed-entries-count.yaml
index 3194607ae39a5..bb2a34277963f 100644
--- a/llvm/test/ObjectYAML/Offload/malformed-entry-size.yaml
+++ b/llvm/test/ObjectYAML/Offload/malformed-entries-count.yaml
@@ -1,6 +1,6 @@
 # RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s
 !Offload
-EntrySize: 999999999
+EntriesCount: 999999999
 Members:
   - ImageKind:        IMG_Cubin
     OffloadKind:      OFK_OpenMP
diff --git a/llvm/test/ObjectYAML/Offload/malformed-offset.yaml 
b/llvm/test/ObjectYAML/Offload/malformed-offset.yaml
index 03c0431053cce..5aecfffd937bf 100644
--- a/llvm/test/ObjectYAML/Offload/malformed-offset.yaml
+++ b/llvm/test/ObjectYAML/Offload/malformed-offset.yaml
@@ -1,6 +1,6 @@
 # RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s
 !Offload
-EntryOffset: 999999999
+EntriesOffset: 999999999
 Members:
   - ImageKind:        IMG_Cubin
     OffloadKind:      OFK_OpenMP
diff --git a/llvm/test/ObjectYAML/Offload/malformed-version.yaml 
b/llvm/test/ObjectYAML/Offload/malformed-version.yaml
index f9279a52e2764..99383491acce0 100644
--- a/llvm/test/ObjectYAML/Offload/malformed-version.yaml
+++ b/llvm/test/ObjectYAML/Offload/malformed-version.yaml
@@ -1,6 +1,6 @@
 # RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s
 !Offload
-Version: 2
+Version: 3
 Members:
   - ImageKind:        IMG_Cubin
     OffloadKind:      OFK_OpenMP

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to