================
@@ -204,59 +232,108 @@ OffloadBinary::create(MemoryBufferRef Buf) {
       new OffloadBinary(Buf, TheHeader, TheEntry));
 }
 
-SmallString<0> OffloadBinary::write(const OffloadingImage &OffloadingData) {
+Expected<std::unique_ptr<OffloadBinary>>
+OffloadBinary::createV2(MemoryBufferRef Buf) {
+  auto HeaderOrErr = extractHeader(Buf);
+  if (!HeaderOrErr)
+    return HeaderOrErr.takeError();
+  const Header *TheHeader = *HeaderOrErr;
+
+  const char *Start = Buf.getBufferStart();
+
+  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);
+  }
+
+  return std::unique_ptr<OffloadBinary>(
+      new OffloadBinary(Buf, TheHeader, Entries));
+}
+
+SmallString<0> OffloadBinary::write(ArrayRef<OffloadingImage> OffloadingData) {
+  uint64_t EntriesCount = OffloadingData.size();
+  assert(EntriesCount > 0 && "At least one offloading image is required");
+
   // Create a null-terminated string table with all the used strings.
+  // Also calculate total size of images.
   StringTableBuilder StrTab(StringTableBuilder::ELF);
-  for (auto &KeyAndValue : OffloadingData.StringData) {
-    StrTab.add(KeyAndValue.first);
-    StrTab.add(KeyAndValue.second);
+  uint64_t TotalStringEntries = 0;
+  uint64_t TotalImagesSize = 0;
+  for (const OffloadingImage &Img : OffloadingData) {
+    for (auto &KeyAndValue : Img.StringData) {
+      StrTab.add(KeyAndValue.first);
+      StrTab.add(KeyAndValue.second);
+    }
+    TotalStringEntries += Img.StringData.size();
+    TotalImagesSize += Img.Image->getBufferSize();
   }
   StrTab.finalize();
 
-  uint64_t StringEntrySize =
-      sizeof(StringEntry) * OffloadingData.StringData.size();
+  uint64_t StringEntrySize = sizeof(StringEntry) * TotalStringEntries;
+  uint64_t EntriesSize = sizeof(Entry) * EntriesCount;
+  uint64_t StrTabOffset = sizeof(Header) + EntriesSize + StringEntrySize;
 
   // Make sure the image we're wrapping around is aligned as well.
-  uint64_t BinaryDataSize = alignTo(sizeof(Header) + sizeof(Entry) +
-                                        StringEntrySize + StrTab.getSize(),
-                                    getAlignment());
+  uint64_t BinaryDataSize =
+      alignTo(StrTabOffset + StrTab.getSize(), getAlignment());
 
-  // Create the header and fill in the offsets. The entry will be directly
+  // Create the header and fill in the offsets. The entries will be directly
   // placed after the header in memory. Align the size to the alignment of the
   // header so this can be placed contiguously in a single section.
   Header TheHeader;
-  TheHeader.Size = alignTo(
-      BinaryDataSize + OffloadingData.Image->getBufferSize(), getAlignment());
-  TheHeader.EntryOffset = sizeof(Header);
-  TheHeader.EntrySize = sizeof(Entry);
-
-  // 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.
-  Entry TheEntry;
-  TheEntry.TheImageKind = OffloadingData.TheImageKind;
-  TheEntry.TheOffloadKind = OffloadingData.TheOffloadKind;
-  TheEntry.Flags = OffloadingData.Flags;
-  TheEntry.StringOffset = sizeof(Header) + sizeof(Entry);
-  TheEntry.NumStrings = OffloadingData.StringData.size();
-
-  TheEntry.ImageOffset = BinaryDataSize;
-  TheEntry.ImageSize = OffloadingData.Image->getBufferSize();
+  TheHeader.Size = alignTo(BinaryDataSize + TotalImagesSize, getAlignment());
+  TheHeader.EntriesOffset = sizeof(Header);
+  TheHeader.EntriesCount = EntriesCount;
 
   SmallString<0> Data;
   Data.reserve(TheHeader.Size);
   raw_svector_ostream OS(Data);
   OS << StringRef(reinterpret_cast<char *>(&TheHeader), sizeof(Header));
-  OS << StringRef(reinterpret_cast<char *>(&TheEntry), sizeof(Entry));
-  for (auto &KeyAndValue : OffloadingData.StringData) {
-    uint64_t Offset = sizeof(Header) + sizeof(Entry) + StringEntrySize;
-    StringEntry Map{Offset + StrTab.getOffset(KeyAndValue.first),
-                    Offset + StrTab.getOffset(KeyAndValue.second)};
-    OS << StringRef(reinterpret_cast<char *>(&Map), sizeof(StringEntry));
+
+  // Create the entries using the string table offsets. The string table will 
be
+  // placed directly after the set of entries in memory, and all the images are
+  // after that.
+  uint64_t StringEntryOffset = sizeof(Header) + EntriesSize;
----------------
jhuber6 wrote:

Right, forgot about the change to the size of the string. I guess it's fine 
because the same information is present in either version so the parsing 
functions should be compatible. If it's version 1 we use strlen, if it's 
version 2 we use the given size, I think that's the only change needed. I was 
just a little confused because it seemed like the placement of the string data 
changed here

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

Reply via email to