summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2024-03-18 20:33:12 +0000
committerElliott Hughes <enh@google.com>2024-03-18 20:33:13 +0000
commitcc9a22dabdc9594674c5c3557e71d9cc4cdfba92 (patch)
tree40c797e6ce55bf499eba77e48b9c7eee1d7f669a
parenteff168fd731068a3faddd9aae056875e10014a51 (diff)
parent24c07df5033183efad8607cba62e746bea7180bf (diff)
downloadzlib-cc9a22dabdc9594674c5c3557e71d9cc4cdfba92.tar.gz
Upgrade zlib to 24c07df5033183efad8607cba62e746bea7180bf
This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update external/zlib For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md Test: TreeHugger Change-Id: I2c3dd6a7b604708cbb1ce52407fb4c603ee3aa32
-rw-r--r--CMakeLists.txt106
-rw-r--r--METADATA6
-rw-r--r--adler32.c3
-rw-r--r--contrib/tests/fuzzers/deflate_fuzzer.cc33
-rw-r--r--contrib/tests/utils_unittest.cc40
-rw-r--r--cpu_features.c32
-rw-r--r--crc32.c6
-rw-r--r--deflate.c23
8 files changed, 193 insertions, 56 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 394d833..34175a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,27 +31,59 @@ if (USE_ZLIB_RABIN_KARP_HASH)
add_definitions(-DUSE_ZLIB_RABIN_KARP_ROLLING_HASH)
endif()
-# TODO(cavalcantii): add support for other OSes (e.g. Android, fuchsia, osx)
-# and architectures (e.g. Arm).
+# TODO(cavalcantii): add support for other OSes (e.g. Android, Fuchsia, etc)
+# and architectures (e.g. RISCV).
if (ENABLE_SIMD_OPTIMIZATIONS)
- add_definitions(-DINFLATE_CHUNK_SIMD_SSE2)
- add_definitions(-DADLER32_SIMD_SSSE3)
- add_definitions(-DINFLATE_CHUNK_READ_64LE)
- add_definitions(-DCRC32_SIMD_SSE42_PCLMUL)
- if (ENABLE_SIMD_AVX512)
- add_definitions(-DCRC32_SIMD_AVX512_PCLMUL)
- add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul)
- else()
- add_compile_options(-msse4.2 -mpclmul)
- endif()
- add_definitions(-DDEFLATE_SLIDE_HASH_SSE2)
- # Required by CPU features detection code.
- add_definitions(-DX86_NOT_WINDOWS)
- # Apparently some environments (e.g. CentOS) require to explicitly link
- # with pthread and that is required by the CPU features detection code.
- find_package (Threads REQUIRED)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
+ # Apparently some environments (e.g. CentOS) require to explicitly link
+ # with pthread and that is required by the CPU features detection code.
+ find_package (Threads REQUIRED)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
+
+ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ add_definitions(-DINFLATE_CHUNK_SIMD_SSE2)
+ add_definitions(-DADLER32_SIMD_SSSE3)
+ add_definitions(-DINFLATE_CHUNK_READ_64LE)
+ add_definitions(-DCRC32_SIMD_SSE42_PCLMUL)
+ if (ENABLE_SIMD_AVX512)
+ add_definitions(-DCRC32_SIMD_AVX512_PCLMUL)
+ add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul)
+ else()
+ add_compile_options(-msse4.2 -mpclmul)
+ endif()
+ add_definitions(-DDEFLATE_SLIDE_HASH_SSE2)
+ # Required by CPU features detection code.
+ add_definitions(-DX86_NOT_WINDOWS)
+ endif()
+
+ if ((CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") OR
+ (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64"))
+ add_definitions(-DINFLATE_CHUNK_SIMD_NEON)
+ add_definitions(-DADLER32_SIMD_NEON)
+ add_definitions(-DINFLATE_CHUNK_READ_64LE)
+ add_definitions(-DCRC32_ARMV8_CRC32)
+ add_definitions(-DDEFLATE_SLIDE_HASH_NEON)
+ # Required by CPU features detection code.
+ if (APPLE)
+ add_definitions(-DARMV8_OS_MACOS)
+ endif()
+
+ if (UNIX AND NOT APPLE)
+ add_definitions(-DARMV8_OS_LINUX)
+ endif()
+
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crc+crypto")
+ endif()
+
+ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
+ add_definitions(-DRISCV_RVV)
+ add_definitions(-DDEFLATE_SLIDE_HASH_RVV)
+ add_definitions(-DADLER32_SIMD_RVV)
+ #TODO(cavalcantii): add remaining flags as we port optimizations to RVV.
+ # Required by CPU features detection code.
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=riscv64-unknown-linux-gnu -march=rv64gcv")
+ endif()
+
endif()
#
@@ -158,20 +190,26 @@ set(ZLIB_SRCS
# Update list of source files if optimizations were enabled
#============================================================================
if (ENABLE_SIMD_OPTIMIZATIONS)
- list(REMOVE_ITEM ZLIB_SRCS inflate.c)
-
- list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h)
- list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h)
- list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h)
- list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h)
- list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.h)
-
- list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c)
- list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c)
- list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c)
- list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c)
- list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.c)
- list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc_folding.c)
+ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
+ message("RISCVV: Add optimizations.")
+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h)
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c)
+ else()
+ list(REMOVE_ITEM ZLIB_SRCS inflate.c)
+
+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.h)
+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/chunkcopy.h)
+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.h)
+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.h)
+ list(APPEND ZLIB_PRIVATE_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.h)
+
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/adler32_simd.c)
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inffast_chunk.c)
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/optimizations/inflate.c)
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_features.c)
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc32_simd.c)
+ list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/crc_folding.c)
+ endif()
endif()
# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
diff --git a/METADATA b/METADATA
index f964749..3d557a3 100644
--- a/METADATA
+++ b/METADATA
@@ -8,12 +8,12 @@ third_party {
license_type: NOTICE
last_upgrade_date {
year: 2024
- month: 2
- day: 26
+ month: 3
+ day: 18
}
identifier {
type: "Git"
value: "https://chromium.googlesource.com/chromium/src/third_party/zlib/"
- version: "3787595bbbd3a374613713164db935e8331f5825"
+ version: "24c07df5033183efad8607cba62e746bea7180bf"
}
}
diff --git a/adler32.c b/adler32.c
index 99a2944..ebd1889 100644
--- a/adler32.c
+++ b/adler32.c
@@ -90,7 +90,8 @@ uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) {
return adler | (sum2 << 16);
}
-#if defined(ADLER32_SIMD_SSSE3) || defined(ADLER32_SIMD_NEON)
+#if defined(ADLER32_SIMD_SSSE3) || defined(ADLER32_SIMD_NEON) \
+ || defined(RISCV_RVV)
/*
* Use SIMD to compute the adler32. Since this function can be
* freely used, check CPU features here. zlib convention is to
diff --git a/contrib/tests/fuzzers/deflate_fuzzer.cc b/contrib/tests/fuzzers/deflate_fuzzer.cc
index 6f3e45e..f986d78 100644
--- a/contrib/tests/fuzzers/deflate_fuzzer.cc
+++ b/contrib/tests/fuzzers/deflate_fuzzer.cc
@@ -53,6 +53,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Stream with random-sized input and output buffers.
while (fdp.ConsumeBool()) {
+ if (fdp.ConsumeBool()) {
+ // Check that copying the stream's state works. Gating this behind
+ // ConsumeBool() allows to interleave deflateCopy() with deflate() calls
+ // to better stress the code.
+ z_stream stream2;
+ ASSERT(deflateCopy(&stream2, &stream) == Z_OK);
+ ret = deflateEnd(&stream);
+ ASSERT(ret == Z_OK || Z_DATA_ERROR);
+ memset(&stream, 0xff, sizeof(stream));
+
+ ASSERT(deflateCopy(&stream, &stream2) == Z_OK);
+ ret = deflateEnd(&stream2);
+ ASSERT(ret == Z_OK || Z_DATA_ERROR);
+ }
+
std::vector<uint8_t> src_chunk = fdp.ConsumeBytes<uint8_t>(
fdp.ConsumeIntegralInRange(kMinChunk, kMaxChunk));
std::vector<uint8_t> out_chunk(
@@ -84,14 +99,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
}
ASSERT(ret == Z_OK || Z_BUF_ERROR);
}
-
- // Check that the bound was correct.
- // size_t deflate_bound = deflateBound(&stream, src.size());
- // TODO(crbug.com/40270738): This does not always hold.
- // ASSERT(compressed.size() <= deflate_bound);
-
deflateEnd(&stream);
+ // Check deflateBound().
+ // Use a newly initialized stream since computing the bound on a "used" stream
+ // may not yield a correct result (https://github.com/madler/zlib/issues/944).
+ z_stream bound_stream;
+ bound_stream.zalloc = Z_NULL;
+ bound_stream.zfree = Z_NULL;
+ ret = deflateInit2(&bound_stream, level, Z_DEFLATED, windowBits, memLevel,
+ strategy);
+ ASSERT(ret == Z_OK);
+ size_t deflate_bound = deflateBound(&bound_stream, src.size());
+ ASSERT(compressed.size() <= deflate_bound);
+ deflateEnd(&bound_stream);
// Verify that the data decompresses correctly.
ret = inflateInit2(&stream, windowBits);
diff --git a/contrib/tests/utils_unittest.cc b/contrib/tests/utils_unittest.cc
index 3d6672d..0cc1081 100644
--- a/contrib/tests/utils_unittest.cc
+++ b/contrib/tests/utils_unittest.cc
@@ -1105,6 +1105,46 @@ TEST(ZlibTest, GzipStored) {
deflateEnd(&stream);
}
+TEST(ZlibTest, DeflateBound) {
+ // Check that the deflateBound() isn't too low when using non-default
+ // parameters (crbug.com/40270738).
+ const int level = 9;
+ const int windowBits = 15;
+ const int memLevel = 1;
+ const int strategy = Z_FIXED;
+ const uint8_t src[] = {
+ 49, 255, 255, 20, 45, 49, 167, 56, 55, 255, 255, 255, 223, 255, 49,
+ 255, 3, 78, 0, 0, 141, 253, 209, 163, 29, 195, 43, 60, 199, 123,
+ 112, 35, 134, 13, 148, 102, 212, 4, 184, 103, 7, 102, 225, 102, 156,
+ 164, 78, 48, 70, 49, 125, 162, 55, 116, 161, 174, 83, 0, 59, 0,
+ 225, 140, 0, 0, 63, 63, 4, 15, 198, 30, 126, 196, 33, 99, 135,
+ 41, 192, 82, 28, 105, 216, 170, 221, 14, 61, 1, 0, 0, 22, 195,
+ 45, 53, 244, 163, 167, 158, 229, 68, 18, 112, 49, 174, 43, 75, 90,
+ 161, 85, 19, 36, 163, 118, 228, 169, 180, 161, 237, 234, 253, 197, 234,
+ 66, 106, 12, 42, 124, 96, 160, 144, 183, 194, 157, 167, 202, 217};
+
+ z_stream stream;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ int ret =
+ deflateInit2(&stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
+ ASSERT_EQ(ret, Z_OK);
+ size_t deflate_bound = deflateBound(&stream, sizeof(src));
+
+ uint8_t out[sizeof(src) * 10];
+ stream.next_in = (uint8_t*)src;
+ stream.avail_in = sizeof(src);
+ stream.next_out = out;
+ stream.avail_out = sizeof(out);
+ ret = deflate(&stream, Z_FINISH);
+ ASSERT_EQ(ret, Z_STREAM_END);
+
+ size_t out_size = sizeof(out) - stream.avail_out;
+ EXPECT_LE(out_size, deflate_bound);
+
+ deflateEnd(&stream);
+}
+
// TODO(gustavoa): make these tests run standalone.
#ifndef CMAKE_STANDALONE_UNITTESTS
diff --git a/cpu_features.c b/cpu_features.c
index 64e0428..34ae7b9 100644
--- a/cpu_features.c
+++ b/cpu_features.c
@@ -33,9 +33,13 @@ int ZLIB_INTERNAL x86_cpu_enable_ssse3 = 0;
int ZLIB_INTERNAL x86_cpu_enable_simd = 0;
int ZLIB_INTERNAL x86_cpu_enable_avx512 = 0;
+int ZLIB_INTERNAL riscv_cpu_enable_rvv = 0;
+int ZLIB_INTERNAL riscv_cpu_enable_vclmul = 0;
+
#ifndef CPU_NO_SIMD
-#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_FUCHSIA) || defined(ARMV8_OS_IOS)
+#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || \
+ defined(ARMV8_OS_FUCHSIA) || defined(ARMV8_OS_IOS)
#include <pthread.h>
#endif
@@ -62,7 +66,10 @@ int ZLIB_INTERNAL x86_cpu_enable_avx512 = 0;
static void _cpu_check_features(void);
#endif
-#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_MACOS) || defined(ARMV8_OS_FUCHSIA) || defined(X86_NOT_WINDOWS) || defined(ARMV8_OS_IOS)
+#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || \
+ defined(ARMV8_OS_MACOS) || defined(ARMV8_OS_FUCHSIA) || \
+ defined(X86_NOT_WINDOWS) || defined(ARMV8_OS_IOS) || \
+ defined(RISCV_RVV)
#if !defined(ARMV8_OS_MACOS)
// _cpu_check_features() doesn't need to do anything on mac/arm since all
// features are known at build time, so don't call it.
@@ -184,6 +191,23 @@ static void _cpu_check_features(void)
x86_cpu_enable_avx512 = _xgetbv(0) & 0x00000040;
#endif
}
+#endif // x86 & NO_SIMD
+
+#elif defined(RISCV_RVV)
+#include <sys/auxv.h>
+
+#ifndef ZLIB_HWCAP_RVV
+#define ZLIB_HWCAP_RVV (1 << ('v' - 'a'))
#endif
-#endif
-#endif
+
+/* TODO(cavalcantii)
+ * - add support for Android@RISCV i.e. __riscv_hwprobe().
+ * - detect vclmul (crypto extensions).
+ */
+static void _cpu_check_features(void)
+{
+ unsigned long features = getauxval(AT_HWCAP);
+ riscv_cpu_enable_rvv = !!(features & ZLIB_HWCAP_RVV);
+}
+#endif // ARM | x86 | RISCV
+#endif // NO SIMD CPU
diff --git a/crc32.c b/crc32.c
index cf8579f..32686f9 100644
--- a/crc32.c
+++ b/crc32.c
@@ -706,7 +706,8 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
* place to cache CPU features if needed for those later, more
* interesting crc32() calls.
*/
-#if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32)
+#if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32) \
+ || defined(RISCV_RVV)
/*
* Since this routine can be freely used, check CPU features here.
*/
@@ -1085,7 +1086,8 @@ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
/* Some bots compile with optimizations disabled, others will emulate
* ARM on x86 and other weird combinations.
*/
-#if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32)
+#if defined(CRC32_SIMD_SSE42_PCLMUL) || defined(CRC32_ARMV8_CRC32) \
+ || defined(RISCV_RVV)
/* We got to verify CPU features, so exploit the common usage pattern
* of calling this function with Z_NULL for an initial valid crc value.
* This allows to cache the result of the feature check and avoid extraneous
diff --git a/deflate.c b/deflate.c
index 4920e70..b9a3120 100644
--- a/deflate.c
+++ b/deflate.c
@@ -387,11 +387,12 @@ int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version,
/* To do: ignore strm->next_in if we use it as window */
}
+#define WINDOW_PADDING 8
+
/* ========================================================================= */
int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
int windowBits, int memLevel, int strategy,
const char *version, int stream_size) {
- unsigned window_padding = 8;
deflate_state *s;
int wrap = 1;
static const char my_version[] = ZLIB_VERSION;
@@ -400,7 +401,8 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
// for all wrapper formats (e.g. RAW, ZLIB, GZIP).
// Feature detection is not triggered while using RAW mode (i.e. we never
// call crc32() with a NULL buffer).
-#if defined(CRC32_ARMV8_CRC32) || defined(CRC32_SIMD_SSE42_PCLMUL)
+#if defined(CRC32_ARMV8_CRC32) || defined(CRC32_SIMD_SSE42_PCLMUL) \
+ || defined(RISCV_RVV)
cpu_check_features();
#endif
@@ -477,11 +479,11 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH);
s->window = (Bytef *) ZALLOC(strm,
- s->w_size + window_padding,
+ s->w_size + WINDOW_PADDING,
2*sizeof(Byte));
/* Avoid use of unitialized values in the window, see crbug.com/1137613 and
* crbug.com/1144420 */
- zmemzero(s->window, (s->w_size + window_padding) * (2 * sizeof(Byte)));
+ zmemzero(s->window, (s->w_size + WINDOW_PADDING) * (2 * sizeof(Byte)));
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
/* Avoid use of uninitialized value, see:
* https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11360
@@ -923,6 +925,12 @@ uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
wraplen = 6;
}
+ /* With Chromium's hashing, s->hash_bits may not correspond to the
+ memLevel, making the computations below incorrect. Return the
+ conservative bound. */
+ if (s->chromium_zlib_hash)
+ return (fixedlen > storelen ? fixedlen : storelen) + wraplen;
+
/* if not default parameters, return one of the conservative bounds */
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) +
@@ -1342,7 +1350,9 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
ds->strm = dest;
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->window = (Bytef *) ZALLOC(dest,
+ ds->w_size + WINDOW_PADDING,
+ 2*sizeof(Byte));
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
#ifdef LIT_MEM
@@ -1357,7 +1367,8 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
return Z_MEM_ERROR;
}
/* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->window, ss->window,
+ (ds->w_size + WINDOW_PADDING) * 2 * sizeof(Byte));
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
#ifdef LIT_MEM