[llvm] [LLVM] Add zstd compressed frame magic to LLVM magic (PR #222773)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 14:06:54 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: Joseph Huber (jhuber6)
<details>
<summary>Changes</summary>
Summary:
ZSTD uses magic to indentify compressed frames in the bitstream. Add
this as a recognized file magic type so that we can identify compressed
streams that LLVM creates.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Full diff: https://github.com/llvm/llvm-project/pull/222773.diff
6 Files Affected:
- (modified) llvm/include/llvm/BinaryFormat/Magic.h (+1)
- (modified) llvm/lib/BinaryFormat/Magic.cpp (+5)
- (modified) llvm/lib/Object/Binary.cpp (+1)
- (modified) llvm/lib/Object/ObjectFile.cpp (+1)
- (modified) llvm/unittests/BinaryFormat/CMakeLists.txt (+1)
- (modified) llvm/unittests/BinaryFormat/TestFileMagic.cpp (+27-2)
``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/Magic.h b/llvm/include/llvm/BinaryFormat/Magic.h
index 11922d843af9e..ecc40212dbd2f 100644
--- a/llvm/include/llvm/BinaryFormat/Magic.h
+++ b/llvm/include/llvm/BinaryFormat/Magic.h
@@ -60,6 +60,7 @@ struct file_magic {
offload_bundle, ///< Clang offload bundle file
offload_bundle_compressed, ///< Compressed clang offload bundle file
spirv_object, ///< A binary SPIR-V file
+ zstd, ///< Zstandard compressed frame
};
bool is_object() const { return V != unknown; }
diff --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index 0786c4b9889fb..ce5d2eb248806 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -270,6 +270,11 @@ file_magic llvm::identify_magic(StringRef Magic) {
return file_magic::coff_object;
break;
+ case 0x28: // Zstandard compressed frame magic 0xFD2FB528, little-endian.
+ if (startswith(Magic, "\x28\xb5\x2f\xfd"))
+ return file_magic::zstd;
+ break;
+
case '_': {
const char OBMagic[] = "__CLANG_OFFLOAD_BUNDLE__";
if (Magic.size() >= sizeof(OBMagic) && startswith(Magic, OBMagic))
diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp
index 30414257fa90b..5cb10d7ae25c2 100644
--- a/llvm/lib/Object/Binary.cpp
+++ b/llvm/lib/Object/Binary.cpp
@@ -91,6 +91,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
case file_magic::offload_bundle:
case file_magic::offload_bundle_compressed:
case file_magic::spirv_object:
+ case file_magic::zstd:
// 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 c4b4cdff6de93..f045fda97683f 100644
--- a/llvm/lib/Object/ObjectFile.cpp
+++ b/llvm/lib/Object/ObjectFile.cpp
@@ -168,6 +168,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
case file_magic::offload_bundle:
case file_magic::offload_bundle_compressed:
case file_magic::spirv_object:
+ case file_magic::zstd:
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/CMakeLists.txt b/llvm/unittests/BinaryFormat/CMakeLists.txt
index eac5977a2c1c3..b89d38e47f602 100644
--- a/llvm/unittests/BinaryFormat/CMakeLists.txt
+++ b/llvm/unittests/BinaryFormat/CMakeLists.txt
@@ -1,5 +1,6 @@
set(LLVM_LINK_COMPONENTS
BinaryFormat
+ Support
TargetParser
)
diff --git a/llvm/unittests/BinaryFormat/TestFileMagic.cpp b/llvm/unittests/BinaryFormat/TestFileMagic.cpp
index 7d235d7c84842..42fffc1868e15 100644
--- a/llvm/unittests/BinaryFormat/TestFileMagic.cpp
+++ b/llvm/unittests/BinaryFormat/TestFileMagic.cpp
@@ -6,9 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@@ -92,6 +96,7 @@ 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";
+const char zstd[] = "\x28\xb5\x2f\xfd";
TEST_F(MagicTest, Magic) {
struct type {
@@ -126,9 +131,10 @@ TEST_F(MagicTest, Magic) {
{"macho_type_0x10001", macho_type_0x10001, sizeof(macho_type_0x10001),
file_magic::macho_object},
{"spirv_object_le", spirv_object_le, sizeof(spirv_object_le),
- file_magic ::spirv_object},
+ file_magic::spirv_object},
{"spirv_object_be", spirv_object_be, sizeof(spirv_object_be),
- file_magic ::spirv_object},
+ file_magic::spirv_object},
+ DEFINE(zstd),
DEFINE(windows_resource),
DEFINE(pdb),
{"ms_dos_stub_broken", ms_dos_stub_broken, sizeof(ms_dos_stub_broken),
@@ -154,3 +160,22 @@ TEST_F(MagicTest, Magic) {
ASSERT_NO_ERROR(fs::remove(Twine(file_pathname)));
}
}
+
+TEST_F(MagicTest, ZstdCompressedBlob) {
+ if (!compression::zstd::isAvailable())
+ GTEST_SKIP() << "zstd is not available";
+
+ static const int Levels[] = {compression::zstd::NoCompression,
+ compression::zstd::BestSpeedCompression,
+ compression::zstd::DefaultCompression,
+ compression::zstd::BestSizeCompression};
+
+ StringRef Input("hello, world!");
+ for (int Level : Levels) {
+ SmallVector<uint8_t, 0> Compressed;
+ compression::zstd::compress(arrayRefFromStringRef(Input), Compressed,
+ Level);
+ EXPECT_EQ(file_magic::zstd, identify_magic(toStringRef(Compressed)))
+ << "level=" << Level;
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/222773
More information about the llvm-commits
mailing list