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 new file mode 100644 index 0000000..c69d9bc --- /dev/null +++ b/zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch @@ -0,0 +1,206 @@ +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-fix.patch b/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch new file mode 100644 index 0000000..a9e5e29 --- /dev/null +++ b/zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch @@ -0,0 +1,516 @@ +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-covscan-issues.patch b/zlib-1.2.11-covscan-issues.patch new file mode 100644 index 0000000..28e8604 --- /dev/null +++ b/zlib-1.2.11-covscan-issues.patch @@ -0,0 +1,74 @@ +From f776e1609cc63bf486634ee9bc6226dac2c0d2f3 Mon Sep 17 00:00:00 2001 +From: Ondrej Dubaj +Date: Tue, 15 Oct 2019 11:27:15 +0200 +Subject: [PATCH] fixed covscan issues + +--- + crc32.c | 2 +- + deflate.c | 2 +- + test/crc32_test.c | 8 ++++---- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/crc32.c b/crc32.c +index 406d350..34132ea 100644 +--- a/crc32.c ++++ b/crc32.c +@@ -302,7 +302,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) + + if (!crc32_func) + crc32_func = crc32_z_ifunc(); +- return (*crc32_func)(crc, buf, len); ++ return (*crc32_func)(crc, buf, len); + } + + #endif /* defined(Z_IFUNC_ASM) || defined(Z_IFUNC_NATIVE) */ +diff --git a/deflate.c b/deflate.c +index 089285a..9b09718 100644 +--- a/deflate.c ++++ b/deflate.c +@@ -1015,7 +1015,7 @@ int ZEXPORT deflate (strm, flush) + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { +- block_state bstate; ++ block_state bstate = 0; + + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : + s->level == 0 ? deflate_stored(s, flush) : +diff --git a/test/crc32_test.c b/test/crc32_test.c +index 5d73128..2d2a6c7 100644 +--- a/test/crc32_test.c ++++ b/test/crc32_test.c +@@ -11,25 +11,25 @@ + # include + #endif + +-void test_crc32 OF((uLong crc, Byte* buf, z_size_t len, uLong chk, int line)); ++void test_crc32 OF((uLong crc, char* buf, z_size_t len, uLong chk, int line)); + int main OF((void)); + + typedef struct { + int line; + uLong crc; +- Byte* buf; ++ char* buf; + int len; + uLong expect; + } crc32_test; + + void test_crc32(crc, buf, len, chk, line) + uLong crc; +- Byte *buf; ++ char *buf; + z_size_t len; + uLong chk; + int line; + { +- uLong res = crc32(crc, buf, len); ++ uLong res = crc32(crc, (Bytef *) buf, len); + if (res != chk) { + fprintf(stderr, "FAIL [%d]: crc32 returned 0x%08X expected 0x%08X\n", + line, (unsigned int)res, (unsigned int)chk); +-- +2.19.1 + diff --git a/zlib-1.2.11-inflateSyncPoint-return-value-fix.patch b/zlib-1.2.11-inflateSyncPoint-return-value-fix.patch new file mode 100644 index 0000000..f9b3756 --- /dev/null +++ b/zlib-1.2.11-inflateSyncPoint-return-value-fix.patch @@ -0,0 +1,45 @@ +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 new file mode 100644 index 0000000..4f7b0ef --- /dev/null +++ b/zlib-1.2.11-permit-deflateParams-change.patch @@ -0,0 +1,70 @@ +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.spec b/zlib.spec index 800fa01..561af27 100644 --- a/zlib.spec +++ b/zlib.spec @@ -2,7 +2,7 @@ Name: zlib Version: 1.2.11 -Release: 22%{?dist} +Release: 23%{?dist} Summary: The compression and decompression library # /contrib/dotzlib/ have Boost license License: zlib and Boost @@ -23,6 +23,17 @@ Patch7: zlib-1.2.11-IBM-Z-hw-accelrated-deflate-s390x.patch Patch8: zlib-1.2.11-optimized-CRC32-framework.patch # fixed firefox crash + added test case Patch9: zlib-1.2.11-firefox-crash-fix.patch +# fixed covscan issues +Patch10: zlib-1.2.11-covscan-issues.patch +# fix for IBM Z optimalizations +Patch11: zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch +# permit a deflateParams() parameter change +Patch12: zlib-1.2.11-permit-deflateParams-change.patch +# fixed DFLTCC compression level switching issues +# enabled HW compression for compression levels 1 through 6 +Patch13: zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch +# fixed inflateSyncPoint() bad return value on z15 +Patch14: zlib-1.2.11-inflateSyncPoint-return-value-fix.patch BuildRequires: automake, autoconf, libtool @@ -88,6 +99,11 @@ developing applications which use minizip. %patch7 -p1 %patch8 -p1 %patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 iconv -f iso-8859-2 -t utf-8 < ChangeLog > ChangeLog.tmp @@ -175,6 +191,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete %changelog +* Wed Nov 18 2020 Ondrej Dubaj - 1.2.11-23 +- backport IBM Z updates to fedora + * Wed Jul 29 2020 Fedora Release Engineering - 1.2.11-22 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild