jhuber6 created this revision.
jhuber6 added reviewers: jdoerfert, tra, JonChesterfield, MaskRay.
Herald added a reviewer: deadalnix.
Herald added subscribers: ormris, StephenFan, hiraditya.
Herald added a project: All.
jhuber6 requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, aheejin.
Herald added projects: clang, LLVM.

We use the `OffloadBinary` to create binary images of offloading files
and their corresonding metadata. This patch changes this to inherit from
the base `Binary` class. This allows us to create and insepect these
more generically. This patch includes all the necessary glue to
implement this as a new binary format, along with added the magic bytes
we use to distinguish the offloading binary to the `file_magic`
implementation.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126812

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  llvm/include/llvm-c/Object.h
  llvm/include/llvm/BinaryFormat/Magic.h
  llvm/include/llvm/Object/Binary.h
  llvm/include/llvm/Object/OffloadBinary.h
  llvm/lib/BinaryFormat/Magic.cpp
  llvm/lib/Object/Binary.cpp
  llvm/lib/Object/Object.cpp
  llvm/lib/Object/ObjectFile.cpp
  llvm/lib/Object/OffloadBinary.cpp

Index: llvm/lib/Object/OffloadBinary.cpp
===================================================================
--- llvm/lib/Object/OffloadBinary.cpp
+++ llvm/lib/Object/OffloadBinary.cpp
@@ -9,22 +9,22 @@
 #include "llvm/Object/OffloadBinary.h"
 
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Magic.h"
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Support/FileOutputBuffer.h"
 
 using namespace llvm;
-
-namespace llvm {
+using namespace object;
 
 Expected<std::unique_ptr<OffloadBinary>>
 OffloadBinary::create(MemoryBufferRef Buf) {
   if (Buf.getBufferSize() < sizeof(Header) + sizeof(Entry))
-    return errorCodeToError(llvm::object::object_error::parse_failed);
+    return errorCodeToError(object_error::parse_failed);
 
   // Check for 0x10FF1OAD magic bytes.
-  if (!Buf.getBuffer().startswith("\x10\xFF\x10\xAD"))
-    return errorCodeToError(llvm::object::object_error::parse_failed);
+  if (identify_magic(Buf.getBuffer()) != file_magic::offload_binary)
+    return errorCodeToError(object_error::parse_failed);
 
   const char *Start = Buf.getBufferStart();
   const Header *TheHeader = reinterpret_cast<const Header *>(Start);
@@ -32,7 +32,7 @@
       reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);
 
   return std::unique_ptr<OffloadBinary>(
-      new OffloadBinary(Buf.getBufferStart(), TheHeader, TheEntry));
+      new OffloadBinary(Buf, TheHeader, TheEntry));
 }
 
 std::unique_ptr<MemoryBuffer>
@@ -93,7 +93,7 @@
   return MemoryBuffer::getMemBufferCopy(OS.str());
 }
 
