[clang] afd2f7e - [Binary] Promote OffloadBinary to inherit from Binary
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 1 15:41:06 PDT 2022
Author: Joseph Huber
Date: 2022-06-01T18:40:57-04:00
New Revision: afd2f7e9919737e30f9fae2d3cff892189301a55
URL: https://github.com/llvm/llvm-project/commit/afd2f7e9919737e30f9fae2d3cff892189301a55
DIFF: https://github.com/llvm/llvm-project/commit/afd2f7e9919737e30f9fae2d3cff892189301a55.diff
LOG: [Binary] Promote OffloadBinary to inherit from Binary
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.
Reviewed By: tra
Differential Revision: https://reviews.llvm.org/D126812
Added:
Modified:
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
llvm/unittests/Object/OffloadingTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 94808e8a625e6..0de15b1e48078 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1221,6 +1221,6 @@ void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
}
llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
- Align(OffloadBinary::getAlignment()));
+ Align(object::OffloadBinary::getAlignment()));
}
}
diff --git a/llvm/include/llvm-c/Object.h b/llvm/include/llvm-c/Object.h
index 9a9596aaa08cd..f422c1ad224d2 100644
--- a/llvm/include/llvm-c/Object.h
+++ b/llvm/include/llvm-c/Object.h
@@ -38,21 +38,23 @@ typedef struct LLVMOpaqueSymbolIterator *LLVMSymbolIteratorRef;
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;
/**
diff --git a/llvm/include/llvm/BinaryFormat/Magic.h b/llvm/include/llvm/BinaryFormat/Magic.h
index b6bc4e9b2a7a3..c8e0dad42b0bc 100644
--- a/llvm/include/llvm/BinaryFormat/Magic.h
+++ b/llvm/include/llvm/BinaryFormat/Magic.h
@@ -52,6 +52,7 @@ struct file_magic {
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
};
diff --git a/llvm/include/llvm/Object/Binary.h b/llvm/include/llvm/Object/Binary.h
index b496956fc2123..77ebf250bc0e7 100644
--- a/llvm/include/llvm/Object/Binary.h
+++ b/llvm/include/llvm/Object/Binary.h
@@ -69,6 +69,8 @@ class Binary {
ID_Wasm,
+ ID_Offload, // Offloading binary file.
+
ID_EndObjects
};
@@ -133,6 +135,8 @@ class Binary {
bool isWasm() const { return TypeID == ID_Wasm; }
+ bool isOffloadFile() const { return TypeID == ID_Offload; }
+
bool isCOFFImportFile() const {
return TypeID == ID_COFFImportFile;
}
diff --git a/llvm/include/llvm/Object/OffloadBinary.h b/llvm/include/llvm/Object/OffloadBinary.h
index d8a7d5fff7ae4..3a8c98105c93b 100644
--- a/llvm/include/llvm/Object/OffloadBinary.h
+++ b/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 @@ enum ImageKind : uint16_t {
/// 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 @@ class OffloadBinary {
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,10 @@ class OffloadBinary {
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 StringEntry *StringMapBegin =
reinterpret_cast<const StringEntry *>(&Buffer[TheEntry->StringOffset]);
for (uint64_t I = 0, E = TheEntry->NumStrings; I != E; ++I) {
@@ -127,7 +132,7 @@ class OffloadBinary {
/// 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 +152,7 @@ OffloadKind getOffloadKind(StringRef Name);
/// Convert an offload kind to its string representation.
StringRef getOffloadKindName(OffloadKind Name);
+} // namespace object
+
} // namespace llvm
#endif
diff --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index 99d3f692889de..d45195fb95c5c 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -74,6 +74,11 @@ file_magic llvm::identify_magic(StringRef Magic) {
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;
diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp
index 1703f76cf318f..8065e3eb1d852 100644
--- a/llvm/lib/Object/Binary.cpp
+++ b/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 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
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:
diff --git a/llvm/lib/Object/Object.cpp b/llvm/lib/Object/Object.cpp
index 576eb8d069d62..d5e67160dfa36 100644
--- a/llvm/lib/Object/Object.cpp
+++ b/llvm/lib/Object/Object.cpp
@@ -120,6 +120,8 @@ LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {
return LLVMBinaryTypeMachO64L;
case ID_MachO64B:
return LLVMBinaryTypeMachO64B;
+ case ID_Offload:
+ return LLVMBinaryTypeOffload;
case ID_Wasm:
return LLVMBinaryTypeWasm;
case ID_StartObjects:
diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp
index 609dfae25929e..1be8f11751beb 100644
--- a/llvm/lib/Object/ObjectFile.cpp
+++ b/llvm/lib/Object/ObjectFile.cpp
@@ -147,6 +147,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
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:
diff --git a/llvm/lib/Object/OffloadBinary.cpp b/llvm/lib/Object/OffloadBinary.cpp
index 6a64147ecebf7..f57d07c390233 100644
--- a/llvm/lib/Object/OffloadBinary.cpp
+++ b/llvm/lib/Object/OffloadBinary.cpp
@@ -9,22 +9,23 @@
#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 {
+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 +33,7 @@ OffloadBinary::create(MemoryBufferRef Buf) {
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>
@@ -141,4 +142,6 @@ StringRef getImageKindName(ImageKind Kind) {
}
}
+} // namespace object
+
} // namespace llvm
diff --git a/llvm/unittests/Object/OffloadingTest.cpp b/llvm/unittests/Object/OffloadingTest.cpp
index c404068c9424a..97c89ec450c3c 100644
--- a/llvm/unittests/Object/OffloadingTest.cpp
+++ b/llvm/unittests/Object/OffloadingTest.cpp
@@ -4,6 +4,9 @@
#include "gtest/gtest.h"
#include <random>
+using namespace llvm;
+using namespace llvm::object;
+
TEST(OffloadingTest, checkOffloadingBinary) {
// Create random data to fill the image.
std::mt19937 Rng(std::random_device{}());
@@ -27,23 +30,22 @@ TEST(OffloadingTest, checkOffloadingBinary) {
}
// Create the image.
- llvm::StringMap<llvm::StringRef> StringData;
+ StringMap<StringRef> StringData;
for (auto &KeyAndValue : Strings)
StringData[KeyAndValue.first] = KeyAndValue.second;
- std::unique_ptr<llvm::MemoryBuffer> ImageData =
- llvm::MemoryBuffer::getMemBuffer(
- {reinterpret_cast<char *>(Image.data()), Image.size()}, "", false);
+ std::unique_ptr<MemoryBuffer> ImageData = MemoryBuffer::getMemBuffer(
+ {reinterpret_cast<char *>(Image.data()), Image.size()}, "", false);
- llvm::OffloadBinary::OffloadingImage Data;
- Data.TheImageKind = static_cast<llvm::ImageKind>(KindDist(Rng));
- Data.TheOffloadKind = static_cast<llvm::OffloadKind>(KindDist(Rng));
+ OffloadBinary::OffloadingImage Data;
+ Data.TheImageKind = static_cast<ImageKind>(KindDist(Rng));
+ Data.TheOffloadKind = static_cast<OffloadKind>(KindDist(Rng));
Data.Flags = KindDist(Rng);
Data.StringData = StringData;
Data.Image = *ImageData;
- auto BinaryBuffer = llvm::OffloadBinary::write(Data);
+ auto BinaryBuffer = OffloadBinary::write(Data);
- auto BinaryOrErr = llvm::OffloadBinary::create(*BinaryBuffer);
+ auto BinaryOrErr = OffloadBinary::create(*BinaryBuffer);
if (!BinaryOrErr)
FAIL();
@@ -60,6 +62,6 @@ TEST(OffloadingTest, checkOffloadingBinary) {
EXPECT_TRUE(Data.Image.getBuffer() == Binary.getImage());
// Ensure the size and alignment of the data is correct.
- EXPECT_TRUE(Binary.getSize() % llvm::OffloadBinary::getAlignment() == 0);
+ EXPECT_TRUE(Binary.getSize() % OffloadBinary::getAlignment() == 0);
EXPECT_TRUE(Binary.getSize() == BinaryBuffer->getBuffer().size());
}
More information about the cfe-commits
mailing list