From 150356207c8d6a3e0af465b676430d19d62f884c Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 12 Jan 2025 12:59:20 +0200 Subject: [PATCH] liblzma: Fix the encoder breakage on big endian ARM64 When the 8-byte method was enabled for ARM64, a check for endianness wasn't added. This broke the LZMA/LZMA2 encoder. Test suite caught it. Fixes: cd64dd70d5665b6048829c45772d08606f44672e Co-authored-by: Marcus Comstedt --- src/liblzma/common/memcmplen.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/liblzma/common/memcmplen.h b/src/liblzma/common/memcmplen.h index 394a4856..86b5d6f3 100644 --- a/src/liblzma/common/memcmplen.h +++ b/src/liblzma/common/memcmplen.h @@ -65,8 +65,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, || (defined(_MSC_VER) && (defined(_M_X64) \ || defined(_M_ARM64) || defined(_M_ARM64EC)))) // This is only for x86-64 and ARM64 for now. This might be fine on - // other 64-bit processors too. On big endian one should use xor - // instead of subtraction and switch to __builtin_clzll(). + // other 64-bit processors too. // // Reasons to use subtraction instead of xor: // @@ -82,7 +81,11 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, // version 2023-05-26. https://www.agner.org/optimize/ #define LZMA_MEMCMPLEN_EXTRA 8 while (len < limit) { +# ifdef WORDS_BIGENDIAN + const uint64_t x = read64ne(buf1 + len) ^ read64ne(buf2 + len); +# else const uint64_t x = read64ne(buf1 + len) - read64ne(buf2 + len); +# endif if (x != 0) { // MSVC or Intel C compiler on Windows # if defined(_MSC_VER) || defined(__INTEL_COMPILER) @@ -90,6 +93,8 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, _BitScanForward64(&tmp, x); len += (uint32_t)tmp >> 3; // GCC, Clang, or Intel C compiler +# elif defined(WORDS_BIGENDIAN) + len += (uint32_t)__builtin_clzll(x) >> 3; # else len += (uint32_t)__builtin_ctzll(x) >> 3; # endif