aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorJoseph Huber <huberjn@outlook.com>2023-12-13 20:39:50 -0600
committerGitHub <noreply@github.com>2023-12-13 20:39:50 -0600
commitedc83886d479e110c87d104e7241ce67ee1b6316 (patch)
treece15637d5de410009c79867441d3c1c8b86d50d3 /llvm
parent1f3d13c415a2a92e5a3811740ed55c4bcff3f539 (diff)
downloadllvm-edc83886d479e110c87d104e7241ce67ee1b6316.zip
llvm-edc83886d479e110c87d104e7241ce67ee1b6316.tar.gz
llvm-edc83886d479e110c87d104e7241ce67ee1b6316.tar.bz2
[LLVM] Add file magic detection for SPIR-V files. (#75363)
Summary: More SPIR-V related patches are being upstreamed. We should add support to detect when a binary file is SPIR-V. This will be used in the future when support for SPIR-V is added to the offloading runtime or more support for bundling. The magic number is described in the official documentation: https://registry.khronos.org/SPIR-V/specs/1.0/SPIRV.html#Magic. Notably, SPIR-V files are streams of 32-bit words. This means that the magic numbers differ depending on the endianness. Here we simply check the strandard and byte-reversed versions.
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/BinaryFormat/Magic.h1
-rw-r--r--llvm/lib/BinaryFormat/Magic.cpp8
-rw-r--r--llvm/lib/Object/Binary.cpp1
-rw-r--r--llvm/lib/Object/ObjectFile.cpp1
-rw-r--r--llvm/unittests/BinaryFormat/TestFileMagic.cpp6
5 files changed, 17 insertions, 0 deletions
diff --git a/llvm/include/llvm/BinaryFormat/Magic.h b/llvm/include/llvm/BinaryFormat/Magic.h
index a28710d..c635a26 100644
--- a/llvm/include/llvm/BinaryFormat/Magic.h
+++ b/llvm/include/llvm/BinaryFormat/Magic.h
@@ -57,6 +57,7 @@ struct file_magic {
dxcontainer_object, ///< DirectX container file
offload_bundle, ///< Clang offload bundle file
offload_bundle_compressed, ///< Compressed clang offload bundle file
+ spirv_object, ///< A binary SPIR-V file
};
bool is_object() const { return V != unknown; }
diff --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index 255937a..45a0b7e 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -72,6 +72,14 @@ file_magic llvm::identify_magic(StringRef Magic) {
case 0x03:
if (startswith(Magic, "\x03\xF0\x00"))
return file_magic::goff_object;
+ // SPIR-V format in little-endian mode.
+ if (startswith(Magic, "\x03\x02\x23\x07"))
+ return file_magic::spirv_object;
+ break;
+
+ case 0x07: // SPIR-V format in big-endian mode.
+ if (startswith(Magic, "\x07\x23\x02\x03"))
+ return file_magic::spirv_object;
break;
case 0x10:
diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp
index 0ee9f7f..0b9d954 100644
--- a/llvm/lib/Object/Binary.cpp
+++ b/llvm/lib/Object/Binary.cpp
@@ -89,6 +89,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
case file_magic::dxcontainer_object:
case file_magic::offload_bundle:
case file_magic::offload_bundle_compressed:
+ case file_magic::spirv_object:
// Unrecognized object file format.
return errorCodeToError(object_error::invalid_file_type);
case file_magic::offload_binary:
diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp
index 428166f..ca92183 100644
--- a/llvm/lib/Object/ObjectFile.cpp
+++ b/llvm/lib/Object/ObjectFile.cpp
@@ -160,6 +160,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
case file_magic::dxcontainer_object:
case file_magic::offload_bundle:
case file_magic::offload_bundle_compressed:
+ case file_magic::spirv_object:
return errorCodeToError(object_error::invalid_file_type);
case file_magic::tapi_file:
return errorCodeToError(object_error::invalid_file_type);
diff --git a/llvm/unittests/BinaryFormat/TestFileMagic.cpp b/llvm/unittests/BinaryFormat/TestFileMagic.cpp
index b09a2c0..766f8bf 100644
--- a/llvm/unittests/BinaryFormat/TestFileMagic.cpp
+++ b/llvm/unittests/BinaryFormat/TestFileMagic.cpp
@@ -87,6 +87,8 @@ const char pdb[] = "Microsoft C/C++ MSF 7.00\r\n\x1a"
"DS\x00\x00\x00";
const char tapi_file[] = "--- !tapi-tbd-v1\n";
const char tapi_file_tbd_v1[] = "---\narchs: [";
+const char spirv_object_le[] = "\x03\x02\x23\x07";
+const char spirv_object_be[] = "\x07\x23\x02\x03";
TEST_F(MagicTest, Magic) {
struct type {
@@ -117,6 +119,10 @@ TEST_F(MagicTest, Magic) {
DEFINE(macho_dynamically_linked_shared_lib_stub),
DEFINE(macho_dsym_companion),
DEFINE(macho_kext_bundle),
+ {"spirv_object_le", spirv_object_le, sizeof(spirv_object_le),
+ file_magic ::spirv_object},
+ {"spirv_object_be", spirv_object_be, sizeof(spirv_object_be),
+ file_magic ::spirv_object},
DEFINE(windows_resource),
DEFINE(pdb),
{"ms_dos_stub_broken", ms_dos_stub_broken, sizeof(ms_dos_stub_broken),