diff --git a/zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch b/zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch deleted file mode 100644 index 3fa0c37..0000000 --- a/zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch +++ /dev/null @@ -1,2004 +0,0 @@ -From 171d0ff3c9ed40da0ac14085ab16b766b1162069 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 - -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 patch adds DFLTCC support to zlib. 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. - -Two DFLTCC compression calls produce the same results only when they -both are made on machines of the same generation, and when the -respective buffers have the same offset relative to the start of the -page. Therefore care should be taken when using hardware compression -when reproducible results are desired. One such use case - reproducible -software builds - is handled explicitly: when SOURCE_DATE_EPOCH -environment variable is set, the hardware compression is disabled. - -DFLTCC does not support every single zlib feature, in particular: - - * inflate(Z_BLOCK) and inflate(Z_TREES) - * inflateMark() - * inflatePrime() - * 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 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 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 -doubleword-aligned, and it's reasonable to allocate it alongside -deflate and inflate states, ZALLOC_STATE, ZFREE_STATE and ZCOPY_STATE -macros were introduced in order to encapsulate the allocation details. -The same is true for window, for which ZALLOC_WINDOW and -TRY_FREE_WINDOW macros were introduced. - -While for inflate software and hardware window formats match, this is -not the case for deflate. Therefore, deflateSetDictionary and -deflateGetDictionary need special handling, which is triggered using the -new DEFLATE_SET_DICTIONARY_HOOK and DEFLATE_GET_DICTIONARY_HOOK macros. - -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. - -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 -return the correct results for the hardware implementation, the new -DEFLATE_BOUND_ADJUST_COMPLEN and DEFLATE_NEED_CONSERVATIVE_BOUND macros -were introduced. - -Actual compression and decompression are handled by the new DEFLATE_HOOK -and INFLATE_TYPEDO_HOOK macros. Since inflation with DFLTCC manages the -window on its own, calling updatewindow() is suppressed using the new -INFLATE_NEED_UPDATEWINDOW() macro. - -In addition to compression, DFLTCC computes CRC-32 and Adler-32 -checksums, therefore, whenever it's used, software checksumming needs to -be suppressed using the new DEFLATE_NEED_CHECKSUM and -INFLATE_NEED_CHECKSUM macros. - -DFLTCC will refuse to write an End-of-block Symbol if there is no input -data, thus in some cases it is necessary to do this manually. In order -to achieve this, send_bits, bi_reverse, bi_windup and flush_pending -were promoted from local to ZLIB_INTERNAL. Furthermore, since block and -stream termination must be handled in software as well, block_state enum -was moved to deflate.h. - -Since the first call to dfltcc_inflate already needs the window, and it -might be not allocated yet, inflate_ensure_window was factored out of -updatewindow and made ZLIB_INTERNAL. ---- - Makefile.in | 8 + - compress.c | 14 +- - configure | 24 + - contrib/README.contrib | 4 + - 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 | 87 ++- - inflate.h | 2 + - test/infcover.c | 4 +- - test/minigzip.c | 4 + - trees.c | 13 +- - 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 fd28bbfbf..66e3a8057 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -143,6 +143,14 @@ match.lo: match.S - mv _match.o match.lo - rm -f _match.s - -+dfltcc.o: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h -+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)contrib/s390/dfltcc.c -+ -+dfltcc.lo: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h -+ -@mkdir objs 2>/dev/null || test -d objs -+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/dfltcc.o $(SRCDIR)contrib/s390/dfltcc.c -+ -@mv objs/dfltcc.o $@ -+ - 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 fbaf25357..02e325e22 100755 ---- a/configure -+++ b/configure -@@ -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 - -+# Check whether sys/sdt.h is available -+cat > $test.c << EOF -+#include -+int main() { return 0; } -+EOF -+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" -+else -+ echo "Checking for sys/sdt.h ... No." | tee -a configure.log -+fi -+ - # show the results in the log - echo >> configure.log - echo ALL = $ALL >> configure.log -diff --git a/contrib/README.contrib b/contrib/README.contrib -index 335e43508..130a28bdb 100644 ---- a/contrib/README.contrib -+++ b/contrib/README.contrib -@@ -46,6 +46,10 @@ puff/ by Mark Adler - Small, low memory usage inflate. Also serves to provide an - unambiguous description of the deflate format. - -+s390/ by Ilya Leoshkevich -+ Hardware-accelerated deflate on IBM Z with DEFLATE CONVERSION CALL -+ instruction. -+ - 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 000000000..cd959290d ---- /dev/null -+++ b/contrib/s390/dfltcc.c -@@ -0,0 +1,996 @@ -+/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ -+ -+/* -+ Use the following commands to build zlib with DFLTCC support: -+ -+ $ ./configure --dfltcc -+ $ make -+*/ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../zutil.h" -+#include "../../deflate.h" -+#include "../../inftrees.h" -+#include "../../inflate.h" -+#include "dfltcc.h" -+#include "dfltcc_deflate.h" -+#ifdef HAVE_SYS_SDT_H -+#include -+#endif -+ -+/* -+ C wrapper for the DEFLATE CONVERSION CALL instruction. -+ */ -+typedef enum { -+ DFLTCC_CC_OK = 0, -+ DFLTCC_CC_OP1_TOO_SHORT = 1, -+ DFLTCC_CC_OP2_TOO_SHORT = 2, -+ DFLTCC_CC_OP2_CORRUPT = 2, -+ DFLTCC_CC_AGAIN = 3, -+} dfltcc_cc; -+ -+#define DFLTCC_QAF 0 -+#define DFLTCC_GDHT 1 -+#define DFLTCC_CMPR 2 -+#define DFLTCC_XPND 4 -+#define HBT_CIRCULAR (1 << 7) -+#define HB_BITS 15 -+#define HB_SIZE (1 << HB_BITS) -+#define DFLTCC_FACILITY 151 -+ -+local inline dfltcc_cc dfltcc OF((int fn, void *param, -+ Bytef **op1, size_t *len1, -+ z_const Bytef **op2, size_t *len2, -+ void *hist)); -+local inline dfltcc_cc dfltcc(fn, param, op1, len1, op2, len2, hist) -+ int fn; -+ void *param; -+ Bytef **op1; -+ size_t *len1; -+ z_const Bytef **op2; -+ size_t *len2; -+ void *hist; -+{ -+ Bytef *t2 = op1 ? *op1 : NULL; -+ size_t t3 = len1 ? *len1 : 0; -+ z_const Bytef *t4 = op2 ? *op2 : NULL; -+ size_t t5 = len2 ? *len2 : 0; -+ register int r0 __asm__("r0") = fn; -+ register void *r1 __asm__("r1") = param; -+ register Bytef *r2 __asm__("r2") = t2; -+ register size_t r3 __asm__("r3") = t3; -+ register z_const Bytef *r4 __asm__("r4") = t4; -+ register size_t r5 __asm__("r5") = t5; -+ int cc; -+ -+ __asm__ volatile( -+#ifdef HAVE_SYS_SDT_H -+ STAP_PROBE_ASM(zlib, dfltcc_entry, -+ STAP_PROBE_ASM_TEMPLATE(5)) -+#endif -+ ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n" -+#ifdef HAVE_SYS_SDT_H -+ STAP_PROBE_ASM(zlib, dfltcc_exit, -+ STAP_PROBE_ASM_TEMPLATE(5)) -+#endif -+ "ipm %[cc]\n" -+ : [r2] "+r" (r2) -+ , [r3] "+r" (r3) -+ , [r4] "+r" (r4) -+ , [r5] "+r" (r5) -+ , [cc] "=r" (cc) -+ : [r0] "r" (r0) -+ , [r1] "r" (r1) -+ , [hist] "r" (hist) -+#ifdef HAVE_SYS_SDT_H -+ , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist) -+#endif -+ : "cc", "memory"); -+ t2 = r2; t3 = r3; t4 = r4; t5 = r5; -+ -+ if (op1) -+ *op1 = t2; -+ if (len1) -+ *len1 = t3; -+ if (op2) -+ *op2 = t4; -+ if (len2) -+ *len2 = t5; -+ return (cc >> 28) & 3; -+} -+ -+/* -+ Parameter Block for Query Available Functions. -+ */ -+#define static_assert(c, msg) \ -+ __attribute__((unused)) \ -+ static char static_assert_failed_ ## msg[c ? 1 : -1] -+ -+struct dfltcc_qaf_param { -+ char fns[16]; -+ char reserved1[8]; -+ char fmts[2]; -+ char reserved2[6]; -+}; -+ -+static_assert(sizeof(struct dfltcc_qaf_param) == 32, -+ sizeof_struct_dfltcc_qaf_param_is_32); -+ -+local inline int is_bit_set OF((const char *bits, int n)); -+local inline int is_bit_set(bits, n) -+ const char *bits; -+ int n; -+{ -+ return bits[n / 8] & (1 << (7 - (n % 8))); -+} -+ -+local inline void clear_bit OF((char *bits, int n)); -+local inline void clear_bit(bits, n) -+ char *bits; -+ int n; -+{ -+ bits[n / 8] &= ~(1 << (7 - (n % 8))); -+} -+ -+#define DFLTCC_FMT0 0 -+ -+/* -+ Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand. -+ */ -+#define CVT_CRC32 0 -+#define CVT_ADLER32 1 -+#define HTT_FIXED 0 -+#define HTT_DYNAMIC 1 -+ -+struct dfltcc_param_v0 { -+ uint16_t pbvn; /* Parameter-Block-Version Number */ -+ uint8_t mvn; /* Model-Version Number */ -+ uint8_t ribm; /* Reserved for IBM use */ -+ unsigned reserved32 : 31; -+ unsigned cf : 1; /* Continuation Flag */ -+ uint8_t reserved64[8]; -+ unsigned nt : 1; /* New Task */ -+ unsigned reserved129 : 1; -+ unsigned cvt : 1; /* Check Value Type */ -+ unsigned reserved131 : 1; -+ unsigned htt : 1; /* Huffman-Table Type */ -+ unsigned bcf : 1; /* Block-Continuation Flag */ -+ unsigned bcc : 1; /* Block Closing Control */ -+ unsigned bhf : 1; /* Block Header Final */ -+ unsigned reserved136 : 1; -+ unsigned reserved137 : 1; -+ unsigned dhtgc : 1; /* DHT Generation Control */ -+ unsigned reserved139 : 5; -+ unsigned reserved144 : 5; -+ unsigned sbb : 3; /* Sub-Byte Boundary */ -+ uint8_t oesc; /* Operation-Ending-Supplemental Code */ -+ unsigned reserved160 : 12; -+ unsigned ifs : 4; /* Incomplete-Function Status */ -+ uint16_t ifl; /* Incomplete-Function Length */ -+ uint8_t reserved192[8]; -+ uint8_t reserved256[8]; -+ uint8_t reserved320[4]; -+ uint16_t hl; /* History Length */ -+ unsigned reserved368 : 1; -+ uint16_t ho : 15; /* History Offset */ -+ uint32_t cv; /* Check Value */ -+ unsigned eobs : 15; /* End-of-block Symbol */ -+ unsigned reserved431: 1; -+ uint8_t eobl : 4; /* End-of-block Length */ -+ unsigned reserved436 : 12; -+ unsigned reserved448 : 4; -+ uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table -+ Length */ -+ uint8_t reserved464[6]; -+ uint8_t cdht[288]; -+ uint8_t reserved[32]; -+ uint8_t csb[1152]; -+}; -+ -+static_assert(sizeof(struct dfltcc_param_v0) == 1536, -+ sizeof_struct_dfltcc_param_v0_is_1536); -+ -+local z_const char *oesc_msg OF((char *buf, int oesc)); -+local z_const char *oesc_msg(buf, oesc) -+ char *buf; -+ int oesc; -+{ -+ if (oesc == 0x00) -+ return NULL; /* Successful completion */ -+ else { -+ sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc); -+ return buf; -+ } -+} -+ -+/* -+ Extension of inflate_state and deflate_state. Must be doubleword-aligned. -+*/ -+struct dfltcc_state { -+ struct dfltcc_param_v0 param; /* Parameter block. */ -+ struct dfltcc_qaf_param af; /* Available functions. */ -+ uLong level_mask; /* Levels on which to use DFLTCC */ -+ uLong block_size; /* New block each X bytes */ -+ uLong block_threshold; /* New block after total_in > X */ -+ uLong dht_threshold; /* New block only if avail_in >= X */ -+ char msg[64]; /* Buffer for strm->msg */ -+}; -+ -+#define ALIGN_UP(p, size) \ -+ (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1)) -+ -+#define GET_DFLTCC_STATE(state) ((struct dfltcc_state FAR *)( \ -+ (char FAR *)(state) + ALIGN_UP(sizeof(*state), 8))) -+ -+/* -+ Compress. -+ */ -+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; -+{ -+ deflate_state FAR *state = (deflate_state FAR *)strm->state; -+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); -+ -+ /* Unsupported compression settings */ -+ 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 */ -+ if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) || -+ !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) || -+ !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0)) -+ return 0; -+ -+ 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; -+{ -+ deflate_state FAR *state = (deflate_state FAR *)strm->state; -+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; -+ size_t avail_in = avail_in = strm->avail_in; -+ -+ dfltcc(DFLTCC_GDHT, -+ param, NULL, NULL, -+ &strm->next_in, &avail_in, NULL); -+} -+ -+local dfltcc_cc dfltcc_cmpr OF((z_streamp strm)); -+local dfltcc_cc dfltcc_cmpr(strm) -+ z_streamp strm; -+{ -+ deflate_state FAR *state = (deflate_state FAR *)strm->state; -+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; -+ size_t avail_in = strm->avail_in; -+ size_t avail_out = strm->avail_out; -+ dfltcc_cc cc; -+ -+ cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR, -+ param, &strm->next_out, &avail_out, -+ &strm->next_in, &avail_in, state->window); -+ strm->total_in += (strm->avail_in - avail_in); -+ strm->total_out += (strm->avail_out - avail_out); -+ strm->avail_in = avail_in; -+ strm->avail_out = avail_out; -+ return cc; -+} -+ -+local void send_eobs OF((z_streamp strm, -+ z_const struct dfltcc_param_v0 FAR *param)); -+local void send_eobs(strm, param) -+ z_streamp strm; -+ z_const struct dfltcc_param_v0 FAR *param; -+{ -+ deflate_state FAR *state = (deflate_state FAR *)strm->state; -+ -+ _tr_send_bits( -+ state, -+ bi_reverse(param->eobs >> (15 - param->eobl), param->eobl), -+ param->eobl); -+ flush_pending(strm); -+ if (state->pending != 0) { -+ /* The remaining data is located in pending_out[0:pending]. If someone -+ * calls put_byte() - this might happen in deflate() - the byte will be -+ * placed into pending_buf[pending], which is incorrect. Move the -+ * remaining data to the beginning of pending_buf so that put_byte() is -+ * usable again. -+ */ -+ memmove(state->pending_buf, state->pending_out, state->pending); -+ state->pending_out = state->pending_buf; -+ } -+#ifdef ZLIB_DEBUG -+ state->compressed_len += param->eobl; -+#endif -+} -+ -+int ZLIB_INTERNAL dfltcc_deflate(strm, flush, result) -+ z_streamp strm; -+ int flush; -+ block_state *result; -+{ -+ 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; -+ uInt masked_avail_in; -+ dfltcc_cc cc; -+ int need_empty_block; -+ int soft_bcc; -+ int no_flush; -+ -+ 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; -+ -+ /* 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 (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; -+ } -+ /* 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; -+ } -+ -+ /* There is an open non-BFINAL block, we are not going to close it just -+ * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see -+ * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new -+ * DHT in order to adapt to a possibly changed input data distribution. -+ */ -+ if (param->bcf && no_flush && -+ strm->total_in > dfltcc_state->block_threshold && -+ strm->avail_in >= dfltcc_state->dht_threshold) { -+ if (param->cf) { -+ /* We need to flush the DFLTCC buffer before writing the -+ * End-of-block Symbol. Mask the input data and proceed as usual. -+ */ -+ masked_avail_in += strm->avail_in; -+ strm->avail_in = 0; -+ no_flush = 0; -+ } else { -+ /* DFLTCC buffer is empty, so we can manually write the -+ * End-of-block Symbol right away. -+ */ -+ send_eobs(strm, param); -+ param->bcf = 0; -+ dfltcc_state->block_threshold = -+ strm->total_in + dfltcc_state->block_size; -+ } -+ } -+ -+ /* 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. -+ */ -+ if (no_flush && strm->avail_in > dfltcc_state->block_size) { -+ masked_avail_in += (strm->avail_in - dfltcc_state->block_size); -+ strm->avail_in = dfltcc_state->block_size; -+ } -+ -+ /* When we have an open non-BFINAL deflate block and caller indicates that -+ * the stream is ending, we need to close an open deflate block and open a -+ * BFINAL one. -+ */ -+ need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf; -+ -+ /* Translate stream to parameter block */ -+ 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 honor BCC. */ -+ soft_bcc = 1; -+ if (flush == Z_FINISH && !param->bcf) -+ /* We are about to open a BFINAL block, set Block Header Final bit -+ * until the stream ends. -+ */ -+ param->bhf = 1; -+ /* DFLTCC-CMPR will write to next_out, so make sure that buffers with -+ * higher precedence are empty. -+ */ -+ Assert(state->pending == 0, "There must be no pending bytes"); -+ Assert(state->bi_valid < 8, "There must be less than 8 pending bits"); -+ param->sbb = (unsigned int)state->bi_valid; -+ if (param->sbb > 0) -+ *strm->next_out = (Bytef)state->bi_buf; -+ /* 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 */ -+ if (!param->bcf) { -+ if (state->strategy == Z_FIXED || -+ (strm->total_in == 0 && dfltcc_state->block_threshold > 0)) -+ param->htt = HTT_FIXED; -+ else { -+ param->htt = HTT_DYNAMIC; -+ dfltcc_gdht(strm); -+ } -+ } -+ -+ /* Deflate */ -+ do { -+ cc = dfltcc_cmpr(strm); -+ if (strm->avail_in < 4096 && masked_avail_in > 0) -+ /* We are about to call DFLTCC with a small input buffer, which is -+ * inefficient. Since there is masked data, there will be at least -+ * one more DFLTCC call, so skip the current one and make the next -+ * one handle more data. -+ */ -+ break; -+ } while (cc == DFLTCC_CC_AGAIN); -+ -+ /* Translate parameter block to stream */ -+ strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); -+ state->bi_valid = param->sbb; -+ if (state->bi_valid == 0) -+ state->bi_buf = 0; /* Avoid accessing next_out */ -+ else -+ state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1); -+ strm->adler = state->wrap == 2 ? ZSWAP32(param->cv) : param->cv; -+ -+ /* Unmask the input data */ -+ strm->avail_in += masked_avail_in; -+ masked_avail_in = 0; -+ -+ /* If we encounter an error, it means there is a bug in DFLTCC call */ -+ Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG"); -+ -+ /* Update Block-Continuation Flag. It will be used to check whether to call -+ * GDHT the next time. -+ */ -+ if (cc == DFLTCC_CC_OK) { -+ if (soft_bcc) { -+ send_eobs(strm, param); -+ param->bcf = 0; -+ dfltcc_state->block_threshold = -+ strm->total_in + dfltcc_state->block_size; -+ } else -+ param->bcf = 1; -+ if (flush == Z_FINISH) { -+ if (need_empty_block) -+ /* Make the current deflate() call also close the stream */ -+ return 0; -+ else { -+ bi_windup(state); -+ *result = finish_done; -+ } -+ } else { -+ if (flush == Z_FULL_FLUSH) -+ param->hl = 0; /* Clear history */ -+ *result = flush == Z_NO_FLUSH ? need_more : block_done; -+ } -+ } else { -+ param->bcf = 1; -+ *result = need_more; -+ } -+ if (strm->avail_in != 0 && strm->avail_out != 0) -+ goto again; /* deflate() must use all input or all output */ -+ return 1; -+} -+ -+/* -+ Expand. -+ */ -+int ZLIB_INTERNAL dfltcc_can_inflate(strm) -+ z_streamp strm; -+{ -+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; -+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); -+ -+ /* Unsupported compression settings */ -+ if (state->wbits != HB_BITS) -+ return 0; -+ -+ /* Unsupported hardware */ -+ return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) && -+ is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0); -+} -+ -+local dfltcc_cc dfltcc_xpnd OF((z_streamp strm)); -+local dfltcc_cc dfltcc_xpnd(strm) -+ z_streamp strm; -+{ -+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; -+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; -+ size_t avail_in = strm->avail_in; -+ size_t avail_out = strm->avail_out; -+ dfltcc_cc cc; -+ -+ cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR, -+ param, &strm->next_out, &avail_out, -+ &strm->next_in, &avail_in, state->window); -+ strm->avail_in = avail_in; -+ strm->avail_out = avail_out; -+ return cc; -+} -+ -+dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate(strm, flush, ret) -+ z_streamp strm; -+ int flush; -+ int *ret; -+{ -+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; -+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); -+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; -+ dfltcc_cc cc; -+ -+ if (flush == Z_BLOCK || flush == Z_TREES) { -+ /* DFLTCC does not support stopping on block boundaries */ -+ if (dfltcc_inflate_disable(strm)) { -+ *ret = Z_STREAM_ERROR; -+ return DFLTCC_INFLATE_BREAK; -+ } else -+ return DFLTCC_INFLATE_SOFTWARE; -+ } -+ -+ if (state->last) { -+ if (state->bits != 0) { -+ strm->next_in++; -+ strm->avail_in--; -+ state->bits = 0; -+ } -+ state->mode = CHECK; -+ return DFLTCC_INFLATE_CONTINUE; -+ } -+ -+ if (strm->avail_in == 0 && !param->cf) -+ return DFLTCC_INFLATE_BREAK; -+ -+ if (inflate_ensure_window(state)) { -+ state->mode = MEM; -+ return DFLTCC_INFLATE_CONTINUE; -+ } -+ -+ /* Translate stream to parameter block */ -+ param->cvt = state->flags ? CVT_CRC32 : CVT_ADLER32; -+ param->sbb = state->bits; -+ param->hl = state->whave; /* Software and hardware history formats match */ -+ param->ho = (state->wnext - state->whave) & ((1 << HB_BITS) - 1); -+ if (param->hl) -+ param->nt = 0; /* Honor history for the first block */ -+ param->cv = state->flags ? ZSWAP32(state->check) : state->check; -+ -+ /* Inflate */ -+ do { -+ cc = dfltcc_xpnd(strm); -+ } while (cc == DFLTCC_CC_AGAIN); -+ -+ /* Translate parameter block to stream */ -+ strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); -+ state->last = cc == DFLTCC_CC_OK; -+ state->bits = param->sbb; -+ state->whave = param->hl; -+ state->wnext = (param->ho + param->hl) & ((1 << HB_BITS) - 1); -+ strm->adler = state->check = state->flags ? ZSWAP32(param->cv) : param->cv; -+ if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { -+ /* Report an error if stream is corrupted */ -+ state->mode = BAD; -+ return DFLTCC_INFLATE_CONTINUE; -+ } -+ state->mode = TYPEDO; -+ /* Break if operands are exhausted, otherwise continue looping */ -+ return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ? -+ DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE; -+} -+ -+int ZLIB_INTERNAL dfltcc_was_inflate_used(strm) -+ z_streamp strm; -+{ -+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; -+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; -+ -+ return !param->nt; -+} -+ -+int ZLIB_INTERNAL dfltcc_inflate_disable(strm) -+ z_streamp strm; -+{ -+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; -+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); -+ -+ if (!dfltcc_can_inflate(strm)) -+ return 0; -+ if (dfltcc_was_inflate_used(strm)) -+ /* DFLTCC has already decompressed some data. Since there is not -+ * enough information to resume decompression in software, the call -+ * must fail. -+ */ -+ return 1; -+ /* DFLTCC was not used yet - decompress in software */ -+ memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); -+ 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. -+*/ -+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)); -+ -+ memcpy(&dfltcc_state->af, &cpu_af, sizeof(dfltcc_state->af)); -+ -+ if (env_source_date_epoch) -+ /* User needs reproducible results, but the output of DFLTCC_CMPR -+ * depends on buffers' page offsets. -+ */ -+ clear_bit(dfltcc_state->af.fns, DFLTCC_CMPR); -+ -+ /* Initialize parameter block */ -+ memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param)); -+ dfltcc_state->param.nt = 1; -+ -+ /* Initialize tuning parameters */ -+ 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) -+ z_streamp strm; -+ uInt items; -+ uInt size; -+{ -+ return ZALLOC(strm, -+ ALIGN_UP(items * size, 8) + sizeof(struct dfltcc_state), -+ sizeof(unsigned char)); -+} -+ -+void ZLIB_INTERNAL dfltcc_copy_state(dst, src, size) -+ voidpf dst; -+ const voidpf src; -+ uInt size; -+{ -+ zmemcpy(dst, src, ALIGN_UP(size, 8) + sizeof(struct dfltcc_state)); -+} -+ -+static const int PAGE_ALIGN = 0x1000; -+ -+voidpf ZLIB_INTERNAL dfltcc_alloc_window(strm, items, size) -+ z_streamp strm; -+ uInt items; -+ uInt size; -+{ -+ voidpf p, w; -+ -+ /* To simplify freeing, we store the pointer to the allocated buffer right -+ * before the window. -+ */ -+ p = ZALLOC(strm, sizeof(voidpf) + items * size + PAGE_ALIGN, -+ sizeof(unsigned char)); -+ if (p == NULL) -+ return NULL; -+ w = ALIGN_UP((char FAR *)p + sizeof(voidpf), PAGE_ALIGN); -+ *(voidpf *)((char FAR *)w - sizeof(voidpf)) = p; -+ return w; -+} -+ -+void ZLIB_INTERNAL dfltcc_free_window(strm, w) -+ z_streamp strm; -+ voidpf w; -+{ -+ if (w) -+ ZFREE(strm, *(voidpf *)((unsigned char FAR *)w - sizeof(voidpf))); -+} -+ -+/* -+ 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, 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_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 */ -+ return Z_OK; -+ -+ if (strm->total_in == 0 && param->nt == 1 && param->hl == 0) -+ /* DFLTCC was not used yet - no changes needed */ -+ return Z_OK; -+ -+ /* 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); -+} -+ -+/* -+ Preloading history. -+*/ -+local void append_history OF((struct dfltcc_param_v0 FAR *param, -+ Bytef *history, -+ const Bytef *buf, -+ uInt count)); -+local void append_history(param, history, buf, count) -+ struct dfltcc_param_v0 FAR *param; -+ Bytef *history; -+ const Bytef *buf; -+ uInt count; -+{ -+ size_t offset; -+ size_t n; -+ -+ /* Do not use more than 32K */ -+ if (count > HB_SIZE) { -+ buf += count - HB_SIZE; -+ count = HB_SIZE; -+ } -+ offset = (param->ho + param->hl) % HB_SIZE; -+ if (offset + count <= HB_SIZE) -+ /* Circular history buffer does not wrap - copy one chunk */ -+ zmemcpy(history + offset, buf, count); -+ else { -+ /* Circular history buffer wraps - copy two chunks */ -+ n = HB_SIZE - offset; -+ zmemcpy(history + offset, buf, n); -+ zmemcpy(history, buf + n, count - n); -+ } -+ n = param->hl + count; -+ if (n <= HB_SIZE) -+ /* All history fits into buffer - no need to discard anything */ -+ param->hl = n; -+ else { -+ /* History does not fit into buffer - discard extra bytes */ -+ param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE; -+ param->hl = HB_SIZE; -+ } -+} -+ -+int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length) -+ z_streamp strm; -+ const Bytef *dictionary; -+ uInt dict_length; -+{ -+ 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; -+ -+ 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; -+} -+ -+int ZLIB_INTERNAL dfltcc_deflate_get_dictionary(strm, dictionary, dict_length) -+ z_streamp strm; -+ Bytef *dictionary; -+ uInt *dict_length; -+{ -+ 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; -+ -+ if (dictionary) { -+ if (param->ho + param->hl <= HB_SIZE) -+ /* Circular history buffer does not wrap - copy one chunk */ -+ zmemcpy(dictionary, state->window + param->ho, param->hl); -+ else { -+ /* Circular history buffer wraps - copy two chunks */ -+ zmemcpy(dictionary, -+ state->window + param->ho, -+ HB_SIZE - param->ho); -+ zmemcpy(dictionary + HB_SIZE - param->ho, -+ state->window, -+ param->ho + param->hl - HB_SIZE); -+ } -+ } -+ if (dict_length) -+ *dict_length = param->hl; -+ return Z_OK; -+} -diff --git a/contrib/s390/dfltcc.h b/contrib/s390/dfltcc.h -new file mode 100644 -index 000000000..da26612ca ---- /dev/null -+++ b/contrib/s390/dfltcc.h -@@ -0,0 +1,81 @@ -+#ifndef DFLTCC_H -+#define DFLTCC_H -+ -+#include "../../zlib.h" -+#include "../../zutil.h" -+ -+voidpf ZLIB_INTERNAL dfltcc_alloc_state OF((z_streamp strm, uInt items, -+ uInt size)); -+void ZLIB_INTERNAL dfltcc_copy_state OF((voidpf dst, const voidpf src, -+ uInt size)); -+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, -+ DFLTCC_INFLATE_BREAK, -+ DFLTCC_INFLATE_SOFTWARE, -+} dfltcc_inflate_action; -+dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate OF((z_streamp strm, -+ int flush, int *ret)); -+int ZLIB_INTERNAL dfltcc_was_inflate_used OF((z_streamp strm)); -+int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm)); -+ -+#define ZALLOC_STATE dfltcc_alloc_state -+#define ZFREE_STATE ZFREE -+#define ZCOPY_STATE dfltcc_copy_state -+#define ZALLOC_WINDOW dfltcc_alloc_window -+#define ZFREE_WINDOW dfltcc_free_window -+#define TRY_FREE_WINDOW dfltcc_free_window -+#define INFLATE_RESET_KEEP_HOOK(strm) \ -+ dfltcc_reset((strm), sizeof(struct inflate_state)) -+#define INFLATE_PRIME_HOOK(strm, bits, value) \ -+ do { if (dfltcc_inflate_disable((strm))) return Z_STREAM_ERROR; } while (0) -+#define INFLATE_TYPEDO_HOOK(strm, flush) \ -+ if (dfltcc_can_inflate((strm))) { \ -+ dfltcc_inflate_action action; \ -+\ -+ RESTORE(); \ -+ action = dfltcc_inflate((strm), (flush), &ret); \ -+ LOAD(); \ -+ if (action == DFLTCC_INFLATE_CONTINUE) \ -+ break; \ -+ else if (action == DFLTCC_INFLATE_BREAK) \ -+ goto inf_leave; \ -+ } -+#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm))) -+#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm))) -+#define INFLATE_MARK_HOOK(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 -diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h -new file mode 100644 -index 000000000..46acfc550 ---- /dev/null -+++ b/contrib/s390/dfltcc_deflate.h -@@ -0,0 +1,55 @@ -+#ifndef DFLTCC_DEFLATE_H -+#define DFLTCC_DEFLATE_H -+ -+#include "dfltcc.h" -+ -+int ZLIB_INTERNAL dfltcc_can_deflate OF((z_streamp strm)); -+int ZLIB_INTERNAL dfltcc_deflate OF((z_streamp strm, -+ int flush, -+ block_state *result)); -+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)); -+int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm, -+ Bytef *dictionary, -+ uInt* dict_length)); -+ -+#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ -+ do { \ -+ if (dfltcc_can_deflate((strm))) \ -+ return dfltcc_deflate_set_dictionary((strm), (dict), (dict_len)); \ -+ } while (0) -+#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ -+ do { \ -+ if (dfltcc_can_deflate((strm))) \ -+ return dfltcc_deflate_get_dictionary((strm), (dict), (dict_len)); \ -+ } while (0) -+#define DEFLATE_RESET_KEEP_HOOK(strm) \ -+ dfltcc_reset((strm), sizeof(deflate_state)) -+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ -+ do { \ -+ int err; \ -+\ -+ 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) = 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 -diff --git a/deflate.c b/deflate.c -index 7f421e4da..a56c1783c 100644 ---- a/deflate.c -+++ b/deflate.c -@@ -61,15 +61,30 @@ const char deflate_copyright[] = - */ - - /* =========================================================================== -- * Function prototypes. -+ * Architecture-specific bits. - */ --typedef enum { -- need_more, /* block not completed, need more input or more output */ -- block_done, /* block flush performed */ -- finish_started, /* finish started, need only more output at next deflate */ -- finish_done /* finish done, accept no more input or output */ --} block_state; -+#ifdef DFLTCC -+# include "contrib/s390/dfltcc_deflate.h" -+#else -+#define ZALLOC_STATE ZALLOC -+#define ZFREE_STATE ZFREE -+#define ZCOPY_STATE zmemcpy -+#define ZALLOC_WINDOW ZALLOC -+#define TRY_FREE_WINDOW TRY_FREE -+#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, 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 -+#define DEFLATE_NEED_CHECKSUM(strm) 1 -+#endif - -+/* =========================================================================== -+ * Function prototypes. -+ */ - typedef block_state (*compress_func) OF((deflate_state *s, int flush)); - /* Compression function. Returns the block state after the call. */ - -@@ -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)); --local void flush_pending OF((z_streamp strm)); - 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") -@@ -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 */ -- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); -+ s = (deflate_state *) ZALLOC_STATE(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; -@@ -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); - -- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); -+ s->window = (Bytef *) ZALLOC_WINDOW(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - -@@ -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); -+ DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ -@@ -492,6 +507,7 @@ int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; -+ DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) -@@ -538,6 +554,8 @@ int ZEXPORT deflateResetKeep (strm) - - _tr_init(s); - -+ DEFLATE_RESET_KEEP_HOOK(strm); -+ - return Z_OK; - } - -@@ -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, &hook_flush); - func = configuration_table[s->level].func; - -- 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; -+ DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen); - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (deflateStateCheck(strm)) -@@ -741,7 +764,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) - } - - /* if not default parameters, return conservative bound */ -- if (s->w_bits != 15 || s->hash_bits != 8 + 7) -+ if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || -+ s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ -@@ -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()). - */ --local void flush_pending(strm) -+void ZLIB_INTERNAL flush_pending(strm) - z_streamp strm; - { - unsigned len; -@@ -1040,7 +1064,8 @@ int ZEXPORT deflate (strm, flush) - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - -- bstate = s->level == 0 ? deflate_stored(s, flush) : -+ bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : -+ s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); -@@ -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); -- TRY_FREE(strm, strm->state->window); -+ TRY_FREE_WINDOW(strm, strm->state->window); - -- ZFREE(strm, strm->state); -+ ZFREE_STATE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -@@ -1161,13 +1189,13 @@ int ZEXPORT deflateCopy (dest, source) - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - -- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); -+ ds = (deflate_state *) ZALLOC_STATE(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; -- zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); -+ ZCOPY_STATE((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - -- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); -+ ds->window = (Bytef *) ZALLOC_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)); - 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)) {} -+ else if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } - #ifdef GZIP -diff --git a/deflate.h b/deflate.h -index 1a06cd5f2..f92750ca6 100644 ---- a/deflate.h -+++ b/deflate.h -@@ -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)); -+void ZLIB_INTERNAL _tr_send_bits OF((deflate_state *s, int value, int length)); - - #define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -@@ -343,4 +344,15 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - flush = _tr_tally(s, distance, length) - #endif - -+typedef enum { -+ need_more, /* block not completed, need more input or more output */ -+ block_done, /* block flush performed */ -+ finish_started, /* finish started, need only more output at next deflate */ -+ finish_done /* finish done, accept no more input or output */ -+} block_state; -+ -+unsigned ZLIB_INTERNAL bi_reverse OF((unsigned code, int len)); -+void ZLIB_INTERNAL bi_windup OF((deflate_state *s)); -+void ZLIB_INTERNAL flush_pending OF((z_streamp strm)); -+ - #endif /* DEFLATE_H */ -diff --git a/gzguts.h b/gzguts.h -index 57faf3716..581f2b631 100644 ---- a/gzguts.h -+++ b/gzguts.h -@@ -153,7 +153,11 @@ - - /* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -+#ifdef DFLTCC -+#define GZBUFSIZE 131072 -+#else - #define GZBUFSIZE 8192 -+#endif - - /* 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 2a3c4fe98..ca0f8c9a4 100644 ---- a/inflate.c -+++ b/inflate.c -@@ -85,6 +85,24 @@ - #include "inflate.h" - #include "inffast.h" - -+/* architecture-specific bits */ -+#ifdef DFLTCC -+# include "contrib/s390/dfltcc.h" -+#else -+#define ZALLOC_STATE ZALLOC -+#define ZFREE_STATE ZFREE -+#define ZCOPY_STATE zmemcpy -+#define ZALLOC_WINDOW ZALLOC -+#define ZFREE_WINDOW ZFREE -+#define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0) -+#define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0) -+#define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0) -+#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 -@@ -138,6 +156,7 @@ z_streamp strm; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; -+ INFLATE_RESET_KEEP_HOOK(strm); - Tracev((stderr, "inflate: reset\n")); - return Z_OK; - } -@@ -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) { -- ZFREE(strm, state->window); -+ ZFREE_WINDOW(strm, state->window); - state->window = Z_NULL; - } - -@@ -222,7 +241,7 @@ int stream_size; - strm->zfree = zcfree; - #endif - state = (struct inflate_state FAR *) -- ZALLOC(strm, 1, sizeof(struct inflate_state)); -+ ZALLOC_STATE(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; -@@ -231,7 +250,7 @@ int stream_size; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { -- ZFREE(strm, state); -+ ZFREE_STATE(strm, state); - strm->state = Z_NULL; - } - return ret; -@@ -253,6 +272,7 @@ int value; - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; -+ INFLATE_PRIME_HOOK(strm, bits, value); - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; -@@ -380,6 +400,27 @@ void makefixed() - } - #endif /* MAKEFIXED */ - -+int ZLIB_INTERNAL inflate_ensure_window(state) -+ struct inflate_state *state; -+{ -+ /* if it hasn't been done already, allocate space for the window */ -+ if (state->window == Z_NULL) { -+ state->window = (unsigned char FAR *) -+ ZALLOC_WINDOW(state->strm, 1U << state->wbits, -+ sizeof(unsigned char)); -+ if (state->window == Z_NULL) return 1; -+ } -+ -+ /* if window not in use yet, initialize */ -+ if (state->wsize == 0) { -+ state->wsize = 1U << state->wbits; -+ state->wnext = 0; -+ state->whave = 0; -+ } -+ -+ return 0; -+} -+ - /* - 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 -@@ -404,20 +445,7 @@ unsigned copy; - - state = (struct inflate_state FAR *)strm->state; - -- /* if it hasn't been done already, allocate space for the window */ -- if (state->window == Z_NULL) { -- state->window = (unsigned char FAR *) -- ZALLOC(strm, 1U << state->wbits, -- sizeof(unsigned char)); -- if (state->window == Z_NULL) return 1; -- } -- -- /* if window not in use yet, initialize */ -- if (state->wsize == 0) { -- state->wsize = 1U << state->wbits; -- state->wnext = 0; -- state->whave = 0; -- } -+ if (inflate_ensure_window(state)) return 1; - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { -@@ -861,6 +889,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; -@@ -1222,7 +1251,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_CHECK(state->check, put - out, out); - out = left; -@@ -1277,8 +1306,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)))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; -@@ -1288,7 +1318,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_CHECK(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + -@@ -1306,8 +1336,8 @@ z_streamp strm; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -- if (state->window != Z_NULL) ZFREE(strm, state->window); -- ZFREE(strm, strm->state); -+ if (state->window != Z_NULL) ZFREE_WINDOW(strm, state->window); -+ ZFREE_STATE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -@@ -1486,6 +1516,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; - } -@@ -1506,21 +1537,22 @@ z_streamp source; - - /* allocate space */ - copy = (struct inflate_state FAR *) -- ZALLOC(source, 1, sizeof(struct inflate_state)); -+ ZALLOC_STATE(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - 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)); - if (window == Z_NULL) { -- ZFREE(source, copy); -+ ZFREE_STATE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); -- zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); -+ ZCOPY_STATE((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { -@@ -1577,6 +1609,7 @@ z_streamp strm; - - if (inflateStateCheck(strm)) - return -(1L << 16); -+ INFLATE_MARK_HOOK(strm); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : -diff --git a/inflate.h b/inflate.h -index f127b6b1f..519ed3535 100644 ---- a/inflate.h -+++ b/inflate.h -@@ -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 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) - } - - /* input and output functions for inflateBack() */ --local unsigned pull(void *desc, unsigned char **buf) -+local unsigned pull(void *desc, z_const unsigned char **buf) - { - static unsigned int next = 0; - static unsigned char dat[] = {0x63, 0, 2, 0}; -diff --git a/test/minigzip.c b/test/minigzip.c -index e22fb08c0..4b5f4efed 100644 ---- a/test/minigzip.c -+++ b/test/minigzip.c -@@ -132,7 +132,11 @@ static void pwinerror (s) - #endif - #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) - -+#ifdef DFLTCC -+#define BUFLEN 262144 -+#else - #define BUFLEN 16384 -+#endif - #define MAX_NAME_LEN 1024 - - #ifdef MAXSEG_64K -diff --git a/trees.c b/trees.c -index 72b521fb0..534f29c98 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 code, int len)); --local void bi_windup OF((deflate_state *s)); - local void bi_flush OF((deflate_state *s)); - - #ifdef GEN_TREES_H -@@ -223,6 +221,13 @@ local void send_bits(s, value, length) - } - #endif /* ZLIB_DEBUG */ - -+void ZLIB_INTERNAL _tr_send_bits(s, value, length) -+ deflate_state *s; -+ int value; -+ int length; -+{ -+ send_bits(s, value, length); -+} - - /* the arguments must not have side effects */ - -@@ -1134,7 +1139,7 @@ local int detect_data_type(s) - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ --local unsigned bi_reverse(code, len) -+unsigned ZLIB_INTERNAL bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ - { -@@ -1166,7 +1171,7 @@ local void bi_flush(s) - /* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ --local void bi_windup(s) -+void ZLIB_INTERNAL bi_windup(s) - deflate_state *s; - { - if (s->bi_valid > 8) { -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)) diff --git a/zlib-1.2.12-add-optimized-slide_hash-for-power.patch b/zlib-1.2.12-add-optimized-slide_hash-for-power.patch index 8d1740c..2b973c7 100644 --- a/zlib-1.2.12-add-optimized-slide_hash-for-power.patch +++ b/zlib-1.2.12-add-optimized-slide_hash-for-power.patch @@ -27,11 +27,11 @@ Author: Matheus Castanho create mode 100644 contrib/power/slide_hash_power8.c create mode 100644 contrib/power/slide_hash_resolver.c -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 44de486f6..8208c626b 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -186,7 +186,8 @@ if(CMAKE_COMPILER_IS_GNUCC) +Index: zlib-1.2.13/CMakeLists.txt +=================================================================== +--- zlib-1.2.13.orig/CMakeLists.txt ++++ zlib-1.2.13/CMakeLists.txt +@@ -174,7 +174,8 @@ if(CMAKE_COMPILER_IS_GNUCC) add_definitions(-DZ_POWER8) set(ZLIB_POWER8 contrib/power/adler32_power8.c @@ -41,11 +41,11 @@ index 44de486f6..8208c626b 100644 set_source_files_properties( ${ZLIB_POWER8} -diff --git a/Makefile.in b/Makefile.in -index 9ef9fa9b5..f71c6eae0 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -183,6 +183,9 @@ crc32_z_power8.o: $(SRCDIR)contrib/power/crc32_z_power8.c +Index: zlib-1.2.13/Makefile.in +=================================================================== +--- zlib-1.2.13.orig/Makefile.in ++++ zlib-1.2.13/Makefile.in +@@ -185,6 +185,9 @@ crc32-vx.o: $(SRCDIR)contrib/s390/crc32- deflate.o: $(SRCDIR)deflate.c $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c @@ -55,7 +55,7 @@ index 9ef9fa9b5..f71c6eae0 100644 infback.o: $(SRCDIR)infback.c $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c -@@ -245,6 +248,11 @@ deflate.lo: $(SRCDIR)deflate.c +@@ -252,6 +255,11 @@ deflate.lo: $(SRCDIR)deflate.c $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c -@mv objs/deflate.o $@ @@ -67,11 +67,11 @@ index 9ef9fa9b5..f71c6eae0 100644 infback.lo: $(SRCDIR)infback.c -@mkdir objs 2>/dev/null || test -d objs $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c -diff --git a/configure b/configure -index 810a7404d..d0dacf9c2 100755 ---- a/configure -+++ b/configure -@@ -879,8 +879,8 @@ if tryboth $CC -c $CFLAGS $test.c; then +Index: zlib-1.2.13/configure +=================================================================== +--- zlib-1.2.13.orig/configure ++++ zlib-1.2.13/configure +@@ -898,8 +898,8 @@ if tryboth $CC -c $CFLAGS $test.c; then if tryboth $CC -c $CFLAGS -mcpu=power8 $test.c; then POWER8="-DZ_POWER8" @@ -82,10 +82,10 @@ index 810a7404d..d0dacf9c2 100755 echo "Checking for -mcpu=power8 support... Yes." | tee -a configure.log else echo "Checking for -mcpu=power8 support... No." | tee -a configure.log -diff --git a/contrib/power/power.h b/contrib/power/power.h -index f57c76167..28c8f78ca 100644 ---- a/contrib/power/power.h -+++ b/contrib/power/power.h +Index: zlib-1.2.13/contrib/power/power.h +=================================================================== +--- zlib-1.2.13.orig/contrib/power/power.h ++++ zlib-1.2.13/contrib/power/power.h @@ -4,7 +4,10 @@ */ #include "../../zconf.h" @@ -97,11 +97,10 @@ index f57c76167..28c8f78ca 100644 unsigned long _crc32_z_power8(unsigned long, const Bytef *, z_size_t); + +void _slide_hash_power8(deflate_state *s); -diff --git a/contrib/power/slide_hash_power8.c b/contrib/power/slide_hash_power8.c -new file mode 100644 -index 000000000..c5a0eb5a6 +Index: zlib-1.2.13/contrib/power/slide_hash_power8.c +=================================================================== --- /dev/null -+++ b/contrib/power/slide_hash_power8.c ++++ zlib-1.2.13/contrib/power/slide_hash_power8.c @@ -0,0 +1,63 @@ + /* Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h @@ -166,11 +165,10 @@ index 000000000..c5a0eb5a6 + slide_hash_power8_loop(s,n,p); +#endif +} -diff --git a/contrib/power/slide_hash_resolver.c b/contrib/power/slide_hash_resolver.c -new file mode 100644 -index 000000000..54fa1eb21 +Index: zlib-1.2.13/contrib/power/slide_hash_resolver.c +=================================================================== --- /dev/null -+++ b/contrib/power/slide_hash_resolver.c ++++ zlib-1.2.13/contrib/power/slide_hash_resolver.c @@ -0,0 +1,15 @@ +/* Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h @@ -187,12 +185,12 @@ index 000000000..54fa1eb21 + + return slide_hash_default; +} -diff --git a/deflate.c b/deflate.c -index 799fb93cc..b2db576dc 100644 ---- a/deflate.c -+++ b/deflate.c -@@ -196,6 +196,13 @@ local const config configuration_table[10] = { - (unsigned)(s->hash_size-1)*sizeof(*s->head)); \ +Index: zlib-1.2.13/deflate.c +=================================================================== +--- zlib-1.2.13.orig/deflate.c ++++ zlib-1.2.13/deflate.c +@@ -204,6 +204,13 @@ local const config configuration_table[1 + (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ } while (0) +#ifdef Z_POWER_OPT @@ -205,7 +203,7 @@ index 799fb93cc..b2db576dc 100644 /* =========================================================================== * Slide the hash table when sliding the window down (could be avoided with 32 * bit values at the expense of memory usage). We slide even when level == 0 to -@@ -227,6 +234,11 @@ local void slide_hash(s) +@@ -235,6 +242,11 @@ local void slide_hash(s) #endif } diff --git a/zlib-1.2.12-add-vectorized-longest_match-for-power.patch b/zlib-1.2.12-add-vectorized-longest_match-for-power.patch index 62281ff..9bdd24b 100644 --- a/zlib-1.2.12-add-vectorized-longest_match-for-power.patch +++ b/zlib-1.2.12-add-vectorized-longest_match-for-power.patch @@ -20,11 +20,11 @@ Author: Matheus Castanho create mode 100644 contrib/power/longest_match_power9.c create mode 100644 contrib/power/longest_match_resolver.c -Index: zlib-1.2.12/CMakeLists.txt +Index: zlib-1.2.13/CMakeLists.txt =================================================================== ---- zlib-1.2.12.orig/CMakeLists.txt -+++ zlib-1.2.12/CMakeLists.txt -@@ -199,7 +199,8 @@ if(CMAKE_COMPILER_IS_GNUCC) +--- zlib-1.2.13.orig/CMakeLists.txt ++++ zlib-1.2.13/CMakeLists.txt +@@ -187,7 +187,8 @@ if(CMAKE_COMPILER_IS_GNUCC) if(POWER9) add_definitions(-DZ_POWER9) @@ -34,11 +34,11 @@ Index: zlib-1.2.12/CMakeLists.txt set_source_files_properties( ${ZLIB_POWER9} -Index: zlib-1.2.12/Makefile.in +Index: zlib-1.2.13/Makefile.in =================================================================== ---- zlib-1.2.12.orig/Makefile.in -+++ zlib-1.2.12/Makefile.in -@@ -189,6 +189,9 @@ crc32-vx.o: $(SRCDIR)contrib/s390/crc32- +--- zlib-1.2.13.orig/Makefile.in ++++ zlib-1.2.13/Makefile.in +@@ -185,6 +185,9 @@ crc32-vx.o: $(SRCDIR)contrib/s390/crc32- deflate.o: $(SRCDIR)deflate.c $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c @@ -48,7 +48,7 @@ Index: zlib-1.2.12/Makefile.in slide_hash_power8.o: $(SRCDIR)contrib/power/slide_hash_power8.c $(CC) $(CFLAGS) -mcpu=power8 $(ZINC) -c -o $@ $(SRCDIR)contrib/power/slide_hash_power8.c -@@ -259,6 +262,11 @@ deflate.lo: $(SRCDIR)deflate.c +@@ -255,6 +258,11 @@ deflate.lo: $(SRCDIR)deflate.c $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c -@mv objs/deflate.o $@ @@ -60,11 +60,11 @@ Index: zlib-1.2.12/Makefile.in slide_hash_power8.lo: $(SRCDIR)contrib/power/slide_hash_power8.c -@mkdir objs 2>/dev/null || test -d objs $(CC) $(SFLAGS) -mcpu=power8 $(ZINC) -DPIC -c -o objs/slide_hash_power8.o $(SRCDIR)contrib/power/slide_hash_power8.c -Index: zlib-1.2.12/configure +Index: zlib-1.2.13/configure =================================================================== ---- zlib-1.2.12.orig/configure -+++ zlib-1.2.12/configure -@@ -915,8 +915,8 @@ if tryboth $CC -c $CFLAGS $test.c; then +--- zlib-1.2.13.orig/configure ++++ zlib-1.2.13/configure +@@ -907,8 +907,8 @@ if tryboth $CC -c $CFLAGS $test.c; then if tryboth $CC -c $CFLAGS -mcpu=power9 $test.c; then POWER9="-DZ_POWER9" @@ -75,10 +75,10 @@ Index: zlib-1.2.12/configure echo "Checking for -mcpu=power9 support... Yes." | tee -a configure.log else echo "Checking for -mcpu=power9 support... No." | tee -a configure.log -Index: zlib-1.2.12/contrib/power/longest_match_power9.c +Index: zlib-1.2.13/contrib/power/longest_match_power9.c =================================================================== --- /dev/null -+++ zlib-1.2.12/contrib/power/longest_match_power9.c ++++ zlib-1.2.13/contrib/power/longest_match_power9.c @@ -0,0 +1,194 @@ +/* Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h @@ -274,10 +274,10 @@ Index: zlib-1.2.12/contrib/power/longest_match_power9.c + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} -Index: zlib-1.2.12/contrib/power/longest_match_resolver.c +Index: zlib-1.2.13/contrib/power/longest_match_resolver.c =================================================================== --- /dev/null -+++ zlib-1.2.12/contrib/power/longest_match_resolver.c ++++ zlib-1.2.13/contrib/power/longest_match_resolver.c @@ -0,0 +1,15 @@ +/* Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h @@ -294,10 +294,10 @@ Index: zlib-1.2.12/contrib/power/longest_match_resolver.c + + return longest_match_default; +} -Index: zlib-1.2.12/contrib/power/power.h +Index: zlib-1.2.13/contrib/power/power.h =================================================================== ---- zlib-1.2.12.orig/contrib/power/power.h -+++ zlib-1.2.12/contrib/power/power.h +--- zlib-1.2.13.orig/contrib/power/power.h ++++ zlib-1.2.13/contrib/power/power.h @@ -10,4 +10,6 @@ uLong _adler32_power8(uLong adler, const unsigned long _crc32_z_power8(unsigned long, const Bytef *, z_size_t); @@ -305,13 +305,13 @@ Index: zlib-1.2.12/contrib/power/power.h +uInt _longest_match_power9(deflate_state *s, IPos cur_match); + void _slide_hash_power8(deflate_state *s); -Index: zlib-1.2.12/deflate.c +Index: zlib-1.2.13/deflate.c =================================================================== ---- zlib-1.2.12.orig/deflate.c -+++ zlib-1.2.12/deflate.c -@@ -1309,6 +1309,14 @@ local void lm_init (s) - /* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. +--- zlib-1.2.13.orig/deflate.c ++++ zlib-1.2.13/deflate.c +@@ -1313,6 +1313,14 @@ local void lm_init(s) + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. */ + +#ifdef Z_POWER_OPT @@ -324,9 +324,9 @@ Index: zlib-1.2.12/deflate.c local uInt longest_match(s, pcur_match) deflate_state *s; IPos pcur_match; /* current match */ -@@ -1454,6 +1462,11 @@ local uInt longest_match(s, pcur_match) +@@ -1460,6 +1468,11 @@ local uInt longest_match(s, pcur_match) + return s->lookahead; } - #endif /* ASMV */ +#ifdef Z_POWER_OPT +#undef longest_match diff --git a/zlib-1.2.12-correct-inputs-provided-to-crc-func.patch b/zlib-1.2.12-correct-inputs-provided-to-crc-func.patch deleted file mode 100644 index 62cbeb4..0000000 --- a/zlib-1.2.12-correct-inputs-provided-to-crc-func.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ec3df00224d4b396e2ac6586ab5d25f673caa4c2 Mon Sep 17 00:00:00 2001 -From: Mark Adler -Date: Wed, 30 Mar 2022 11:14:53 -0700 -Subject: [PATCH] Correct incorrect inputs provided to the CRC functions. - -The previous releases of zlib were not sensitive to incorrect CRC -inputs with bits set above the low 32. This commit restores that -behavior, so that applications with such bugs will continue to -operate as before. ---- - crc32.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/crc32.c b/crc32.c -index a1bdce5c2..451887bc7 100644 ---- a/crc32.c -+++ b/crc32.c -@@ -630,7 +630,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) - #endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ -- crc ^= 0xffffffff; -+ crc = (~crc) & 0xffffffff; - - /* Compute the CRC up to a word boundary. */ - while (len && ((z_size_t)buf & 7) != 0) { -@@ -749,7 +749,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) - #endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ -- crc ^= 0xffffffff; -+ crc = (~crc) & 0xffffffff; - - #ifdef W - -@@ -1077,7 +1077,7 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - #ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); - #endif /* DYNAMIC_CRC_TABLE */ -- return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; -+ return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); - } - - /* ========================================================================= */ -@@ -1112,5 +1112,5 @@ uLong crc32_combine_op(crc1, crc2, op) - uLong crc2; - uLong op; - { -- return multmodp(op, crc1) ^ crc2; -+ return multmodp(op, crc1) ^ (crc2 & 0xffffffff); - } diff --git a/zlib-1.2.12-fix-CVE-2022-37434.patch b/zlib-1.2.12-fix-CVE-2022-37434.patch deleted file mode 100644 index e5c1e87..0000000 --- a/zlib-1.2.12-fix-CVE-2022-37434.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- zlib-1.2.12/inflate.c.old 2022-08-09 10:30:18.831225181 +0000 -+++ zlib-1.2.12/inflate.c 2022-08-09 10:29:33.251225181 +0000 -@@ -792,8 +792,9 @@ int flush; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && -- state->head->extra != Z_NULL) { -- len = state->head->extra_len - state->length; -+ state->head->extra != Z_NULL && -+ (len = state->head->extra_len - state->length) < -+ state->head->extra_max) { - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); diff --git a/zlib-1.2.12-fix-configure.patch b/zlib-1.2.12-fix-configure.patch deleted file mode 100644 index a117b48..0000000 --- a/zlib-1.2.12-fix-configure.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6378872888c85c02f340126712684e0f603f5e76 Mon Sep 17 00:00:00 2001 -From: Ilya Leoshkevich -Date: Wed, 27 Apr 2022 14:38:23 +0200 -Subject: [PATCH] zlib-1.2.12-fix-configure.patch - ---- - configure | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/configure b/configure -index cff6207ec..dd01b5c0e 100755 ---- a/configure -+++ b/configure -@@ -185,7 +185,10 @@ if test -z "$CC"; then - else - cc=${CROSS_PREFIX}cc - fi -+else -+ cc=${CC} - fi -+ - cflags=${CFLAGS-"-O3"} - # to force the asm version use: CFLAGS="-O3 -DASMV" ./configure - case "$cc" in diff --git a/zlib-1.2.12-s390-vectorize-crc32.patch b/zlib-1.2.12-s390-vectorize-crc32.patch index 5c8f7fb..4477d6e 100644 --- a/zlib-1.2.12-s390-vectorize-crc32.patch +++ b/zlib-1.2.12-s390-vectorize-crc32.patch @@ -18,19 +18,19 @@ choose between the regular and the vectorized implementations. create mode 100644 contrib/s390/crc32-vx.c create mode 100644 contrib/s390/crc32_z_resolver.c -diff --git a/Makefile.in b/Makefile.in -index 2e78f3844..04c2f5d53 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -29,6 +29,7 @@ LDFLAGS= - TEST_LDFLAGS=-L. libz.a +Index: zlib-1.2.13/Makefile.in +=================================================================== +--- zlib-1.2.13.orig/Makefile.in ++++ zlib-1.2.13/Makefile.in +@@ -25,6 +25,7 @@ LDFLAGS= + TEST_LDFLAGS=$(LDFLAGS) -L. libz.a LDSHARED=$(CC) CPP=$(CC) -E +VGFMAFLAG= STATICLIB=libz.a SHAREDLIB=libz.so -@@ -179,6 +180,9 @@ crc32.o: $(SRCDIR)crc32.c +@@ -175,6 +176,9 @@ crc32.o: $(SRCDIR)crc32.c crc32_z_power8.o: $(SRCDIR)contrib/power/crc32_z_power8.c $(CC) $(CFLAGS) -mcpu=power8 $(ZINC) -c -o $@ $(SRCDIR)contrib/power/crc32_z_power8.c @@ -40,7 +40,7 @@ index 2e78f3844..04c2f5d53 100644 deflate.o: $(SRCDIR)deflate.c $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c -@@ -229,6 +233,11 @@ crc32.lo: $(SRCDIR)crc32.c +@@ -225,6 +229,11 @@ crc32.lo: $(SRCDIR)crc32.c $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c -@mv objs/crc32.o $@ @@ -52,11 +52,11 @@ index 2e78f3844..04c2f5d53 100644 crc32_z_power8.lo: $(SRCDIR)contrib/power/crc32_z_power8.c -@mkdir objs 2>/dev/null || test -d objs $(CC) $(SFLAGS) -mcpu=power8 $(ZINC) -DPIC -c -o objs/crc32_z_power8.o $(SRCDIR)contrib/power/crc32_z_power8.c -diff --git a/configure b/configure -index dd01b5c0e..acf94a599 100755 ---- a/configure -+++ b/configure -@@ -929,6 +929,32 @@ else +Index: zlib-1.2.13/configure +=================================================================== +--- zlib-1.2.13.orig/configure ++++ zlib-1.2.13/configure +@@ -921,6 +921,32 @@ else echo "Checking for Power optimizations support... No." | tee -a configure.log fi @@ -89,7 +89,7 @@ index dd01b5c0e..acf94a599 100755 # show the results in the log echo >> configure.log echo ALL = $ALL >> configure.log -@@ -960,6 +986,7 @@ echo mandir = $mandir >> configure.log +@@ -952,6 +978,7 @@ echo mandir = $mandir >> configure.log echo prefix = $prefix >> configure.log echo sharedlibdir = $sharedlibdir >> configure.log echo uname = $uname >> configure.log @@ -97,7 +97,7 @@ index dd01b5c0e..acf94a599 100755 # udpate Makefile with the configure results sed < ${SRCDIR}Makefile.in " -@@ -969,6 +996,7 @@ sed < ${SRCDIR}Makefile.in " +@@ -961,6 +988,7 @@ sed < ${SRCDIR}Makefile.in " /^LDFLAGS *=/s#=.*#=$LDFLAGS# /^LDSHARED *=/s#=.*#=$LDSHARED# /^CPP *=/s#=.*#=$CPP# @@ -105,10 +105,10 @@ index dd01b5c0e..acf94a599 100755 /^STATICLIB *=/s#=.*#=$STATICLIB# /^SHAREDLIB *=/s#=.*#=$SHAREDLIB# /^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -diff --git a/contrib/gcc/zifunc.h b/contrib/gcc/zifunc.h -index daf4fe442..b62379ed8 100644 ---- a/contrib/gcc/zifunc.h -+++ b/contrib/gcc/zifunc.h +Index: zlib-1.2.13/contrib/gcc/zifunc.h +=================================================================== +--- zlib-1.2.13.orig/contrib/gcc/zifunc.h ++++ zlib-1.2.13/contrib/gcc/zifunc.h @@ -8,9 +8,28 @@ /* Helpers for arch optimizations */ @@ -139,11 +139,10 @@ index daf4fe442..b62379ed8 100644 /* This is a helper macro to declare a resolver for an indirect function * (ifunc). Let's say you have function * -diff --git a/contrib/s390/crc32-vx.c b/contrib/s390/crc32-vx.c -new file mode 100644 -index 000000000..fa5387c11 +Index: zlib-1.2.13/contrib/s390/crc32-vx.c +=================================================================== --- /dev/null -+++ b/contrib/s390/crc32-vx.c ++++ zlib-1.2.13/contrib/s390/crc32-vx.c @@ -0,0 +1,195 @@ +/* + * Hardware-accelerated CRC-32 variants for Linux on z Systems @@ -340,11 +339,10 @@ index 000000000..fa5387c11 + + return ((uv4si)v2)[2]; +} -diff --git a/contrib/s390/crc32_z_resolver.c b/contrib/s390/crc32_z_resolver.c -new file mode 100644 -index 000000000..9749cab40 +Index: zlib-1.2.13/contrib/s390/crc32_z_resolver.c +=================================================================== --- /dev/null -+++ b/contrib/s390/crc32_z_resolver.c ++++ zlib-1.2.13/contrib/s390/crc32_z_resolver.c @@ -0,0 +1,41 @@ +#include +#include "../gcc/zifunc.h" @@ -387,11 +385,11 @@ index 000000000..9749cab40 + return s390_crc32_vx; + return crc32_z_default; +} -diff --git a/crc32.c b/crc32.c -index ae7b7e792..c2122615b 100644 ---- a/crc32.c -+++ b/crc32.c -@@ -736,12 +736,12 @@ local z_word_t crc_word_big(data) +Index: zlib-1.2.13/crc32.c +=================================================================== +--- zlib-1.2.13.orig/crc32.c ++++ zlib-1.2.13/crc32.c +@@ -745,12 +745,12 @@ local z_word_t crc_word_big(data) #endif /* ========================================================================= */ @@ -406,7 +404,7 @@ index ae7b7e792..c2122615b 100644 unsigned long ZEXPORT crc32_z(crc, buf, len) unsigned long crc; -@@ -1064,10 +1064,15 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) +@@ -1073,10 +1073,15 @@ unsigned long ZEXPORT crc32_z(crc, buf, return crc ^ 0xffffffff; } diff --git a/zlib-1.2.12.tar.gz b/zlib-1.2.12.tar.gz deleted file mode 100644 index a572d32..0000000 --- a/zlib-1.2.12.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9 -size 1490071 diff --git a/zlib-1.2.12.tar.gz.asc b/zlib-1.2.12.tar.gz.asc deleted file mode 100644 index a4c7be2..0000000 --- a/zlib-1.2.12.tar.gz.asc +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Comment: GPGTools - http://gpgtools.org - -iF0EABECAB0WIQRe1GpnIdNlWHeR4qp4P82OWLyvugUCYkEexwAKCRB4P82OWLyv -ulGRAJ9CLw3LBVZKeIM2JY0MS3obrzTSzgCgqEHUCY42CMzYyrTLazKS6ymTC/4= -=mgXG ------END PGP SIGNATURE----- diff --git a/zlib-1.2.12-optimized-crc32-power8.patch b/zlib-1.2.13-IBM-Z-hw-accelerated-deflate-s390x.patch similarity index 57% rename from zlib-1.2.12-optimized-crc32-power8.patch rename to zlib-1.2.13-IBM-Z-hw-accelerated-deflate-s390x.patch index 5256e51..36d1215 100644 --- a/zlib-1.2.12-optimized-crc32-power8.patch +++ b/zlib-1.2.13-IBM-Z-hw-accelerated-deflate-s390x.patch @@ -1,46 +1,47 @@ -From 8c6fc7cb5f408f1fb92eaf8cee8ce571c174b5e0 Mon Sep 17 00:00:00 2001 -From: Ilya Leoshkevich -Date: Wed, 27 Apr 2022 14:38:11 +0200 -Subject: [PATCH] zlib-1.2.12-optimized-crc32-power8.patch +From e382a919a5bce2aa0738e85540942d7af7d6c1c0 Mon Sep 17 00:00:00 2001 +From: Manjunath S Matti +Date: Tue, 15 Nov 2022 02:45:53 -0600 +Subject: [PATCH 1/4] Preparation for Power optimizations +Optimized functions for Power will make use of GNU indirect functions, +an extension to support different implementations of the same function, +which can be selected during runtime. This will be used to provide +optimized functions for different processor versions. + +Since this is a GNU extension, we placed the definition of the Z_IFUNC +macro under `contrib/gcc`. This can be reused by other archs as well. + +Author: Matheus Castanho +Author: Rogerio Alves +Signed-off-by: Manjunath Matti --- - CMakeLists.txt | 72 ++ - Makefile.in | 43 +- - configure | 69 ++ - contrib/README.contrib | 9 + - contrib/gcc/zifunc.h | 60 ++ - contrib/power/clang_workaround.h | 87 +++ - contrib/power/crc32_constants.h | 1206 ++++++++++++++++++++++++++++++ - contrib/power/crc32_z_power8.c | 679 +++++++++++++++++ - contrib/power/crc32_z_resolver.c | 15 + - contrib/power/power.h | 8 + - crc32.c | 12 + - test/crc32_test.c | 205 +++++ - 12 files changed, 2455 insertions(+), 10 deletions(-) + CMakeLists.txt | 71 ++++++++++++++++++++++++++++++++++++++++++ + configure | 66 +++++++++++++++++++++++++++++++++++++++ + contrib/README.contrib | 8 +++++ + contrib/gcc/zifunc.h | 60 +++++++++++++++++++++++++++++++++++ + contrib/power/power.h | 4 +++ + 5 files changed, 209 insertions(+) create mode 100644 contrib/gcc/zifunc.h - create mode 100644 contrib/power/clang_workaround.h - create mode 100644 contrib/power/crc32_constants.h - create mode 100644 contrib/power/crc32_z_power8.c - create mode 100644 contrib/power/crc32_z_resolver.c create mode 100644 contrib/power/power.h - create mode 100644 test/crc32_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt -index e6fbb37d1..581e1fa6d 100644 +index b3a58b30e..dd1752757 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -7,6 +7,7 @@ set(VERSION "1.2.12") +@@ -5,6 +5,8 @@ project(zlib C) + + set(VERSION "1.2.13") - option(ASM686 "Enable building i686 assembly implementation") - option(AMD64 "Enable building amd64 assembly implementation") +option(POWER "Enable building power implementation") - ++ set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -@@ -140,6 +141,73 @@ if(CMAKE_COMPILER_IS_GNUCC) - add_definitions(-DASMV) - set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) - endif() + set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") +@@ -126,6 +128,75 @@ if(NOT MINGW) + ) + endif() + ++if(CMAKE_COMPILER_IS_GNUCC) + + # test to see if we can use a GNU indirect function to detect and load optimized code at runtime + CHECK_C_SOURCE_COMPILES(" @@ -84,8 +85,7 @@ index e6fbb37d1..581e1fa6d 100644 + + if(POWER8) + add_definitions(-DZ_POWER8) -+ set(ZLIB_POWER8 -+ contrib/power/crc32_z_power8.c) ++ set(ZLIB_POWER8 ) + + set_source_files_properties( + ${ZLIB_POWER8} @@ -108,170 +108,17 @@ index e6fbb37d1..581e1fa6d 100644 + set(ZLIB_SRCS ${ZLIB_SRCS} ${ZLIB_POWER8} ${ZLIB_POWER9}) + endif() + endif() - endif() - - if(MSVC) -@@ -234,6 +302,10 @@ add_executable(example test/example.c) - target_link_libraries(example zlib) - add_test(example example) - -+add_executable(crc32_test test/crc32_test.c) -+target_link_libraries(crc32_test zlib) -+add_test(crc32_test crc32_test) ++endif() + - add_executable(minigzip test/minigzip.c) - target_link_libraries(minigzip zlib) - -diff --git a/Makefile.in b/Makefile.in -index 6c1d28223..2e78f3844 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -75,11 +75,11 @@ PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) - - all: static shared - --static: example$(EXE) minigzip$(EXE) -+static: crc32_test$(EXE) example$(EXE) minigzip$(EXE) - --shared: examplesh$(EXE) minigzipsh$(EXE) -+shared: crc32_testsh$(EXE) examplesh$(EXE) minigzipsh$(EXE) - --all64: example64$(EXE) minigzip64$(EXE) -+all64: crc32_test64$(EXE) example64$(EXE) minigzip64$(EXE) - - check: test - -@@ -87,7 +87,7 @@ test: all teststatic testshared - - teststatic: static - @TMPST=tmpst_$$; \ -- if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \ -+ if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST && ./crc32_test; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; false; \ -@@ -100,7 +100,7 @@ testshared: shared - DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ - SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ - TMPSH=tmpsh_$$; \ -- if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \ -+ if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH && ./crc32_testsh; then \ - echo ' *** zlib shared test OK ***'; \ - else \ - echo ' *** zlib shared test FAILED ***'; false; \ -@@ -109,7 +109,7 @@ testshared: shared - - test64: all64 - @TMP64=tmp64_$$; \ -- if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \ -+ if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64 && ./crc32_test64; then \ - echo ' *** zlib 64-bit test OK ***'; \ - else \ - echo ' *** zlib 64-bit test FAILED ***'; false; \ -@@ -151,12 +151,18 @@ dfltcc.lo: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/dfltcc.o $(SRCDIR)contrib/s390/dfltcc.c - -@mv objs/dfltcc.o $@ - -+crc32_test.o: $(SRCDIR)test/crc32_test.c $(SRCDIR)zlib.h zconf.h -+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/crc32_test.c -+ - example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c - - minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c - -+crc32_test64.o: $(SRCDIR)test/crc32_test.c $(SRCDIR)zlib.h zconf.h -+ $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/crc32_test.c -+ - example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c - -@@ -170,6 +176,9 @@ adler32.o: $(SRCDIR)adler32.c - crc32.o: $(SRCDIR)crc32.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c - -+crc32_z_power8.o: $(SRCDIR)contrib/power/crc32_z_power8.c -+ $(CC) $(CFLAGS) -mcpu=power8 $(ZINC) -c -o $@ $(SRCDIR)contrib/power/crc32_z_power8.c -+ - deflate.o: $(SRCDIR)deflate.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c - -@@ -220,6 +229,11 @@ crc32.lo: $(SRCDIR)crc32.c - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c - -@mv objs/crc32.o $@ - -+crc32_z_power8.lo: $(SRCDIR)contrib/power/crc32_z_power8.c -+ -@mkdir objs 2>/dev/null || test -d objs -+ $(CC) $(SFLAGS) -mcpu=power8 $(ZINC) -DPIC -c -o objs/crc32_z_power8.o $(SRCDIR)contrib/power/crc32_z_power8.c -+ -@mv objs/crc32_z_power8.o $@ -+ - deflate.lo: $(SRCDIR)deflate.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c -@@ -293,18 +307,27 @@ placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a - ln -s $@ $(SHAREDLIBM) - -@rmdir objs - -+crc32_test$(EXE): crc32_test.o $(STATICLIB) -+ $(CC) $(CFLAGS) -o $@ crc32_test.o $(TEST_LDFLAGS) -+ - example$(EXE): example.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) - - minigzip$(EXE): minigzip.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) - -+crc32_testsh$(EXE): crc32_test.o $(SHAREDLIBV) -+ $(CC) $(CFLAGS) -o $@ crc32_test.o -L. $(SHAREDLIBV) -+ - examplesh$(EXE): example.o $(SHAREDLIBV) - $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) - - minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) - $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) - -+crc32_test64$(EXE): crc32_test64.o $(STATICLIB) -+ $(CC) $(CFLAGS) -o $@ crc32_test64.o $(TEST_LDFLAGS) -+ - example64$(EXE): example64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) - -@@ -374,8 +397,8 @@ zconf: $(SRCDIR)zconf.h.in - mostlyclean: clean - clean: - rm -f *.o *.lo *~ \ -- example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ -- example64$(EXE) minigzip64$(EXE) \ -+ crc32_test$(EXE) example$(EXE) minigzip$(EXE) crc32_testsh$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ -+ crc32_test64$(EXE) example64$(EXE) minigzip64$(EXE) \ - infcover \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o -@@ -397,7 +420,7 @@ tags: - - adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h - gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h --compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h -+compress.o crc32_test.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h - crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h - deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h - infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h -@@ -407,7 +430,7 @@ trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)tr - - adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h - gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h --compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h -+compress.lo crc32_test.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h - crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h - deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h - infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h + # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION + file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) + string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" diff --git a/configure b/configure -index a21be36af..cff6207ec 100755 +index fa4d5daab..9ee7008c3 100755 --- a/configure +++ b/configure -@@ -857,6 +857,75 @@ else - echo "Checking for sys/sdt.h ... No." | tee -a configure.log +@@ -828,6 +828,72 @@ EOF + fi fi +# test to see if we can use a gnu indirection function to detect and load optimized code at runtime @@ -304,9 +151,6 @@ index a21be36af..cff6207ec 100755 +#ifndef _ARCH_PPC + #error "Target is not Power" +#endif -+#if !(defined(__PPC64__) || defined(__powerpc64__)) -+ #error "Target is not 64 bits" -+#endif +#ifndef HAVE_IFUNC + #error "Target doesn't support ifunc" +#endif @@ -320,8 +164,8 @@ index a21be36af..cff6207ec 100755 + + if tryboth $CC -c $CFLAGS -mcpu=power8 $test.c; then + POWER8="-DZ_POWER8" -+ PIC_OBJC="${PIC_OBJC} crc32_z_power8.lo" -+ OBJC="${OBJC} crc32_z_power8.o" ++ PIC_OBJC="${PIC_OBJC}" ++ OBJC="${OBJC}" + echo "Checking for -mcpu=power8 support... Yes." | tee -a configure.log + else + echo "Checking for -mcpu=power8 support... No." | tee -a configure.log @@ -347,7 +191,7 @@ index a21be36af..cff6207ec 100755 echo >> configure.log echo ALL = $ALL >> configure.log diff --git a/contrib/README.contrib b/contrib/README.contrib -index 130a28bdb..1199184b7 100644 +index 5e5f95054..c57b52012 100644 --- a/contrib/README.contrib +++ b/contrib/README.contrib @@ -11,6 +11,10 @@ ada/ by Dmitriy Anisimkov @@ -361,12 +205,11 @@ index 130a28bdb..1199184b7 100644 delphi/ by Cosmin Truta Support for Delphi and C++ Builder -@@ -42,6 +46,11 @@ minizip/ by Gilles Vollant +@@ -42,6 +46,10 @@ minizip/ by Gilles Vollant pascal/ by Bob Dellaca et al. Support for Pascal -+power/ by Daniel Black -+ Matheus Castanho ++power/ by Matheus Castanho + and Rogerio Alves + Optimized functions for Power processors + @@ -439,12 +282,266 @@ index 000000000..daf4fe442 + */ + +#endif /* Z_IFUNC_H_ */ +diff --git a/contrib/power/power.h b/contrib/power/power.h +new file mode 100644 +index 000000000..b42c7d6c6 +--- /dev/null ++++ b/contrib/power/power.h +@@ -0,0 +1,4 @@ ++/* Copyright (C) 2019 Matheus Castanho , IBM ++ * 2019 Rogerio Alves , IBM ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ + +From b7ee6436703e5e8716f3b82df669422035a84385 Mon Sep 17 00:00:00 2001 +From: Manjunath S Matti +Date: Wed, 16 Nov 2022 03:53:53 -0600 +Subject: [PATCH 2/4] Add Power8+ optimized crc32 + +This commit adds an optimized version for the crc32 function based +on crc32-vpmsum from https://github.com/antonblanchard/crc32-vpmsum/ + +This is the C implementation created by Rogerio Alves + + +It makes use of vector instructions to speed up CRC32 algorithm. + +Author: Rogerio Alves +Signed-off-by: Manjunath Matti +--- + .gitignore | 3 + + CMakeLists.txt | 7 +- + Makefile.in | 43 +- + configure | 7 +- + contrib/README.contrib | 3 +- + contrib/power/clang_workaround.h | 82 ++ + contrib/power/crc32_constants.h | 1206 ++++++++++++++++++++++++++++++ + contrib/power/crc32_z_power8.c | 679 +++++++++++++++++ + contrib/power/crc32_z_resolver.c | 15 + + contrib/power/power.h | 4 + + crc32.c | 12 + + test/crc32_test.c | 205 +++++ + 12 files changed, 2252 insertions(+), 14 deletions(-) + create mode 100644 contrib/power/clang_workaround.h + create mode 100644 contrib/power/crc32_constants.h + create mode 100644 contrib/power/crc32_z_power8.c + create mode 100644 contrib/power/crc32_z_resolver.c + create mode 100644 test/crc32_test.c + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index dd1752757..1077c83ef 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -172,7 +172,8 @@ if(CMAKE_COMPILER_IS_GNUCC) + + if(POWER8) + add_definitions(-DZ_POWER8) +- set(ZLIB_POWER8 ) ++ set(ZLIB_POWER8 ++ contrib/power/crc32_z_power8.c) + + set_source_files_properties( + ${ZLIB_POWER8} +@@ -269,6 +270,10 @@ add_executable(example test/example.c) + target_link_libraries(example zlib) + add_test(example example) + ++add_executable(crc32_test test/crc32_test.c) ++target_link_libraries(crc32_test zlib) ++add_test(crc32_test crc32_test) ++ + add_executable(minigzip test/minigzip.c) + target_link_libraries(minigzip zlib) + +diff --git a/Makefile.in b/Makefile.in +index 9cdb85259..83d8ca47d 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -71,11 +71,11 @@ PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) + + all: static shared + +-static: example$(EXE) minigzip$(EXE) ++static: crc32_test$(EXE) example$(EXE) minigzip$(EXE) + +-shared: examplesh$(EXE) minigzipsh$(EXE) ++shared: crc32_testsh$(EXE) examplesh$(EXE) minigzipsh$(EXE) + +-all64: example64$(EXE) minigzip64$(EXE) ++all64: crc32_test64$(EXE) example64$(EXE) minigzip64$(EXE) + + check: test + +@@ -83,7 +83,7 @@ test: all teststatic testshared + + teststatic: static + @TMPST=tmpst_$$; \ +- if echo hello world | ${QEMU_RUN} ./minigzip | ${QEMU_RUN} ./minigzip -d && ${QEMU_RUN} ./example $$TMPST ; then \ ++ if echo hello world | ${QEMU_RUN} ./minigzip | ${QEMU_RUN} ./minigzip -d && ${QEMU_RUN} ./example $$TMPST && ${QEMU_RUN} ./crc32_test; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; false; \ +@@ -96,7 +96,7 @@ testshared: shared + DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ + TMPSH=tmpsh_$$; \ +- if echo hello world | ${QEMU_RUN} ./minigzipsh | ${QEMU_RUN} ./minigzipsh -d && ${QEMU_RUN} ./examplesh $$TMPSH; then \ ++ if echo hello world | ${QEMU_RUN} ./minigzipsh | ${QEMU_RUN} ./minigzipsh -d && ${QEMU_RUN} ./examplesh $$TMPSH && ${QEMU_RUN} ./crc32_testsh; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; false; \ +@@ -105,7 +105,7 @@ testshared: shared + + test64: all64 + @TMP64=tmp64_$$; \ +- if echo hello world | ${QEMU_RUN} ./minigzip64 | ${QEMU_RUN} ./minigzip64 -d && ${QEMU_RUN} ./example64 $$TMP64; then \ ++ if echo hello world | ${QEMU_RUN} ./minigzip64 | ${QEMU_RUN} ./minigzip64 -d && ${QEMU_RUN} ./example64 $$TMP64 && ${QEMU_RUN} ./crc32_test64; then \ + echo ' *** zlib 64-bit test OK ***'; \ + else \ + echo ' *** zlib 64-bit test FAILED ***'; false; \ +@@ -139,12 +139,18 @@ match.lo: match.S + mv _match.o match.lo + rm -f _match.s + ++crc32_test.o: $(SRCDIR)test/crc32_test.c $(SRCDIR)zlib.h zconf.h ++ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/crc32_test.c ++ + example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c + + minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c + ++crc32_test64.o: $(SRCDIR)test/crc32_test.c $(SRCDIR)zlib.h zconf.h ++ $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/crc32_test.c ++ + example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c + +@@ -158,6 +164,9 @@ adler32.o: $(SRCDIR)adler32.c + crc32.o: $(SRCDIR)crc32.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c + ++crc32_z_power8.o: $(SRCDIR)contrib/power/crc32_z_power8.c ++ $(CC) $(CFLAGS) -mcpu=power8 $(ZINC) -c -o $@ $(SRCDIR)contrib/power/crc32_z_power8.c ++ + deflate.o: $(SRCDIR)deflate.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c + +@@ -208,6 +217,11 @@ crc32.lo: $(SRCDIR)crc32.c + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c + -@mv objs/crc32.o $@ + ++crc32_z_power8.lo: $(SRCDIR)contrib/power/crc32_z_power8.c ++ -@mkdir objs 2>/dev/null || test -d objs ++ $(CC) $(SFLAGS) -mcpu=power8 $(ZINC) -DPIC -c -o objs/crc32_z_power8.o $(SRCDIR)contrib/power/crc32_z_power8.c ++ -@mv objs/crc32_z_power8.o $@ ++ + deflate.lo: $(SRCDIR)deflate.c + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c +@@ -281,18 +295,27 @@ placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a + ln -s $@ $(SHAREDLIBM) + -@rmdir objs + ++crc32_test$(EXE): crc32_test.o $(STATICLIB) ++ $(CC) $(CFLAGS) -o $@ crc32_test.o $(TEST_LDFLAGS) ++ + example$(EXE): example.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) + + minigzip$(EXE): minigzip.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) + ++crc32_testsh$(EXE): crc32_test.o $(SHAREDLIBV) ++ $(CC) $(CFLAGS) -o $@ crc32_test.o -L. $(SHAREDLIBV) ++ + examplesh$(EXE): example.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) -L. $(SHAREDLIBV) + + minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) -L. $(SHAREDLIBV) + ++crc32_test64$(EXE): crc32_test64.o $(STATICLIB) ++ $(CC) $(CFLAGS) -o $@ crc32_test64.o $(TEST_LDFLAGS) ++ + example64$(EXE): example64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + +@@ -362,8 +385,8 @@ zconf: $(SRCDIR)zconf.h.in + mostlyclean: clean + clean: + rm -f *.o *.lo *~ \ +- example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ +- example64$(EXE) minigzip64$(EXE) \ ++ crc32_test$(EXE) example$(EXE) minigzip$(EXE) crc32_testsh$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ ++ crc32_test64$(EXE) example64$(EXE) minigzip64$(EXE) \ + infcover \ + libz.* foo.gz so_locations \ + _match.s maketree contrib/infback9/*.o +@@ -385,7 +408,7 @@ tags: + + adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h + gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h +-compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h ++compress.o crc32_test.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h + crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h + deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h + infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h +@@ -395,7 +418,7 @@ trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)tr + + adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h + gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h +-compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h ++compress.lo crc32_test.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h + crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h + deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h + infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h +diff --git a/configure b/configure +index 9ee7008c3..45d51e596 100755 +--- a/configure ++++ b/configure +@@ -858,6 +858,9 @@ cat > $test.c < + pascal/ by Bob Dellaca et al. + Support for Pascal + +-power/ by Matheus Castanho ++power/ by Daniel Black ++ Matheus Castanho + and Rogerio Alves + Optimized functions for Power processors + diff --git a/contrib/power/clang_workaround.h b/contrib/power/clang_workaround.h new file mode 100644 -index 000000000..915f7e528 +index 000000000..b5e7dae01 --- /dev/null +++ b/contrib/power/clang_workaround.h -@@ -0,0 +1,87 @@ +@@ -0,0 +1,82 @@ +#ifndef CLANG_WORKAROUNDS_H +#define CLANG_WORKAROUNDS_H + @@ -486,12 +583,7 @@ index 000000000..915f7e528 + return __v; +} + -+/* -+ * Clang 7 changed the behavior of vec_xxpermdi in order to provide the same -+ * behavior of GCC. That means code adapted to Clang >= 7 does not work on -+ * Clang <= 6. So, fallback to __builtin_unpack_vector() on Clang <= 6. -+ */ -+#if !defined vec_xxpermdi || __clang_major__ <= 6 ++#ifndef vec_xxpermdi + +static inline +unsigned long __builtin_unpack_vector (__vector unsigned long long __v, @@ -514,9 +606,9 @@ index 000000000..915f7e528 +unsigned long __builtin_unpack_vector_0 (__vector unsigned long long __v) +{ + #if defined(__BIG_ENDIAN__) -+ return vec_xxpermdi(__v, __v, 0x0)[0]; ++ return vec_xxpermdi(__v, __v, 0x0)[1]; + #else -+ return vec_xxpermdi(__v, __v, 0x3)[0]; ++ return vec_xxpermdi(__v, __v, 0x0)[0]; + #endif +} + @@ -524,9 +616,9 @@ index 000000000..915f7e528 +unsigned long __builtin_unpack_vector_1 (__vector unsigned long long __v) +{ + #if defined(__BIG_ENDIAN__) -+ return vec_xxpermdi(__v, __v, 0x3)[0]; ++ return vec_xxpermdi(__v, __v, 0x3)[1]; + #else -+ return vec_xxpermdi(__v, __v, 0x0)[0]; ++ return vec_xxpermdi(__v, __v, 0x3)[0]; + #endif +} +#endif /* vec_xxpermdi */ @@ -2451,24 +2543,22 @@ index 000000000..f4e9aa491 + return crc32_z_default; +} diff --git a/contrib/power/power.h b/contrib/power/power.h -new file mode 100644 -index 000000000..79123aa90 ---- /dev/null +index b42c7d6c6..79123aa90 100644 +--- a/contrib/power/power.h +++ b/contrib/power/power.h -@@ -0,0 +1,8 @@ -+/* Copyright (C) 2019 Matheus Castanho , IBM -+ * 2019 Rogerio Alves , IBM -+ * For conditions of distribution and use, see copyright notice in zlib.h -+ */ +@@ -2,3 +2,7 @@ + * 2019 Rogerio Alves , IBM + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zconf.h" + +unsigned long _crc32_z_power8(unsigned long, const Bytef *, z_size_t); diff --git a/crc32.c b/crc32.c -index a1bdce5c2..ae7b7e792 100644 +index f8357b083..4e5830b86 100644 --- a/crc32.c +++ b/crc32.c -@@ -736,6 +736,13 @@ local z_word_t crc_word_big(data) +@@ -745,6 +745,13 @@ local z_word_t crc_word_big(data) #endif /* ========================================================================= */ @@ -2482,7 +2572,7 @@ index a1bdce5c2..ae7b7e792 100644 unsigned long ZEXPORT crc32_z(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; -@@ -1057,6 +1064,11 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) +@@ -1066,6 +1073,11 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) return crc ^ 0xffffffff; } @@ -2705,3 +2795,2219 @@ index 000000000..3155553e6 + } + return 0; +} + +From 8ef06a3a9f26205a08a12c324665d5620662264f Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Wed, 25 Mar 2020 12:16:41 -0300 +Subject: [PATCH 3/4] Fix clang's behavior on versions >= 7 + +Clang 7 changed the behavior of vec_xxpermdi in order to match GCC's +behavior. After this change, code that used to work on Clang 6 stopped +to work on Clang >= 7. + +Tested on Clang 6, 7, 8 and 9. + +Reference: https://bugs.llvm.org/show_bug.cgi?id=38192 + +Signed-off-by: Tulio Magno Quites Machado Filho +--- + contrib/power/clang_workaround.h | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/contrib/power/clang_workaround.h b/contrib/power/clang_workaround.h +index b5e7dae01..915f7e528 100644 +--- a/contrib/power/clang_workaround.h ++++ b/contrib/power/clang_workaround.h +@@ -39,7 +39,12 @@ __vector unsigned long long __builtin_pack_vector (unsigned long __a, + return __v; + } + +-#ifndef vec_xxpermdi ++/* ++ * Clang 7 changed the behavior of vec_xxpermdi in order to provide the same ++ * behavior of GCC. That means code adapted to Clang >= 7 does not work on ++ * Clang <= 6. So, fallback to __builtin_unpack_vector() on Clang <= 6. ++ */ ++#if !defined vec_xxpermdi || __clang_major__ <= 6 + + static inline + unsigned long __builtin_unpack_vector (__vector unsigned long long __v, +@@ -62,9 +67,9 @@ static inline + unsigned long __builtin_unpack_vector_0 (__vector unsigned long long __v) + { + #if defined(__BIG_ENDIAN__) +- return vec_xxpermdi(__v, __v, 0x0)[1]; +- #else + return vec_xxpermdi(__v, __v, 0x0)[0]; ++ #else ++ return vec_xxpermdi(__v, __v, 0x3)[0]; + #endif + } + +@@ -72,9 +77,9 @@ static inline + unsigned long __builtin_unpack_vector_1 (__vector unsigned long long __v) + { + #if defined(__BIG_ENDIAN__) +- return vec_xxpermdi(__v, __v, 0x3)[1]; +- #else + return vec_xxpermdi(__v, __v, 0x3)[0]; ++ #else ++ return vec_xxpermdi(__v, __v, 0x0)[0]; + #endif + } + #endif /* vec_xxpermdi */ + +From 113203437eda67261848b14b6c80a33ff7e33d34 Mon Sep 17 00:00:00 2001 +From: Ilya Leoshkevich +Date: Wed, 18 Jul 2018 13:14:07 +0200 +Subject: [PATCH 4/4] Add support for IBM Z hardware-accelerated deflate + +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 patch adds DFLTCC support to zlib. 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. + +Two DFLTCC compression calls produce the same results only when they +both are made on machines of the same generation, and when the +respective buffers have the same offset relative to the start of the +page. Therefore care should be taken when using hardware compression +when reproducible results are desired. One such use case - reproducible +software builds - is handled explicitly: when SOURCE_DATE_EPOCH +environment variable is set, the hardware compression is disabled. + +DFLTCC does not support every single zlib feature, in particular: + + * inflate(Z_BLOCK) and inflate(Z_TREES) + * inflateMark() + * inflatePrime() + * 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 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 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 +doubleword-aligned, and it's reasonable to allocate it alongside +deflate and inflate states, ZALLOC_STATE, ZFREE_STATE and ZCOPY_STATE +macros were introduced in order to encapsulate the allocation details. +The same is true for window, for which ZALLOC_WINDOW and +TRY_FREE_WINDOW macros were introduced. + +Software and hardware window formats do not match, therefore, +deflateSetDictionary(), deflateGetDictionary(), inflateSetDictionary() +and inflateGetDictionary() need special handling, which is triggered +using DEFLATE_SET_DICTIONARY_HOOK, DEFLATE_GET_DICTIONARY_HOOK, +INFLATE_SET_DICTIONARY_HOOK and INFLATE_GET_DICTIONARY_HOOK macros. + +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. + +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 +return the correct results for the hardware implementation, the new +DEFLATE_BOUND_ADJUST_COMPLEN and DEFLATE_NEED_CONSERVATIVE_BOUND macros +were introduced. + +Actual compression and decompression are handled by the new DEFLATE_HOOK +and INFLATE_TYPEDO_HOOK macros. Since inflation with DFLTCC manages the +window on its own, calling updatewindow() is suppressed using the new +INFLATE_NEED_UPDATEWINDOW() macro. + +In addition to compression, DFLTCC computes CRC-32 and Adler-32 +checksums, therefore, whenever it's used, software checksumming needs to +be suppressed using the new DEFLATE_NEED_CHECKSUM and +INFLATE_NEED_CHECKSUM macros. + +DFLTCC will refuse to write an End-of-block Symbol if there is no input +data, thus in some cases it is necessary to do this manually. In order +to achieve this, send_bits, bi_reverse, bi_windup and flush_pending +were promoted from local to ZLIB_INTERNAL. Furthermore, since block and +stream termination must be handled in software as well, block_state enum +was moved to deflate.h. + +Since the first call to dfltcc_inflate already needs the window, and it +might be not allocated yet, inflate_ensure_window was factored out of +updatewindow and made ZLIB_INTERNAL. +--- + Makefile.in | 8 + + compress.c | 14 +- + configure | 24 + + contrib/README.contrib | 4 + + contrib/s390/README.txt | 17 + + contrib/s390/dfltcc.c | 1089 +++++++++++++++++++++++++++++++++ + contrib/s390/dfltcc.h | 100 +++ + contrib/s390/dfltcc_deflate.h | 55 ++ + deflate.c | 82 ++- + deflate.h | 12 + + gzguts.h | 4 + + inflate.c | 97 ++- + inflate.h | 2 + + test/infcover.c | 4 +- + test/minigzip.c | 4 + + trees.c | 13 +- + zutil.h | 2 + + 17 files changed, 1469 insertions(+), 62 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 83d8ca47d..54c529b3b 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -139,6 +139,14 @@ match.lo: match.S + mv _match.o match.lo + rm -f _match.s + ++dfltcc.o: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h ++ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)contrib/s390/dfltcc.c ++ ++dfltcc.lo: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h ++ -@mkdir objs 2>/dev/null || test -d objs ++ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/dfltcc.o $(SRCDIR)contrib/s390/dfltcc.c ++ -@mv objs/dfltcc.o $@ ++ + crc32_test.o: $(SRCDIR)test/crc32_test.c $(SRCDIR)zlib.h zconf.h + $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/crc32_test.c + +diff --git a/compress.c b/compress.c +index 2ad5326c1..179ee2773 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 45d51e596..ab3204a6d 100755 +--- a/configure ++++ b/configure +@@ -118,6 +118,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 ;; +@@ -142,6 +143,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 +@@ -828,6 +839,19 @@ EOF + fi + fi + ++# Check whether sys/sdt.h is available ++cat > $test.c << EOF ++#include ++int main() { return 0; } ++EOF ++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" ++else ++ echo "Checking for sys/sdt.h ... No." | tee -a configure.log ++fi ++ + # test to see if we can use a gnu indirection function to detect and load optimized code at runtime + echo >> configure.log + cat > $test.c < + Small, low memory usage inflate. Also serves to provide an + unambiguous description of the deflate format. + ++s390/ by Ilya Leoshkevich ++ Hardware-accelerated deflate on IBM Z with DEFLATE CONVERSION CALL ++ instruction. ++ + 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 000000000..b8c20bded +--- /dev/null ++++ b/contrib/s390/dfltcc.c +@@ -0,0 +1,1089 @@ ++/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ ++ ++/* ++ Use the following commands to build zlib with DFLTCC support: ++ ++ $ ./configure --dfltcc ++ $ make ++*/ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../../zutil.h" ++#include "../../deflate.h" ++#include "../../inftrees.h" ++#include "../../inflate.h" ++#include "dfltcc.h" ++#include "dfltcc_deflate.h" ++#ifdef HAVE_SYS_SDT_H ++#include ++#endif ++ ++/* ++ C wrapper for the DEFLATE CONVERSION CALL instruction. ++ */ ++typedef enum { ++ DFLTCC_CC_OK = 0, ++ DFLTCC_CC_OP1_TOO_SHORT = 1, ++ DFLTCC_CC_OP2_TOO_SHORT = 2, ++ DFLTCC_CC_OP2_CORRUPT = 2, ++ DFLTCC_CC_AGAIN = 3, ++} dfltcc_cc; ++ ++#define DFLTCC_QAF 0 ++#define DFLTCC_GDHT 1 ++#define DFLTCC_CMPR 2 ++#define DFLTCC_XPND 4 ++#define HBT_CIRCULAR (1 << 7) ++#define HB_BITS 15 ++#define HB_SIZE (1 << HB_BITS) ++#define DFLTCC_FACILITY 151 ++ ++local inline dfltcc_cc dfltcc OF((int fn, void *param, ++ Bytef **op1, size_t *len1, ++ z_const Bytef **op2, size_t *len2, ++ void *hist)); ++local inline dfltcc_cc dfltcc(fn, param, op1, len1, op2, len2, hist) ++ int fn; ++ void *param; ++ Bytef **op1; ++ size_t *len1; ++ z_const Bytef **op2; ++ size_t *len2; ++ void *hist; ++{ ++ Bytef *t2 = op1 ? *op1 : NULL; ++ size_t t3 = len1 ? *len1 : 0; ++ z_const Bytef *t4 = op2 ? *op2 : NULL; ++ size_t t5 = len2 ? *len2 : 0; ++ register int r0 __asm__("r0") = fn; ++ register void *r1 __asm__("r1") = param; ++ register Bytef *r2 __asm__("r2") = t2; ++ register size_t r3 __asm__("r3") = t3; ++ register z_const Bytef *r4 __asm__("r4") = t4; ++ register size_t r5 __asm__("r5") = t5; ++ int cc; ++ ++ __asm__ volatile( ++#ifdef HAVE_SYS_SDT_H ++ STAP_PROBE_ASM(zlib, dfltcc_entry, ++ STAP_PROBE_ASM_TEMPLATE(5)) ++#endif ++ ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n" ++#ifdef HAVE_SYS_SDT_H ++ STAP_PROBE_ASM(zlib, dfltcc_exit, ++ STAP_PROBE_ASM_TEMPLATE(5)) ++#endif ++ "ipm %[cc]\n" ++ : [r2] "+r" (r2) ++ , [r3] "+r" (r3) ++ , [r4] "+r" (r4) ++ , [r5] "+r" (r5) ++ , [cc] "=r" (cc) ++ : [r0] "r" (r0) ++ , [r1] "r" (r1) ++ , [hist] "r" (hist) ++#ifdef HAVE_SYS_SDT_H ++ , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist) ++#endif ++ : "cc", "memory"); ++ t2 = r2; t3 = r3; t4 = r4; t5 = r5; ++ ++ if (op1) ++ *op1 = t2; ++ if (len1) ++ *len1 = t3; ++ if (op2) ++ *op2 = t4; ++ if (len2) ++ *len2 = t5; ++ return (cc >> 28) & 3; ++} ++ ++/* ++ Parameter Block for Query Available Functions. ++ */ ++#define static_assert(c, msg) \ ++ __attribute__((unused)) \ ++ static char static_assert_failed_ ## msg[c ? 1 : -1] ++ ++struct dfltcc_qaf_param { ++ char fns[16]; ++ char reserved1[8]; ++ char fmts[2]; ++ char reserved2[6]; ++}; ++ ++static_assert(sizeof(struct dfltcc_qaf_param) == 32, ++ sizeof_struct_dfltcc_qaf_param_is_32); ++ ++local inline int is_bit_set OF((const char *bits, int n)); ++local inline int is_bit_set(bits, n) ++ const char *bits; ++ int n; ++{ ++ return bits[n / 8] & (1 << (7 - (n % 8))); ++} ++ ++local inline void clear_bit OF((char *bits, int n)); ++local inline void clear_bit(bits, n) ++ char *bits; ++ int n; ++{ ++ bits[n / 8] &= ~(1 << (7 - (n % 8))); ++} ++ ++#define DFLTCC_FMT0 0 ++ ++/* ++ Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand. ++ */ ++#define CVT_CRC32 0 ++#define CVT_ADLER32 1 ++#define HTT_FIXED 0 ++#define HTT_DYNAMIC 1 ++ ++struct dfltcc_param_v0 { ++ uint16_t pbvn; /* Parameter-Block-Version Number */ ++ uint8_t mvn; /* Model-Version Number */ ++ uint8_t ribm; /* Reserved for IBM use */ ++ unsigned reserved32 : 31; ++ unsigned cf : 1; /* Continuation Flag */ ++ uint8_t reserved64[8]; ++ unsigned nt : 1; /* New Task */ ++ unsigned reserved129 : 1; ++ unsigned cvt : 1; /* Check Value Type */ ++ unsigned reserved131 : 1; ++ unsigned htt : 1; /* Huffman-Table Type */ ++ unsigned bcf : 1; /* Block-Continuation Flag */ ++ unsigned bcc : 1; /* Block Closing Control */ ++ unsigned bhf : 1; /* Block Header Final */ ++ unsigned reserved136 : 1; ++ unsigned reserved137 : 1; ++ unsigned dhtgc : 1; /* DHT Generation Control */ ++ unsigned reserved139 : 5; ++ unsigned reserved144 : 5; ++ unsigned sbb : 3; /* Sub-Byte Boundary */ ++ uint8_t oesc; /* Operation-Ending-Supplemental Code */ ++ unsigned reserved160 : 12; ++ unsigned ifs : 4; /* Incomplete-Function Status */ ++ uint16_t ifl; /* Incomplete-Function Length */ ++ uint8_t reserved192[8]; ++ uint8_t reserved256[8]; ++ uint8_t reserved320[4]; ++ uint16_t hl; /* History Length */ ++ unsigned reserved368 : 1; ++ uint16_t ho : 15; /* History Offset */ ++ uint32_t cv; /* Check Value */ ++ unsigned eobs : 15; /* End-of-block Symbol */ ++ unsigned reserved431: 1; ++ uint8_t eobl : 4; /* End-of-block Length */ ++ unsigned reserved436 : 12; ++ unsigned reserved448 : 4; ++ uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table ++ Length */ ++ uint8_t reserved464[6]; ++ uint8_t cdht[288]; ++ uint8_t reserved[32]; ++ uint8_t csb[1152]; ++}; ++ ++static_assert(sizeof(struct dfltcc_param_v0) == 1536, ++ sizeof_struct_dfltcc_param_v0_is_1536); ++ ++local z_const char *oesc_msg OF((char *buf, int oesc)); ++local z_const char *oesc_msg(buf, oesc) ++ char *buf; ++ int oesc; ++{ ++ if (oesc == 0x00) ++ return NULL; /* Successful completion */ ++ else { ++ sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc); ++ return buf; ++ } ++} ++ ++/* ++ Extension of inflate_state and deflate_state. Must be doubleword-aligned. ++*/ ++struct dfltcc_state { ++ struct dfltcc_param_v0 param; /* Parameter block. */ ++ struct dfltcc_qaf_param af; /* Available functions. */ ++ uLong level_mask; /* Levels on which to use DFLTCC */ ++ uLong block_size; /* New block each X bytes */ ++ uLong block_threshold; /* New block after total_in > X */ ++ uLong dht_threshold; /* New block only if avail_in >= X */ ++ char msg[64]; /* Buffer for strm->msg */ ++}; ++ ++#define ALIGN_UP(p, size) \ ++ (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1)) ++ ++#define GET_DFLTCC_STATE(state) ((struct dfltcc_state FAR *)( \ ++ (char FAR *)(state) + ALIGN_UP(sizeof(*state), 8))) ++ ++/* ++ Compress. ++ */ ++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; ++{ ++ deflate_state FAR *state = (deflate_state FAR *)strm->state; ++ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); ++ ++ /* Unsupported compression settings */ ++ 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 */ ++ if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) || ++ !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) || ++ !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0)) ++ return 0; ++ ++ 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; ++{ ++ deflate_state FAR *state = (deflate_state FAR *)strm->state; ++ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; ++ size_t avail_in = avail_in = strm->avail_in; ++ ++ dfltcc(DFLTCC_GDHT, ++ param, NULL, NULL, ++ &strm->next_in, &avail_in, NULL); ++} ++ ++local dfltcc_cc dfltcc_cmpr OF((z_streamp strm)); ++local dfltcc_cc dfltcc_cmpr(strm) ++ z_streamp strm; ++{ ++ deflate_state FAR *state = (deflate_state FAR *)strm->state; ++ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; ++ size_t avail_in = strm->avail_in; ++ size_t avail_out = strm->avail_out; ++ dfltcc_cc cc; ++ ++ cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR, ++ param, &strm->next_out, &avail_out, ++ &strm->next_in, &avail_in, state->window); ++ strm->total_in += (strm->avail_in - avail_in); ++ strm->total_out += (strm->avail_out - avail_out); ++ strm->avail_in = avail_in; ++ strm->avail_out = avail_out; ++ return cc; ++} ++ ++local void send_eobs OF((z_streamp strm, ++ z_const struct dfltcc_param_v0 FAR *param)); ++local void send_eobs(strm, param) ++ z_streamp strm; ++ z_const struct dfltcc_param_v0 FAR *param; ++{ ++ deflate_state FAR *state = (deflate_state FAR *)strm->state; ++ ++ _tr_send_bits( ++ state, ++ bi_reverse(param->eobs >> (15 - param->eobl), param->eobl), ++ param->eobl); ++ flush_pending(strm); ++ if (state->pending != 0) { ++ /* The remaining data is located in pending_out[0:pending]. If someone ++ * calls put_byte() - this might happen in deflate() - the byte will be ++ * placed into pending_buf[pending], which is incorrect. Move the ++ * remaining data to the beginning of pending_buf so that put_byte() is ++ * usable again. ++ */ ++ memmove(state->pending_buf, state->pending_out, state->pending); ++ state->pending_out = state->pending_buf; ++ } ++#ifdef ZLIB_DEBUG ++ state->compressed_len += param->eobl; ++#endif ++} ++ ++int ZLIB_INTERNAL dfltcc_deflate(strm, flush, result) ++ z_streamp strm; ++ int flush; ++ block_state *result; ++{ ++ 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; ++ uInt masked_avail_in; ++ dfltcc_cc cc; ++ int need_empty_block; ++ int soft_bcc; ++ int no_flush; ++ ++ 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; ++ ++ /* 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 (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; ++ } ++ /* 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; ++ } ++ ++ /* There is an open non-BFINAL block, we are not going to close it just ++ * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see ++ * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new ++ * DHT in order to adapt to a possibly changed input data distribution. ++ */ ++ if (param->bcf && no_flush && ++ strm->total_in > dfltcc_state->block_threshold && ++ strm->avail_in >= dfltcc_state->dht_threshold) { ++ if (param->cf) { ++ /* We need to flush the DFLTCC buffer before writing the ++ * End-of-block Symbol. Mask the input data and proceed as usual. ++ */ ++ masked_avail_in += strm->avail_in; ++ strm->avail_in = 0; ++ no_flush = 0; ++ } else { ++ /* DFLTCC buffer is empty, so we can manually write the ++ * End-of-block Symbol right away. ++ */ ++ send_eobs(strm, param); ++ param->bcf = 0; ++ dfltcc_state->block_threshold = ++ strm->total_in + dfltcc_state->block_size; ++ } ++ } ++ ++ /* 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. ++ */ ++ if (no_flush && strm->avail_in > dfltcc_state->block_size) { ++ masked_avail_in += (strm->avail_in - dfltcc_state->block_size); ++ strm->avail_in = dfltcc_state->block_size; ++ } ++ ++ /* When we have an open non-BFINAL deflate block and caller indicates that ++ * the stream is ending, we need to close an open deflate block and open a ++ * BFINAL one. ++ */ ++ need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf; ++ ++ /* Translate stream to parameter block */ ++ 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 honor BCC. */ ++ soft_bcc = 1; ++ if (flush == Z_FINISH && !param->bcf) ++ /* We are about to open a BFINAL block, set Block Header Final bit ++ * until the stream ends. ++ */ ++ param->bhf = 1; ++ /* DFLTCC-CMPR will write to next_out, so make sure that buffers with ++ * higher precedence are empty. ++ */ ++ Assert(state->pending == 0, "There must be no pending bytes"); ++ Assert(state->bi_valid < 8, "There must be less than 8 pending bits"); ++ param->sbb = (unsigned int)state->bi_valid; ++ if (param->sbb > 0) ++ *strm->next_out = (Bytef)state->bi_buf; ++ /* Honor history and check value */ ++ param->nt = 0; ++ if (state->wrap == 1) ++ param->cv = strm->adler; ++ else if (state->wrap == 2) ++ param->cv = ZSWAP32(strm->adler); ++ ++ /* When opening a block, choose a Huffman-Table Type */ ++ if (!param->bcf) { ++ if (state->strategy == Z_FIXED || ++ (strm->total_in == 0 && dfltcc_state->block_threshold > 0)) ++ param->htt = HTT_FIXED; ++ else { ++ param->htt = HTT_DYNAMIC; ++ dfltcc_gdht(strm); ++ } ++ } ++ ++ /* Deflate */ ++ do { ++ cc = dfltcc_cmpr(strm); ++ if (strm->avail_in < 4096 && masked_avail_in > 0) ++ /* We are about to call DFLTCC with a small input buffer, which is ++ * inefficient. Since there is masked data, there will be at least ++ * one more DFLTCC call, so skip the current one and make the next ++ * one handle more data. ++ */ ++ break; ++ } while (cc == DFLTCC_CC_AGAIN); ++ ++ /* Translate parameter block to stream */ ++ strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); ++ state->bi_valid = param->sbb; ++ if (state->bi_valid == 0) ++ state->bi_buf = 0; /* Avoid accessing next_out */ ++ else ++ state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1); ++ if (state->wrap == 1) ++ strm->adler = param->cv; ++ else if (state->wrap == 2) ++ strm->adler = ZSWAP32(param->cv); ++ ++ /* Unmask the input data */ ++ strm->avail_in += masked_avail_in; ++ masked_avail_in = 0; ++ ++ /* If we encounter an error, it means there is a bug in DFLTCC call */ ++ Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG"); ++ ++ /* Update Block-Continuation Flag. It will be used to check whether to call ++ * GDHT the next time. ++ */ ++ if (cc == DFLTCC_CC_OK) { ++ if (soft_bcc) { ++ send_eobs(strm, param); ++ param->bcf = 0; ++ dfltcc_state->block_threshold = ++ strm->total_in + dfltcc_state->block_size; ++ } else ++ param->bcf = 1; ++ if (flush == Z_FINISH) { ++ if (need_empty_block) ++ /* Make the current deflate() call also close the stream */ ++ return 0; ++ else { ++ bi_windup(state); ++ *result = finish_done; ++ } ++ } else { ++ if (flush == Z_FULL_FLUSH) ++ param->hl = 0; /* Clear history */ ++ *result = flush == Z_NO_FLUSH ? need_more : block_done; ++ } ++ } else { ++ param->bcf = 1; ++ *result = need_more; ++ } ++ if (strm->avail_in != 0 && strm->avail_out != 0) ++ goto again; /* deflate() must use all input or all output */ ++ return 1; ++} ++ ++/* ++ Expand. ++ */ ++int ZLIB_INTERNAL dfltcc_can_inflate(strm) ++ z_streamp strm; ++{ ++ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; ++ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); ++ ++ /* Unsupported hardware */ ++ return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) && ++ is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0); ++} ++ ++local dfltcc_cc dfltcc_xpnd OF((z_streamp strm)); ++local dfltcc_cc dfltcc_xpnd(strm) ++ z_streamp strm; ++{ ++ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; ++ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; ++ size_t avail_in = strm->avail_in; ++ size_t avail_out = strm->avail_out; ++ dfltcc_cc cc; ++ ++ cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR, ++ param, &strm->next_out, &avail_out, ++ &strm->next_in, &avail_in, state->window); ++ strm->avail_in = avail_in; ++ strm->avail_out = avail_out; ++ return cc; ++} ++ ++dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate(strm, flush, ret) ++ z_streamp strm; ++ int flush; ++ int *ret; ++{ ++ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; ++ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); ++ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; ++ dfltcc_cc cc; ++ ++ if (flush == Z_BLOCK || flush == Z_TREES) { ++ /* DFLTCC does not support stopping on block boundaries */ ++ if (dfltcc_inflate_disable(strm)) { ++ *ret = Z_STREAM_ERROR; ++ return DFLTCC_INFLATE_BREAK; ++ } else ++ return DFLTCC_INFLATE_SOFTWARE; ++ } ++ ++ if (state->last) { ++ if (state->bits != 0) { ++ strm->next_in++; ++ strm->avail_in--; ++ state->bits = 0; ++ } ++ state->mode = CHECK; ++ return DFLTCC_INFLATE_CONTINUE; ++ } ++ ++ if (strm->avail_in == 0 && !param->cf) ++ return DFLTCC_INFLATE_BREAK; ++ ++ if (inflate_ensure_window(state)) { ++ state->mode = MEM; ++ return DFLTCC_INFLATE_CONTINUE; ++ } ++ ++ /* Translate stream to parameter block */ ++ param->cvt = ((state->wrap & 4) && state->flags) ? CVT_CRC32 : CVT_ADLER32; ++ param->sbb = state->bits; ++ if (param->hl) ++ param->nt = 0; /* Honor history for the first block */ ++ if (state->wrap & 4) ++ param->cv = state->flags ? ZSWAP32(state->check) : state->check; ++ ++ /* Inflate */ ++ do { ++ cc = dfltcc_xpnd(strm); ++ } while (cc == DFLTCC_CC_AGAIN); ++ ++ /* Translate parameter block to stream */ ++ strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); ++ state->last = cc == DFLTCC_CC_OK; ++ state->bits = param->sbb; ++ if (state->wrap & 4) ++ strm->adler = state->check = state->flags ? ++ ZSWAP32(param->cv) : param->cv; ++ if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { ++ /* Report an error if stream is corrupted */ ++ state->mode = BAD; ++ return DFLTCC_INFLATE_CONTINUE; ++ } ++ state->mode = TYPEDO; ++ /* Break if operands are exhausted, otherwise continue looping */ ++ return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ? ++ DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE; ++} ++ ++int ZLIB_INTERNAL dfltcc_was_inflate_used(strm) ++ z_streamp strm; ++{ ++ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; ++ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param; ++ ++ return !param->nt; ++} ++ ++/* ++ Rotates a circular buffer. ++ The implementation is based on https://cplusplus.com/reference/algorithm/rotate/ ++ */ ++local void rotate OF((Bytef *start, Bytef *pivot, Bytef *end)); ++local void rotate(start, pivot, end) ++ Bytef *start; ++ Bytef *pivot; ++ Bytef *end; ++{ ++ Bytef *p = pivot; ++ Bytef tmp; ++ ++ while (p != start) { ++ tmp = *start; ++ *start = *p; ++ *p = tmp; ++ ++ start++; ++ p++; ++ ++ if (p == end) ++ p = pivot; ++ else if (start == pivot) ++ pivot = p; ++ } ++} ++ ++#define MIN(x, y) ({ \ ++ typeof(x) _x = (x); \ ++ typeof(y) _y = (y); \ ++ _x < _y ? _x : _y; \ ++}) ++ ++#define MAX(x, y) ({ \ ++ typeof(x) _x = (x); \ ++ typeof(y) _y = (y); \ ++ _x > _y ? _x : _y; \ ++}) ++ ++int ZLIB_INTERNAL dfltcc_inflate_disable(strm) ++ z_streamp strm; ++{ ++ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; ++ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); ++ struct dfltcc_param_v0 *param = &dfltcc_state->param; ++ ++ if (!dfltcc_can_inflate(strm)) ++ return 0; ++ if (dfltcc_was_inflate_used(strm)) ++ /* DFLTCC has already decompressed some data. Since there is not ++ * enough information to resume decompression in software, the call ++ * must fail. ++ */ ++ return 1; ++ /* DFLTCC was not used yet - decompress in software */ ++ memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); ++ /* Convert the window from the hardware to the software format */ ++ rotate(state->window, state->window + param->ho, state->window + HB_SIZE); ++ state->whave = state->wnext = MIN(param->hl, state->wsize); ++ 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 *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. ++*/ ++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)); ++ ++ memcpy(&dfltcc_state->af, &cpu_af, sizeof(dfltcc_state->af)); ++ ++ if (env_source_date_epoch) ++ /* User needs reproducible results, but the output of DFLTCC_CMPR ++ * depends on buffers' page offsets. ++ */ ++ clear_bit(dfltcc_state->af.fns, DFLTCC_CMPR); ++ ++ /* Initialize parameter block */ ++ memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param)); ++ dfltcc_state->param.nt = 1; ++ ++ /* Initialize tuning parameters */ ++ 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) ++ z_streamp strm; ++ uInt items; ++ uInt size; ++{ ++ return ZALLOC(strm, ++ ALIGN_UP(items * size, 8) + sizeof(struct dfltcc_state), ++ sizeof(unsigned char)); ++} ++ ++void ZLIB_INTERNAL dfltcc_copy_state(dst, src, size) ++ voidpf dst; ++ const voidpf src; ++ uInt size; ++{ ++ zmemcpy(dst, src, ALIGN_UP(size, 8) + sizeof(struct dfltcc_state)); ++} ++ ++static const int PAGE_ALIGN = 0x1000; ++ ++voidpf ZLIB_INTERNAL dfltcc_alloc_window(strm, items, size) ++ z_streamp strm; ++ uInt items; ++ uInt size; ++{ ++ voidpf p, w; ++ ++ /* To simplify freeing, we store the pointer to the allocated buffer right ++ * before the window. Note that DFLTCC always uses HB_SIZE bytes. ++ */ ++ p = ZALLOC(strm, sizeof(voidpf) + MAX(items * size, HB_SIZE) + PAGE_ALIGN, ++ sizeof(unsigned char)); ++ if (p == NULL) ++ return NULL; ++ w = ALIGN_UP((char FAR *)p + sizeof(voidpf), PAGE_ALIGN); ++ *(voidpf *)((char FAR *)w - sizeof(voidpf)) = p; ++ return w; ++} ++ ++void ZLIB_INTERNAL dfltcc_copy_window(dest, src, n) ++ void *dest; ++ const void *src; ++ size_t n; ++{ ++ memcpy(dest, src, MAX(n, HB_SIZE)); ++} ++ ++void ZLIB_INTERNAL dfltcc_free_window(strm, w) ++ z_streamp strm; ++ voidpf w; ++{ ++ if (w) ++ ZFREE(strm, *(voidpf *)((unsigned char FAR *)w - sizeof(voidpf))); ++} ++ ++/* ++ 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, 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_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 */ ++ return Z_OK; ++ ++ if (strm->total_in == 0 && param->nt == 1 && param->hl == 0) ++ /* DFLTCC was not used yet - no changes needed */ ++ return Z_OK; ++ ++ /* 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); ++} ++ ++/* ++ Preloading history. ++*/ ++local void append_history OF((struct dfltcc_param_v0 FAR *param, ++ Bytef *history, ++ const Bytef *buf, ++ uInt count)); ++local void append_history(param, history, buf, count) ++ struct dfltcc_param_v0 FAR *param; ++ Bytef *history; ++ const Bytef *buf; ++ uInt count; ++{ ++ size_t offset; ++ size_t n; ++ ++ /* Do not use more than 32K */ ++ if (count > HB_SIZE) { ++ buf += count - HB_SIZE; ++ count = HB_SIZE; ++ } ++ offset = (param->ho + param->hl) % HB_SIZE; ++ if (offset + count <= HB_SIZE) ++ /* Circular history buffer does not wrap - copy one chunk */ ++ zmemcpy(history + offset, buf, count); ++ else { ++ /* Circular history buffer wraps - copy two chunks */ ++ n = HB_SIZE - offset; ++ zmemcpy(history + offset, buf, n); ++ zmemcpy(history, buf + n, count - n); ++ } ++ n = param->hl + count; ++ if (n <= HB_SIZE) ++ /* All history fits into buffer - no need to discard anything */ ++ param->hl = n; ++ else { ++ /* History does not fit into buffer - discard extra bytes */ ++ param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE; ++ param->hl = HB_SIZE; ++ } ++} ++ ++local void get_history OF((struct dfltcc_param_v0 FAR *param, ++ const Bytef *history, ++ Bytef *buf)); ++local void get_history(param, history, buf) ++ struct dfltcc_param_v0 FAR *param; ++ const Bytef *history; ++ Bytef *buf; ++{ ++ if (param->ho + param->hl <= HB_SIZE) ++ /* Circular history buffer does not wrap - copy one chunk */ ++ memcpy(buf, history + param->ho, param->hl); ++ else { ++ /* Circular history buffer wraps - copy two chunks */ ++ memcpy(buf, history + param->ho, HB_SIZE - param->ho); ++ memcpy(buf + HB_SIZE - param->ho, history, param->ho + param->hl - HB_SIZE); ++ } ++} ++ ++int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length) ++ z_streamp strm; ++ const Bytef *dictionary; ++ uInt dict_length; ++{ ++ 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; ++ ++ 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; ++} ++ ++int ZLIB_INTERNAL dfltcc_deflate_get_dictionary(strm, dictionary, dict_length) ++ z_streamp strm; ++ Bytef *dictionary; ++ uInt *dict_length; ++{ ++ 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; ++ ++ if (dictionary) ++ get_history(param, state->window, dictionary); ++ if (dict_length) ++ *dict_length = param->hl; ++ return Z_OK; ++} ++ ++int ZLIB_INTERNAL dfltcc_inflate_set_dictionary(strm, dictionary, dict_length) ++ z_streamp strm; ++ const Bytef *dictionary; ++ uInt dict_length; ++{ ++ struct inflate_state *state = (struct inflate_state *)strm->state; ++ struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); ++ struct dfltcc_param_v0 *param = &dfltcc_state->param; ++ ++ if (inflate_ensure_window(state)) { ++ state->mode = MEM; ++ return Z_MEM_ERROR; ++ } ++ ++ append_history(param, state->window, dictionary, dict_length); ++ state->havedict = 1; ++ return Z_OK; ++} ++ ++int ZLIB_INTERNAL dfltcc_inflate_get_dictionary(strm, dictionary, dict_length) ++ z_streamp strm; ++ Bytef *dictionary; ++ uInt *dict_length; ++{ ++ struct inflate_state *state = (struct inflate_state *)strm->state; ++ struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); ++ struct dfltcc_param_v0 *param = &dfltcc_state->param; ++ ++ if (dictionary && state->window) ++ get_history(param, state->window, dictionary); ++ if (dict_length) ++ *dict_length = param->hl; ++ return Z_OK; ++} +diff --git a/contrib/s390/dfltcc.h b/contrib/s390/dfltcc.h +new file mode 100644 +index 000000000..be28b8ad4 +--- /dev/null ++++ b/contrib/s390/dfltcc.h +@@ -0,0 +1,100 @@ ++#ifndef DFLTCC_H ++#define DFLTCC_H ++ ++#include "../../zlib.h" ++#include "../../zutil.h" ++ ++voidpf ZLIB_INTERNAL dfltcc_alloc_state OF((z_streamp strm, uInt items, ++ uInt size)); ++void ZLIB_INTERNAL dfltcc_copy_state OF((voidpf dst, const voidpf src, ++ uInt size)); ++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_copy_window OF((void *dest, const void *src, ++ size_t n)); ++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, ++ DFLTCC_INFLATE_BREAK, ++ DFLTCC_INFLATE_SOFTWARE, ++} dfltcc_inflate_action; ++dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate OF((z_streamp strm, ++ int flush, int *ret)); ++int ZLIB_INTERNAL dfltcc_was_inflate_used OF((z_streamp strm)); ++int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm)); ++int ZLIB_INTERNAL dfltcc_inflate_set_dictionary OF((z_streamp strm, ++ const Bytef *dictionary, ++ uInt dict_length)); ++int ZLIB_INTERNAL dfltcc_inflate_get_dictionary OF((z_streamp strm, ++ Bytef *dictionary, ++ uInt* dict_length)); ++ ++#define ZALLOC_STATE dfltcc_alloc_state ++#define ZFREE_STATE ZFREE ++#define ZCOPY_STATE dfltcc_copy_state ++#define ZALLOC_WINDOW dfltcc_alloc_window ++#define ZCOPY_WINDOW dfltcc_copy_window ++#define ZFREE_WINDOW dfltcc_free_window ++#define TRY_FREE_WINDOW dfltcc_free_window ++#define INFLATE_RESET_KEEP_HOOK(strm) \ ++ dfltcc_reset((strm), sizeof(struct inflate_state)) ++#define INFLATE_PRIME_HOOK(strm, bits, value) \ ++ do { if (dfltcc_inflate_disable((strm))) return Z_STREAM_ERROR; } while (0) ++#define INFLATE_TYPEDO_HOOK(strm, flush) \ ++ if (dfltcc_can_inflate((strm))) { \ ++ dfltcc_inflate_action action; \ ++\ ++ RESTORE(); \ ++ action = dfltcc_inflate((strm), (flush), &ret); \ ++ LOAD(); \ ++ if (action == DFLTCC_INFLATE_CONTINUE) \ ++ break; \ ++ else if (action == DFLTCC_INFLATE_BREAK) \ ++ goto inf_leave; \ ++ } ++#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm))) ++#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm))) ++#define INFLATE_MARK_HOOK(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) ++#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ ++ do { \ ++ if (dfltcc_can_inflate(strm)) \ ++ return dfltcc_inflate_set_dictionary(strm, dict, dict_len); \ ++ } while (0) ++#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ ++ do { \ ++ if (dfltcc_can_inflate(strm)) \ ++ return dfltcc_inflate_get_dictionary(strm, dict, dict_len); \ ++ } while (0) ++ ++#endif +diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h +new file mode 100644 +index 000000000..46acfc550 +--- /dev/null ++++ b/contrib/s390/dfltcc_deflate.h +@@ -0,0 +1,55 @@ ++#ifndef DFLTCC_DEFLATE_H ++#define DFLTCC_DEFLATE_H ++ ++#include "dfltcc.h" ++ ++int ZLIB_INTERNAL dfltcc_can_deflate OF((z_streamp strm)); ++int ZLIB_INTERNAL dfltcc_deflate OF((z_streamp strm, ++ int flush, ++ block_state *result)); ++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)); ++int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm, ++ Bytef *dictionary, ++ uInt* dict_length)); ++ ++#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ ++ do { \ ++ if (dfltcc_can_deflate((strm))) \ ++ return dfltcc_deflate_set_dictionary((strm), (dict), (dict_len)); \ ++ } while (0) ++#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ ++ do { \ ++ if (dfltcc_can_deflate((strm))) \ ++ return dfltcc_deflate_get_dictionary((strm), (dict), (dict_len)); \ ++ } while (0) ++#define DEFLATE_RESET_KEEP_HOOK(strm) \ ++ dfltcc_reset((strm), sizeof(deflate_state)) ++#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ ++ do { \ ++ int err; \ ++\ ++ 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) = 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 +diff --git a/deflate.c b/deflate.c +index 4a512e1f9..ba446d982 100644 +--- a/deflate.c ++++ b/deflate.c +@@ -61,15 +61,30 @@ const char deflate_copyright[] = + */ + + /* =========================================================================== +- * Function prototypes. ++ * Architecture-specific bits. + */ +-typedef enum { +- need_more, /* block not completed, need more input or more output */ +- block_done, /* block flush performed */ +- finish_started, /* finish started, need only more output at next deflate */ +- finish_done /* finish done, accept no more input or output */ +-} block_state; ++#ifdef DFLTCC ++# include "contrib/s390/dfltcc_deflate.h" ++#else ++#define ZALLOC_STATE ZALLOC ++#define ZFREE_STATE ZFREE ++#define ZCOPY_STATE zmemcpy ++#define ZALLOC_WINDOW ZALLOC ++#define TRY_FREE_WINDOW TRY_FREE ++#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, 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 ++#define DEFLATE_NEED_CHECKSUM(strm) 1 ++#endif + ++/* =========================================================================== ++ * Function prototypes. ++ */ + typedef block_state (*compress_func) OF((deflate_state *s, int flush)); + /* Compression function. Returns the block state after the call. */ + +@@ -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)); +-local void flush_pending OF((z_streamp strm)); + local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); + local uInt longest_match OF((deflate_state *s, IPos cur_match)); + +@@ -295,7 +309,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 */ +- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); ++ s = (deflate_state *) ZALLOC_STATE(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; +@@ -312,7 +326,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); + +- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); ++ s->window = (Bytef *) ZALLOC_WINDOW(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + +@@ -430,6 +444,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); ++ DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ +@@ -488,6 +503,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; ++ DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) +@@ -534,6 +550,8 @@ int ZEXPORT deflateResetKeep(strm) + + _tr_init(s); + ++ DEFLATE_RESET_KEEP_HOOK(strm); ++ + return Z_OK; + } + +@@ -609,6 +627,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; +@@ -621,15 +640,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, &hook_flush); + func = configuration_table[s->level].func; + +- 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) { +@@ -705,11 +727,13 @@ uLong ZEXPORT deflateBound(strm, sourceLen) + ~13% overhead plus a small constant */ + fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + + (sourceLen >> 9) + 4; ++ DEFLATE_BOUND_ADJUST_COMPLEN(strm, fixedlen, sourceLen); + + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + + (sourceLen >> 11) + 7; ++ DEFLATE_BOUND_ADJUST_COMPLEN(strm, storelen, sourceLen); + + /* if can't get parameters, return larger bound plus a zlib wrapper */ + if (deflateStateCheck(strm)) +@@ -751,7 +775,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) + } + + /* if not default parameters, return one of the conservative bounds */ +- if (s->w_bits != 15 || s->hash_bits != 8 + 7) ++ if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || ++ s->w_bits != 15 || s->hash_bits != 8 + 7) + return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + + wraplen; + +@@ -780,7 +805,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()). + */ +-local void flush_pending(strm) ++void ZLIB_INTERNAL flush_pending(strm) + z_streamp strm; + { + unsigned len; +@@ -1052,7 +1077,8 @@ int ZEXPORT deflate(strm, flush) + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + +- bstate = s->level == 0 ? deflate_stored(s, flush) : ++ bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : ++ s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); +@@ -1099,7 +1125,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 +@@ -1115,7 +1140,7 @@ int ZEXPORT deflate(strm, flush) + } + else + #endif +- { ++ if (s->wrap == 1) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } +@@ -1124,7 +1149,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; + } + + /* ========================================================================= */ +@@ -1141,9 +1170,9 @@ int ZEXPORT deflateEnd(strm) + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); +- TRY_FREE(strm, strm->state->window); ++ TRY_FREE_WINDOW(strm, strm->state->window); + +- ZFREE(strm, strm->state); ++ ZFREE_STATE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +@@ -1173,13 +1202,13 @@ int ZEXPORT deflateCopy(dest, source) + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + +- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); ++ ds = (deflate_state *) ZALLOC_STATE(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; +- zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); ++ ZCOPY_STATE((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + +- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ++ ds->window = (Bytef *) ZALLOC_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)); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); +@@ -1226,7 +1255,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)) {} ++ else if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } + #ifdef GZIP +diff --git a/deflate.h b/deflate.h +index 1a06cd5f2..f92750ca6 100644 +--- a/deflate.h ++++ b/deflate.h +@@ -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)); ++void ZLIB_INTERNAL _tr_send_bits OF((deflate_state *s, int value, int length)); + + #define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +@@ -343,4 +344,15 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + flush = _tr_tally(s, distance, length) + #endif + ++typedef enum { ++ need_more, /* block not completed, need more input or more output */ ++ block_done, /* block flush performed */ ++ finish_started, /* finish started, need only more output at next deflate */ ++ finish_done /* finish done, accept no more input or output */ ++} block_state; ++ ++unsigned ZLIB_INTERNAL bi_reverse OF((unsigned code, int len)); ++void ZLIB_INTERNAL bi_windup OF((deflate_state *s)); ++void ZLIB_INTERNAL flush_pending OF((z_streamp strm)); ++ + #endif /* DEFLATE_H */ +diff --git a/gzguts.h b/gzguts.h +index 57faf3716..581f2b631 100644 +--- a/gzguts.h ++++ b/gzguts.h +@@ -153,7 +153,11 @@ + + /* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ ++#ifdef DFLTCC ++#define GZBUFSIZE 131072 ++#else + #define GZBUFSIZE 8192 ++#endif + + /* 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 8acbef44e..19dc7242f 100644 +--- a/inflate.c ++++ b/inflate.c +@@ -85,6 +85,27 @@ + #include "inflate.h" + #include "inffast.h" + ++/* architecture-specific bits */ ++#ifdef DFLTCC ++# include "contrib/s390/dfltcc.h" ++#else ++#define ZALLOC_STATE ZALLOC ++#define ZFREE_STATE ZFREE ++#define ZCOPY_STATE zmemcpy ++#define ZALLOC_WINDOW ZALLOC ++#define ZCOPY_WINDOW zmemcpy ++#define ZFREE_WINDOW ZFREE ++#define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0) ++#define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0) ++#define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0) ++#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) ++#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) ++#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) ++#endif ++ + #ifdef MAKEFIXED + # ifndef BUILDFIXED + # define BUILDFIXED +@@ -138,6 +159,7 @@ z_streamp strm; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; ++ INFLATE_RESET_KEEP_HOOK(strm); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; + } +@@ -185,7 +207,7 @@ int windowBits; + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { +- ZFREE(strm, state->window); ++ ZFREE_WINDOW(strm, state->window); + state->window = Z_NULL; + } + +@@ -224,7 +246,7 @@ int stream_size; + strm->zfree = zcfree; + #endif + state = (struct inflate_state FAR *) +- ZALLOC(strm, 1, sizeof(struct inflate_state)); ++ ZALLOC_STATE(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; +@@ -233,7 +255,7 @@ int stream_size; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { +- ZFREE(strm, state); ++ ZFREE_STATE(strm, state); + strm->state = Z_NULL; + } + return ret; +@@ -255,6 +277,7 @@ int value; + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ INFLATE_PRIME_HOOK(strm, bits, value); + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; +@@ -382,6 +405,27 @@ void makefixed() + } + #endif /* MAKEFIXED */ + ++int ZLIB_INTERNAL inflate_ensure_window(state) ++ struct inflate_state *state; ++{ ++ /* if it hasn't been done already, allocate space for the window */ ++ if (state->window == Z_NULL) { ++ state->window = (unsigned char FAR *) ++ ZALLOC_WINDOW(state->strm, 1U << state->wbits, ++ sizeof(unsigned char)); ++ if (state->window == Z_NULL) return 1; ++ } ++ ++ /* if window not in use yet, initialize */ ++ if (state->wsize == 0) { ++ state->wsize = 1U << state->wbits; ++ state->wnext = 0; ++ state->whave = 0; ++ } ++ ++ return 0; ++} ++ + /* + 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 +@@ -406,20 +450,7 @@ unsigned copy; + + state = (struct inflate_state FAR *)strm->state; + +- /* if it hasn't been done already, allocate space for the window */ +- if (state->window == Z_NULL) { +- state->window = (unsigned char FAR *) +- ZALLOC(strm, 1U << state->wbits, +- sizeof(unsigned char)); +- if (state->window == Z_NULL) return 1; +- } +- +- /* if window not in use yet, initialize */ +- if (state->wsize == 0) { +- state->wsize = 1U << state->wbits; +- state->wnext = 0; +- state->whave = 0; +- } ++ if (inflate_ensure_window(state)) return 1; + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { +@@ -863,6 +894,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; +@@ -1224,7 +1256,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_CHECK(state->check, put - out, out); + out = left; +@@ -1279,8 +1311,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)))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; +@@ -1290,7 +1323,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_CHECK(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + +@@ -1308,8 +1341,8 @@ z_streamp strm; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +- if (state->window != Z_NULL) ZFREE(strm, state->window); +- ZFREE(strm, strm->state); ++ if (state->window != Z_NULL) ZFREE_WINDOW(strm, state->window); ++ ZFREE_STATE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +@@ -1326,6 +1359,8 @@ uInt *dictLength; + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + ++ INFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); ++ + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, +@@ -1361,6 +1396,8 @@ uInt dictLength; + return Z_DATA_ERROR; + } + ++ INFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); ++ + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); +@@ -1488,6 +1525,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; + } +@@ -1508,21 +1546,22 @@ z_streamp source; + + /* allocate space */ + copy = (struct inflate_state FAR *) +- ZALLOC(source, 1, sizeof(struct inflate_state)); ++ ZALLOC_STATE(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + 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)); + if (window == Z_NULL) { +- ZFREE(source, copy); ++ ZFREE_STATE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); +- zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); ++ ZCOPY_STATE((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { +@@ -1531,8 +1570,7 @@ z_streamp source; + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { +- wsize = 1U << state->wbits; +- zmemcpy(window, state->window, wsize); ++ ZCOPY_WINDOW(window, state->window, 1U << state->wbits); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; +@@ -1579,6 +1617,7 @@ z_streamp strm; + + if (inflateStateCheck(strm)) + return -(1L << 16); ++ INFLATE_MARK_HOOK(strm); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : +diff --git a/inflate.h b/inflate.h +index f127b6b1f..519ed3535 100644 +--- a/inflate.h ++++ b/inflate.h +@@ -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 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) + } + + /* input and output functions for inflateBack() */ +-local unsigned pull(void *desc, unsigned char **buf) ++local unsigned pull(void *desc, z_const unsigned char **buf) + { + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; +diff --git a/test/minigzip.c b/test/minigzip.c +index a649d2b3d..964408a40 100644 +--- a/test/minigzip.c ++++ b/test/minigzip.c +@@ -132,7 +132,11 @@ static void pwinerror (s) + #endif + #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + ++#ifdef DFLTCC ++#define BUFLEN 262144 ++#else + #define BUFLEN 16384 ++#endif + #define MAX_NAME_LEN 1024 + + #ifdef MAXSEG_64K +diff --git a/trees.c b/trees.c +index 5f305c472..4924bdfc8 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 code, int len)); +-local void bi_windup OF((deflate_state *s)); + local void bi_flush OF((deflate_state *s)); + + #ifdef GEN_TREES_H +@@ -223,6 +221,13 @@ local void send_bits(s, value, length) + } + #endif /* ZLIB_DEBUG */ + ++void ZLIB_INTERNAL _tr_send_bits(s, value, length) ++ deflate_state *s; ++ int value; ++ int length; ++{ ++ send_bits(s, value, length); ++} + + /* the arguments must not have side effects */ + +@@ -1133,7 +1138,7 @@ local int detect_data_type(s) + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +-local unsigned bi_reverse(code, len) ++unsigned ZLIB_INTERNAL bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ + { +@@ -1165,7 +1170,7 @@ local void bi_flush(s) + /* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +-local void bi_windup(s) ++void ZLIB_INTERNAL bi_windup(s) + deflate_state *s; + { + if (s->bi_valid > 8) { +diff --git a/zutil.h b/zutil.h +index 0bc7f4ecd..75eb4df47 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.13-fix-bug-deflateBound.patch b/zlib-1.2.13-fix-bug-deflateBound.patch new file mode 100644 index 0000000..c04546f --- /dev/null +++ b/zlib-1.2.13-fix-bug-deflateBound.patch @@ -0,0 +1,27 @@ +From e554695638228b846d49657f31eeff0ca4680e8a Mon Sep 17 00:00:00 2001 +From: Mark Adler +Date: Thu, 15 Dec 2022 09:07:13 -0800 +Subject: [PATCH] Fix bug in deflateBound() for level 0 and memLevel 9. + +memLevel 9 would cause deflateBound() to assume the use of fixed +blocks, even if the compression level was 0, which forces stored +blocks. That could result in a bound less than the size of the +compressed data. Now level 0 always uses the stored blocks bound. +--- + deflate.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/deflate.c b/deflate.c +index cd538b8ac..4a512e1f9 100644 +--- a/deflate.c ++++ b/deflate.c +@@ -752,7 +752,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) + + /* if not default parameters, return one of the conservative bounds */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) +- return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen; ++ return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + ++ wraplen; + + /* default settings: return tight bound for that case -- ~0.03% overhead + plus a small constant */ diff --git a/zlib-1.2.11-optimized-s390.patch b/zlib-1.2.13-optimized-s390.patch similarity index 81% rename from zlib-1.2.11-optimized-s390.patch rename to zlib-1.2.13-optimized-s390.patch index 99850bb..9fe256d 100644 --- a/zlib-1.2.11-optimized-s390.patch +++ b/zlib-1.2.13-optimized-s390.patch @@ -3,8 +3,8 @@ Index: deflate.c --- deflate.c.orig +++ deflate.c @@ -1233,15 +1233,16 @@ local void lm_init (s) - /* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. */ -local uInt longest_match(s, cur_match) +local uInt longest_match(s, pcur_match) @@ -27,14 +27,14 @@ Index: deflate.c */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; -- register ush scan_end = *(ushf*)(scan+best_len-1); +- register ush scan_end = *(ushf*)(scan + best_len - 1); + register uInt scan_start = *(ushf*)scan; -+ register uInt scan_end = *(ushf*)(scan+best_len-1); ++ register uInt scan_end = *(ushf*)(scan + best_len - 1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; -- register Byte scan_end1 = scan[best_len-1]; +- register Byte scan_end1 = scan[best_len - 1]; - register Byte scan_end = scan[best_len]; -+ register uInt scan_end1 = scan[best_len-1]; ++ register uInt scan_end1 = scan[best_len - 1]; + register uInt scan_end = scan[best_len]; #endif diff --git a/zlib-1.2.13.tar.gz b/zlib-1.2.13.tar.gz new file mode 100644 index 0000000..e0a654a --- /dev/null +++ b/zlib-1.2.13.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30 +size 1497445 diff --git a/zlib-1.2.13.tar.gz.asc b/zlib-1.2.13.tar.gz.asc new file mode 100644 index 0000000..b6fe0df --- /dev/null +++ b/zlib-1.2.13.tar.gz.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Comment: GPGTools - http://gpgtools.org + +iF0EABECAB0WIQRe1GpnIdNlWHeR4qp4P82OWLyvugUCY0h42QAKCRB4P82OWLyv +upvZAKCF7EgWGaMEfO78WnkA8hivLlBMlACgyI7Vm2A5BI2jI+h23yqrKjgQC5s= +=umRA +-----END PGP SIGNATURE----- diff --git a/zlib.changes b/zlib.changes index 6de0411..93b798e 100644 --- a/zlib.changes +++ b/zlib.changes @@ -1,3 +1,33 @@ +------------------------------------------------------------------- +Thu Jan 19 11:07:25 UTC 2023 - Danilo Spinella + +- Update to 1.13: + * Fix configure issue that discarded provided CC definition + * Correct incorrect inputs provided to the CRC functions + * Repair prototypes and exporting of new CRC functions + * Fix inflateBack to detect invalid input with distances too far + * Have infback() deliver all of the available output up to any error + * Fix a bug when getting a gzip header extra field with inflate() + * Fix bug in block type selection when Z_FIXED used + * Tighten deflateBound bounds + * Remove deleted assembler code references + * Various portability and appearance improvements +- Added patches: + * zlib-1.2.13-IBM-Z-hw-accelerated-deflate-s390x.patch + * zlib-1.2.13-fix-bug-deflateBound.patch + * zlib-1.2.13-optimized-s390.patch +- Refreshed patches: + * zlib-1.2.12-add-optimized-slide_hash-for-power.patch + * zlib-1.2.12-add-vectorized-longest_match-for-power.patch + * zlib-1.2.12-s390-vectorize-crc32.patch +- Removed patches: + * zlib-1.2.12-fix-configure.patch + * zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch + * zlib-1.2.12-optimized-crc32-power8.patch + * zlib-1.2.12-correct-inputs-provided-to-crc-func.patch + * zlib-1.2.12-fix-CVE-2022-37434.patch + * zlib-1.2.11-optimized-s390.patch + ------------------------------------------------------------------- Sun Dec 11 16:41:51 UTC 2022 - Dirk Müller diff --git a/zlib.spec b/zlib.spec index 1dfff0f..9e4ed7a 100644 --- a/zlib.spec +++ b/zlib.spec @@ -1,7 +1,7 @@ # # spec file for package zlib # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: zlib -Version: 1.2.12 +Version: 1.2.13 Release: 0 Summary: Library implementing the DEFLATE compression algorithm License: Zlib @@ -30,26 +30,23 @@ Source5: baselibs.conf Source6: zlib-rpmlintrc #PATCH-FIX-SUSE: compiler check of varguments passed to gzprintf Patch1: zlib-format.patch -#PATCH-FIX-UPSTREAM do not store negative values in uInt +#PATCH-FIX-SUSE do not store negative values in uInt Patch2: 0001-Do-not-try-to-store-negative-values-in-unsigned-int.patch #PATCH-FIX-SUSE do not check exact version match as the lib can be updated # we should simply rely on soname versioning to protect us Patch3: zlib-no-version-check.patch -#PATCH-FIX-UPSTREAM https://github.com/madler/zlib/commit/ec3df00224d4 -Patch4: zlib-1.2.12-correct-inputs-provided-to-crc-func.patch -#PATCH-FIX-UPSTREAM https://github.com/madler/zlib/commit/1eb7682f845ac9e9bf9ae35bbfb3bad5dacbd91d -Patch5: zlib-1.2.12-fix-CVE-2022-37434.patch -#PATCH-FIX-UPSTREAM https://github.com/madler/zlib/pull/229 -Patch6: minizip-dont-install-crypt-header.patch -# The following patches are taken from https://github.com/iii-i/zlib/commits/crc32vx-v3 +#PATCH-FIX-SUSE https://github.com/madler/zlib/pull/229 +Patch4: minizip-dont-install-crypt-header.patch +# PATCH-FIX-UPSTREAM https://github.com/madler/zlib/commit/e554695638228b846d49657f31eeff0ca4680e8a +Patch5: zlib-1.2.13-fix-bug-deflateBound.patch +#PATCH-FIX-SUSE https://github.com/madler/zlib/pull/410 +Patch6: zlib-1.2.13-IBM-Z-hw-accelerated-deflate-s390x.patch +# Patches taken from https://github.com/iii-i/zlib/releases/tag/crc32vx-v3 Patch7: zlib-1.2.5-minizip-fixuncrypt.patch -Patch8: zlib-1.2.11-optimized-s390.patch +Patch8: zlib-1.2.13-optimized-s390.patch # https://github.com/iii-i/zlib/commit/171d0ff3c9ed40da0ac14085ab16b766b1162069 -Patch9: zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch Patch10: zlib-1.2.11-covscan-issues.patch Patch11: zlib-1.2.11-covscan-issues-rhel9.patch -Patch12: zlib-1.2.12-optimized-crc32-power8.patch -Patch13: zlib-1.2.12-fix-configure.patch Patch14: zlib-1.2.12-s390-vectorize-crc32.patch # The following patches are taken from https://github.com/mscastanho/zlib/commits/power-optimizations-1.2.12 Patch15: zlib-1.2.12-adler32-vector-optimizations-for-power.patch @@ -148,11 +145,8 @@ It should exit 0 %patch6 -p1 %patch7 -p1 %patch8 -%patch9 -p1 %patch10 -p1 %patch11 -p1 -%patch12 -p1 -%patch13 -p1 %patch14 -p1 %patch15 -p1 %patch16 -p1