]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
liblzma: Add raw ARM64, RISC-V, and x86 BCJ filter APIs
authorLasse Collin <lasse.collin@tukaani.org>
Mon, 20 Jan 2025 14:44:27 +0000 (16:44 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Mon, 20 Jan 2025 14:44:27 +0000 (16:44 +0200)
Put them behind the LZMA_UNSTABLE macro for now.

These low-level special APIs might become useful in erofs-utils.

src/liblzma/api/lzma/bcj.h
src/liblzma/common/common.h
src/liblzma/liblzma_generic.map
src/liblzma/liblzma_linux.map
src/liblzma/simple/arm64.c
src/liblzma/simple/riscv.c
src/liblzma/simple/x86.c

index 7f6611feb32563853ea708f6e378bf3c7c7f4e8c..35c0477b8437997029aa9a5f7bc7cf07967e28e7 100644 (file)
@@ -96,3 +96,102 @@ typedef struct {
        uint32_t start_offset;
 
 } lzma_options_bcj;
+
+
+#ifdef LZMA_UNSTABLE
+/**
+ * \brief       Raw ARM64 BCJ encoder
+ *
+ * This is for special use cases only.
+ *
+ * \param       start_offset  The lowest 32 bits of the offset in the
+ *                            executable being filtered. For the ARM64
+ *                            filter, this must be a multiple of four.
+ *                            For the very best results, this should also
+ *                            be in sync with 4096-byte page boundaries
+ *                            in the executable due to how ARM64's ADRP
+ *                            instruction works.
+ * \param       buf           Buffer to be filtered in place
+ * \param       size          Size of the buffer
+ *
+ * \return      Number of bytes that were processed in `buf`. This is at most
+ *              `size`. With the ARM64 filter, the return value is always
+ *              a multiple of 4, and at most 3 bytes are left unfiltered.
+ *
+ * \since       5.7.1alpha
+ */
+extern LZMA_API(size_t) lzma_bcj_arm64_encode(
+               uint32_t start_offset, uint8_t *buf, size_t size) lzma_nothrow;
+
+/**
+ * \brief       Raw ARM64 BCJ decoder
+ *
+ * See lzma_bcj_arm64_encode().
+ *
+ * \since       5.7.1alpha
+ */
+extern LZMA_API(size_t) lzma_bcj_arm64_decode(
+               uint32_t start_offset, uint8_t *buf, size_t size) lzma_nothrow;
+
+
+/**
+ * \brief       Raw RISC-V BCJ encoder
+ *
+ * This is for special use cases only.
+ *
+ * \param       start_offset  The lowest 32 bits of the offset in the
+ *                            executable being filtered. For the RISC-V
+ *                            filter, this must be a multiple of 2.
+ * \param       buf           Buffer to be filtered in place
+ * \param       size          Size of the buffer
+ *
+ * \return      Number of bytes that were processed in `buf`. This is at most
+ *              `size`. With the RISC-V filter, the return value is always
+ *              a multiple of 2, and at most 7 bytes are left unfiltered.
+ *
+ * \since       5.7.1alpha
+ */
+extern LZMA_API(size_t) lzma_bcj_riscv_encode(
+               uint32_t start_offset, uint8_t *buf, size_t size) lzma_nothrow;
+
+/**
+ * \brief       Raw RISC-V BCJ decoder
+ *
+ * See lzma_bcj_riscv_encode().
+ *
+ * \since       5.7.1alpha
+ */
+extern LZMA_API(size_t) lzma_bcj_riscv_decode(
+               uint32_t start_offset, uint8_t *buf, size_t size) lzma_nothrow;
+
+
+/**
+ * \brief       Raw x86 BCJ encoder
+ *
+ * This is for special use cases only.
+ *
+ * \param       start_offset  The lowest 32 bits of the offset in the
+ *                            executable being filtered. For the x86
+ *                            filter, all values are valid.
+ * \param       buf           Buffer to be filtered in place
+ * \param       size          Size of the buffer
+ *
+ * \return      Number of bytes that were processed in `buf`. This is at most
+ *              `size`. For the x86 filter, the return value is always
+ *              a multiple of 1, and at most 4 bytes are left unfiltered.
+ *
+ * \since       5.7.1alpha
+ */
+extern LZMA_API(size_t) lzma_bcj_x86_encode(
+               uint32_t start_offset, uint8_t *buf, size_t size) lzma_nothrow;
+
+/**
+ * \brief       Raw x86 BCJ decoder
+ *
+ * See lzma_bcj_x86_encode().
+ *
+ * \since       5.7.1alpha
+ */
+extern LZMA_API(size_t) lzma_bcj_x86_decode(
+               uint32_t start_offset, uint8_t *buf, size_t size) lzma_nothrow;
+#endif
index 20af32f6d6cd9a322bce101674c7eb02a3d6d593..fd8f8c8b4af7ab9b9d7697a6c47b6e2ccb2c8327 100644 (file)
@@ -42,6 +42,8 @@
 
 #define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
 
+#define LZMA_UNSTABLE
+
 #include "lzma.h"
 
 // This is for detecting modern GCC and Clang attributes
index f74c154845598ec2ffcaf314658f263d63ab99b9..6bdc2446b0cca2bf11e59ea2e91394548bdf4168 100644 (file)
@@ -126,3 +126,13 @@ XZ_5.6.0 {
 global:
        lzma_mt_block_size;
 } XZ_5.4;
+
+XZ_5.7.0alpha {
+global:
+       lzma_bcj_arm64_encode;
+       lzma_bcj_arm64_decode;
+       lzma_bcj_riscv_encode;
+       lzma_bcj_riscv_decode;
+       lzma_bcj_x86_encode;
+       lzma_bcj_x86_decode;
+} XZ_5.6.0;
index 7e4b25e17620a0395ae1819b4fab586427546dee..8743ee36afc1354832e26b31630133d4bdae6ad2 100644 (file)
@@ -141,3 +141,13 @@ XZ_5.6.0 {
 global:
        lzma_mt_block_size;
 } XZ_5.4;
+
+XZ_5.7.0alpha {
+global:
+       lzma_bcj_arm64_encode;
+       lzma_bcj_arm64_decode;
+       lzma_bcj_riscv_encode;
+       lzma_bcj_riscv_decode;
+       lzma_bcj_x86_encode;
+       lzma_bcj_x86_decode;
+} XZ_5.6.0;
index bc5d3c3208aaee4b174c4f96c73dfe20715baeb5..2ec10d937fbdea7ead44ebc1e4af40a6cd035529 100644 (file)
@@ -124,6 +124,15 @@ lzma_simple_arm64_encoder_init(lzma_next_coder *next,
 {
        return arm64_coder_init(next, allocator, filters, true);
 }
+
+
+extern LZMA_API(size_t)
+lzma_bcj_arm64_encode(uint32_t start_offset, uint8_t *buf, size_t size)
+{
+       // start_offset must be a multiple of four.
+       start_offset &= ~UINT32_C(3);
+       return arm64_code(NULL, start_offset, true, buf, size);
+}
 #endif
 
 
@@ -135,4 +144,13 @@ lzma_simple_arm64_decoder_init(lzma_next_coder *next,
 {
        return arm64_coder_init(next, allocator, filters, false);
 }
+
+
+extern LZMA_API(size_t)
+lzma_bcj_arm64_decode(uint32_t start_offset, uint8_t *buf, size_t size)
+{
+       // start_offset must be a multiple of four.
+       start_offset &= ~UINT32_C(3);
+       return arm64_code(NULL, start_offset, false, buf, size);
+}
 #endif
index b18df8b637d050f83506f31aea20c406b0fac26c..bc97ebdbb0fbfa60723c82b1824d754a08765206 100644 (file)
@@ -617,6 +617,15 @@ lzma_simple_riscv_encoder_init(lzma_next_coder *next,
        return lzma_simple_coder_init(next, allocator, filters,
                        &riscv_encode, 0, 8, 2, true);
 }
+
+
+extern LZMA_API(size_t)
+lzma_bcj_riscv_encode(uint32_t start_offset, uint8_t *buf, size_t size)
+{
+       // start_offset must be a multiple of two.
+       start_offset &= ~UINT32_C(1);
+       return riscv_encode(NULL, start_offset, true, buf, size);
+}
 #endif
 
 
@@ -752,4 +761,13 @@ lzma_simple_riscv_decoder_init(lzma_next_coder *next,
        return lzma_simple_coder_init(next, allocator, filters,
                        &riscv_decode, 0, 8, 2, false);
 }
+
+
+extern LZMA_API(size_t)
+lzma_bcj_riscv_decode(uint32_t start_offset, uint8_t *buf, size_t size)
+{
+       // start_offset must be a multiple of two.
+       start_offset &= ~UINT32_C(1);
+       return riscv_decode(NULL, start_offset, false, buf, size);
+}
 #endif
index f216231f2d12e9c05a3bf2019ac384a1851af9df..dffa7863131ae98cd91a671ec5cd1f74ed561602 100644 (file)
@@ -143,6 +143,18 @@ lzma_simple_x86_encoder_init(lzma_next_coder *next,
 {
        return x86_coder_init(next, allocator, filters, true);
 }
+
+
+extern LZMA_API(size_t)
+lzma_bcj_x86_encode(uint32_t start_offset, uint8_t *buf, size_t size)
+{
+       lzma_simple_x86 simple = {
+               .prev_mask = 0,
+               .prev_pos = (uint32_t)(-5),
+       };
+
+       return x86_code(&simple, start_offset, true, buf, size);
+}
 #endif
 
 
@@ -154,4 +166,16 @@ lzma_simple_x86_decoder_init(lzma_next_coder *next,
 {
        return x86_coder_init(next, allocator, filters, false);
 }
+
+
+extern LZMA_API(size_t)
+lzma_bcj_x86_decode(uint32_t start_offset, uint8_t *buf, size_t size)
+{
+       lzma_simple_x86 simple = {
+               .prev_mask = 0,
+               .prev_pos = (uint32_t)(-5),
+       };
+
+       return x86_code(&simple, start_offset, false, buf, size);
+}
 #endif