[llvm] [clang] [LLVM] Add file magic detection for SPIR-V files. (PR #75363)

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 13 12:23:07 PST 2023


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/75363

>From 2700151916b0fd91c793930127412af5690c9e41 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Wed, 13 Dec 2023 11:35:13 -0600
Subject: [PATCH 1/2] [LLVM] Add file magic detection for SPIR-V files.

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.
---
 llvm/include/llvm/BinaryFormat/Magic.h | 1 +
 llvm/lib/BinaryFormat/Magic.cpp        | 9 +++++++++
 llvm/lib/Object/Binary.cpp             | 1 +
 llvm/lib/Object/ObjectFile.cpp         | 1 +
 4 files changed, 12 insertions(+)

diff --git a/llvm/include/llvm/BinaryFormat/Magic.h b/llvm/include/llvm/BinaryFormat/Magic.h
index a28710dcdfaf2c..c635a269576587 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 255937a5bdd04a..b0f0043f0e492a 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -72,6 +72,15 @@ 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 0ee9f7fac448a2..0b9d95485287dc 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 428166f58070d0..ca921836b7f65a 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);

>From 758de880dbd853c37a1e9abb72a1cb0624c4247d Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Wed, 13 Dec 2023 14:22:52 -0600
Subject: [PATCH 2/2] Add test

---
 clang/tools/clang-offload-packager/ClangOffloadPackager.cpp | 6 ++++++
 llvm/lib/BinaryFormat/Magic.cpp                             | 3 +--
 llvm/unittests/BinaryFormat/TestFileMagic.cpp               | 6 ++++++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp b/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
index 08de3f3a3771c1..87e491e057e844 100644
--- a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
+++ b/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
@@ -234,6 +234,12 @@ int main(int argc, const char **argv) {
     return EXIT_SUCCESS;
   }
 
+  const char spirv_object_le[] =  "\x03\x02\x23\x07";
+
+  StringRef str(spirv_object_le, sizeof(spirv_object_le));
+  llvm::errs() << str.size() << "\n";
+  llvm::errs() << identify_magic(str) << "\n";
+
   PackagerExecutable = argv[0];
   auto reportError = [argv](Error E) {
     logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
diff --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index b0f0043f0e492a..45a0b7e11452b4 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -77,8 +77,7 @@ file_magic llvm::identify_magic(StringRef Magic) {
       return file_magic::spirv_object;
     break;
 
-  case 0x07:
-    // SPIR-V format in big-endian mode.
+  case 0x07: // SPIR-V format in big-endian mode.
     if (startswith(Magic, "\x07\x23\x02\x03"))
       return file_magic::spirv_object;
     break;
diff --git a/llvm/unittests/BinaryFormat/TestFileMagic.cpp b/llvm/unittests/BinaryFormat/TestFileMagic.cpp
index b09a2c07309f82..766f8bfae72b00 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),



More information about the cfe-commits mailing list