From 410c955f9f9f329ea6853b96d757c64a8737a7a6 Mon Sep 17 00:00:00 2001 From: Lukas Javorsky Date: Wed, 22 Jun 2022 17:27:43 +0000 Subject: [PATCH] [2/6] Unify IBM-Z-hw-accelerated patch Source: https://github.com/madler/zlib/pull/410 --- ...C-compression-level-switching-issues.patch | 206 ----- ...accelrated-deflate-compressBound-fix.patch | 93 --- ...2.11-IBM-Z-hw-accelrated-deflate-fix.patch | 516 ------------- ...11-inflateSyncPoint-return-value-fix.patch | 45 -- zlib-1.2.11-permit-deflateParams-change.patch | 70 -- ...-1.2.12-IBM-Z-hw-accelerated-deflate.patch | 727 ++++++++++++------ 6 files changed, 511 insertions(+), 1146 deletions(-) delete mode 100644 zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch delete mode 100644 zlib-1.2.11-IBM-Z-hw-accelrated-deflate-compressBound-fix.patch delete mode 100644 zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch delete mode 100644 zlib-1.2.11-inflateSyncPoint-return-value-fix.patch delete mode 100644 zlib-1.2.11-permit-deflateParams-change.patch rename zlib-1.2.11-IBM-Z-hw-accelrated-deflate-s390x.patch => zlib-1.2.12-IBM-Z-hw-accelerated-deflate.patch (74%) diff --git a/zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch b/zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch deleted file mode 100644 index c69d9bc..0000000 --- a/zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch +++ /dev/null @@ -1,206 +0,0 @@ -Subject: [PATCH] Fixed DFLTCC compression level switching issues - ---- - configure | 4 +-- - contrib/s390/dfltcc.c | 52 ++++++++++++++++++++++++++++++----- - contrib/s390/dfltcc_deflate.h | 2 ++ - deflate.c | 12 ++++---- - test/infcover.c | 2 +- - 5 files changed, 57 insertions(+), 15 deletions(-) - -diff --git a/configure b/configure -index bfe4386..70ed86b 100755 ---- a/configure -+++ b/configure -@@ -139,7 +139,7 @@ case "$1" in - -w* | --warn) warn=1; shift ;; - -d* | --debug) debug=1; shift ;; - --dfltcc) -- CFLAGS="$CFLAGS -DDFLTCC" -+ CFLAGS="$CFLAGS -DDFLTCC -DDFLTCC_LEVEL_MASK=0x7e" - OBJC="$OBJC dfltcc.o" - PIC_OBJC="$PIC_OBJC dfltcc.lo" - shift -@@ -838,7 +838,7 @@ cat > $test.c << EOF - #include - int main() { return 0; } - EOF --if try ${CC} ${CFLAGS} $test.c; then -+ if try $CC -c $CFLAGS $test.c; then - echo "Checking for sys/sdt.h ... Yes." | tee -a configure.log - CFLAGS="$CFLAGS -DHAVE_SYS_SDT_H" - SFLAGS="$SFLAGS -DHAVE_SYS_SDT_H" -diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c -index d88a0d6..94a196f 100644 ---- a/contrib/s390/dfltcc.c -+++ b/contrib/s390/dfltcc.c -@@ -350,8 +350,12 @@ int ZLIB_INTERNAL dfltcc_deflate(strm, flush, result) - int soft_bcc; - int no_flush; - -- if (!dfltcc_can_deflate(strm)) -+ if (!dfltcc_can_deflate(strm)) { -+ /* Clear history. */ -+ if (flush == Z_FULL_FLUSH) -+ param->hl = 0; - return 0; -+ } - - again: - masked_avail_in = 0; -@@ -376,7 +380,8 @@ again: - /* Clear history. */ - if (flush == Z_FULL_FLUSH) - param->hl = 0; -- *result = need_more; -+ /* Trigger block post-processing if necessary. */ -+ *result = no_flush ? need_more : block_done; - return 1; - } - -@@ -403,13 +408,18 @@ again: - param->bcf = 0; - dfltcc_state->block_threshold = - strm->total_in + dfltcc_state->block_size; -- if (strm->avail_out == 0) { -- *result = need_more; -- return 1; -- } - } - } - -+ /* No space for compressed data. If we proceed, dfltcc_cmpr() will return -+ * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still -+ * set BCF=1, which is wrong. Avoid complications and return early. -+ */ -+ if (strm->avail_out == 0) { -+ *result = need_more; -+ return 1; -+ } -+ - /* The caller gave us too much data. Pass only one block worth of - * uncompressed data to DFLTCC and mask the rest, so that on the next - * iteration we start a new block. -@@ -737,10 +747,15 @@ __attribute__((constructor)) local void init_globals(void) - * compiling with -m31, gcc defaults to ESA mode, however, since the kernel - * is 64-bit, it's always z/Architecture mode at runtime. - */ -- __asm__ volatile(".machinemode push\n" -+ __asm__ volatile( -+#ifndef __clang__ -+ ".machinemode push\n" - ".machinemode zarch\n" -+#endif - "stfle %[facilities]\n" -+#ifndef __clang__ - ".machinemode pop\n" -+#endif - : [facilities] "=Q" (cpu_facilities) - , [r0] "+r" (r0) - : -@@ -872,6 +887,28 @@ int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush) - return Z_OK; - } - -+int ZLIB_INTERNAL dfltcc_deflate_done(strm, flush) -+ z_streamp strm; -+ int flush; -+{ -+ deflate_state FAR *state = (deflate_state FAR *)strm->state; -+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); -+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; -+ -+ /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might -+ * close the block without resetting the compression state. Detect this -+ * situation and return that deflation is not done. -+ */ -+ if (flush == Z_FULL_FLUSH && strm->avail_out == 0) -+ return 0; -+ -+ /* Return that deflation is not done if DFLTCC is used and either it -+ * buffered some data (Continuation Flag is set), or has not written EOBS -+ * yet (Block-Continuation Flag is set). -+ */ -+ return !dfltcc_can_deflate(strm) || (!param->cf && !param->bcf); -+} -+ - /* - Preloading history. - */ -@@ -925,6 +962,7 @@ int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length) - - append_history(param, state->window, dictionary, dict_length); - state->strstart = 1; /* Add FDICT to zlib header */ -+ state->block_start = state->strstart; /* Make deflate_stored happy */ - return Z_OK; - } - -diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h -index de36784..914daa4 100644 ---- a/contrib/s390/dfltcc_deflate.h -+++ b/contrib/s390/dfltcc_deflate.h -@@ -11,6 +11,7 @@ int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm, - int level, - int strategy, - int *flush)); -+int ZLIB_INTERNAL dfltcc_deflate_done OF((z_streamp strm, int flush)); - int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dict_length)); -@@ -41,6 +42,7 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm, - if (err == Z_STREAM_ERROR) \ - return err; \ - } while (0) -+#define DEFLATE_DONE dfltcc_deflate_done - #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ - do { \ - if (dfltcc_can_deflate((strm))) \ -diff --git a/deflate.c b/deflate.c -index d907a1b..085abbe 100644 ---- a/deflate.c -+++ b/deflate.c -@@ -75,6 +75,7 @@ const char deflate_copyright[] = - #define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) - #define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) - #define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) -+#define DEFLATE_DONE(strm, flush) 1 - #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) - #define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 - #define DEFLATE_HOOK(strm, flush, bstate) 0 -@@ -605,14 +606,15 @@ int ZEXPORT deflateParams(strm, level, strategy) - DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); - func = configuration_table[s->level].func; - -- if ((strategy != s->strategy || func != configuration_table[level].func || -- hook_flush != Z_NO_FLUSH) && s->last_flush != -2) { -+ if (((strategy != s->strategy || func != configuration_table[level].func) && -+ s->last_flush != -2) || hook_flush != Z_NO_FLUSH) { - /* Flush the last buffer: */ -- int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ? -- hook_flush : Z_BLOCK); -+ int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK; -+ int err = deflate(strm, flush); - if (err == Z_STREAM_ERROR) - return err; -- if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) -+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead || -+ !DEFLATE_DONE(strm, flush)) - return Z_BUF_ERROR; - } - if (s->level != level) { -diff --git a/test/infcover.c b/test/infcover.c -index a34cd17..a208219 100644 ---- a/test/infcover.c -+++ b/test/infcover.c -@@ -373,7 +373,7 @@ local void cover_support(void) - mem_setup(&strm); - strm.avail_in = 0; - strm.next_in = Z_NULL; -- ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream)); -+ ret = inflateInit_(&strm, &ZLIB_VERSION[1], (int)sizeof(z_stream)); - assert(ret == Z_VERSION_ERROR); - mem_done(&strm, "wrong version"); - --- -2.26.0 - diff --git a/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-compressBound-fix.patch b/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-compressBound-fix.patch deleted file mode 100644 index 27454ab..0000000 --- a/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-compressBound-fix.patch +++ /dev/null @@ -1,93 +0,0 @@ -Source from https://gitlab.com/redhat/centos-stream/rpms/zlib/-/merge_requests/9 -Author: Ilya Leoshkevich - ---- a/compress.c -+++ b/compress.c -@@ -5,9 +5,15 @@ - - /* @(#) $Id$ */ - --#define ZLIB_INTERNAL -+#include "zutil.h" - #include "zlib.h" - -+#ifdef DFLTCC -+# include "contrib/s390/dfltcc.h" -+#else -+#define DEFLATE_BOUND_COMPLEN(source_len) 0 -+#endif -+ - /* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte -@@ -81,6 +87,12 @@ int ZEXPORT compress (dest, destLen, source, sourceLen) - uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; - { -+ uLong complen = DEFLATE_BOUND_COMPLEN(sourceLen); -+ -+ if (complen > 0) -+ /* Architecture-specific code provided an upper bound. */ -+ return complen + ZLIB_WRAPLEN; -+ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; - } ---- a/contrib/s390/dfltcc.h -+++ b/contrib/s390/dfltcc.h -@@ -12,6 +12,28 @@ void ZLIB_INTERNAL dfltcc_reset OF((z_streamp strm, uInt size)); - voidpf ZLIB_INTERNAL dfltcc_alloc_window OF((z_streamp strm, uInt items, - uInt size)); - void ZLIB_INTERNAL dfltcc_free_window OF((z_streamp strm, voidpf w)); -+#define DFLTCC_BLOCK_HEADER_BITS 3 -+#define DFLTCC_HLITS_COUNT_BITS 5 -+#define DFLTCC_HDISTS_COUNT_BITS 5 -+#define DFLTCC_HCLENS_COUNT_BITS 4 -+#define DFLTCC_MAX_HCLENS 19 -+#define DFLTCC_HCLEN_BITS 3 -+#define DFLTCC_MAX_HLITS 286 -+#define DFLTCC_MAX_HDISTS 30 -+#define DFLTCC_MAX_HLIT_HDIST_BITS 7 -+#define DFLTCC_MAX_SYMBOL_BITS 16 -+#define DFLTCC_MAX_EOBS_BITS 15 -+#define DFLTCC_MAX_PADDING_BITS 7 -+#define DEFLATE_BOUND_COMPLEN(source_len) \ -+ ((DFLTCC_BLOCK_HEADER_BITS + \ -+ DFLTCC_HLITS_COUNT_BITS + \ -+ DFLTCC_HDISTS_COUNT_BITS + \ -+ DFLTCC_HCLENS_COUNT_BITS + \ -+ DFLTCC_MAX_HCLENS * DFLTCC_HCLEN_BITS + \ -+ (DFLTCC_MAX_HLITS + DFLTCC_MAX_HDISTS) * DFLTCC_MAX_HLIT_HDIST_BITS + \ -+ (source_len) * DFLTCC_MAX_SYMBOL_BITS + \ -+ DFLTCC_MAX_EOBS_BITS + \ -+ DFLTCC_MAX_PADDING_BITS) >> 3) - int ZLIB_INTERNAL dfltcc_can_inflate OF((z_streamp strm)); - typedef enum { - DFLTCC_INFLATE_CONTINUE, -diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h -index 03f7f53..46acfc5 100644 ---- a/contrib/s390/dfltcc_deflate.h -+++ b/contrib/s390/dfltcc_deflate.h -@@ -46,8 +46,7 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm, - #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ - do { \ - if (dfltcc_can_deflate((strm))) \ -- (complen) = (3 + 5 + 5 + 4 + 19 * 3 + (286 + 30) * 7 + \ -- (source_len) * 16 + 15 + 7) >> 3; \ -+ (complen) = DEFLATE_BOUND_COMPLEN(source_len); \ - } while (0) - #define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (dfltcc_can_deflate((strm))) - #define DEFLATE_HOOK dfltcc_deflate -diff --git a/zutil.h b/zutil.h -index 14277bc..cf90e49 100644 ---- a/zutil.h -+++ b/zutil.h -@@ -87,6 +87,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ - - #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - -+#define ZLIB_WRAPLEN 6 /* zlib format overhead */ -+ - /* target dependencies */ - - #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) diff --git a/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch b/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch deleted file mode 100644 index a9e5e29..0000000 --- a/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch +++ /dev/null @@ -1,516 +0,0 @@ -From 608b71008c16ce6fbf2305145c5ffb69cd88ef59 Mon Sep 17 00:00:00 2001 -From: Ondrej Dubaj -Date: Fri, 7 Aug 2020 07:12:50 +0200 -Subject: [PATCH] Fix for Z hardware-accelerated deflate for s390x - ---- - configure | 7 + - contrib/s390/dfltcc.c | 244 +++++++++++++++++++++------------- - contrib/s390/dfltcc_deflate.h | 10 +- - deflate.c | 21 +-- - 4 files changed, 177 insertions(+), 105 deletions(-) - -diff --git a/configure b/configure -index 66caece..bfe4386 100755 ---- a/configure -+++ b/configure -@@ -114,6 +114,7 @@ case "$1" in - echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log - echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log - echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log -+ echo ' [--dfltcc]' | tee -a configure.log - exit 0 ;; - -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; - -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; -@@ -137,6 +138,12 @@ case "$1" in - -c* | --const) zconst=1; shift ;; - -w* | --warn) warn=1; shift ;; - -d* | --debug) debug=1; shift ;; -+ --dfltcc) -+ CFLAGS="$CFLAGS -DDFLTCC" -+ OBJC="$OBJC dfltcc.o" -+ PIC_OBJC="$PIC_OBJC dfltcc.lo" -+ shift -+ ;; - *) - echo "unknown option: $1" | tee -a configure.log - echo "$0 --help for help" | tee -a configure.log -diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c -index d187796..d88a0d6 100644 ---- a/contrib/s390/dfltcc.c -+++ b/contrib/s390/dfltcc.c -@@ -2,12 +2,13 @@ - - /* - Use the following commands to build zlib with DFLTCC support: -- $ CFLAGS=-DDFLTCC ./configure -- $ make OBJA=dfltcc.o PIC_OBJA=dfltcc.lo -+ $ ./configure --dfltcc -+ $ make - */ - - #define _GNU_SOURCE - #include -+#include - #include - #include - #include -@@ -230,31 +231,28 @@ struct dfltcc_state { - /* - Compress. - */ --local inline int dfltcc_are_params_ok(int level, -- uInt window_bits, -- int strategy, -- uLong level_mask); --local inline int dfltcc_are_params_ok(level, window_bits, strategy, level_mask) -+local inline int dfltcc_can_deflate_with_params(z_streamp strm, -+ int level, -+ uInt window_bits, -+ int strategy); -+local inline int dfltcc_can_deflate_with_params(strm, -+ level, -+ window_bits, -+ strategy) -+ z_streamp strm; - int level; - uInt window_bits; - int strategy; -- uLong level_mask; --{ -- return (level_mask & (1 << level)) != 0 && -- (window_bits == HB_BITS) && -- (strategy == Z_FIXED || strategy == Z_DEFAULT_STRATEGY); --} -- -- --int ZLIB_INTERNAL dfltcc_can_deflate(strm) -- z_streamp strm; - { - deflate_state FAR *state = (deflate_state FAR *)strm->state; - struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); - - /* Unsupported compression settings */ -- if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy, -- dfltcc_state->level_mask)) -+ if ((dfltcc_state->level_mask & (1 << level)) == 0) -+ return 0; -+ if (window_bits != HB_BITS) -+ return 0; -+ if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY) - return 0; - - /* Unsupported hardware */ -@@ -266,6 +264,17 @@ int ZLIB_INTERNAL dfltcc_can_deflate(strm) - return 1; - } - -+int ZLIB_INTERNAL dfltcc_can_deflate(strm) -+ z_streamp strm; -+{ -+ deflate_state FAR *state = (deflate_state FAR *)strm->state; -+ -+ return dfltcc_can_deflate_with_params(strm, -+ state->level, -+ state->w_bits, -+ state->strategy); -+} -+ - local void dfltcc_gdht OF((z_streamp strm)); - local void dfltcc_gdht(strm) - z_streamp strm; -@@ -349,22 +358,24 @@ again: - soft_bcc = 0; - no_flush = flush == Z_NO_FLUSH; - -- /* Trailing empty block. Switch to software, except when Continuation Flag -- * is set, which means that DFLTCC has buffered some output in the -- * parameter block and needs to be called again in order to flush it. -+ /* No input data. Return, except when Continuation Flag is set, which means -+ * that DFLTCC has buffered some output in the parameter block and needs to -+ * be called again in order to flush it. - */ -- if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) { -- if (param->bcf) { -- /* A block is still open, and the hardware does not support closing -- * blocks without adding data. Thus, close it manually. -- */ -+ if (strm->avail_in == 0 && !param->cf) { -+ /* A block is still open, and the hardware does not support closing -+ * blocks without adding data. Thus, close it manually. -+ */ -+ if (!no_flush && param->bcf) { - send_eobs(strm, param); - param->bcf = 0; - } -- return 0; -- } -- -- if (strm->avail_in == 0 && !param->cf) { -+ /* Let one of deflate_* functions write a trailing empty block. */ -+ if (flush == Z_FINISH) -+ return 0; -+ /* Clear history. */ -+ if (flush == Z_FULL_FLUSH) -+ param->hl = 0; - *result = need_more; - return 1; - } -@@ -418,7 +429,7 @@ again: - param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32; - if (!no_flush) - /* We need to close a block. Always do this in software - when there is -- * no input data, the hardware will not nohor BCC. */ -+ * no input data, the hardware will not honor BCC. */ - soft_bcc = 1; - if (flush == Z_FINISH && !param->bcf) - /* We are about to open a BFINAL block, set Block Header Final bit -@@ -433,8 +444,8 @@ again: - param->sbb = (unsigned int)state->bi_valid; - if (param->sbb > 0) - *strm->next_out = (Bytef)state->bi_buf; -- if (param->hl) -- param->nt = 0; /* Honor history */ -+ /* Honor history and check value */ -+ param->nt = 0; - param->cv = state->wrap == 2 ? ZSWAP32(strm->adler) : strm->adler; - - /* When opening a block, choose a Huffman-Table Type */ -@@ -642,27 +653,86 @@ int ZLIB_INTERNAL dfltcc_inflate_disable(strm) - return 0; - } - --/* -- Memory management. -- DFLTCC requires parameter blocks and window to be aligned. zlib allows -- users to specify their own allocation functions, so using e.g. -- `posix_memalign' is not an option. Thus, we overallocate and take the -- aligned portion of the buffer. --*/ -+local int env_dfltcc_disabled; -+local int env_source_date_epoch; -+local unsigned long env_level_mask; -+local unsigned long env_block_size; -+local unsigned long env_block_threshold; -+local unsigned long env_dht_threshold; -+local unsigned long env_ribm; -+local uint64_t cpu_facilities[(DFLTCC_FACILITY / 64) + 1]; -+local struct dfltcc_qaf_param cpu_af __attribute__((aligned(8))); -+ - local inline int is_dfltcc_enabled OF((void)); - local inline int is_dfltcc_enabled(void) -+{ -+ if (env_dfltcc_disabled) -+ /* User has explicitly disabled DFLTCC. */ -+ return 0; -+ -+ return is_bit_set((const char *)cpu_facilities, DFLTCC_FACILITY); -+} -+ -+local unsigned long xstrtoul OF((const char *s, unsigned long _default)); -+local unsigned long xstrtoul(s, _default) -+ const char *s; -+ unsigned long _default; -+{ -+ char *endptr; -+ unsigned long result; -+ -+ if (!(s && *s)) -+ return _default; -+ errno = 0; -+ result = strtoul(s, &endptr, 0); -+ return (errno || *endptr) ? _default : result; -+} -+ -+__attribute__((constructor)) local void init_globals OF((void)); -+__attribute__((constructor)) local void init_globals(void) - { - const char *env; -- uint64_t facilities[(DFLTCC_FACILITY / 64) + 1]; - register char r0 __asm__("r0"); - - env = secure_getenv("DFLTCC"); -- if (env && !strcmp(env, "0")) -- /* User has explicitly disabled DFLTCC. */ -- return 0; -+ -+ -+ env_dfltcc_disabled = env && !strcmp(env, "0"); -+ -+ env = secure_getenv("SOURCE_DATE_EPOCH"); -+ env_source_date_epoch = !!env; -+ -+#ifndef DFLTCC_LEVEL_MASK -+#define DFLTCC_LEVEL_MASK 0x2 -+#endif -+ env_level_mask = xstrtoul(secure_getenv("DFLTCC_LEVEL_MASK"), -+ DFLTCC_LEVEL_MASK); -+ -+#ifndef DFLTCC_BLOCK_SIZE -+#define DFLTCC_BLOCK_SIZE 1048576 -+#endif -+ env_block_size = xstrtoul(secure_getenv("DFLTCC_BLOCK_SIZE"), -+ DFLTCC_BLOCK_SIZE); - -- memset(facilities, 0, sizeof(facilities)); -- r0 = sizeof(facilities) / sizeof(facilities[0]) - 1; -+#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE -+#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 -+#endif -+ env_block_threshold = xstrtoul(secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE"), -+ DFLTCC_FIRST_FHT_BLOCK_SIZE); -+ -+#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE -+#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 -+#endif -+ env_dht_threshold = xstrtoul(secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE"), -+ DFLTCC_DHT_MIN_SAMPLE_SIZE); -+ -+#ifndef DFLTCC_RIBM -+#define DFLTCC_RIBM 0 -+#endif -+ env_ribm = xstrtoul(secure_getenv("DFLTCC_RIBM"), DFLTCC_RIBM); -+ -+ memset(cpu_facilities, 0, sizeof(cpu_facilities)); -+ r0 = sizeof(cpu_facilities) / sizeof(cpu_facilities[0]) - 1; - /* STFLE is supported since z9-109 and only in z/Architecture mode. When - * compiling with -m31, gcc defaults to ESA mode, however, since the kernel - * is 64-bit, it's always z/Architecture mode at runtime. -@@ -671,31 +741,35 @@ local inline int is_dfltcc_enabled(void) - ".machinemode zarch\n" - "stfle %[facilities]\n" - ".machinemode pop\n" -- : [facilities] "=Q" (facilities) -+ : [facilities] "=Q" (cpu_facilities) - , [r0] "+r" (r0) - : - : "cc"); -- return is_bit_set((const char *)facilities, DFLTCC_FACILITY); -+ /* Initialize available functions */ -+ if (is_dfltcc_enabled()) -+ dfltcc(DFLTCC_QAF, &cpu_af, NULL, NULL, NULL, NULL, NULL); -+ else -+ memset(&cpu_af, 0, sizeof(cpu_af)); - } - -+/* -+ Memory management. -+ -+ DFLTCC requires parameter blocks and window to be aligned. zlib allows -+ users to specify their own allocation functions, so using e.g. -+ `posix_memalign' is not an option. Thus, we overallocate and take the -+ aligned portion of the buffer. -+*/ - void ZLIB_INTERNAL dfltcc_reset(strm, size) - z_streamp strm; - uInt size; - { - struct dfltcc_state *dfltcc_state = - (struct dfltcc_state *)((char FAR *)strm->state + ALIGN_UP(size, 8)); -- struct dfltcc_qaf_param *param = -- (struct dfltcc_qaf_param *)&dfltcc_state->param; -- const char *s; - -- /* Initialize available functions */ -- if (is_dfltcc_enabled()) { -- dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL); -- memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af)); -- } else -- memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); -+ memcpy(&dfltcc_state->af, &cpu_af, sizeof(dfltcc_state->af)); - -- if (secure_getenv("SOURCE_DATE_EPOCH")) -+ if (env_source_date_epoch) - /* User needs reproducible results, but the output of DFLTCC_CMPR - * depends on buffers' page offsets. - */ -@@ -706,36 +780,11 @@ void ZLIB_INTERNAL dfltcc_reset(strm, size) - dfltcc_state->param.nt = 1; - - /* Initialize tuning parameters */ --#ifndef DFLTCC_LEVEL_MASK --#define DFLTCC_LEVEL_MASK 0x2 --#endif -- s = secure_getenv("DFLTCC_LEVEL_MASK"); -- dfltcc_state->level_mask = (s && *s) ? strtoul(s, NULL, 0) : -- DFLTCC_LEVEL_MASK; --#ifndef DFLTCC_BLOCK_SIZE --#define DFLTCC_BLOCK_SIZE 1048576 --#endif -- s = secure_getenv("DFLTCC_BLOCK_SIZE"); -- dfltcc_state->block_size = (s && *s) ? strtoul(s, NULL, 0) : -- DFLTCC_BLOCK_SIZE; --#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE --#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 --#endif -- s = secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE"); -- dfltcc_state->block_threshold = (s && *s) ? strtoul(s, NULL, 0) : -- DFLTCC_FIRST_FHT_BLOCK_SIZE; --#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE --#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 --#endif -- s = secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE"); -- dfltcc_state->dht_threshold = (s && *s) ? strtoul(s, NULL, 0) : -- DFLTCC_DHT_MIN_SAMPLE_SIZE; --#ifndef DFLTCC_RIBM --#define DFLTCC_RIBM 0 --#endif -- s = secure_getenv("DFLTCC_RIBM"); -- dfltcc_state->param.ribm = (s && *s) ? strtoul(s, NULL, 0) : -- DFLTCC_RIBM; -+ dfltcc_state->level_mask = env_level_mask; -+ dfltcc_state->block_size = env_block_size; -+ dfltcc_state->block_threshold = env_block_threshold; -+ dfltcc_state->dht_threshold = env_dht_threshold; -+ dfltcc_state->param.ribm = env_ribm; - } - - voidpf ZLIB_INTERNAL dfltcc_alloc_state(strm, items, size) -@@ -787,22 +836,26 @@ void ZLIB_INTERNAL dfltcc_free_window(strm, w) - - /* - Switching between hardware and software compression. -+ - DFLTCC does not support all zlib settings, e.g. generation of non-compressed - blocks or alternative window sizes. When such settings are applied on the - fly with deflateParams, we need to convert between hardware and software - window formats. - */ --int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy) -+int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush) - z_streamp strm; - int level; - int strategy; -+ int *flush; - { - deflate_state FAR *state = (deflate_state FAR *)strm->state; - struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); - struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; - int could_deflate = dfltcc_can_deflate(strm); -- int can_deflate = dfltcc_are_params_ok(level, state->w_bits, strategy, -- dfltcc_state->level_mask); -+ int can_deflate = dfltcc_can_deflate_with_params(strm, -+ level, -+ state->w_bits, -+ strategy); - - if (can_deflate == could_deflate) - /* We continue to work in the same mode - no changes needed */ -@@ -812,8 +865,11 @@ int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy) - /* DFLTCC was not used yet - no changes needed */ - return Z_OK; - -- /* Switching between hardware and software is not implemented */ -- return Z_STREAM_ERROR; -+ /* For now, do not convert between window formats - simply get rid of the -+ * old data instead. -+ */ -+ *flush = Z_FULL_FLUSH; -+ return Z_OK; - } - - /* -diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h -index a129a91..de36784 100644 ---- a/contrib/s390/dfltcc_deflate.h -+++ b/contrib/s390/dfltcc_deflate.h -@@ -9,7 +9,8 @@ int ZLIB_INTERNAL dfltcc_deflate OF((z_streamp strm, - block_state *result)); - int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm, - int level, -- int strategy)); -+ int strategy, -+ int *flush)); - int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dict_length)); -@@ -29,11 +30,14 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm, - } while (0) - #define DEFLATE_RESET_KEEP_HOOK(strm) \ - dfltcc_reset((strm), sizeof(deflate_state)) --#define DEFLATE_PARAMS_HOOK(strm, level, strategy) \ -+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ - do { \ - int err; \ - \ -- err = dfltcc_deflate_params((strm), (level), (strategy)); \ -+ err = dfltcc_deflate_params((strm), \ -+ (level), \ -+ (strategy), \ -+ (hook_flush)); \ - if (err == Z_STREAM_ERROR) \ - return err; \ - } while (0) -diff --git a/deflate.c b/deflate.c -index b17a7dd..a80bd3e 100644 ---- a/deflate.c -+++ b/deflate.c -@@ -74,7 +74,7 @@ const char deflate_copyright[] = - #define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) - #define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) - #define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) --#define DEFLATE_PARAMS_HOOK(strm, level, strategy) do {} while (0) -+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) - #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) - #define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 - #define DEFLATE_HOOK(strm, flush, bstate) 0 -@@ -589,6 +589,7 @@ int ZEXPORT deflateParams(strm, level, strategy) - { - deflate_state *s; - compress_func func; -+ int hook_flush = Z_NO_FLUSH; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; -@@ -601,13 +602,14 @@ int ZEXPORT deflateParams(strm, level, strategy) - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } -- DEFLATE_PARAMS_HOOK(strm, level, strategy); -+ DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); - func = configuration_table[s->level].func; - -- if ((strategy != s->strategy || func != configuration_table[level].func) && -- s->high_water) { -+ if ((strategy != s->strategy || func != configuration_table[level].func || -+ hook_flush != Z_NO_FLUSH) && s->high_water) { - /* Flush the last buffer: */ -- int err = deflate(strm, Z_BLOCK); -+ int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ? -+ hook_flush : Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_out == 0) -@@ -1065,7 +1067,6 @@ int ZEXPORT deflate (strm, flush) - } - - if (flush != Z_FINISH) return Z_OK; -- if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ - #ifdef GZIP -@@ -1081,7 +1082,7 @@ int ZEXPORT deflate (strm, flush) - } - else - #endif -- { -+ if (s->wrap == 1) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } -@@ -1090,7 +1091,11 @@ int ZEXPORT deflate (strm, flush) - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ -- return s->pending != 0 ? Z_OK : Z_STREAM_END; -+ if (s->pending == 0) { -+ Assert(s->bi_valid == 0, "bi_buf not flushed"); -+ return Z_STREAM_END; -+ } -+ return Z_OK; - } - - /* ========================================================================= */ --- -2.26.0 - diff --git a/zlib-1.2.11-inflateSyncPoint-return-value-fix.patch b/zlib-1.2.11-inflateSyncPoint-return-value-fix.patch deleted file mode 100644 index f9b3756..0000000 --- a/zlib-1.2.11-inflateSyncPoint-return-value-fix.patch +++ /dev/null @@ -1,45 +0,0 @@ -Subject: [PATCH] Fixed inflateSyncPoint() bad return value on z15 - ---- - contrib/s390/dfltcc.h | 4 ++++ - inflate.c | 2 ++ - 2 files changed, 6 insertions(+) - -diff --git a/contrib/s390/dfltcc.h b/contrib/s390/dfltcc.h -index 574e84c..7960626 100644 ---- a/contrib/s390/dfltcc.h -+++ b/contrib/s390/dfltcc.h -@@ -51,5 +51,9 @@ int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm)); - do { \ - if (dfltcc_was_inflate_used((strm))) return -(1L << 16); \ - } while (0) -+#define INFLATE_SYNC_POINT_HOOK(strm) \ -+ do { \ -+ if (dfltcc_was_inflate_used((strm))) return Z_STREAM_ERROR; \ -+ } while (0) - - #endif -\ No newline at end of file -diff --git a/inflate.c b/inflate.c -index f77c2ae..596034c 100644 ---- a/inflate.c -+++ b/inflate.c -@@ -100,6 +100,7 @@ - #define INFLATE_NEED_CHECKSUM(strm) 1 - #define INFLATE_NEED_UPDATEWINDOW(strm) 1 - #define INFLATE_MARK_HOOK(strm) do {} while (0) -+#define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0) - #endif - - #ifdef MAKEFIXED -@@ -1483,6 +1484,7 @@ z_streamp strm; - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; -+ INFLATE_SYNC_POINT_HOOK(strm); - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; - } --- -2.26.0 - diff --git a/zlib-1.2.11-permit-deflateParams-change.patch b/zlib-1.2.11-permit-deflateParams-change.patch deleted file mode 100644 index 4f7b0ef..0000000 --- a/zlib-1.2.11-permit-deflateParams-change.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d09bb1ab8ef9bb91457c0ead09589e8807489260 Mon Sep 17 00:00:00 2001 -From: Ondrej Dubaj -Date: Thu, 6 Aug 2020 08:09:53 +0200 -Subject: [PATCH] Permit a deflateParams() parameter change. - -This change allows a parameter change even if the input data has -not all been compressed and copied to the application output -buffer, so long as all of the input data has been compressed to -the internal pending output buffer. This also allows an immediate -deflateParams change so long as there have been no deflate calls -since initialization or reset. ---- - deflate.c | 6 +++--- - zlib.h | 11 ++++++----- - 2 files changed, 9 insertions(+), 8 deletions(-) - -diff --git a/deflate.c b/deflate.c -index 9705c1c..f3c9924 100644 ---- a/deflate.c -+++ b/deflate.c -@@ -509,7 +509,7 @@ int ZEXPORT deflateResetKeep (strm) - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : - #endif - adler32(0L, Z_NULL, 0); -- s->last_flush = Z_NO_FLUSH; -+ s->last_flush = -2; - - _tr_init(s); - -@@ -606,13 +606,13 @@ int ZEXPORT deflateParams(strm, level, strategy) - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func || -- hook_flush != Z_NO_FLUSH) && s->high_water) { -+ hook_flush != Z_NO_FLUSH) && s->last_flush != -2) { - /* Flush the last buffer: */ - int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ? - hook_flush : Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; -- if (strm->avail_out == 0) -+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) - return Z_BUF_ERROR; - } - if (s->level != level) { -diff --git a/zlib.h b/zlib.h -index f09cdaf..001624e 100644 ---- a/zlib.h -+++ b/zlib.h -@@ -712,11 +712,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the -- strategy is changed, and if any input has been consumed in a previous -- deflate() call, then the input available so far is compressed with the old -- level and strategy using deflate(strm, Z_BLOCK). There are three approaches -- for the compression levels 0, 1..3, and 4..9 respectively. The new level -- and strategy will take effect at the next call of deflate(). -+ strategy is changed, and if there have been any deflate() calls since the -+ state was initialized or reset, then the input available so far is -+ compressed with the old level and strategy using deflate(strm, Z_BLOCK). -+ There are three approaches for the compression levels 0, 1..3, and 4..9 -+ respectively. The new level and strategy will take effect at the next call -+ of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not --- -2.26.0 - diff --git a/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-s390x.patch b/zlib-1.2.12-IBM-Z-hw-accelerated-deflate.patch similarity index 74% rename from zlib-1.2.11-IBM-Z-hw-accelrated-deflate-s390x.patch rename to zlib-1.2.12-IBM-Z-hw-accelerated-deflate.patch index 002a0d5..bf30042 100644 --- a/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-s390x.patch +++ b/zlib-1.2.12-IBM-Z-hw-accelerated-deflate.patch @@ -1,9 +1,9 @@ -From 4e65ca20fc242e4a03471558a357d7809adeb9c4 Mon Sep 17 00:00:00 2001 -From: IBM developers -Date: Thu, 1 Aug 2019 09:02:01 +0200 +From e6aed68ff815be74855ec6a19d6ae35065a4adb4 Mon Sep 17 00:00:00 2001 +From: Ilya Leoshkevich +Date: Wed, 18 Jul 2018 13:14:07 +0200 Subject: [PATCH] Add support for IBM Z hardware-accelerated deflate -Future versions of IBM Z mainframes will provide DFLTCC instruction, +IBM Z mainframes starting from version z15 provide DFLTCC instruction, which implements deflate algorithm in hardware with estimated compression and decompression performance orders of magnitude faster than the current zlib and ratio comparable with that of level 1. @@ -11,15 +11,15 @@ than the current zlib and ratio comparable with that of level 1. This patch adds DFLTCC support to zlib. In order to enable it, the following build commands should be used: - $ CFLAGS=-DDFLTCC ./configure - $ make OBJA=dfltcc.o PIC_OBJA=dfltcc.lo + $ ./configure --dfltcc + $ make When built like this, zlib would compress in hardware on level 1, and in software on all other levels. Decompression will always happen in hardware. In order to enable DFLTCC compression for levels 1-6 (i.e. to -make it used by default) one could either add -DDFLTCC_LEVEL_MASK=0x7e -at compile time, or set the environment variable DFLTCC_LEVEL_MASK to -0x7e at run time. +make it used by default) one could either configure with +--dfltcc-level-mask=0x7e or set the environment variable +DFLTCC_LEVEL_MASK to 0x7e at run time. Two DFLTCC compression calls produce the same results only when they both are made on machines of the same generation, and when the @@ -34,15 +34,15 @@ DFLTCC does not support every single zlib feature, in particular: * inflate(Z_BLOCK) and inflate(Z_TREES) * inflateMark() * inflatePrime() - * deflateParams() after the first deflate() call + * inflateSyncPoint() When used, these functions will either switch to software, or, in case this is not possible, gracefully fail. -This patch tries to add DFLTCC support in a least intrusive way. -All SystemZ-specific code was placed into a separate file, but +This patch tries to add DFLTCC support in the least intrusive way. +All SystemZ-specific code is placed into a separate file, but unfortunately there is still a noticeable amount of changes in the -main zlib code. Below is the summary of those changes. +main zlib code. Below is the summary of these changes. DFLTCC takes as arguments a parameter block, an input buffer, an output buffer and a window. Since DFLTCC requires parameter block to be @@ -61,9 +61,12 @@ deflateResetKeep() and inflateResetKeep() now update the DFLTCC parameter block, which is allocated alongside zlib state, using the new DEFLATE_RESET_KEEP_HOOK and INFLATE_RESET_KEEP_HOOK macros. -In order to make unsupported deflateParams(), inflatePrime() and -inflateMark() calls to fail gracefully, the new DEFLATE_PARAMS_HOOK, -INFLATE_PRIME_HOOK and INFLATE_MARK_HOOK macros were introduced. +The new DEFLATE_PARAMS_HOOK switches between hardware and software +deflate implementations when deflateParams() arguments demand this. + +The new INFLATE_PRIME_HOOK, INFLATE_MARK_HOOK and +INFLATE_SYNC_POINT_HOOK macros make the respective unsupported calls +gracefully fail. The algorithm implemented in hardware has different compression ratio than the one implemented in software. In order for deflateBound() to @@ -93,26 +96,30 @@ might be not allocated yet, inflate_ensure_window was factored out of updatewindow and made ZLIB_INTERNAL. --- Makefile.in | 8 + - configure | 13 + + compress.c | 14 +- + configure | 24 + contrib/README.contrib | 4 + - contrib/s390/dfltcc.c | 901 ++++++++++++++++++++++++++++++++++ - contrib/s390/dfltcc.h | 55 +++ - contrib/s390/dfltcc_deflate.h | 50 ++ - deflate.c | 60 ++- + contrib/s390/README.txt | 17 + + contrib/s390/dfltcc.c | 996 ++++++++++++++++++++++++++++++++++ + contrib/s390/dfltcc.h | 81 +++ + contrib/s390/dfltcc_deflate.h | 55 ++ + deflate.c | 81 ++- deflate.h | 12 + gzguts.h | 4 + - inflate.c | 84 +++- + inflate.c | 87 ++- inflate.h | 2 + - test/infcover.c | 2 +- + test/infcover.c | 4 +- test/minigzip.c | 4 + trees.c | 13 +- - 14 files changed, 1161 insertions(+), 51 deletions(-) + zutil.h | 2 + + 17 files changed, 1348 insertions(+), 60 deletions(-) + create mode 100644 contrib/s390/README.txt create mode 100644 contrib/s390/dfltcc.c create mode 100644 contrib/s390/dfltcc.h create mode 100644 contrib/s390/dfltcc_deflate.h diff --git a/Makefile.in b/Makefile.in -index 5a77949..e756e2f 100644 +index fd28bbfbf..66e3a8057 100644 --- a/Makefile.in +++ b/Makefile.in @@ -143,6 +143,14 @@ match.lo: match.S @@ -130,11 +137,70 @@ index 5a77949..e756e2f 100644 example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c +diff --git a/compress.c b/compress.c +index e2db404ab..78fc6568f 100644 +--- a/compress.c ++++ b/compress.c +@@ -5,9 +5,15 @@ + + /* @(#) $Id$ */ + +-#define ZLIB_INTERNAL ++#include "zutil.h" + #include "zlib.h" + ++#ifdef DFLTCC ++# include "contrib/s390/dfltcc.h" ++#else ++#define DEFLATE_BOUND_COMPLEN(source_len) 0 ++#endif ++ + /* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte +@@ -81,6 +87,12 @@ int ZEXPORT compress (dest, destLen, source, sourceLen) + uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; + { ++ uLong complen = DEFLATE_BOUND_COMPLEN(sourceLen); ++ ++ if (complen > 0) ++ /* Architecture-specific code provided an upper bound. */ ++ return complen + ZLIB_WRAPLEN; ++ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; + } diff --git a/configure b/configure -index e974d1f..8fab355 100755 +index 3fa3e8618..cdf0e5b6b 100755 --- a/configure +++ b/configure -@@ -826,6 +826,19 @@ EOF +@@ -115,6 +115,7 @@ case "$1" in + echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log ++ echo ' [--dfltcc] [--dfltcc-level-mask=MASK]' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; +@@ -139,6 +140,16 @@ case "$1" in + -w* | --warn) warn=1; shift ;; + -d* | --debug) debug=1; shift ;; + --sanitize) sanitize=1; shift ;; ++ --dfltcc) ++ CFLAGS="$CFLAGS -DDFLTCC" ++ OBJC="$OBJC dfltcc.o" ++ PIC_OBJC="$PIC_OBJC dfltcc.lo" ++ shift ++ ;; ++ --dfltcc-level-mask=*) ++ CFLAGS="$CFLAGS -DDFLTCC_LEVEL_MASK=`echo $1 | sed 's/.*=//'`" ++ shift ++ ;; + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log +@@ -836,6 +847,19 @@ EOF fi fi @@ -143,7 +209,7 @@ index e974d1f..8fab355 100755 +#include +int main() { return 0; } +EOF -+if try ${CC} ${CFLAGS} $test.c; then ++if try $CC -c $CFLAGS $test.c; then + echo "Checking for sys/sdt.h ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_SYS_SDT_H" + SFLAGS="$SFLAGS -DHAVE_SYS_SDT_H" @@ -155,10 +221,10 @@ index e974d1f..8fab355 100755 echo >> configure.log echo ALL = $ALL >> configure.log diff --git a/contrib/README.contrib b/contrib/README.contrib -index a411d5c..b4d3b18 100644 +index 335e43508..130a28bdb 100644 --- a/contrib/README.contrib +++ b/contrib/README.contrib -@@ -67,6 +67,10 @@ puff/ by Mark Adler +@@ -46,6 +46,10 @@ puff/ by Mark Adler Small, low memory usage inflate. Also serves to provide an unambiguous description of the deflate format. @@ -169,22 +235,47 @@ index a411d5c..b4d3b18 100644 testzlib/ by Gilles Vollant Example of the use of zlib +diff --git a/contrib/s390/README.txt b/contrib/s390/README.txt +new file mode 100644 +index 000000000..48be008bd +--- /dev/null ++++ b/contrib/s390/README.txt +@@ -0,0 +1,17 @@ ++IBM Z mainframes starting from version z15 provide DFLTCC instruction, ++which implements deflate algorithm in hardware with estimated ++compression and decompression performance orders of magnitude faster ++than the current zlib and ratio comparable with that of level 1. ++ ++This directory adds DFLTCC support. In order to enable it, the following ++build commands should be used: ++ ++ $ ./configure --dfltcc ++ $ make ++ ++When built like this, zlib would compress in hardware on level 1, and in ++software on all other levels. Decompression will always happen in ++hardware. In order to enable DFLTCC compression for levels 1-6 (i.e. to ++make it used by default) one could either configure with ++--dfltcc-level-mask=0x7e or set the environment variable ++DFLTCC_LEVEL_MASK to 0x7e at run time. diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c new file mode 100644 -index 0000000..d187796 +index 000000000..fe81bebfe --- /dev/null +++ b/contrib/s390/dfltcc.c -@@ -0,0 +1,901 @@ +@@ -0,0 +1,996 @@ +/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ + +/* + Use the following commands to build zlib with DFLTCC support: -+ $ CFLAGS=-DDFLTCC ./configure -+ $ make OBJA=dfltcc.o PIC_OBJA=dfltcc.lo ++ ++ $ ./configure --dfltcc ++ $ make +*/ + +#define _GNU_SOURCE +#include ++#include +#include +#include +#include @@ -407,31 +498,28 @@ index 0000000..d187796 +/* + Compress. + */ -+local inline int dfltcc_are_params_ok(int level, -+ uInt window_bits, -+ int strategy, -+ uLong level_mask); -+local inline int dfltcc_are_params_ok(level, window_bits, strategy, level_mask) ++local inline int dfltcc_can_deflate_with_params(z_streamp strm, ++ int level, ++ uInt window_bits, ++ int strategy); ++local inline int dfltcc_can_deflate_with_params(strm, ++ level, ++ window_bits, ++ strategy) ++ z_streamp strm; + int level; + uInt window_bits; + int strategy; -+ uLong level_mask; -+{ -+ return (level_mask & (1 << level)) != 0 && -+ (window_bits == HB_BITS) && -+ (strategy == Z_FIXED || strategy == Z_DEFAULT_STRATEGY); -+} -+ -+ -+int ZLIB_INTERNAL dfltcc_can_deflate(strm) -+ z_streamp strm; +{ + deflate_state FAR *state = (deflate_state FAR *)strm->state; + struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); + + /* Unsupported compression settings */ -+ if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy, -+ dfltcc_state->level_mask)) ++ if ((dfltcc_state->level_mask & (1 << level)) == 0) ++ return 0; ++ if (window_bits != HB_BITS) ++ return 0; ++ if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY) + return 0; + + /* Unsupported hardware */ @@ -443,6 +531,17 @@ index 0000000..d187796 + return 1; +} + ++int ZLIB_INTERNAL dfltcc_can_deflate(strm) ++ z_streamp strm; ++{ ++ deflate_state FAR *state = (deflate_state FAR *)strm->state; ++ ++ return dfltcc_can_deflate_with_params(strm, ++ state->level, ++ state->w_bits, ++ state->strategy); ++} ++ +local void dfltcc_gdht OF((z_streamp strm)); +local void dfltcc_gdht(strm) + z_streamp strm; @@ -518,31 +617,38 @@ index 0000000..d187796 + int soft_bcc; + int no_flush; + -+ if (!dfltcc_can_deflate(strm)) ++ if (!dfltcc_can_deflate(strm)) { ++ /* Clear history. */ ++ if (flush == Z_FULL_FLUSH) ++ param->hl = 0; + return 0; ++ } + +again: + masked_avail_in = 0; + soft_bcc = 0; + no_flush = flush == Z_NO_FLUSH; + -+ /* Trailing empty block. Switch to software, except when Continuation Flag -+ * is set, which means that DFLTCC has buffered some output in the -+ * parameter block and needs to be called again in order to flush it. ++ /* No input data. Return, except when Continuation Flag is set, which means ++ * that DFLTCC has buffered some output in the parameter block and needs to ++ * be called again in order to flush it. + */ -+ if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) { -+ if (param->bcf) { -+ /* A block is still open, and the hardware does not support closing -+ * blocks without adding data. Thus, close it manually. -+ */ ++ if (strm->avail_in == 0 && !param->cf) { ++ /* A block is still open, and the hardware does not support closing ++ * blocks without adding data. Thus, close it manually. ++ */ ++ if (!no_flush && param->bcf) { + send_eobs(strm, param); + param->bcf = 0; + } -+ return 0; -+ } -+ -+ if (strm->avail_in == 0 && !param->cf) { -+ *result = need_more; ++ /* Let one of deflate_* functions write a trailing empty block. */ ++ if (flush == Z_FINISH) ++ return 0; ++ /* Clear history. */ ++ if (flush == Z_FULL_FLUSH) ++ param->hl = 0; ++ /* Trigger block post-processing if necessary. */ ++ *result = no_flush ? need_more : block_done; + return 1; + } + @@ -569,13 +675,18 @@ index 0000000..d187796 + param->bcf = 0; + dfltcc_state->block_threshold = + strm->total_in + dfltcc_state->block_size; -+ if (strm->avail_out == 0) { -+ *result = need_more; -+ return 1; -+ } + } + } + ++ /* No space for compressed data. If we proceed, dfltcc_cmpr() will return ++ * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still ++ * set BCF=1, which is wrong. Avoid complications and return early. ++ */ ++ if (strm->avail_out == 0) { ++ *result = need_more; ++ return 1; ++ } ++ + /* The caller gave us too much data. Pass only one block worth of + * uncompressed data to DFLTCC and mask the rest, so that on the next + * iteration we start a new block. @@ -595,7 +706,7 @@ index 0000000..d187796 + param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32; + if (!no_flush) + /* We need to close a block. Always do this in software - when there is -+ * no input data, the hardware will not nohor BCC. */ ++ * no input data, the hardware will not honor BCC. */ + soft_bcc = 1; + if (flush == Z_FINISH && !param->bcf) + /* We are about to open a BFINAL block, set Block Header Final bit @@ -610,8 +721,8 @@ index 0000000..d187796 + param->sbb = (unsigned int)state->bi_valid; + if (param->sbb > 0) + *strm->next_out = (Bytef)state->bi_buf; -+ if (param->hl) -+ param->nt = 0; /* Honor history */ ++ /* Honor history and check value */ ++ param->nt = 0; + param->cv = state->wrap == 2 ? ZSWAP32(strm->adler) : strm->adler; + + /* When opening a block, choose a Huffman-Table Type */ @@ -819,60 +930,128 @@ index 0000000..d187796 + return 0; +} + ++local int env_dfltcc_disabled; ++local int env_source_date_epoch; ++local unsigned long env_level_mask; ++local unsigned long env_block_size; ++local unsigned long env_block_threshold; ++local unsigned long env_dht_threshold; ++local unsigned long env_ribm; ++local uint64_t cpu_facilities[(DFLTCC_FACILITY / 64) + 1]; ++local struct dfltcc_qaf_param cpu_af __attribute__((aligned(8))); ++ ++local inline int is_dfltcc_enabled OF((void)); ++local inline int is_dfltcc_enabled(void) ++{ ++ if (env_dfltcc_disabled) ++ /* User has explicitly disabled DFLTCC. */ ++ return 0; ++ ++ return is_bit_set((const char *)cpu_facilities, DFLTCC_FACILITY); ++} ++ ++local unsigned long xstrtoul OF((const char *s, unsigned long _default)); ++local unsigned long xstrtoul(s, _default) ++ const char *s; ++ unsigned long _default; ++{ ++ char *endptr; ++ unsigned long result; ++ ++ if (!(s && *s)) ++ return _default; ++ errno = 0; ++ result = strtoul(s, &endptr, 0); ++ return (errno || *endptr) ? _default : result; ++} ++ ++__attribute__((constructor)) local void init_globals OF((void)); ++__attribute__((constructor)) local void init_globals(void) ++{ ++ const char *endptr; ++ const char *env; ++ register char r0 __asm__("r0"); ++ ++ env = secure_getenv("DFLTCC"); ++ env_dfltcc_disabled = env && !strcmp(env, "0"); ++ ++ env = secure_getenv("SOURCE_DATE_EPOCH"); ++ env_source_date_epoch = !!env; ++ ++#ifndef DFLTCC_LEVEL_MASK ++#define DFLTCC_LEVEL_MASK 0x2 ++#endif ++ env_level_mask = xstrtoul(secure_getenv("DFLTCC_LEVEL_MASK"), ++ DFLTCC_LEVEL_MASK); ++ ++#ifndef DFLTCC_BLOCK_SIZE ++#define DFLTCC_BLOCK_SIZE 1048576 ++#endif ++ env_block_size = xstrtoul(secure_getenv("DFLTCC_BLOCK_SIZE"), ++ DFLTCC_BLOCK_SIZE); ++ ++#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE ++#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 ++#endif ++ env_block_threshold = xstrtoul(secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE"), ++ DFLTCC_FIRST_FHT_BLOCK_SIZE); ++ ++#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE ++#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 ++#endif ++ env_dht_threshold = xstrtoul(secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE"), ++ DFLTCC_DHT_MIN_SAMPLE_SIZE); ++ ++#ifndef DFLTCC_RIBM ++#define DFLTCC_RIBM 0 ++#endif ++ env_ribm = xstrtoul(secure_getenv("DFLTCC_RIBM"), DFLTCC_RIBM); ++ ++ memset(cpu_facilities, 0, sizeof(cpu_facilities)); ++ r0 = sizeof(cpu_facilities) / sizeof(cpu_facilities[0]) - 1; ++ /* STFLE is supported since z9-109 and only in z/Architecture mode. When ++ * compiling with -m31, gcc defaults to ESA mode, however, since the kernel ++ * is 64-bit, it's always z/Architecture mode at runtime. ++ */ ++ __asm__ volatile( ++#ifndef __clang__ ++ ".machinemode push\n" ++ ".machinemode zarch\n" ++#endif ++ "stfle %[facilities]\n" ++#ifndef __clang__ ++ ".machinemode pop\n" ++#endif ++ : [facilities] "=Q" (cpu_facilities) ++ , [r0] "+r" (r0) ++ : ++ : "cc"); ++ ++ /* Initialize available functions */ ++ if (is_dfltcc_enabled()) ++ dfltcc(DFLTCC_QAF, &cpu_af, NULL, NULL, NULL, NULL, NULL); ++ else ++ memset(&cpu_af, 0, sizeof(cpu_af)); ++} ++ +/* + Memory management. ++ + DFLTCC requires parameter blocks and window to be aligned. zlib allows + users to specify their own allocation functions, so using e.g. + `posix_memalign' is not an option. Thus, we overallocate and take the + aligned portion of the buffer. +*/ -+local inline int is_dfltcc_enabled OF((void)); -+local inline int is_dfltcc_enabled(void) -+{ -+ const char *env; -+ uint64_t facilities[(DFLTCC_FACILITY / 64) + 1]; -+ register char r0 __asm__("r0"); -+ -+ env = secure_getenv("DFLTCC"); -+ if (env && !strcmp(env, "0")) -+ /* User has explicitly disabled DFLTCC. */ -+ return 0; -+ -+ memset(facilities, 0, sizeof(facilities)); -+ r0 = sizeof(facilities) / sizeof(facilities[0]) - 1; -+ /* STFLE is supported since z9-109 and only in z/Architecture mode. When -+ * compiling with -m31, gcc defaults to ESA mode, however, since the kernel -+ * is 64-bit, it's always z/Architecture mode at runtime. -+ */ -+ __asm__ volatile(".machinemode push\n" -+ ".machinemode zarch\n" -+ "stfle %[facilities]\n" -+ ".machinemode pop\n" -+ : [facilities] "=Q" (facilities) -+ , [r0] "+r" (r0) -+ : -+ : "cc"); -+ return is_bit_set((const char *)facilities, DFLTCC_FACILITY); -+} -+ +void ZLIB_INTERNAL dfltcc_reset(strm, size) + z_streamp strm; + uInt size; +{ + struct dfltcc_state *dfltcc_state = + (struct dfltcc_state *)((char FAR *)strm->state + ALIGN_UP(size, 8)); -+ struct dfltcc_qaf_param *param = -+ (struct dfltcc_qaf_param *)&dfltcc_state->param; -+ const char *s; + -+ /* Initialize available functions */ -+ if (is_dfltcc_enabled()) { -+ dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL); -+ memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af)); -+ } else -+ memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); ++ memcpy(&dfltcc_state->af, &cpu_af, sizeof(dfltcc_state->af)); + -+ if (secure_getenv("SOURCE_DATE_EPOCH")) ++ if (env_source_date_epoch) + /* User needs reproducible results, but the output of DFLTCC_CMPR + * depends on buffers' page offsets. + */ @@ -883,36 +1062,11 @@ index 0000000..d187796 + dfltcc_state->param.nt = 1; + + /* Initialize tuning parameters */ -+#ifndef DFLTCC_LEVEL_MASK -+#define DFLTCC_LEVEL_MASK 0x2 -+#endif -+ s = secure_getenv("DFLTCC_LEVEL_MASK"); -+ dfltcc_state->level_mask = (s && *s) ? strtoul(s, NULL, 0) : -+ DFLTCC_LEVEL_MASK; -+#ifndef DFLTCC_BLOCK_SIZE -+#define DFLTCC_BLOCK_SIZE 1048576 -+#endif -+ s = secure_getenv("DFLTCC_BLOCK_SIZE"); -+ dfltcc_state->block_size = (s && *s) ? strtoul(s, NULL, 0) : -+ DFLTCC_BLOCK_SIZE; -+#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE -+#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 -+#endif -+ s = secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE"); -+ dfltcc_state->block_threshold = (s && *s) ? strtoul(s, NULL, 0) : -+ DFLTCC_FIRST_FHT_BLOCK_SIZE; -+#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE -+#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 -+#endif -+ s = secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE"); -+ dfltcc_state->dht_threshold = (s && *s) ? strtoul(s, NULL, 0) : -+ DFLTCC_DHT_MIN_SAMPLE_SIZE; -+#ifndef DFLTCC_RIBM -+#define DFLTCC_RIBM 0 -+#endif -+ s = secure_getenv("DFLTCC_RIBM"); -+ dfltcc_state->param.ribm = (s && *s) ? strtoul(s, NULL, 0) : -+ DFLTCC_RIBM; ++ dfltcc_state->level_mask = env_level_mask; ++ dfltcc_state->block_size = env_block_size; ++ dfltcc_state->block_threshold = env_block_threshold; ++ dfltcc_state->dht_threshold = env_dht_threshold; ++ dfltcc_state->param.ribm = env_ribm; +} + +voidpf ZLIB_INTERNAL dfltcc_alloc_state(strm, items, size) @@ -964,22 +1118,26 @@ index 0000000..d187796 + +/* + Switching between hardware and software compression. ++ + DFLTCC does not support all zlib settings, e.g. generation of non-compressed + blocks or alternative window sizes. When such settings are applied on the + fly with deflateParams, we need to convert between hardware and software + window formats. +*/ -+int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy) ++int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush) + z_streamp strm; + int level; + int strategy; ++ int *flush; +{ + deflate_state FAR *state = (deflate_state FAR *)strm->state; + struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; + int could_deflate = dfltcc_can_deflate(strm); -+ int can_deflate = dfltcc_are_params_ok(level, state->w_bits, strategy, -+ dfltcc_state->level_mask); ++ int can_deflate = dfltcc_can_deflate_with_params(strm, ++ level, ++ state->w_bits, ++ strategy); + + if (can_deflate == could_deflate) + /* We continue to work in the same mode - no changes needed */ @@ -989,8 +1147,33 @@ index 0000000..d187796 + /* DFLTCC was not used yet - no changes needed */ + return Z_OK; + -+ /* Switching between hardware and software is not implemented */ -+ return Z_STREAM_ERROR; ++ /* For now, do not convert between window formats - simply get rid of the ++ * old data instead. ++ */ ++ *flush = Z_FULL_FLUSH; ++ return Z_OK; ++} ++ ++int ZLIB_INTERNAL dfltcc_deflate_done(strm, flush) ++ z_streamp strm; ++ int flush; ++{ ++ deflate_state FAR *state = (deflate_state FAR *)strm->state; ++ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); ++ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; ++ ++ /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might ++ * close the block without resetting the compression state. Detect this ++ * situation and return that deflation is not done. ++ */ ++ if (flush == Z_FULL_FLUSH && strm->avail_out == 0) ++ return 0; ++ ++ /* Return that deflation is not done if DFLTCC is used and either it ++ * buffered some data (Continuation Flag is set), or has not written EOBS ++ * yet (Block-Continuation Flag is set). ++ */ ++ return !dfltcc_can_deflate(strm) || (!param->cf && !param->bcf); +} + +/* @@ -1046,6 +1229,7 @@ index 0000000..d187796 + + append_history(param, state->window, dictionary, dict_length); + state->strstart = 1; /* Add FDICT to zlib header */ ++ state->block_start = state->strstart; /* Make deflate_stored happy */ + return Z_OK; +} + @@ -1076,13 +1260,12 @@ index 0000000..d187796 + *dict_length = param->hl; + return Z_OK; +} -\ No newline at end of file diff --git a/contrib/s390/dfltcc.h b/contrib/s390/dfltcc.h new file mode 100644 -index 0000000..574e84c +index 000000000..da26612ca --- /dev/null +++ b/contrib/s390/dfltcc.h -@@ -0,0 +1,55 @@ +@@ -0,0 +1,81 @@ +#ifndef DFLTCC_H +#define DFLTCC_H + @@ -1097,6 +1280,28 @@ index 0000000..574e84c +voidpf ZLIB_INTERNAL dfltcc_alloc_window OF((z_streamp strm, uInt items, + uInt size)); +void ZLIB_INTERNAL dfltcc_free_window OF((z_streamp strm, voidpf w)); ++#define DFLTCC_BLOCK_HEADER_BITS 3 ++#define DFLTCC_HLITS_COUNT_BITS 5 ++#define DFLTCC_HDISTS_COUNT_BITS 5 ++#define DFLTCC_HCLENS_COUNT_BITS 4 ++#define DFLTCC_MAX_HCLENS 19 ++#define DFLTCC_HCLEN_BITS 3 ++#define DFLTCC_MAX_HLITS 286 ++#define DFLTCC_MAX_HDISTS 30 ++#define DFLTCC_MAX_HLIT_HDIST_BITS 7 ++#define DFLTCC_MAX_SYMBOL_BITS 16 ++#define DFLTCC_MAX_EOBS_BITS 15 ++#define DFLTCC_MAX_PADDING_BITS 7 ++#define DEFLATE_BOUND_COMPLEN(source_len) \ ++ ((DFLTCC_BLOCK_HEADER_BITS + \ ++ DFLTCC_HLITS_COUNT_BITS + \ ++ DFLTCC_HDISTS_COUNT_BITS + \ ++ DFLTCC_HCLENS_COUNT_BITS + \ ++ DFLTCC_MAX_HCLENS * DFLTCC_HCLEN_BITS + \ ++ (DFLTCC_MAX_HLITS + DFLTCC_MAX_HDISTS) * DFLTCC_MAX_HLIT_HDIST_BITS + \ ++ (source_len) * DFLTCC_MAX_SYMBOL_BITS + \ ++ DFLTCC_MAX_EOBS_BITS + \ ++ DFLTCC_MAX_PADDING_BITS) >> 3) +int ZLIB_INTERNAL dfltcc_can_inflate OF((z_streamp strm)); +typedef enum { + DFLTCC_INFLATE_CONTINUE, @@ -1136,15 +1341,18 @@ index 0000000..574e84c + do { \ + if (dfltcc_was_inflate_used((strm))) return -(1L << 16); \ + } while (0) ++#define INFLATE_SYNC_POINT_HOOK(strm) \ ++ do { \ ++ if (dfltcc_was_inflate_used((strm))) return Z_STREAM_ERROR; \ ++ } while (0) + +#endif -\ No newline at end of file diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h new file mode 100644 -index 0000000..a129a91 +index 000000000..46acfc550 --- /dev/null +++ b/contrib/s390/dfltcc_deflate.h -@@ -0,0 +1,50 @@ +@@ -0,0 +1,55 @@ +#ifndef DFLTCC_DEFLATE_H +#define DFLTCC_DEFLATE_H + @@ -1156,7 +1364,9 @@ index 0000000..a129a91 + block_state *result)); +int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm, + int level, -+ int strategy)); ++ int strategy, ++ int *flush)); ++int ZLIB_INTERNAL dfltcc_deflate_done OF((z_streamp strm, int flush)); +int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dict_length)); @@ -1176,31 +1386,33 @@ index 0000000..a129a91 + } while (0) +#define DEFLATE_RESET_KEEP_HOOK(strm) \ + dfltcc_reset((strm), sizeof(deflate_state)) -+#define DEFLATE_PARAMS_HOOK(strm, level, strategy) \ ++#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ + do { \ + int err; \ +\ -+ err = dfltcc_deflate_params((strm), (level), (strategy)); \ ++ err = dfltcc_deflate_params((strm), \ ++ (level), \ ++ (strategy), \ ++ (hook_flush)); \ + if (err == Z_STREAM_ERROR) \ + return err; \ + } while (0) ++#define DEFLATE_DONE dfltcc_deflate_done +#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ + do { \ + if (dfltcc_can_deflate((strm))) \ -+ (complen) = (3 + 5 + 5 + 4 + 19 * 3 + (286 + 30) * 7 + \ -+ (source_len) * 16 + 15 + 7) >> 3; \ ++ (complen) = DEFLATE_BOUND_COMPLEN(source_len); \ + } while (0) +#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (dfltcc_can_deflate((strm))) +#define DEFLATE_HOOK dfltcc_deflate +#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm))) + +#endif -\ No newline at end of file diff --git a/deflate.c b/deflate.c -index 1ec7614..089285a 100644 +index 6ac891d7d..afca18ce2 100644 --- a/deflate.c +++ b/deflate.c -@@ -61,15 +61,29 @@ const char deflate_copyright[] = +@@ -61,15 +61,30 @@ const char deflate_copyright[] = */ /* =========================================================================== @@ -1224,7 +1436,8 @@ index 1ec7614..089285a 100644 +#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +#define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) -+#define DEFLATE_PARAMS_HOOK(strm, level, strategy) do {} while (0) ++#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) ++#define DEFLATE_DONE(strm, flush) 1 +#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) +#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 +#define DEFLATE_HOOK(strm, flush, bstate) 0 @@ -1237,7 +1450,7 @@ index 1ec7614..089285a 100644 typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ -@@ -85,7 +99,6 @@ local block_state deflate_rle OF((deflate_state *s, int flush)); +@@ -85,7 +100,6 @@ local block_state deflate_rle OF((deflate_state *s, int flush)); local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); @@ -1245,7 +1458,7 @@ index 1ec7614..089285a 100644 local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV # pragma message("Assembler code may have bugs -- use at your own risk") -@@ -301,7 +314,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, +@@ -299,7 +313,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ @@ -1254,7 +1467,7 @@ index 1ec7614..089285a 100644 if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; -@@ -318,7 +331,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, +@@ -316,7 +330,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); @@ -1263,7 +1476,7 @@ index 1ec7614..089285a 100644 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); -@@ -394,6 +407,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) +@@ -434,6 +448,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) /* when using zlib wrappers, compute Adler-32 for provided dictionary */ if (wrap == 1) strm->adler = adler32(strm->adler, dictionary, dictLength); @@ -1271,7 +1484,7 @@ index 1ec7614..089285a 100644 s->wrap = 0; /* avoid computing Adler-32 in read_buf */ /* if dictionary would fill window, just replace the history */ -@@ -452,6 +466,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) +@@ -492,6 +507,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1279,7 +1492,7 @@ index 1ec7614..089285a 100644 s = strm->state; len = s->strstart + s->lookahead; if (len > s->w_size) -@@ -498,6 +513,8 @@ int ZEXPORT deflateResetKeep (strm) +@@ -538,6 +554,8 @@ int ZEXPORT deflateResetKeep (strm) _tr_init(s); @@ -1288,15 +1501,38 @@ index 1ec7614..089285a 100644 return Z_OK; } -@@ -584,6 +601,7 @@ int ZEXPORT deflateParams(strm, level, strategy) +@@ -613,6 +631,7 @@ int ZEXPORT deflateParams(strm, level, strategy) + { + deflate_state *s; + compress_func func; ++ int hook_flush = Z_NO_FLUSH; + + if (deflateStateCheck(strm)) return Z_STREAM_ERROR; + s = strm->state; +@@ -625,15 +644,18 @@ int ZEXPORT deflateParams(strm, level, strategy) if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } -+ DEFLATE_PARAMS_HOOK(strm, level, strategy); ++ DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); func = configuration_table[s->level].func; - if ((strategy != s->strategy || func != configuration_table[level].func) && -@@ -659,6 +677,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) +- if ((strategy != s->strategy || func != configuration_table[level].func) && +- s->last_flush != -2) { ++ if (((strategy != s->strategy || func != configuration_table[level].func) && ++ s->last_flush != -2) || hook_flush != Z_NO_FLUSH) { + /* Flush the last buffer: */ +- int err = deflate(strm, Z_BLOCK); ++ int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK; ++ int err = deflate(strm, flush); + if (err == Z_STREAM_ERROR) + return err; +- if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) ++ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead || ++ !DEFLATE_DONE(strm, flush)) + return Z_BUF_ERROR; + } + if (s->level != level) { +@@ -700,6 +722,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) /* conservative upper bound for compressed data */ complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; @@ -1304,7 +1540,7 @@ index 1ec7614..089285a 100644 /* if can't get parameters, return conservative bound plus zlib wrapper */ if (deflateStateCheck(strm)) -@@ -700,7 +719,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) +@@ -741,7 +764,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) } /* if not default parameters, return conservative bound */ @@ -1314,7 +1550,7 @@ index 1ec7614..089285a 100644 return complen + wraplen; /* default settings: return tight bound for that case */ -@@ -727,7 +747,7 @@ local void putShortMSB (s, b) +@@ -768,7 +792,7 @@ local void putShortMSB (s, b) * applications may wish to modify it to avoid allocating a large * strm->next_out buffer and copying into it. (See also read_buf()). */ @@ -1323,7 +1559,7 @@ index 1ec7614..089285a 100644 z_streamp strm; { unsigned len; -@@ -997,7 +1017,8 @@ int ZEXPORT deflate (strm, flush) +@@ -1040,7 +1064,8 @@ int ZEXPORT deflate (strm, flush) (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; @@ -1333,7 +1569,37 @@ index 1ec7614..089285a 100644 s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush); -@@ -1086,9 +1107,9 @@ int ZEXPORT deflateEnd (strm) +@@ -1087,7 +1112,6 @@ int ZEXPORT deflate (strm, flush) + } + + if (flush != Z_FINISH) return Z_OK; +- if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ + #ifdef GZIP +@@ -1103,7 +1127,7 @@ int ZEXPORT deflate (strm, flush) + } + else + #endif +- { ++ if (s->wrap == 1) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } +@@ -1112,7 +1136,11 @@ int ZEXPORT deflate (strm, flush) + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ +- return s->pending != 0 ? Z_OK : Z_STREAM_END; ++ if (s->pending == 0) { ++ Assert(s->bi_valid == 0, "bi_buf not flushed"); ++ return Z_STREAM_END; ++ } ++ return Z_OK; + } + + /* ========================================================================= */ +@@ -1129,9 +1157,9 @@ int ZEXPORT deflateEnd (strm) TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); @@ -1345,7 +1611,7 @@ index 1ec7614..089285a 100644 strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -@@ -1119,13 +1140,13 @@ int ZEXPORT deflateCopy (dest, source) +@@ -1161,13 +1189,13 @@ int ZEXPORT deflateCopy (dest, source) zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); @@ -1361,22 +1627,22 @@ index 1ec7614..089285a 100644 + ds->window = (Bytef *) ZALLOC_WINDOW(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); -@@ -1174,7 +1195,8 @@ local unsigned read_buf(strm, buf, size) + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); +@@ -1214,7 +1242,8 @@ local unsigned read_buf(strm, buf, size) strm->avail_in -= len; zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { -+ if (!DEFLATE_NEED_CHECKSUM(strm)) {} ++ if (!DEFLATE_NEED_CHECKSUM(strm)) {} + else if (strm->state->wrap == 1) { strm->adler = adler32(strm->adler, buf, len); } #ifdef GZIP diff --git a/deflate.h b/deflate.h -index 23ecdd3..821a4b9 100644 +index 1a06cd5f2..f92750ca6 100644 --- a/deflate.h +++ b/deflate.h -@@ -304,6 +304,7 @@ void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +@@ -299,6 +299,7 @@ void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); @@ -1384,7 +1650,7 @@ index 23ecdd3..821a4b9 100644 #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -@@ -346,4 +347,15 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, +@@ -343,4 +344,15 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, flush = _tr_tally(s, distance, length) #endif @@ -1401,7 +1667,7 @@ index 23ecdd3..821a4b9 100644 + #endif /* DEFLATE_H */ diff --git a/gzguts.h b/gzguts.h -index 990a4d2..3218395 100644 +index 57faf3716..581f2b631 100644 --- a/gzguts.h +++ b/gzguts.h @@ -153,7 +153,11 @@ @@ -1417,10 +1683,10 @@ index 990a4d2..3218395 100644 /* gzip modes, also provide a little integrity check on the passed structure */ #define GZ_NONE 0 diff --git a/inflate.c b/inflate.c -index ac333e8..f77c2ae 100644 +index 7be8c6366..a0e14e292 100644 --- a/inflate.c +++ b/inflate.c -@@ -85,6 +85,23 @@ +@@ -85,6 +85,24 @@ #include "inflate.h" #include "inffast.h" @@ -1439,12 +1705,13 @@ index ac333e8..f77c2ae 100644 +#define INFLATE_NEED_CHECKSUM(strm) 1 +#define INFLATE_NEED_UPDATEWINDOW(strm) 1 +#define INFLATE_MARK_HOOK(strm) do {} while (0) ++#define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0) +#endif + #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED -@@ -137,6 +154,7 @@ z_streamp strm; +@@ -138,6 +156,7 @@ z_streamp strm; state->lencode = state->distcode = state->next = state->codes; state->sane = 1; state->back = -1; @@ -1452,7 +1719,7 @@ index ac333e8..f77c2ae 100644 Tracev((stderr, "inflate: reset\n")); return Z_OK; } -@@ -182,7 +200,7 @@ int windowBits; +@@ -183,7 +202,7 @@ int windowBits; if (windowBits && (windowBits < 8 || windowBits > 15)) return Z_STREAM_ERROR; if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { @@ -1461,7 +1728,7 @@ index ac333e8..f77c2ae 100644 state->window = Z_NULL; } -@@ -221,7 +239,7 @@ int stream_size; +@@ -222,7 +241,7 @@ int stream_size; strm->zfree = zcfree; #endif state = (struct inflate_state FAR *) @@ -1470,7 +1737,7 @@ index ac333e8..f77c2ae 100644 if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; -@@ -230,7 +248,7 @@ int stream_size; +@@ -231,7 +250,7 @@ int stream_size; state->mode = HEAD; /* to pass state test in inflateReset2() */ ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { @@ -1479,7 +1746,7 @@ index ac333e8..f77c2ae 100644 strm->state = Z_NULL; } return ret; -@@ -252,6 +270,7 @@ int value; +@@ -253,6 +272,7 @@ int value; struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1487,7 +1754,7 @@ index ac333e8..f77c2ae 100644 state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; -@@ -379,6 +398,27 @@ void makefixed() +@@ -380,6 +400,27 @@ void makefixed() } #endif /* MAKEFIXED */ @@ -1515,7 +1782,7 @@ index ac333e8..f77c2ae 100644 /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called -@@ -403,20 +443,7 @@ unsigned copy; +@@ -404,20 +445,7 @@ unsigned copy; state = (struct inflate_state FAR *)strm->state; @@ -1537,45 +1804,45 @@ index ac333e8..f77c2ae 100644 /* copy state->wsize or less output bytes into the circular window */ if (copy >= state->wsize) { -@@ -849,6 +876,7 @@ int flush; - case TYPE: +@@ -860,6 +888,7 @@ int flush; if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + /* fallthrough */ case TYPEDO: + INFLATE_TYPEDO_HOOK(strm, flush); if (state->last) { BYTEBITS(); state->mode = CHECK; -@@ -1200,7 +1228,7 @@ int flush; +@@ -1221,7 +1250,7 @@ int flush; out -= left; strm->total_out += out; state->total += out; - if ((state->wrap & 4) && out) + if (INFLATE_NEED_CHECKSUM(strm) && (state->wrap & 4) && out) strm->adler = state->check = - UPDATE(state->check, put - out, out); + UPDATE_CHECK(state->check, put - out, out); out = left; -@@ -1252,8 +1280,9 @@ int flush; +@@ -1276,8 +1305,9 @@ int flush; */ inf_leave: RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) + if (INFLATE_NEED_UPDATEWINDOW(strm) && -+ (state->wsize || (out != strm->avail_out && state->mode < BAD && -+ (state->mode < CHECK || flush != Z_FINISH)))) ++ (state->wsize || (out != strm->avail_out && state->mode < BAD && ++ (state->mode < CHECK || flush != Z_FINISH)))) if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; -@@ -1263,7 +1292,7 @@ int flush; +@@ -1287,7 +1317,7 @@ int flush; strm->total_in += in; strm->total_out += out; state->total += out; - if ((state->wrap & 4) && out) + if (INFLATE_NEED_CHECKSUM(strm) && (state->wrap & 4) && out) strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); + UPDATE_CHECK(state->check, strm->next_out - out, out); strm->data_type = (int)state->bits + (state->last ? 64 : 0) + -@@ -1281,8 +1310,8 @@ z_streamp strm; +@@ -1305,8 +1335,8 @@ z_streamp strm; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; @@ -1586,7 +1853,15 @@ index ac333e8..f77c2ae 100644 strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; -@@ -1474,21 +1503,21 @@ z_streamp source; +@@ -1485,6 +1515,7 @@ z_streamp strm; + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ INFLATE_SYNC_POINT_HOOK(strm); + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; + } +@@ -1505,21 +1536,22 @@ z_streamp source; /* allocate space */ copy = (struct inflate_state FAR *) @@ -1597,7 +1872,8 @@ index ac333e8..f77c2ae 100644 if (state->window != Z_NULL) { window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); -+ ZALLOC_WINDOW(source, 1U << state->wbits, sizeof(unsigned char)); ++ ZALLOC_WINDOW(source, 1U << state->wbits, ++ sizeof(unsigned char)); if (window == Z_NULL) { - ZFREE(source, copy); + ZFREE_STATE(source, copy); @@ -1612,7 +1888,7 @@ index ac333e8..f77c2ae 100644 copy->strm = dest; if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { -@@ -1545,6 +1574,7 @@ z_streamp strm; +@@ -1576,6 +1608,7 @@ z_streamp strm; if (inflateStateCheck(strm)) return -(1L << 16); @@ -1621,19 +1897,28 @@ index ac333e8..f77c2ae 100644 return (long)(((unsigned long)((long)state->back)) << 16) + (state->mode == COPY ? state->length : diff --git a/inflate.h b/inflate.h -index a46cce6..7b19617 100644 +index f127b6b1f..519ed3535 100644 --- a/inflate.h +++ b/inflate.h -@@ -123,3 +123,5 @@ struct inflate_state { +@@ -124,3 +124,5 @@ struct inflate_state { int back; /* bits back of last unprocessed length/lit */ unsigned was; /* initial length of match */ }; + +int ZLIB_INTERNAL inflate_ensure_window OF((struct inflate_state *state)); diff --git a/test/infcover.c b/test/infcover.c -index 2be0164..a34cd17 100644 +index 2be01646c..a208219dc 100644 --- a/test/infcover.c +++ b/test/infcover.c +@@ -373,7 +373,7 @@ local void cover_support(void) + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; +- ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream)); ++ ret = inflateInit_(&strm, &ZLIB_VERSION[1], (int)sizeof(z_stream)); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); + @@ -444,7 +444,7 @@ local void cover_wrap(void) } @@ -1644,7 +1929,7 @@ index 2be0164..a34cd17 100644 static unsigned int next = 0; static unsigned char dat[] = {0x63, 0, 2, 0}; diff --git a/test/minigzip.c b/test/minigzip.c -index e22fb08..4b5f4ef 100644 +index e22fb08c0..4b5f4efed 100644 --- a/test/minigzip.c +++ b/test/minigzip.c @@ -132,7 +132,11 @@ static void pwinerror (s) @@ -1660,14 +1945,14 @@ index e22fb08..4b5f4ef 100644 #ifdef MAXSEG_64K diff --git a/trees.c b/trees.c -index 50cf4b4..ad51207 100644 +index 8b438cce4..84c1b4732 100644 --- a/trees.c +++ b/trees.c @@ -149,8 +149,6 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, local void compress_block OF((deflate_state *s, const ct_data *ltree, const ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); --local unsigned bi_reverse OF((unsigned value, int length)); +-local unsigned bi_reverse OF((unsigned code, int len)); -local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); @@ -1686,7 +1971,7 @@ index 50cf4b4..ad51207 100644 /* the arguments must not have side effects */ -@@ -1155,7 +1160,7 @@ local int detect_data_type(s) +@@ -1134,7 +1139,7 @@ local int detect_data_type(s) * method would use a table) * IN assertion: 1 <= len <= 15 */ @@ -1695,7 +1980,7 @@ index 50cf4b4..ad51207 100644 unsigned code; /* the value to invert */ int len; /* its bit length */ { -@@ -1187,7 +1192,7 @@ local void bi_flush(s) +@@ -1166,7 +1171,7 @@ local void bi_flush(s) /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ @@ -1704,6 +1989,16 @@ index 50cf4b4..ad51207 100644 deflate_state *s; { if (s->bi_valid > 8) { --- -2.19.1 - +diff --git a/zutil.h b/zutil.h +index d9a20ae1b..bc83f59d0 100644 +--- a/zutil.h ++++ b/zutil.h +@@ -87,6 +87,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ + + #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + ++#define ZLIB_WRAPLEN 6 /* zlib format overhead */ ++ + /* target dependencies */ + + #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))