-OffloadKind getOffloadKind(StringRef Name) {
+OffloadKind llvm::object::getOffloadKind(StringRef Name) {
   return llvm::StringSwitch<OffloadKind>(Name)
       .Case("openmp", OFK_OpenMP)
       .Case("cuda", OFK_Cuda)
@@ -101,7 +101,7 @@
       .Default(OFK_None);
 }
 
-StringRef getOffloadKindName(OffloadKind Kind) {
+StringRef llvm::object::getOffloadKindName(OffloadKind Kind) {
   switch (Kind) {
   case OFK_OpenMP:
     return "openmp";
@@ -114,7 +114,7 @@
   }
 }
 
-ImageKind getImageKind(StringRef Name) {
+ImageKind llvm::object::getImageKind(StringRef Name) {
   return llvm::StringSwitch<ImageKind>(Name)
       .Case("o", IMG_Object)
       .Case("bc", IMG_Bitcode)
@@ -124,7 +124,7 @@
       .Default(IMG_None);
 }
 
-StringRef getImageKindName(ImageKind Kind) {
+StringRef llvm::object::getImageKindName(ImageKind Kind) {
   switch (Kind) {
   case IMG_Object:
     return "o";
@@ -140,5 +140,3 @@
     return "";
   }
 }
-
-} // namespace llvm
Index: llvm/lib/Object/ObjectFile.cpp
===================================================================
--- llvm/lib/Object/ObjectFile.cpp
+++ llvm/lib/Object/ObjectFile.cpp
@@ -147,6 +147,7 @@
   case file_magic::minidump:
   case file_magic::goff_object:
   case file_magic::cuda_fatbinary:
+  case file_magic::offload_binary:
   case file_magic::dxcontainer_object:
     return errorCodeToError(object_error::invalid_file_type);
   case file_magic::tapi_file:
Index: llvm/lib/Object/Object.cpp
===================================================================
--- llvm/lib/Object/Object.cpp
+++ llvm/lib/Object/Object.cpp
@@ -120,6 +120,8 @@
         return LLVMBinaryTypeMachO64L;
       case ID_MachO64B:
         return LLVMBinaryTypeMachO64B;
+      case ID_Offload:
+        return LLVMBinaryTypeOffload;
       case ID_Wasm:
         return LLVMBinaryTypeWasm;
       case ID_StartObjects:
Index: llvm/lib/Object/Binary.cpp
===================================================================
--- llvm/lib/Object/Binary.cpp
+++ llvm/lib/Object/Binary.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/Minidump.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/OffloadBinary.h"
 #include "llvm/Object/TapiUniversal.h"
 #include "llvm/Object/WindowsResource.h"
 #include "llvm/Support/Error.h"
@@ -87,6 +88,8 @@
   case file_magic::dxcontainer_object:
     // Unrecognized object file format.
     return errorCodeToError(object_error::invalid_file_type);
+  case file_magic::offload_binary:
+    return OffloadBinary::create(Buffer);
   case file_magic::minidump:
     return MinidumpFile::create(Buffer);
   case file_magic::tapi_file:
Index: llvm/lib/BinaryFormat/Magic.cpp
===================================================================
--- llvm/lib/BinaryFormat/Magic.cpp
+++ llvm/lib/BinaryFormat/Magic.cpp
@@ -74,6 +74,11 @@
       return file_magic::goff_object;
     break;
 
+  case 0x10:
+    if (startswith(Magic, "\x10\xFF\x10\xAD"))
+      return file_magic::offload_binary;
+    break;
+
   case 0xDE: // 0x0B17C0DE = BC wraper
     if (startswith(Magic, "\xDE\xC0\x17\x0B"))
       return file_magic::bitcode;
Index: llvm/include/llvm/Object/OffloadBinary.h
===================================================================
--- llvm/include/llvm/Object/OffloadBinary.h
+++ llvm/include/llvm/Object/OffloadBinary.h
@@ -19,12 +19,15 @@
 
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Binary.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <memory>
 
 namespace llvm {
 
+namespace object {
+
 /// The producer of the associated offloading image.
 enum OffloadKind : uint16_t {
   OFK_None = 0,
@@ -54,7 +57,7 @@
 /// detect ABI stability and the size is used to find other offloading entries
 /// that may exist in the same section. All offsets are given as absolute byte
 /// offsets from the beginning of the file.
-class OffloadBinary {
+class OffloadBinary : public Binary {
 public:
   /// The offloading metadata that will be serialized to a memory buffer.
   struct OffloadingImage {
@@ -87,6 +90,8 @@
 
   StringRef getString(StringRef Key) const { return StringData.lookup(Key); }
 
+  static bool classof(const Binary *V) { return V->isOffloadFile(); }
+
 private:
   struct Header {
     uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
@@ -111,10 +116,11 @@
     uint64_t ValueOffset;
   };
 
-  OffloadBinary(const char *Buffer, const Header *TheHeader,
+  OffloadBinary(MemoryBufferRef Source, const Header *TheHeader,
                 const Entry *TheEntry)
-      : Buffer(Buffer), TheHeader(TheHeader), TheEntry(TheEntry) {
-
+      : Binary(Binary::ID_Offload, Source), Buffer(Source.getBufferStart()),
+        TheHeader(TheHeader), TheEntry(TheEntry) {
+    const char *Buffer = Data.getBufferStart();
     const StringEntry *StringMapBegin =
         reinterpret_cast<const StringEntry *>(&Buffer[TheEntry->StringOffset]);
     for (uint64_t I = 0, E = TheEntry->NumStrings; I != E; ++I) {
@@ -127,7 +133,7 @@
 
   /// Map from keys to offsets in the binary.
   StringMap<StringRef> StringData;
-  /// Pointer to the beginning of the memory buffer for convenience.
+  /// Raw pointer to the MemoryBufferRef for convenience.
   const char *Buffer;
   /// Location of the header within the binary.
   const Header *TheHeader;
@@ -147,5 +153,7 @@
 /// Convert an offload kind to its string representation.
 StringRef getOffloadKindName(OffloadKind Name);
 
+} // namespace object
+
 } // namespace llvm
 #endif
Index: llvm/include/llvm/Object/Binary.h
===================================================================
--- llvm/include/llvm/Object/Binary.h
+++ llvm/include/llvm/Object/Binary.h
@@ -69,6 +69,8 @@
 
     ID_Wasm,
 
+    ID_Offload, // Offloading binary file.
+
     ID_EndObjects
   };
 
@@ -133,6 +135,8 @@
 
   bool isWasm() const { return TypeID == ID_Wasm; }
 
+  bool isOffloadFile() const { return TypeID == ID_Offload; }
+
   bool isCOFFImportFile() const {
     return TypeID == ID_COFFImportFile;
   }
Index: llvm/include/llvm/BinaryFormat/Magic.h
===================================================================
--- llvm/include/llvm/BinaryFormat/Magic.h
+++ llvm/include/llvm/BinaryFormat/Magic.h
@@ -52,6 +52,7 @@
     pdb,                 ///< Windows PDB debug info file
     tapi_file,           ///< Text-based Dynamic Library Stub file
     cuda_fatbinary,      ///< CUDA Fatbinary object file
+    offload_binary,      ///< LLVM offload object file
     dxcontainer_object,  ///< DirectX container file
   };
 
Index: llvm/include/llvm-c/Object.h
===================================================================
--- llvm/include/llvm-c/Object.h
+++ llvm/include/llvm-c/Object.h
@@ -38,21 +38,23 @@
 typedef struct LLVMOpaqueRelocationIterator *LLVMRelocationIteratorRef;
 
 typedef enum {
-  LLVMBinaryTypeArchive,                /**< Archive file. */
-  LLVMBinaryTypeMachOUniversalBinary,   /**< Mach-O Universal Binary file. */
-  LLVMBinaryTypeCOFFImportFile,         /**< COFF Import file. */
-  LLVMBinaryTypeIR,                     /**< LLVM IR. */
-  LLVMBinaryTypeWinRes,                 /**< Windows resource (.res) file. */
-  LLVMBinaryTypeCOFF,                   /**< COFF Object file. */
-  LLVMBinaryTypeELF32L,                 /**< ELF 32-bit, little endian. */
-  LLVMBinaryTypeELF32B,                 /**< ELF 32-bit, big endian. */
-  LLVMBinaryTypeELF64L,                 /**< ELF 64-bit, little endian. */
-  LLVMBinaryTypeELF64B,                 /**< ELF 64-bit, big endian. */
-  LLVMBinaryTypeMachO32L,               /**< MachO 32-bit, little endian. */
-  LLVMBinaryTypeMachO32B,               /**< MachO 32-bit, big endian. */
-  LLVMBinaryTypeMachO64L,               /**< MachO 64-bit, little endian. */
-  LLVMBinaryTypeMachO64B,               /**< MachO 64-bit, big endian. */
-  LLVMBinaryTypeWasm,                   /**< Web Assembly. */
+  LLVMBinaryTypeArchive,              /**< Archive file. */
+  LLVMBinaryTypeMachOUniversalBinary, /**< Mach-O Universal Binary file. */
+  LLVMBinaryTypeCOFFImportFile,       /**< COFF Import file. */
+  LLVMBinaryTypeIR,                   /**< LLVM IR. */
+  LLVMBinaryTypeWinRes,               /**< Windows resource (.res) file. */
+  LLVMBinaryTypeCOFF,                 /**< COFF Object file. */
+  LLVMBinaryTypeELF32L,               /**< ELF 32-bit, little endian. */
+  LLVMBinaryTypeELF32B,               /**< ELF 32-bit, big endian. */
+  LLVMBinaryTypeELF64L,               /**< ELF 64-bit, little endian. */
+  LLVMBinaryTypeELF64B,               /**< ELF 64-bit, big endian. */
+  LLVMBinaryTypeMachO32L,             /**< MachO 32-bit, little endian. */
+  LLVMBinaryTypeMachO32B,             /**< MachO 32-bit, big endian. */
+  LLVMBinaryTypeMachO64L,             /**< MachO 64-bit, little endian. */
+  LLVMBinaryTypeMachO64B,             /**< MachO 64-bit, big endian. */
+  LLVMBinaryTypeWasm,                 /**< Web Assembly. */
+  LLVMBinaryTypeOffload,              /**< Offloading fatbinary. */
+
 } LLVMBinaryType;
 
 /**
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -1221,6 +1221,6 @@
     }
 
     llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
-                              Align(OffloadBinary::getAlignment()));
+                              Align(object::OffloadBinary::getAlignment()));
   }
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to