diff --git a/bsc1174736-DFLTCC_LEVEL_MASK-set-to-0x1ff.patch b/bsc1174736-DFLTCC_LEVEL_MASK-set-to-0x1ff.patch deleted file mode 100644 index 4022f15..0000000 --- a/bsc1174736-DFLTCC_LEVEL_MASK-set-to-0x1ff.patch +++ /dev/null @@ -1,50 +0,0 @@ -Index: zlib-1.2.11/deflate.c -=================================================================== ---- zlib-1.2.11.orig/deflate.c -+++ zlib-1.2.11/deflate.c -@@ -504,7 +504,7 @@ int ZEXPORT deflateResetKeep (strm) - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : - #endif - adler32(0L, Z_NULL, 0); -- s->last_flush = Z_NO_FLUSH; -+ s->last_flush = -2; - - _tr_init(s); - -@@ -582,12 +582,12 @@ int ZEXPORT deflateParams(strm, level, s - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && -- s->high_water) { -+ s->last_flush != -2) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; -- if (strm->avail_out == 0) -+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) - return Z_BUF_ERROR; - } - if (s->level != level) { -Index: zlib-1.2.11/zlib.h -=================================================================== ---- zlib-1.2.11.orig/zlib.h -+++ zlib-1.2.11/zlib.h -@@ -712,11 +712,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_ - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the -- strategy is changed, and if any input has been consumed in a previous -- deflate() call, then the input available so far is compressed with the old -- level and strategy using deflate(strm, Z_BLOCK). There are three approaches -- for the compression levels 0, 1..3, and 4..9 respectively. The new level -- and strategy will take effect at the next call of deflate(). -+ strategy is changed, and if there have been any deflate() calls since the -+ state was initialized or reset, then the input available so far is -+ compressed with the old level and strategy using deflate(strm, Z_BLOCK). -+ There are three approaches for the compression levels 0, 1..3, and 4..9 -+ respectively. The new level and strategy will take effect at the next call -+ of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not diff --git a/bsc1197459.patch b/bsc1197459.patch deleted file mode 100644 index b40f376..0000000 --- a/bsc1197459.patch +++ /dev/null @@ -1,343 +0,0 @@ -From 5c44459c3b28a9bd3283aaceab7c615f8020c531 Mon Sep 17 00:00:00 2001 -From: Mark Adler -Date: Tue, 17 Apr 2018 22:09:22 -0700 -Subject: [PATCH] Fix a bug that can crash deflate on some input when using - Z_FIXED. - -This bug was reported by Danilo Ramos of Eideticom, Inc. It has -lain in wait 13 years before being found! The bug was introduced -in zlib 1.2.2.2, with the addition of the Z_FIXED option. That -option forces the use of fixed Huffman codes. For rare inputs with -a large number of distant matches, the pending buffer into which -the compressed data is written can overwrite the distance symbol -table which it overlays. That results in corrupted output due to -invalid distances, and can result in out-of-bound accesses, -crashing the application. - -The fix here combines the distance buffer and literal/length -buffers into a single symbol buffer. Now three bytes of pending -buffer space are opened up for each literal or length/distance -pair consumed, instead of the previous two bytes. This assures -that the pending buffer cannot overwrite the symbol table, since -the maximum fixed code compressed length/distance is 31 bits, and -since there are four bytes of pending space for every three bytes -of symbol space. ---- - deflate.c | 74 ++++++++++++++++++++++++++++++++++++++++--------------- - deflate.h | 25 +++++++++---------- - trees.c | 50 +++++++++++-------------------------- - 3 files changed, 79 insertions(+), 70 deletions(-) - -Index: zlib-1.2.11/deflate.c -=================================================================== ---- zlib-1.2.11.orig/deflate.c -+++ zlib-1.2.11/deflate.c -@@ -251,11 +251,6 @@ int ZEXPORT deflateInit2_(strm, level, m - deflate_state *s; - int wrap = 1; - -- ushf *overlay; -- /* We overlay pending_buf and d_buf+l_buf. This works since the average -- * output size for (length,distance) codes is <= 24 bits. -- */ -- - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; -@@ -321,9 +316,47 @@ int ZEXPORT deflateInit2_(strm, level, m - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - -- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); -- s->pending_buf = (uchf *) overlay; -- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); -+ /* We overlay pending_buf and sym_buf. This works since the average size -+ * for length/distance pairs over any compressed block is assured to be 31 -+ * bits or less. -+ * -+ * Analysis: The longest fixed codes are a length code of 8 bits plus 5 -+ * extra bits, for lengths 131 to 257. The longest fixed distance codes are -+ * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest -+ * possible fixed-codes length/distance pair is then 31 bits total. -+ * -+ * sym_buf starts one-fourth of the way into pending_buf. So there are -+ * three bytes in sym_buf for every four bytes in pending_buf. Each symbol -+ * in sym_buf is three bytes -- two for the distance and one for the -+ * literal/length. As each symbol is consumed, the pointer to the next -+ * sym_buf value to read moves forward three bytes. From that symbol, up to -+ * 31 bits are written to pending_buf. The closest the written pending_buf -+ * bits gets to the next sym_buf symbol to read is just before the last -+ * code is written. At that time, 31*(n-2) bits have been written, just -+ * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at -+ * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 -+ * symbols are written.) The closest the writing gets to what is unread is -+ * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and -+ * can range from 128 to 32768. -+ * -+ * Therefore, at a minimum, there are 142 bits of space between what is -+ * written and what is read in the overlain buffers, so the symbols cannot -+ * be overwritten by the compressed data. That space is actually 139 bits, -+ * due to the three-bit fixed-code block header. -+ * -+ * That covers the case where either Z_FIXED is specified, forcing fixed -+ * codes, or when the use of fixed codes is chosen, because that choice -+ * results in a smaller compressed block than dynamic codes. That latter -+ * condition then assures that the above analysis also covers all dynamic -+ * blocks. A dynamic-code block will only be chosen to be emitted if it has -+ * fewer bits than a fixed-code block would for the same set of symbols. -+ * Therefore its average symbol length is assured to be less than 31. So -+ * the compressed data for a dynamic block also cannot overwrite the -+ * symbols from which it is being constructed. -+ */ -+ -+ s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); -+ s->pending_buf_size = (ulg)s->lit_bufsize * 4; - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { -@@ -332,8 +365,12 @@ int ZEXPORT deflateInit2_(strm, level, m - deflateEnd (strm); - return Z_MEM_ERROR; - } -- s->d_buf = overlay + s->lit_bufsize/sizeof(ush); -- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; -+ s->sym_buf = s->pending_buf + s->lit_bufsize; -+ s->sym_end = (s->lit_bufsize - 1) * 3; -+ /* We avoid equality with lit_bufsize*3 because of wraparound at 64K -+ * on 16 bit machines and because stored blocks are restricted to -+ * 64K-1 bytes. -+ */ - - s->level = level; - s->strategy = strategy; -@@ -544,7 +581,7 @@ int ZEXPORT deflatePrime (strm, bits, va - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; -- if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) -+ if (s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; -@@ -1103,7 +1140,6 @@ int ZEXPORT deflateCopy (dest, source) - #else - deflate_state *ds; - deflate_state *ss; -- ushf *overlay; - - - if (deflateStateCheck(source) || dest == Z_NULL) { -@@ -1123,8 +1159,7 @@ int ZEXPORT deflateCopy (dest, source) - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); -- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); -- ds->pending_buf = (uchf *) overlay; -+ ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { -@@ -1138,8 +1173,7 @@ int ZEXPORT deflateCopy (dest, source) - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); -- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); -- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; -+ ds->sym_buf = ds->pending_buf + ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; -@@ -1911,7 +1945,7 @@ local block_state deflate_fast(s, flush) - FLUSH_BLOCK(s, 1); - return finish_done; - } -- if (s->last_lit) -+ if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; - } -@@ -2042,7 +2076,7 @@ local block_state deflate_slow(s, flush) - FLUSH_BLOCK(s, 1); - return finish_done; - } -- if (s->last_lit) -+ if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; - } -@@ -2117,7 +2151,7 @@ local block_state deflate_rle(s, flush) - FLUSH_BLOCK(s, 1); - return finish_done; - } -- if (s->last_lit) -+ if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; - } -@@ -2156,7 +2190,7 @@ local block_state deflate_huff(s, flush) - FLUSH_BLOCK(s, 1); - return finish_done; - } -- if (s->last_lit) -+ if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; - } -Index: zlib-1.2.11/deflate.h -=================================================================== ---- zlib-1.2.11.orig/deflate.h -+++ zlib-1.2.11/deflate.h -@@ -217,7 +217,7 @@ typedef struct internal_state { - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - -- uchf *l_buf; /* buffer for literals or lengths */ -+ uchf *sym_buf; /* buffer for distances and literals/lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for -@@ -239,13 +239,8 @@ typedef struct internal_state { - * - I can't count above 4 - */ - -- uInt last_lit; /* running index in l_buf */ -- -- ushf *d_buf; -- /* Buffer for distances. To simplify the code, d_buf and l_buf have -- * the same number of elements. To use different lengths, an extra flag -- * array would be necessary. -- */ -+ uInt sym_next; /* running index in sym_buf */ -+ uInt sym_end; /* symbol table full when sym_next reaches this */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ -@@ -325,20 +320,22 @@ void ZLIB_INTERNAL _tr_stored_block OF(( - - # define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ -- s->d_buf[s->last_lit] = 0; \ -- s->l_buf[s->last_lit++] = cc; \ -+ s->sym_buf[s->sym_next++] = 0; \ -+ s->sym_buf[s->sym_next++] = 0; \ -+ s->sym_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ -- flush = (s->last_lit == s->lit_bufsize-1); \ -+ flush = (s->sym_next == s->sym_end); \ - } - # define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ -- s->d_buf[s->last_lit] = dist; \ -- s->l_buf[s->last_lit++] = len; \ -+ s->sym_buf[s->sym_next++] = dist; \ -+ s->sym_buf[s->sym_next++] = dist >> 8; \ -+ s->sym_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ -- flush = (s->last_lit == s->lit_bufsize-1); \ -+ flush = (s->sym_next == s->sym_end); \ - } - #else - # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -Index: zlib-1.2.11/trees.c -=================================================================== ---- zlib-1.2.11.orig/trees.c -+++ zlib-1.2.11/trees.c -@@ -416,7 +416,7 @@ local void init_block(s) - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; -- s->last_lit = s->matches = 0; -+ s->sym_next = s->matches = 0; - } - - #define SMALLEST 1 -@@ -947,7 +947,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, bu - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, -- s->last_lit)); -+ s->sym_next / 3)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - -@@ -1016,8 +1016,9 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - { -- s->d_buf[s->last_lit] = (ush)dist; -- s->l_buf[s->last_lit++] = (uch)lc; -+ s->sym_buf[s->sym_next++] = dist; -+ s->sym_buf[s->sym_next++] = dist >> 8; -+ s->sym_buf[s->sym_next++] = lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; -@@ -1032,30 +1033,7 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } -- --#ifdef TRUNCATE_BLOCK -- /* Try to guess if it is profitable to stop the current block here */ -- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { -- /* Compute an upper bound for the compressed length */ -- ulg out_length = (ulg)s->last_lit*8L; -- ulg in_length = (ulg)((long)s->strstart - s->block_start); -- int dcode; -- for (dcode = 0; dcode < D_CODES; dcode++) { -- out_length += (ulg)s->dyn_dtree[dcode].Freq * -- (5L+extra_dbits[dcode]); -- } -- out_length >>= 3; -- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", -- s->last_lit, in_length, out_length, -- 100L - out_length*100L/in_length)); -- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; -- } --#endif -- return (s->last_lit == s->lit_bufsize-1); -- /* We avoid equality with lit_bufsize because of wraparound at 64K -- * on 16 bit machines and because stored blocks are restricted to -- * 64K-1 bytes. -- */ -+ return (s->sym_next == s->sym_end); - } - - /* =========================================================================== -@@ -1068,13 +1046,14 @@ local void compress_block(s, ltree, dtre - { - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ -- unsigned lx = 0; /* running index in l_buf */ -+ unsigned sx = 0; /* running index in sym_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - -- if (s->last_lit != 0) do { -- dist = s->d_buf[lx]; -- lc = s->l_buf[lx++]; -+ if (s->sym_next != 0) do { -+ dist = s->sym_buf[sx++] & 0xff; -+ dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; -+ lc = s->sym_buf[sx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); -@@ -1099,11 +1078,10 @@ local void compress_block(s, ltree, dtre - } - } /* literal or match pair ? */ - -- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ -- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, -- "pendingBuf overflow"); -+ /* Check that the overlay between pending_buf and sym_buf is ok: */ -+ Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - -- } while (lx < s->last_lit); -+ } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); - } diff --git a/zlib-1.2.11-covscan-issues-rhel9.patch b/zlib-1.2.11-covscan-issues-rhel9.patch new file mode 100644 index 0000000..76cd370 --- /dev/null +++ b/zlib-1.2.11-covscan-issues-rhel9.patch @@ -0,0 +1,28 @@ +From a7d3c3076dc316f1408f56af86a72a17fcfdf5dd Mon Sep 17 00:00:00 2001 +From: Ilya Leoshkevich +Date: Wed, 27 Apr 2022 14:37:54 +0200 +Subject: [PATCH] zlib-1.2.11-covscan-issues-rhel9.patch + +--- + contrib/minizip/mztools.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/contrib/minizip/mztools.c b/contrib/minizip/mztools.c +index 96891c2e0..1197928a7 100644 +--- a/contrib/minizip/mztools.c ++++ b/contrib/minizip/mztools.c +@@ -286,6 +286,14 @@ uLong* bytesRecovered; + } + } else { + err = Z_STREAM_ERROR; ++ if(fpZip != NULL) ++ fclose(fpZip); ++ ++ if(fpOut != NULL) ++ fclose(fpOut); ++ ++ if(fpOutCD != NULL) ++ fclose(fpOutCD); + } + return err; + } diff --git a/zlib-1.2.11-covscan-issues.patch b/zlib-1.2.11-covscan-issues.patch new file mode 100644 index 0000000..82cf360 --- /dev/null +++ b/zlib-1.2.11-covscan-issues.patch @@ -0,0 +1,22 @@ +From e4c0c07385f80e260f1f1aa2a80c41c62754b9d4 Mon Sep 17 00:00:00 2001 +From: Ilya Leoshkevich +Date: Wed, 27 Apr 2022 14:37:39 +0200 +Subject: [PATCH] zlib-1.2.11-covscan-issues.patch + +--- + deflate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/deflate.c b/deflate.c +index ac0b865a4..49f056a00 100644 +--- a/deflate.c ++++ b/deflate.c +@@ -1062,7 +1062,7 @@ int ZEXPORT deflate (strm, flush) + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { +- block_state bstate; ++ block_state bstate = 0; + + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : + s->level == 0 ? deflate_stored(s, flush) : diff --git a/zlib-1.2.11.tar.gz b/zlib-1.2.11.tar.gz deleted file mode 100644 index 97e86ef..0000000 --- a/zlib-1.2.11.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 -size 607698 diff --git a/zlib-1.2.11.tar.gz.asc b/zlib-1.2.11.tar.gz.asc deleted file mode 100644 index accd4d2..0000000 --- a/zlib-1.2.11.tar.gz.asc +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Comment: GPGTools - http://gpgtools.org - -iD8DBQBYe7UDeD/Njli8r7oRAgRsAJ4mHDka1VqgCYija3bLjGMyD+tohACg+y+d -JCGR0qc+wctJGy2vEg5nDqk= -=8VNa ------END PGP SIGNATURE----- diff --git a/410.patch b/zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch similarity index 88% rename from 410.patch rename to zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch index bfc726f..7376951 100644 --- a/410.patch +++ b/zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch @@ -1,99 +1,8 @@ -From b25781e735363e04f6c56e21431c47e4afc50b17 Mon Sep 17 00:00:00 2001 +From e1d7e6dc9698968a8536b00ebd9e9b4e429b4306 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 +Date: Wed, 27 Apr 2022 14:37:24 +0200 +Subject: [PATCH] zlib-1.2.12-IBM-Z-hw-accelrated-deflate-s390x.patch -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 +- @@ -118,10 +27,10 @@ updatewindow and made ZLIB_INTERNAL. create mode 100644 contrib/s390/dfltcc.h create mode 100644 contrib/s390/dfltcc_deflate.h -Index: zlib-1.2.11/Makefile.in +Index: zlib-1.2.12/Makefile.in =================================================================== ---- zlib-1.2.11.orig/Makefile.in -+++ zlib-1.2.11/Makefile.in +--- zlib-1.2.12.orig/Makefile.in ++++ zlib-1.2.12/Makefile.in @@ -143,6 +143,14 @@ match.lo: match.S mv _match.o match.lo rm -f _match.s @@ -137,10 +46,10 @@ Index: zlib-1.2.11/Makefile.in example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c -Index: zlib-1.2.11/compress.c +Index: zlib-1.2.12/compress.c =================================================================== ---- zlib-1.2.11.orig/compress.c -+++ zlib-1.2.11/compress.c +--- zlib-1.2.12.orig/compress.c ++++ zlib-1.2.12/compress.c @@ -5,9 +5,15 @@ /* @(#) $Id$ */ @@ -171,11 +80,11 @@ Index: zlib-1.2.11/compress.c return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; } -Index: zlib-1.2.11/configure +Index: zlib-1.2.12/configure =================================================================== ---- zlib-1.2.11.orig/configure -+++ zlib-1.2.11/configure -@@ -114,6 +114,7 @@ case "$1" in +--- zlib-1.2.12.orig/configure ++++ zlib-1.2.12/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 @@ -183,10 +92,10 @@ Index: zlib-1.2.11/configure exit 0 ;; -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; -@@ -137,6 +138,16 @@ case "$1" in - -c* | --const) zconst=1; 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" @@ -200,7 +109,7 @@ Index: zlib-1.2.11/configure *) echo "unknown option: $1" | tee -a configure.log echo "$0 --help for help" | tee -a configure.log -@@ -911,6 +922,19 @@ EOF +@@ -833,6 +844,19 @@ EOF fi fi @@ -220,11 +129,11 @@ Index: zlib-1.2.11/configure # show the results in the log echo >> configure.log echo ALL = $ALL >> configure.log -Index: zlib-1.2.11/contrib/README.contrib +Index: zlib-1.2.12/contrib/README.contrib =================================================================== ---- zlib-1.2.11.orig/contrib/README.contrib -+++ zlib-1.2.11/contrib/README.contrib -@@ -67,6 +67,10 @@ puff/ by Mark Adler Example of the use of zlib -Index: zlib-1.2.11/contrib/s390/README.txt +Index: zlib-1.2.12/contrib/s390/README.txt =================================================================== --- /dev/null -+++ zlib-1.2.11/contrib/s390/README.txt ++++ zlib-1.2.12/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 @@ -257,10 +166,10 @@ Index: zlib-1.2.11/contrib/s390/README.txt +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. -Index: zlib-1.2.11/contrib/s390/dfltcc.c +Index: zlib-1.2.12/contrib/s390/dfltcc.c =================================================================== --- /dev/null -+++ zlib-1.2.11/contrib/s390/dfltcc.c ++++ zlib-1.2.12/contrib/s390/dfltcc.c @@ -0,0 +1,996 @@ +/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ + @@ -1258,10 +1167,10 @@ Index: zlib-1.2.11/contrib/s390/dfltcc.c + *dict_length = param->hl; + return Z_OK; +} -Index: zlib-1.2.11/contrib/s390/dfltcc.h +Index: zlib-1.2.12/contrib/s390/dfltcc.h =================================================================== --- /dev/null -+++ zlib-1.2.11/contrib/s390/dfltcc.h ++++ zlib-1.2.12/contrib/s390/dfltcc.h @@ -0,0 +1,81 @@ +#ifndef DFLTCC_H +#define DFLTCC_H @@ -1344,10 +1253,10 @@ Index: zlib-1.2.11/contrib/s390/dfltcc.h + } while (0) + +#endif -Index: zlib-1.2.11/contrib/s390/dfltcc_deflate.h +Index: zlib-1.2.12/contrib/s390/dfltcc_deflate.h =================================================================== --- /dev/null -+++ zlib-1.2.11/contrib/s390/dfltcc_deflate.h ++++ zlib-1.2.12/contrib/s390/dfltcc_deflate.h @@ -0,0 +1,55 @@ +#ifndef DFLTCC_DEFLATE_H +#define DFLTCC_DEFLATE_H @@ -1404,10 +1313,10 @@ Index: zlib-1.2.11/contrib/s390/dfltcc_deflate.h +#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm))) + +#endif -Index: zlib-1.2.11/deflate.c +Index: zlib-1.2.12/deflate.c =================================================================== ---- zlib-1.2.11.orig/deflate.c -+++ zlib-1.2.11/deflate.c +--- zlib-1.2.12.orig/deflate.c ++++ zlib-1.2.12/deflate.c @@ -61,15 +61,30 @@ const char deflate_copyright[] = */ @@ -1454,7 +1363,7 @@ Index: zlib-1.2.11/deflate.c 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") -@@ -291,7 +305,7 @@ int ZEXPORT deflateInit2_(strm, level, m +@@ -294,7 +308,7 @@ int ZEXPORT deflateInit2_(strm, level, m return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ @@ -1463,7 +1372,7 @@ Index: zlib-1.2.11/deflate.c if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; -@@ -308,7 +322,7 @@ int ZEXPORT deflateInit2_(strm, level, m +@@ -311,7 +325,7 @@ int ZEXPORT deflateInit2_(strm, level, m s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); @@ -1472,7 +1381,7 @@ Index: zlib-1.2.11/deflate.c s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); -@@ -426,6 +440,7 @@ int ZEXPORT deflateSetDictionary (strm, +@@ -429,6 +443,7 @@ int ZEXPORT deflateSetDictionary (strm, /* when using zlib wrappers, compute Adler-32 for provided dictionary */ if (wrap == 1) strm->adler = adler32(strm->adler, dictionary, dictLength); @@ -1480,7 +1389,7 @@ Index: zlib-1.2.11/deflate.c s->wrap = 0; /* avoid computing Adler-32 in read_buf */ /* if dictionary would fill window, just replace the history */ -@@ -484,6 +499,7 @@ int ZEXPORT deflateGetDictionary (strm, +@@ -487,6 +502,7 @@ int ZEXPORT deflateGetDictionary (strm, if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1488,7 +1397,7 @@ Index: zlib-1.2.11/deflate.c s = strm->state; len = s->strstart + s->lookahead; if (len > s->w_size) -@@ -530,6 +546,8 @@ int ZEXPORT deflateResetKeep (strm) +@@ -533,6 +549,8 @@ int ZEXPORT deflateResetKeep (strm) _tr_init(s); @@ -1497,7 +1406,7 @@ Index: zlib-1.2.11/deflate.c return Z_OK; } -@@ -604,6 +622,7 @@ int ZEXPORT deflateParams(strm, level, s +@@ -608,6 +626,7 @@ int ZEXPORT deflateParams(strm, level, s { deflate_state *s; compress_func func; @@ -1505,7 +1414,7 @@ Index: zlib-1.2.11/deflate.c if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; -@@ -616,15 +635,18 @@ int ZEXPORT deflateParams(strm, level, s +@@ -620,15 +639,18 @@ int ZEXPORT deflateParams(strm, level, s if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } @@ -1528,7 +1437,7 @@ Index: zlib-1.2.11/deflate.c return Z_BUF_ERROR; } if (s->level != level) { -@@ -691,6 +713,7 @@ uLong ZEXPORT deflateBound(strm, sourceL +@@ -695,6 +717,7 @@ uLong ZEXPORT deflateBound(strm, sourceL /* conservative upper bound for compressed data */ complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; @@ -1536,7 +1445,7 @@ Index: zlib-1.2.11/deflate.c /* if can't get parameters, return conservative bound plus zlib wrapper */ if (deflateStateCheck(strm)) -@@ -732,7 +755,8 @@ uLong ZEXPORT deflateBound(strm, sourceL +@@ -736,7 +759,8 @@ uLong ZEXPORT deflateBound(strm, sourceL } /* if not default parameters, return conservative bound */ @@ -1546,7 +1455,7 @@ Index: zlib-1.2.11/deflate.c return complen + wraplen; /* default settings: return tight bound for that case */ -@@ -759,7 +783,7 @@ local void putShortMSB (s, b) +@@ -763,7 +787,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()). */ @@ -1555,7 +1464,7 @@ Index: zlib-1.2.11/deflate.c z_streamp strm; { unsigned len; -@@ -1029,7 +1053,8 @@ int ZEXPORT deflate (strm, flush) +@@ -1035,7 +1059,8 @@ int ZEXPORT deflate (strm, flush) (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; @@ -1565,7 +1474,37 @@ Index: zlib-1.2.11/deflate.c s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush); -@@ -1118,9 +1143,9 @@ int ZEXPORT deflateEnd (strm) +@@ -1082,7 +1107,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 +@@ -1098,7 +1122,7 @@ int ZEXPORT deflate (strm, flush) + } + else + #endif +- { ++ if (s->wrap == 1) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } +@@ -1107,7 +1131,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; + } + + /* ========================================================================= */ +@@ -1124,9 +1152,9 @@ int ZEXPORT deflateEnd (strm) TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); @@ -1577,7 +1516,7 @@ Index: zlib-1.2.11/deflate.c strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -@@ -1150,13 +1175,13 @@ int ZEXPORT deflateCopy (dest, source) +@@ -1156,13 +1184,13 @@ int ZEXPORT deflateCopy (dest, source) zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); @@ -1594,7 +1533,7 @@ Index: zlib-1.2.11/deflate.c 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); -@@ -1203,7 +1228,8 @@ local unsigned read_buf(strm, buf, size) +@@ -1209,7 +1237,8 @@ local unsigned read_buf(strm, buf, size) strm->avail_in -= len; zmemcpy(buf, strm->next_in, len); @@ -1604,10 +1543,10 @@ Index: zlib-1.2.11/deflate.c strm->adler = adler32(strm->adler, buf, len); } #ifdef GZIP -Index: zlib-1.2.11/deflate.h +Index: zlib-1.2.12/deflate.h =================================================================== ---- zlib-1.2.11.orig/deflate.h -+++ zlib-1.2.11/deflate.h +--- zlib-1.2.12.orig/deflate.h ++++ zlib-1.2.12/deflate.h @@ -299,6 +299,7 @@ void ZLIB_INTERNAL _tr_flush_bits OF((de void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, @@ -1632,10 +1571,10 @@ Index: zlib-1.2.11/deflate.h +void ZLIB_INTERNAL flush_pending OF((z_streamp strm)); + #endif /* DEFLATE_H */ -Index: zlib-1.2.11/gzguts.h +Index: zlib-1.2.12/gzguts.h =================================================================== ---- zlib-1.2.11.orig/gzguts.h -+++ zlib-1.2.11/gzguts.h +--- zlib-1.2.12.orig/gzguts.h ++++ zlib-1.2.12/gzguts.h @@ -153,7 +153,11 @@ /* default i/o buffer size -- double this for output when reading (this and @@ -1648,10 +1587,10 @@ Index: zlib-1.2.11/gzguts.h /* gzip modes, also provide a little integrity check on the passed structure */ #define GZ_NONE 0 -Index: zlib-1.2.11/inflate.c +Index: zlib-1.2.12/inflate.c =================================================================== ---- zlib-1.2.11.orig/inflate.c -+++ zlib-1.2.11/inflate.c +--- zlib-1.2.12.orig/inflate.c ++++ zlib-1.2.12/inflate.c @@ -85,6 +85,24 @@ #include "inflate.h" #include "inffast.h" @@ -1677,7 +1616,7 @@ Index: zlib-1.2.11/inflate.c #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED -@@ -137,6 +155,7 @@ z_streamp strm; +@@ -138,6 +156,7 @@ z_streamp strm; state->lencode = state->distcode = state->next = state->codes; state->sane = 1; state->back = -1; @@ -1685,7 +1624,7 @@ Index: zlib-1.2.11/inflate.c Tracev((stderr, "inflate: reset\n")); return Z_OK; } -@@ -182,7 +201,7 @@ int windowBits; +@@ -183,7 +202,7 @@ int windowBits; if (windowBits && (windowBits < 8 || windowBits > 15)) return Z_STREAM_ERROR; if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { @@ -1694,7 +1633,7 @@ Index: zlib-1.2.11/inflate.c state->window = Z_NULL; } -@@ -218,7 +237,7 @@ int stream_size; +@@ -219,7 +238,7 @@ int stream_size; strm->zfree = zcfree; #endif state = (struct inflate_state FAR *) @@ -1703,7 +1642,7 @@ Index: zlib-1.2.11/inflate.c if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; -@@ -227,7 +246,7 @@ int stream_size; +@@ -228,7 +247,7 @@ int stream_size; state->mode = HEAD; /* to pass state test in inflateReset2() */ ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { @@ -1712,7 +1651,7 @@ Index: zlib-1.2.11/inflate.c strm->state = Z_NULL; } return ret; -@@ -249,6 +268,7 @@ int value; +@@ -250,6 +269,7 @@ int value; struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1720,7 +1659,7 @@ Index: zlib-1.2.11/inflate.c state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; -@@ -376,6 +396,27 @@ void makefixed() +@@ -377,6 +397,27 @@ void makefixed() } #endif /* MAKEFIXED */ @@ -1748,7 +1687,7 @@ Index: zlib-1.2.11/inflate.c /* 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 -@@ -400,20 +441,7 @@ unsigned copy; +@@ -401,20 +442,7 @@ unsigned copy; state = (struct inflate_state FAR *)strm->state; @@ -1770,24 +1709,24 @@ Index: zlib-1.2.11/inflate.c /* copy state->wsize or less output bytes into the circular window */ if (copy >= state->wsize) { -@@ -846,6 +874,7 @@ int flush; - case TYPE: +@@ -857,6 +885,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; -@@ -1197,7 +1226,7 @@ int flush; +@@ -1218,7 +1247,7 @@ int flush; out -= left; strm->total_out += out; state->total += out; - if ((state->wrap & 4) && out) + if (INFLATE_NEED_CHECKSUM(strm) && (state->wrap & 4) && out) strm->adler = state->check = - UPDATE(state->check, put - out, out); + UPDATE_CHECK(state->check, put - out, out); out = left; -@@ -1249,8 +1278,9 @@ int flush; +@@ -1273,8 +1302,9 @@ int flush; */ inf_leave: RESTORE(); @@ -1799,16 +1738,16 @@ Index: zlib-1.2.11/inflate.c if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; -@@ -1260,7 +1290,7 @@ int flush; +@@ -1284,7 +1314,7 @@ int flush; strm->total_in += in; strm->total_out += out; state->total += out; - if ((state->wrap & 4) && out) + if (INFLATE_NEED_CHECKSUM(strm) && (state->wrap & 4) && out) strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); + UPDATE_CHECK(state->check, strm->next_out - out, out); strm->data_type = (int)state->bits + (state->last ? 64 : 0) + -@@ -1278,8 +1308,8 @@ z_streamp strm; +@@ -1302,8 +1332,8 @@ z_streamp strm; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; @@ -1819,7 +1758,7 @@ Index: zlib-1.2.11/inflate.c strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; -@@ -1451,6 +1481,7 @@ z_streamp strm; +@@ -1482,6 +1512,7 @@ z_streamp strm; struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1827,7 +1766,7 @@ Index: zlib-1.2.11/inflate.c state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } -@@ -1471,21 +1502,22 @@ z_streamp source; +@@ -1502,21 +1533,22 @@ z_streamp source; /* allocate space */ copy = (struct inflate_state FAR *) @@ -1854,7 +1793,7 @@ Index: zlib-1.2.11/inflate.c copy->strm = dest; if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { -@@ -1542,6 +1574,7 @@ z_streamp strm; +@@ -1573,6 +1605,7 @@ z_streamp strm; if (inflateStateCheck(strm)) return -(1L << 16); @@ -1862,20 +1801,20 @@ Index: zlib-1.2.11/inflate.c state = (struct inflate_state FAR *)strm->state; return (long)(((unsigned long)((long)state->back)) << 16) + (state->mode == COPY ? state->length : -Index: zlib-1.2.11/inflate.h +Index: zlib-1.2.12/inflate.h =================================================================== ---- zlib-1.2.11.orig/inflate.h -+++ zlib-1.2.11/inflate.h -@@ -123,3 +123,5 @@ struct inflate_state { +--- zlib-1.2.12.orig/inflate.h ++++ zlib-1.2.12/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)); -Index: zlib-1.2.11/test/infcover.c +Index: zlib-1.2.12/test/infcover.c =================================================================== ---- zlib-1.2.11.orig/test/infcover.c -+++ zlib-1.2.11/test/infcover.c +--- zlib-1.2.12.orig/test/infcover.c ++++ zlib-1.2.12/test/infcover.c @@ -373,7 +373,7 @@ local void cover_support(void) mem_setup(&strm); strm.avail_in = 0; @@ -1894,10 +1833,10 @@ Index: zlib-1.2.11/test/infcover.c { static unsigned int next = 0; static unsigned char dat[] = {0x63, 0, 2, 0}; -Index: zlib-1.2.11/test/minigzip.c +Index: zlib-1.2.12/test/minigzip.c =================================================================== ---- zlib-1.2.11.orig/test/minigzip.c -+++ zlib-1.2.11/test/minigzip.c +--- zlib-1.2.12.orig/test/minigzip.c ++++ zlib-1.2.12/test/minigzip.c @@ -132,7 +132,11 @@ static void pwinerror (s) #endif #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) @@ -1910,15 +1849,15 @@ Index: zlib-1.2.11/test/minigzip.c #define MAX_NAME_LEN 1024 #ifdef MAXSEG_64K -Index: zlib-1.2.11/trees.c +Index: zlib-1.2.12/trees.c =================================================================== ---- zlib-1.2.11.orig/trees.c -+++ zlib-1.2.11/trees.c +--- zlib-1.2.12.orig/trees.c ++++ zlib-1.2.12/trees.c @@ -149,8 +149,6 @@ local void send_all_trees OF((deflate_st local void compress_block OF((deflate_state *s, const ct_data *ltree, const ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); --local unsigned bi_reverse OF((unsigned value, int length)); +-local unsigned bi_reverse OF((unsigned code, int len)); -local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); @@ -1937,7 +1876,7 @@ Index: zlib-1.2.11/trees.c /* the arguments must not have side effects */ -@@ -1133,7 +1138,7 @@ local int detect_data_type(s) +@@ -1134,7 +1139,7 @@ local int detect_data_type(s) * method would use a table) * IN assertion: 1 <= len <= 15 */ @@ -1946,7 +1885,7 @@ Index: zlib-1.2.11/trees.c unsigned code; /* the value to invert */ int len; /* its bit length */ { -@@ -1165,7 +1170,7 @@ local void bi_flush(s) +@@ -1166,7 +1171,7 @@ local void bi_flush(s) /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ @@ -1955,11 +1894,11 @@ Index: zlib-1.2.11/trees.c deflate_state *s; { if (s->bi_valid > 8) { -Index: zlib-1.2.11/zutil.h +Index: zlib-1.2.12/zutil.h =================================================================== ---- zlib-1.2.11.orig/zutil.h -+++ zlib-1.2.11/zutil.h -@@ -80,6 +80,8 @@ extern z_const char * const z_errmsg[10] +--- zlib-1.2.12.orig/zutil.h ++++ zlib-1.2.12/zutil.h +@@ -87,6 +87,8 @@ extern z_const char * const z_errmsg[10] #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ 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 new file mode 100644 index 0000000..62cbeb4 --- /dev/null +++ b/zlib-1.2.12-correct-inputs-provided-to-crc-func.patch @@ -0,0 +1,51 @@ +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 new file mode 100644 index 0000000..e5c1e87 --- /dev/null +++ b/zlib-1.2.12-fix-CVE-2022-37434.patch @@ -0,0 +1,14 @@ +--- 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 new file mode 100644 index 0000000..a117b48 --- /dev/null +++ b/zlib-1.2.12-fix-configure.patch @@ -0,0 +1,24 @@ +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-power8-fate325307.patch b/zlib-1.2.12-optimized-crc32-power8.patch similarity index 75% rename from zlib-power8-fate325307.patch rename to zlib-1.2.12-optimized-crc32-power8.patch index a422789..5256e51 100644 --- a/zlib-power8-fate325307.patch +++ b/zlib-1.2.12-optimized-crc32-power8.patch @@ -1,26 +1,450 @@ -From 25cd259b18b2dc7192837594556644a300dbf5d1 Mon Sep 17 00:00:00 2001 -From: Daniel Black -Date: Wed, 10 Jan 2018 10:50:39 +1100 -Subject: [PATCH 1/8] Add Power8+ optimized crc32-vpmsum from - https://github.com/antonblanchard/crc32-vpmsum/ +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 -This is the C implementation created by Rogerio Alves -Bruce R. - Tweaked patch to have type of crc32_vpmsum conform to usage -(see bsc#1141059) --- - power8-crc/clang_workaround.h | 69 +++ - power8-crc/crc32_constants.h | 1206 +++++++++++++++++++++++++++++++++++++++++ - power8-crc/vec_crc32.c | 672 +++++++++++++++++++++++ - 3 files changed, 1947 insertions(+) - create mode 100644 power8-crc/clang_workaround.h - create mode 100644 power8-crc/crc32_constants.h - create mode 100644 power8-crc/vec_crc32.c + 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(-) + 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 -Index: zlib-1.2.11/contrib/power8-crc/clang_workaround.h -=================================================================== +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e6fbb37d1..581e1fa6d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -7,6 +7,7 @@ set(VERSION "1.2.12") + + 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() ++ ++ # test to see if we can use a GNU indirect function to detect and load optimized code at runtime ++ CHECK_C_SOURCE_COMPILES(" ++ static int test_ifunc_native(void) ++ { ++ return 1; ++ } ++ static int (*(check_ifunc_native(void)))(void) ++ { ++ return test_ifunc_native; ++ } ++ int test_ifunc(void) __attribute__ ((ifunc (\"check_ifunc_native\"))); ++ int main(void) ++ { ++ return 0; ++ } ++ " HAS_C_ATTR_IFUNC) ++ ++ if(HAS_C_ATTR_IFUNC) ++ add_definitions(-DHAVE_IFUNC) ++ set(ZLIB_PRIVATE_HDRS ${ZLIB_PRIVATE_HDRS} contrib/gcc/zifunc.h) ++ endif() ++ ++ if(POWER) ++ # Test to see if we can use the optimizations for Power ++ CHECK_C_SOURCE_COMPILES(" ++ #ifndef _ARCH_PPC ++ #error \"Target is not Power\" ++ #endif ++ #ifndef __BUILTIN_CPU_SUPPORTS__ ++ #error \"Target doesn't support __builtin_cpu_supports()\" ++ #endif ++ int main() { return 0; } ++ " HAS_POWER_SUPPORT) ++ ++ if(HAS_POWER_SUPPORT AND HAS_C_ATTR_IFUNC) ++ add_definitions(-DZ_POWER_OPT) ++ ++ set(CMAKE_REQUIRED_FLAGS -mcpu=power8) ++ CHECK_C_SOURCE_COMPILES("int main(void){return 0;}" POWER8) ++ ++ if(POWER8) ++ add_definitions(-DZ_POWER8) ++ set(ZLIB_POWER8 ++ contrib/power/crc32_z_power8.c) ++ ++ set_source_files_properties( ++ ${ZLIB_POWER8} ++ PROPERTIES COMPILE_FLAGS -mcpu=power8) ++ endif() ++ ++ set(CMAKE_REQUIRED_FLAGS -mcpu=power9) ++ CHECK_C_SOURCE_COMPILES("int main(void){return 0;}" POWER9) ++ ++ if(POWER9) ++ add_definitions(-DZ_POWER9) ++ set(ZLIB_POWER9 ) ++ ++ set_source_files_properties( ++ ${ZLIB_POWER9} ++ PROPERTIES COMPILE_FLAGS -mcpu=power9) ++ endif() ++ ++ set(ZLIB_PRIVATE_HDRS ${ZLIB_PRIVATE_HDRS} contrib/power/power.h) ++ 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) ++ + 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 +diff --git a/configure b/configure +index a21be36af..cff6207ec 100755 +--- a/configure ++++ b/configure +@@ -857,6 +857,75 @@ 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 <> configure.log ++cat > $test.c < $test.c ++ ++ 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" ++ echo "Checking for -mcpu=power8 support... Yes." | tee -a configure.log ++ else ++ echo "Checking for -mcpu=power8 support... No." | tee -a configure.log ++ fi ++ ++ if tryboth $CC -c $CFLAGS -mcpu=power9 $test.c; then ++ POWER9="-DZ_POWER9" ++ PIC_OBJC="${PIC_OBJC}" ++ OBJC="${OBJC}" ++ echo "Checking for -mcpu=power9 support... Yes." | tee -a configure.log ++ else ++ echo "Checking for -mcpu=power9 support... No." | tee -a configure.log ++ fi ++ ++ SFLAGS="${SFLAGS} ${POWER8} ${POWER9} -DZ_POWER_OPT" ++ CFLAGS="${CFLAGS} ${POWER8} ${POWER9} -DZ_POWER_OPT" ++ echo "Checking for Power optimizations support... Yes." | tee -a configure.log ++else ++ echo "Checking for Power optimizations support... 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 130a28bdb..1199184b7 100644 +--- a/contrib/README.contrib ++++ b/contrib/README.contrib +@@ -11,6 +11,10 @@ ada/ by Dmitriy Anisimkov + blast/ by Mark Adler + Decompressor for output of PKWare Data Compression Library (DCL) + ++gcc/ by Matheus Castanho ++ and Rogerio Alves ++ Optimization helpers using GCC-specific extensions ++ + delphi/ by Cosmin Truta + Support for Delphi and C++ Builder + +@@ -42,6 +46,11 @@ minizip/ by Gilles Vollant + pascal/ by Bob Dellaca et al. + Support for Pascal + ++power/ by Daniel Black ++ Matheus Castanho ++ and Rogerio Alves ++ Optimized functions for Power processors ++ + puff/ by Mark Adler + Small, low memory usage inflate. Also serves to provide an + unambiguous description of the deflate format. +diff --git a/contrib/gcc/zifunc.h b/contrib/gcc/zifunc.h +new file mode 100644 +index 000000000..daf4fe442 --- /dev/null -+++ zlib-1.2.11/contrib/power8-crc/clang_workaround.h -@@ -0,0 +1,82 @@ ++++ b/contrib/gcc/zifunc.h +@@ -0,0 +1,60 @@ ++/* Copyright (C) 2019 Matheus Castanho , IBM ++ * 2019 Rogerio Alves , IBM ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#ifndef Z_IFUNC_H_ ++#define Z_IFUNC_H_ ++ ++/* Helpers for arch optimizations */ ++ ++#define Z_IFUNC(fname) \ ++ typeof(fname) fname __attribute__ ((ifunc (#fname "_resolver"))); \ ++ local typeof(fname) *fname##_resolver(void) ++/* This is a helper macro to declare a resolver for an indirect function ++ * (ifunc). Let's say you have function ++ * ++ * int foo (int a); ++ * ++ * for which you want to provide different implementations, for example: ++ * ++ * int foo_clever (int a) { ++ * ... clever things ... ++ * } ++ * ++ * int foo_smart (int a) { ++ * ... smart things ... ++ * } ++ * ++ * You will have to declare foo() as an indirect function and also provide a ++ * resolver for it, to choose between foo_clever() and foo_smart() based on ++ * some criteria you define (e.g. processor features). ++ * ++ * Since most likely foo() has a default implementation somewhere in zlib, you ++ * may have to rename it so the 'foo' symbol can be used by the ifunc without ++ * conflicts. ++ * ++ * #define foo foo_default ++ * int foo (int a) { ++ * ... ++ * } ++ * #undef foo ++ * ++ * Now you just have to provide a resolver function to choose which function ++ * should be used (decided at runtime on the first call to foo()): ++ * ++ * Z_IFUNC(foo) { ++ * if (... some condition ...) ++ * return foo_clever; ++ * ++ * if (... other condition ...) ++ * return foo_smart; ++ * ++ * return foo_default; ++ * } ++ * ++ * All calls to foo() throughout the code can remain untouched, all the magic ++ * will be done by the linker using the resolver function. ++ */ ++ ++#endif /* Z_IFUNC_H_ */ +diff --git a/contrib/power/clang_workaround.h b/contrib/power/clang_workaround.h +new file mode 100644 +index 000000000..915f7e528 +--- /dev/null ++++ b/contrib/power/clang_workaround.h +@@ -0,0 +1,87 @@ +#ifndef CLANG_WORKAROUNDS_H +#define CLANG_WORKAROUNDS_H + @@ -62,7 +486,12 @@ Index: zlib-1.2.11/contrib/power8-crc/clang_workaround.h + 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, @@ -85,9 +514,9 @@ Index: zlib-1.2.11/contrib/power8-crc/clang_workaround.h +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 +} + @@ -95,18 +524,19 @@ Index: zlib-1.2.11/contrib/power8-crc/clang_workaround.h +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 */ + +#endif -Index: zlib-1.2.11/contrib/power8-crc/crc32_constants.h -=================================================================== +diff --git a/contrib/power/crc32_constants.h b/contrib/power/crc32_constants.h +new file mode 100644 +index 000000000..58088dcc0 --- /dev/null -+++ zlib-1.2.11/contrib/power8-crc/crc32_constants.h ++++ b/contrib/power/crc32_constants.h @@ -0,0 +1,1206 @@ +/* +* @@ -1314,10 +1744,11 @@ Index: zlib-1.2.11/contrib/power8-crc/crc32_constants.h +#endif /* POWER8_INTRINSICS */ + +#endif /* __ASSEMBLER__ */ -Index: zlib-1.2.11/contrib/power8-crc/vec_crc32.c -=================================================================== +diff --git a/contrib/power/crc32_z_power8.c b/contrib/power/crc32_z_power8.c +new file mode 100644 +index 000000000..7858cfe0e --- /dev/null -+++ zlib-1.2.11/contrib/power8-crc/vec_crc32.c ++++ b/contrib/power/crc32_z_power8.c @@ -0,0 +1,679 @@ +/* + * Calculate the checksum of data that is 16 byte aligned and a multiple of @@ -1351,6 +1782,8 @@ Index: zlib-1.2.11/contrib/power8-crc/vec_crc32.c + */ + +#include ++#include "../../zutil.h" ++#include "power.h" + +#define POWER8_INTRINSICS +#define CRC_TABLE @@ -1361,8 +1794,6 @@ Index: zlib-1.2.11/contrib/power8-crc/vec_crc32.c +#include "crc32_constants.h" +#endif + -+#include -+ +#define VMX_ALIGN 16 +#define VMX_ALIGN_MASK (VMX_ALIGN-1) + @@ -1387,19 +1818,18 @@ Index: zlib-1.2.11/contrib/power8-crc/vec_crc32.c +static unsigned int __attribute__ ((aligned (32))) +__crc32_vpmsum(unsigned int crc, const void* p, unsigned long len); + -+#ifndef CRC32_FUNCTION -+#define CRC32_FUNCTION crc32_vpmsum -+#endif -+ -+unsigned long CRC32_FUNCTION(unsigned long crc_l, const unsigned char *p, -+ unsigned long len) ++unsigned long ZLIB_INTERNAL _crc32_z_power8(uLong _crc, const Bytef *_p, ++ z_size_t _len) +{ -+ unsigned int prealign, crc = (unsigned int)crc_l; ++ unsigned int prealign; + unsigned int tail; + -+ /* For zlib API */ -+ if (p == NULL) return 0UL; ++ /* Map zlib API to crc32_vpmsum API */ ++ unsigned int crc = (unsigned int) (0xffffffff & _crc); ++ const unsigned char *p = _p; ++ unsigned long len = (unsigned long) _len; + ++ if (p == (const unsigned char *) 0x0) return 0; +#ifdef CRC_XOR + crc ^= 0xffffffff; +#endif @@ -1429,7 +1859,8 @@ Index: zlib-1.2.11/contrib/power8-crc/vec_crc32.c + crc ^= 0xffffffff; +#endif + -+ return (unsigned long)crc; ++ /* Convert to zlib API */ ++ return (unsigned long) crc; +} + +#if defined (__clang__) @@ -1998,268 +2429,279 @@ Index: zlib-1.2.11/contrib/power8-crc/vec_crc32.c + + return result; +} -Index: zlib-1.2.11/Makefile.in -=================================================================== ---- zlib-1.2.11.orig/Makefile.in -+++ zlib-1.2.11/Makefile.in -@@ -162,6 +162,9 @@ adler32.o: $(SRCDIR)adler32.c - crc32.o: $(SRCDIR)crc32.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c - -+crc32_power8.o: $(SRCDIR)contrib/power8-crc/vec_crc32.c -+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)contrib/power8-crc/vec_crc32.c +diff --git a/contrib/power/crc32_z_resolver.c b/contrib/power/crc32_z_resolver.c +new file mode 100644 +index 000000000..f4e9aa491 +--- /dev/null ++++ b/contrib/power/crc32_z_resolver.c +@@ -0,0 +1,15 @@ ++/* Copyright (C) 2019 Matheus Castanho , IBM ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ + - deflate.o: $(SRCDIR)deflate.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c - -@@ -212,6 +215,11 @@ crc32.lo: $(SRCDIR)crc32.c - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c - -@mv objs/crc32.o $@ - -+crc32_power8.lo: $(SRCDIR)contrib/power8-crc/vec_crc32.c -+ -@mkdir objs 2>/dev/null || test -d objs -+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32_power8.o $(SRCDIR)contrib/power8-crc/vec_crc32.c -+ -@mv objs/crc32_power8.o $@ ++#include "../gcc/zifunc.h" ++#include "power.h" + - 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 -Index: zlib-1.2.11/configure -=================================================================== ---- zlib-1.2.11.orig/configure -+++ zlib-1.2.11/configure -@@ -826,6 +826,91 @@ EOF - fi - fi - -+# test to see if Power8+ implementation is compile time possible -+echo >> configure.log -+cat > $test.c < -+#include -+int main() -+{ -+ return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); ++ return crc32_z_default; +} -+#endif +diff --git a/contrib/power/power.h b/contrib/power/power.h +new file mode 100644 +index 000000000..79123aa90 +--- /dev/null ++++ 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 ++ */ + -+#else -+#error No Power 8 or newer architecture, may need -mcpu=power8 -+#endif -+EOF ++#include "../../zconf.h" + -+if tryboth $CC -c $CFLAGS $test.c; then -+ OBJC="$OBJC crc32_power8.o" -+ PIC_OBJC="$PIC_OBJC crc32_power8.lo" -+ echo "Checking for runtime cpu detection and Power 8 (or newer) Architecture support... Yes." | tee -a configure.log -+else -+ echo "Checking for runtime cpu detection and Power 8 (or newer) Architecture support... 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 <> configure.log -+ cat > $test.c <> configure.log - echo ALL = $ALL >> configure.log -Index: zlib-1.2.11/crc32.c -=================================================================== ---- zlib-1.2.11.orig/crc32.c -+++ zlib-1.2.11/crc32.c -@@ -199,13 +199,78 @@ const z_crc_t FAR * ZEXPORT get_crc_tabl - #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 ++unsigned long _crc32_z_power8(unsigned long, const Bytef *, z_size_t); +diff --git a/crc32.c b/crc32.c +index a1bdce5c2..ae7b7e792 100644 +--- a/crc32.c ++++ b/crc32.c +@@ -736,6 +736,13 @@ local z_word_t crc_word_big(data) + #endif /* ========================================================================= */ --unsigned long ZEXPORT crc32_z(crc, buf, len) -+local -+unsigned long ZEXPORT crc32_table_lookup(crc, buf, len) ++#ifdef Z_POWER_OPT ++/* Rename function so resolver can use its symbol. The default version will be ++ * returned by the resolver if the host has no support for an optimized version. ++ */ ++#define crc32_z crc32_z_default ++#endif /* Z_POWER_OPT */ ++ + unsigned long ZEXPORT crc32_z(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; - z_size_t len; - { - if (buf == Z_NULL) return 0UL; - -+ crc = crc ^ 0xffffffffUL; -+ while (len >= 8) { -+ DO8; -+ len -= 8; -+ } -+ if (len) do { -+ DO1; -+ } while (--len); -+ return crc ^ 0xffffffffUL; -+} -+ -+/* Small helper function to compare optfun against the reference table lookup -+ * return test_ref_comparision_##optfn in crc32_z_ifunc -+#include -+#define TEST_COMPARE(optfn) \ -+ static unsigned long test_ref_comparision_ ## optfn(unsigned long crc, const unsigned char FAR *p, z_size_t len) \ -+ { \ -+ unsigned long crc_tbl_lookup = crc32_table_lookup(crc, p, len); \ -+ unsigned long optcrc = optfn(crc, p, len); \ -+ assert( optcrc == crc_tbl_lookup ); \ -+ return optcrc; \ -+ } -+*/ -+ -+#ifdef Z_IFUNC_ASM -+unsigned long (*(crc32_z_ifunc(void)))(unsigned long, const unsigned char FAR *, z_size_t) -+ __asm__ ("crc32_z"); -+__asm__(".type crc32_z, %gnu_indirect_function"); -+#elif defined(Z_IFUNC_NATIVE) -+unsigned long ZEXPORT crc32_z( -+ unsigned long crc, -+ const unsigned char FAR *buf, -+ z_size_t len) -+ __attribute__ ((ifunc ("crc32_z_ifunc"))); -+#endif -+ -+#if _ARCH_PWR8==1 -+unsigned long crc32_vpmsum(unsigned long, const unsigned char FAR *, z_size_t); -+/* for testing TEST_COMPARE(crc32_vpmsum) */ -+#ifndef __BUILTIN_CPU_SUPPORTS__ -+#include -+#include -+#endif -+#endif -+ -+/* due to a quirk of gnu_indirect_function - "local" (aka static) is applied to -+ * crc32_z which is not desired. crc32_z_ifunc is implictly "local" */ -+#ifndef Z_IFUNC_ASM -+local -+#endif -+unsigned long (*(crc32_z_ifunc(void)))(unsigned long, const unsigned char FAR *, z_size_t) -+{ -+#if _ARCH_PWR8==1 -+#if defined(__BUILTIN_CPU_SUPPORTS__) -+ if (__builtin_cpu_supports("arch_2_07")) -+ return crc32_vpmsum; -+#else -+ if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) -+ return crc32_vpmsum; -+#endif -+#endif /* _ARCH_PWR8 */ -+ -+/* return a function pointer for optimized arches here */ -+ - #ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -@@ -217,22 +282,31 @@ unsigned long ZEXPORT crc32_z(crc, buf, - - endian = 1; - if (*((unsigned char *)(&endian))) -- return crc32_little(crc, buf, len); -+ return crc32_little; - else -- return crc32_big(crc, buf, len); -+ return crc32_big; - } - #endif /* BYFOUR */ -- crc = crc ^ 0xffffffffUL; -- while (len >= 8) { -- DO8; -- len -= 8; -- } -- if (len) do { -- DO1; -- } while (--len); -- return crc ^ 0xffffffffUL; -+ -+ return crc32_table_lookup; -+} -+ -+#if !defined(Z_IFUNC_ASM) && !defined(Z_IFUNC_NATIVE) -+ -+unsigned long ZEXPORT crc32_z(crc, buf, len) -+ unsigned long crc; -+ const unsigned char FAR *buf; -+ z_size_t len; -+{ -+ static unsigned long ZEXPORT (*crc32_func)(unsigned long, const unsigned char FAR *, z_size_t) = NULL; -+ -+ if (!crc32_func) -+ crc32_func = crc32_z_ifunc(); -+ return (*crc32_func)(crc, buf, len); +@@ -1057,6 +1064,11 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) + return crc ^ 0xffffffff; } -+#endif /* defined(Z_IFUNC_ASM) || defined(Z_IFUNC_NATIVE) */ ++#ifdef Z_POWER_OPT ++#undef crc32_z ++#include "contrib/power/crc32_z_resolver.c" ++#endif /* Z_POWER_OPT */ + + #endif + /* ========================================================================= */ - unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; -@@ -271,6 +345,7 @@ local unsigned long crc32_little(crc, bu - register z_crc_t c; - register const z_crc_t FAR *buf4; - -+ if (buf == Z_NULL) return 0UL; - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { -@@ -311,6 +386,7 @@ local unsigned long crc32_big(crc, buf, - register z_crc_t c; - register const z_crc_t FAR *buf4; - -+ if (buf == Z_NULL) return 0UL; - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { +diff --git a/test/crc32_test.c b/test/crc32_test.c +new file mode 100644 +index 000000000..3155553e6 +--- /dev/null ++++ b/test/crc32_test.c +@@ -0,0 +1,205 @@ ++/* crc32_tes.c -- unit test for crc32 in the zlib compression library ++ * Copyright (C) 1995-2006, 2010, 2011, 2016, 2019 Rogerio Alves ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include "zlib.h" ++#include ++ ++#ifdef STDC ++# include ++# include ++#endif ++ ++void test_crc32 OF((uLong crc, Byte* buf, z_size_t len, uLong chk, int line)); ++int main OF((void)); ++ ++typedef struct { ++ int line; ++ uLong crc; ++ char* buf; ++ int len; ++ uLong expect; ++} crc32_test; ++ ++void test_crc32(crc, buf, len, chk, line) ++ uLong crc; ++ Byte *buf; ++ z_size_t len; ++ uLong chk; ++ int line; ++{ ++ uLong res = crc32(crc, buf, len); ++ if (res != chk) { ++ fprintf(stderr, "FAIL [%d]: crc32 returned 0x%08X expected 0x%08X\n", ++ line, (unsigned int)res, (unsigned int)chk); ++ exit(1); ++ } ++} ++ ++static const crc32_test tests[] = { ++ {__LINE__, 0x0, 0x0, 0, 0x0}, ++ {__LINE__, 0xffffffff, 0x0, 0, 0x0}, ++ {__LINE__, 0x0, 0x0, 255, 0x0}, /* BZ 174799. */ ++ {__LINE__, 0x0, 0x0, 256, 0x0}, ++ {__LINE__, 0x0, 0x0, 257, 0x0}, ++ {__LINE__, 0x0, 0x0, 32767, 0x0}, ++ {__LINE__, 0x0, 0x0, 32768, 0x0}, ++ {__LINE__, 0x0, 0x0, 32769, 0x0}, ++ {__LINE__, 0x0, "", 0, 0x0}, ++ {__LINE__, 0xffffffff, "", 0, 0xffffffff}, ++ {__LINE__, 0x0, "abacus", 6, 0xc3d7115b}, ++ {__LINE__, 0x0, "backlog", 7, 0x269205}, ++ {__LINE__, 0x0, "campfire", 8, 0x22a515f8}, ++ {__LINE__, 0x0, "delta", 5, 0x9643fed9}, ++ {__LINE__, 0x0, "executable", 10, 0xd68eda01}, ++ {__LINE__, 0x0, "file", 4, 0x8c9f3610}, ++ {__LINE__, 0x0, "greatest", 8, 0xc1abd6cd}, ++ {__LINE__, 0x0, "hello", 5, 0x3610a686}, ++ {__LINE__, 0x0, "inverter", 8, 0xc9e962c9}, ++ {__LINE__, 0x0, "jigsaw", 6, 0xce4e3f69}, ++ {__LINE__, 0x0, "karate", 6, 0x890be0e2}, ++ {__LINE__, 0x0, "landscape", 9, 0xc4e0330b}, ++ {__LINE__, 0x0, "machine", 7, 0x1505df84}, ++ {__LINE__, 0x0, "nanometer", 9, 0xd4e19f39}, ++ {__LINE__, 0x0, "oblivion", 8, 0xdae9de77}, ++ {__LINE__, 0x0, "panama", 6, 0x66b8979c}, ++ {__LINE__, 0x0, "quest", 5, 0x4317f817}, ++ {__LINE__, 0x0, "resource", 8, 0xbc91f416}, ++ {__LINE__, 0x0, "secret", 6, 0x5ca2e8e5}, ++ {__LINE__, 0x0, "test", 4, 0xd87f7e0c}, ++ {__LINE__, 0x0, "ultimate", 8, 0x3fc79b0b}, ++ {__LINE__, 0x0, "vector", 6, 0x1b6e485b}, ++ {__LINE__, 0x0, "walrus", 6, 0xbe769b97}, ++ {__LINE__, 0x0, "xeno", 4, 0xe7a06444}, ++ {__LINE__, 0x0, "yelling", 7, 0xfe3944e5}, ++ {__LINE__, 0x0, "zlib", 4, 0x73887d3a}, ++ {__LINE__, 0x0, "4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1}, ++ {__LINE__, 0x0, "F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e}, ++ {__LINE__, 0x0, "ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76}, ++ {__LINE__, 0x0, "5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a}, ++ {__LINE__, 0x0, "0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d}, ++ {__LINE__, 0x0, "MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5}, ++ {__LINE__, 0x0, "UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11}, ++ {__LINE__, 0x0, "dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac}, ++ {__LINE__, 0x0, "di0nvmY9UYMYDh0r45XT", 20, 0x625437bb}, ++ {__LINE__, 0x0, "2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9}, ++ {__LINE__, 0x0, "ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37}, ++ {__LINE__, 0x0, "v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0}, ++ {__LINE__, 0x0, "Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29}, ++ {__LINE__, 0x0, "GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8}, ++ {__LINE__, 0x0, "kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192}, ++ {__LINE__, 0x0, "70684206568419061514", 20, 0x59a179f0}, ++ {__LINE__, 0x0, "42015093765128581010", 20, 0xcd1013d7}, ++ {__LINE__, 0x0, "88214814356148806939", 20, 0xab927546}, ++ {__LINE__, 0x0, "43472694284527343838", 20, 0x11f3b20c}, ++ {__LINE__, 0x0, "49769333513942933689", 20, 0xd562d4ca}, ++ {__LINE__, 0x0, "54979784887993251199", 20, 0x233395f7}, ++ {__LINE__, 0x0, "58360544869206793220", 20, 0x2d167fd5}, ++ {__LINE__, 0x0, "27347953487840714234", 20, 0x8b5108ba}, ++ {__LINE__, 0x0, "07650690295365319082", 20, 0xc46b3cd8}, ++ {__LINE__, 0x0, "42655507906821911703", 20, 0xc10b2662}, ++ {__LINE__, 0x0, "29977409200786225655", 20, 0xc9a0f9d2}, ++ {__LINE__, 0x0, "85181542907229116674", 20, 0x9341357b}, ++ {__LINE__, 0x0, "87963594337989416799", 20, 0xf0424937}, ++ {__LINE__, 0x0, "21395988329504168551", 20, 0xd7c4c31f}, ++ {__LINE__, 0x0, "51991013580943379423", 20, 0xf11edcc4}, ++ {__LINE__, 0x0, "*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4}, ++ {__LINE__, 0x0, "_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631}, ++ {__LINE__, 0x0, "&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99}, ++ {__LINE__, 0x0, "]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac}, ++ {__LINE__, 0x0, "-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9}, ++ {__LINE__, 0x0, "+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf}, ++ {__LINE__, 0x0, ")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac}, ++ {__LINE__, 0x0, ":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388}, ++ {__LINE__, 0x0, "{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d}, ++ {__LINE__, 0x0, "_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5}, ++ {__LINE__, 0x0, "e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9}, ++ {__LINE__, 0x0, "r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777}, ++ {__LINE__, 0x0, "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048}, ++ {__LINE__, 0x7a30360d, "abacus", 6, 0xf8655a84}, ++ {__LINE__, 0x6fd767ee, "backlog", 7, 0x1ed834b1}, ++ {__LINE__, 0xefeb7589, "campfire", 8, 0x686cfca}, ++ {__LINE__, 0x61cf7e6b, "delta", 5, 0x1554e4b1}, ++ {__LINE__, 0xdc712e2, "executable", 10, 0x761b4254}, ++ {__LINE__, 0xad23c7fd, "file", 4, 0x7abdd09b}, ++ {__LINE__, 0x85cb2317, "greatest", 8, 0x4ba91c6b}, ++ {__LINE__, 0x9eed31b0, "inverter", 8, 0xd5e78ba5}, ++ {__LINE__, 0xb94f34ca, "jigsaw", 6, 0x23649109}, ++ {__LINE__, 0xab058a2, "karate", 6, 0xc5591f41}, ++ {__LINE__, 0x5bff2b7a, "landscape", 9, 0xf10eb644}, ++ {__LINE__, 0x605c9a5f, "machine", 7, 0xbaa0a636}, ++ {__LINE__, 0x51bdeea5, "nanometer", 9, 0x6af89afb}, ++ {__LINE__, 0x85c21c79, "oblivion", 8, 0xecae222b}, ++ {__LINE__, 0x97216f56, "panama", 6, 0x47dffac4}, ++ {__LINE__, 0x18444af2, "quest", 5, 0x70c2fe36}, ++ {__LINE__, 0xbe6ce359, "resource", 8, 0x1471d925}, ++ {__LINE__, 0x843071f1, "secret", 6, 0x50c9a0db}, ++ {__LINE__, 0xf2480c60, "ultimate", 8, 0xf973daf8}, ++ {__LINE__, 0x2d2feb3d, "vector", 6, 0x344ac03d}, ++ {__LINE__, 0x7490310a, "walrus", 6, 0x6d1408ef}, ++ {__LINE__, 0x97d247d4, "xeno", 4, 0xe62670b5}, ++ {__LINE__, 0x93cf7599, "yelling", 7, 0x1b36da38}, ++ {__LINE__, 0x73c84278, "zlib", 4, 0x6432d127}, ++ {__LINE__, 0x228a87d1, "4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0}, ++ {__LINE__, 0xa7a048d0, "F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274}, ++ {__LINE__, 0x1f0ded40, "ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870}, ++ {__LINE__, 0xa804a62f, "5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd}, ++ {__LINE__, 0x508fae6a, "0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc}, ++ {__LINE__, 0xe5adaf4f, "MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178}, ++ {__LINE__, 0x67136a40, "UcixbzPKTIv0SvILHVdO", 20, 0xc5213070}, ++ {__LINE__, 0xb00c4a10, "dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0}, ++ {__LINE__, 0x2e0c84b5, "di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72}, ++ {__LINE__, 0x81238d44, "2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620}, ++ {__LINE__, 0xf853aa92, "ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d}, ++ {__LINE__, 0x5a692325, "v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24}, ++ {__LINE__, 0x3275b9f, "Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df}, ++ {__LINE__, 0x38371feb, "GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30}, ++ {__LINE__, 0xafc8bf62, "kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9}, ++ {__LINE__, 0x9b07db73, "70684206568419061514", 20, 0xae1fb7b7}, ++ {__LINE__, 0xe75b214, "42015093765128581010", 20, 0xd4eecd2d}, ++ {__LINE__, 0x72d0fe6f, "88214814356148806939", 20, 0x4660ec7}, ++ {__LINE__, 0xf857a4b1, "43472694284527343838", 20, 0xfd8afdf7}, ++ {__LINE__, 0x54b8e14, "49769333513942933689", 20, 0xc6d1b5f2}, ++ {__LINE__, 0xd6aa5616, "54979784887993251199", 20, 0x32476461}, ++ {__LINE__, 0x11e63098, "58360544869206793220", 20, 0xd917cf1a}, ++ {__LINE__, 0xbe92385, "27347953487840714234", 20, 0x4ad14a12}, ++ {__LINE__, 0x49511de0, "07650690295365319082", 20, 0xe37b5c6c}, ++ {__LINE__, 0x3db13bc1, "42655507906821911703", 20, 0x7cc497f1}, ++ {__LINE__, 0xbb899bea, "29977409200786225655", 20, 0x99781bb2}, ++ {__LINE__, 0xf6cd9436, "85181542907229116674", 20, 0x132256a1}, ++ {__LINE__, 0x9109e6c3, "87963594337989416799", 20, 0xbfdb2c83}, ++ {__LINE__, 0x75770fc, "21395988329504168551", 20, 0x8d9d1e81}, ++ {__LINE__, 0x69b1d19b, "51991013580943379423", 20, 0x7b6d4404}, ++ {__LINE__, 0xc6132975, "*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010}, ++ {__LINE__, 0xd58cb00c, "_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3}, ++ {__LINE__, 0xb63b8caa, "&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f}, ++ {__LINE__, 0x8a45a2b8, "]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de}, ++ {__LINE__, 0xcbe95b78, "-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59}, ++ {__LINE__, 0x4ef8a54b, "+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f}, ++ {__LINE__, 0x76ad267a, ")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac}, ++ {__LINE__, 0x569e613c, ":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66}, ++ {__LINE__, 0x36aa61da, "{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7}, ++ {__LINE__, 0xf67222df, "_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a}, ++ {__LINE__, 0x74b34fd3, "e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060}, ++ {__LINE__, 0x351fd770, "r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312}, ++ {__LINE__, 0xc45aef77, "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912}, ++ {__LINE__, 0xc45aef77, "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" ++ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" ++ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" ++ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" ++ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" ++ "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B} ++}; ++ ++static const int test_size = sizeof(tests) / sizeof(tests[0]); ++ ++int main(void) ++{ ++ int i; ++ for (i = 0; i < test_size; i++) { ++ test_crc32(tests[i].crc, (Byte*) tests[i].buf, tests[i].len, ++ tests[i].expect, tests[i].line); ++ } ++ return 0; ++} diff --git a/zlib-1.2.12-s390-vectorize-crc32.patch b/zlib-1.2.12-s390-vectorize-crc32.patch new file mode 100644 index 0000000..5c8f7fb --- /dev/null +++ b/zlib-1.2.12-s390-vectorize-crc32.patch @@ -0,0 +1,425 @@ +From 957bc67cfb4e01403c01fe6243850383183a7c19 Mon Sep 17 00:00:00 2001 +From: Ilya Leoshkevich +Date: Thu, 19 Mar 2020 11:52:03 +0100 +Subject: [PATCH] s390x: vectorize crc32 + +Use vector extensions when compiling for s390x and binutils knows +about them. At runtime, check whether kernel supports vector +extensions (it has to be not just the CPU, but also the kernel) and +choose between the regular and the vectorized implementations. +--- + Makefile.in | 9 ++ + configure | 28 +++++ + contrib/gcc/zifunc.h | 21 +++- + contrib/s390/crc32-vx.c | 195 ++++++++++++++++++++++++++++++++ + contrib/s390/crc32_z_resolver.c | 41 +++++++ + crc32.c | 11 +- + 6 files changed, 301 insertions(+), 4 deletions(-) + 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 + LDSHARED=$(CC) + CPP=$(CC) -E ++VGFMAFLAG= + + STATICLIB=libz.a + SHAREDLIB=libz.so +@@ -179,6 +180,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 + ++crc32-vx.o: $(SRCDIR)contrib/s390/crc32-vx.c ++ $(CC) $(CFLAGS) $(VGFMAFLAG) $(ZINC) -c -o $@ $(SRCDIR)contrib/s390/crc32-vx.c ++ + deflate.o: $(SRCDIR)deflate.c + $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c + +@@ -229,6 +233,11 @@ crc32.lo: $(SRCDIR)crc32.c + $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c + -@mv objs/crc32.o $@ + ++crc32-vx.lo: $(SRCDIR)contrib/s390/crc32-vx.c ++ -@mkdir objs 2>/dev/null || test -d objs ++ $(CC) $(SFLAGS) $(VGFMAFLAG) $(ZINC) -DPIC -c -o objs/crc32-vx.o $(SRCDIR)contrib/s390/crc32-vx.c ++ -@mv objs/crc32-vx.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 +diff --git a/configure b/configure +index dd01b5c0e..acf94a599 100755 +--- a/configure ++++ b/configure +@@ -929,6 +929,32 @@ else + echo "Checking for Power optimizations support... No." | tee -a configure.log + fi + ++# check if we are compiling for s390 and binutils support vector extensions ++VGFMAFLAG=-march=z13 ++cat > $test.c <> configure.log + echo ALL = $ALL >> configure.log +@@ -960,6 +986,7 @@ echo mandir = $mandir >> configure.log + echo prefix = $prefix >> configure.log + echo sharedlibdir = $sharedlibdir >> configure.log + echo uname = $uname >> configure.log ++echo VGFMAFLAG = $VGFMAFLAG >> configure.log + + # udpate Makefile with the configure results + sed < ${SRCDIR}Makefile.in " +@@ -969,6 +996,7 @@ sed < ${SRCDIR}Makefile.in " + /^LDFLAGS *=/s#=.*#=$LDFLAGS# + /^LDSHARED *=/s#=.*#=$LDSHARED# + /^CPP *=/s#=.*#=$CPP# ++/^VGFMAFLAG *=/s#=.*#=$VGFMAFLAG# + /^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 +@@ -8,9 +8,28 @@ + + /* Helpers for arch optimizations */ + ++#if defined(__clang__) ++#if __has_feature(coverage_sanitizer) ++#define Z_IFUNC_NO_SANCOV __attribute__((no_sanitize("coverage"))) ++#else /* __has_feature(coverage_sanitizer) */ ++#define Z_IFUNC_NO_SANCOV ++#endif /* __has_feature(coverage_sanitizer) */ ++#else /* __clang__ */ ++#define Z_IFUNC_NO_SANCOV ++#endif /* __clang__ */ ++ ++#ifdef __s390__ ++#define Z_IFUNC_PARAMS unsigned long hwcap ++#define Z_IFUNC_ATTRS Z_IFUNC_NO_SANCOV ++#else /* __s390__ */ ++#define Z_IFUNC_PARAMS void ++#define Z_IFUNC_ATTRS ++#endif /* __s390__ */ ++ + #define Z_IFUNC(fname) \ + typeof(fname) fname __attribute__ ((ifunc (#fname "_resolver"))); \ +- local typeof(fname) *fname##_resolver(void) ++ Z_IFUNC_ATTRS \ ++ local typeof(fname) *fname##_resolver(Z_IFUNC_PARAMS) + /* 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 +--- /dev/null ++++ b/contrib/s390/crc32-vx.c +@@ -0,0 +1,195 @@ ++/* ++ * Hardware-accelerated CRC-32 variants for Linux on z Systems ++ * ++ * Use the z/Architecture Vector Extension Facility to accelerate the ++ * computing of bitreflected CRC-32 checksums. ++ * ++ * This CRC-32 implementation algorithm is bitreflected and processes ++ * the least-significant bit first (Little-Endian). ++ * ++ * This code was originally written by Hendrik Brueckner ++ * for use in the Linux kernel and has been ++ * relicensed under the zlib license. ++ */ ++ ++#include "../../zutil.h" ++ ++#include ++#include ++ ++typedef unsigned char uv16qi __attribute__((vector_size(16))); ++typedef unsigned int uv4si __attribute__((vector_size(16))); ++typedef unsigned long long uv2di __attribute__((vector_size(16))); ++ ++uint32_t crc32_le_vgfm_16(uint32_t crc, const unsigned char *buf, size_t len) { ++ /* ++ * The CRC-32 constant block contains reduction constants to fold and ++ * process particular chunks of the input data stream in parallel. ++ * ++ * For the CRC-32 variants, the constants are precomputed according to ++ * these definitions: ++ * ++ * R1 = [(x4*128+32 mod P'(x) << 32)]' << 1 ++ * R2 = [(x4*128-32 mod P'(x) << 32)]' << 1 ++ * R3 = [(x128+32 mod P'(x) << 32)]' << 1 ++ * R4 = [(x128-32 mod P'(x) << 32)]' << 1 ++ * R5 = [(x64 mod P'(x) << 32)]' << 1 ++ * R6 = [(x32 mod P'(x) << 32)]' << 1 ++ * ++ * The bitreflected Barret reduction constant, u', is defined as ++ * the bit reversal of floor(x**64 / P(x)). ++ * ++ * where P(x) is the polynomial in the normal domain and the P'(x) is the ++ * polynomial in the reversed (bitreflected) domain. ++ * ++ * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials: ++ * ++ * P(x) = 0x04C11DB7 ++ * P'(x) = 0xEDB88320 ++ */ ++ const uv16qi perm_le2be = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; /* BE->LE mask */ ++ const uv2di r2r1 = {0x1C6E41596, 0x154442BD4}; /* R2, R1 */ ++ const uv2di r4r3 = {0x0CCAA009E, 0x1751997D0}; /* R4, R3 */ ++ const uv2di r5 = {0, 0x163CD6124}; /* R5 */ ++ const uv2di ru_poly = {0, 0x1F7011641}; /* u' */ ++ const uv2di crc_poly = {0, 0x1DB710641}; /* P'(x) << 1 */ ++ ++ /* ++ * Load the initial CRC value. ++ * ++ * The CRC value is loaded into the rightmost word of the ++ * vector register and is later XORed with the LSB portion ++ * of the loaded input data. ++ */ ++ uv2di v0 = {0, 0}; ++ v0 = (uv2di)vec_insert(crc, (uv4si)v0, 3); ++ ++ /* Load a 64-byte data chunk and XOR with CRC */ ++ uv2di v1 = vec_perm(((uv2di *)buf)[0], ((uv2di *)buf)[0], perm_le2be); ++ uv2di v2 = vec_perm(((uv2di *)buf)[1], ((uv2di *)buf)[1], perm_le2be); ++ uv2di v3 = vec_perm(((uv2di *)buf)[2], ((uv2di *)buf)[2], perm_le2be); ++ uv2di v4 = vec_perm(((uv2di *)buf)[3], ((uv2di *)buf)[3], perm_le2be); ++ ++ v1 ^= v0; ++ buf += 64; ++ len -= 64; ++ ++ while (len >= 64) { ++ /* Load the next 64-byte data chunk */ ++ uv16qi part1 = vec_perm(((uv16qi *)buf)[0], ((uv16qi *)buf)[0], perm_le2be); ++ uv16qi part2 = vec_perm(((uv16qi *)buf)[1], ((uv16qi *)buf)[1], perm_le2be); ++ uv16qi part3 = vec_perm(((uv16qi *)buf)[2], ((uv16qi *)buf)[2], perm_le2be); ++ uv16qi part4 = vec_perm(((uv16qi *)buf)[3], ((uv16qi *)buf)[3], perm_le2be); ++ ++ /* ++ * Perform a GF(2) multiplication of the doublewords in V1 with ++ * the R1 and R2 reduction constants in V0. The intermediate result ++ * is then folded (accumulated) with the next data chunk in PART1 and ++ * stored in V1. Repeat this step for the register contents ++ * in V2, V3, and V4 respectively. ++ */ ++ v1 = (uv2di)vec_gfmsum_accum_128(r2r1, v1, part1); ++ v2 = (uv2di)vec_gfmsum_accum_128(r2r1, v2, part2); ++ v3 = (uv2di)vec_gfmsum_accum_128(r2r1, v3, part3); ++ v4 = (uv2di)vec_gfmsum_accum_128(r2r1, v4, part4); ++ ++ buf += 64; ++ len -= 64; ++ } ++ ++ /* ++ * Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3 ++ * and R4 and accumulating the next 128-bit chunk until a single 128-bit ++ * value remains. ++ */ ++ v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); ++ v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v3); ++ v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v4); ++ ++ while (len >= 16) { ++ /* Load next data chunk */ ++ v2 = vec_perm(*(uv2di *)buf, *(uv2di *)buf, perm_le2be); ++ ++ /* Fold next data chunk */ ++ v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); ++ ++ buf += 16; ++ len -= 16; ++ } ++ ++ /* ++ * Set up a vector register for byte shifts. The shift value must ++ * be loaded in bits 1-4 in byte element 7 of a vector register. ++ * Shift by 8 bytes: 0x40 ++ * Shift by 4 bytes: 0x20 ++ */ ++ uv16qi v9 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ++ v9 = vec_insert((unsigned char)0x40, v9, 7); ++ ++ /* ++ * Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes ++ * to move R4 into the rightmost doubleword and set the leftmost ++ * doubleword to 0x1. ++ */ ++ v0 = vec_srb(r4r3, (uv2di)v9); ++ v0[0] = 1; ++ ++ /* ++ * Compute GF(2) product of V1 and V0. The rightmost doubleword ++ * of V1 is multiplied with R4. The leftmost doubleword of V1 is ++ * multiplied by 0x1 and is then XORed with rightmost product. ++ * Implicitly, the intermediate leftmost product becomes padded ++ */ ++ v1 = (uv2di)vec_gfmsum_128(v0, v1); ++ ++ /* ++ * Now do the final 32-bit fold by multiplying the rightmost word ++ * in V1 with R5 and XOR the result with the remaining bits in V1. ++ * ++ * To achieve this by a single VGFMAG, right shift V1 by a word ++ * and store the result in V2 which is then accumulated. Use the ++ * vector unpack instruction to load the rightmost half of the ++ * doubleword into the rightmost doubleword element of V1; the other ++ * half is loaded in the leftmost doubleword. ++ * The vector register with CONST_R5 contains the R5 constant in the ++ * rightmost doubleword and the leftmost doubleword is zero to ignore ++ * the leftmost product of V1. ++ */ ++ v9 = vec_insert((unsigned char)0x20, v9, 7); ++ v2 = vec_srb(v1, (uv2di)v9); ++ v1 = vec_unpackl((uv4si)v1); /* Split rightmost doubleword */ ++ v1 = (uv2di)vec_gfmsum_accum_128(r5, v1, (uv16qi)v2); ++ ++ /* ++ * Apply a Barret reduction to compute the final 32-bit CRC value. ++ * ++ * The input values to the Barret reduction are the degree-63 polynomial ++ * in V1 (R(x)), degree-32 generator polynomial, and the reduction ++ * constant u. The Barret reduction result is the CRC value of R(x) mod ++ * P(x). ++ * ++ * The Barret reduction algorithm is defined as: ++ * ++ * 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u ++ * 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x) ++ * 3. C(x) = R(x) XOR T2(x) mod x^32 ++ * ++ * Note: The leftmost doubleword of vector register containing ++ * CONST_RU_POLY is zero and, thus, the intermediate GF(2) product ++ * is zero and does not contribute to the final result. ++ */ ++ ++ /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */ ++ v2 = vec_unpackl((uv4si)v1); ++ v2 = (uv2di)vec_gfmsum_128(ru_poly, v2); ++ ++ /* ++ * Compute the GF(2) product of the CRC polynomial with T1(x) in ++ * V2 and XOR the intermediate result, T2(x), with the value in V1. ++ * The final result is stored in word element 2 of V2. ++ */ ++ v2 = vec_unpackl((uv4si)v2); ++ v2 = (uv2di)vec_gfmsum_accum_128(crc_poly, v2, (uv16qi)v1); ++ ++ 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 +--- /dev/null ++++ b/contrib/s390/crc32_z_resolver.c +@@ -0,0 +1,41 @@ ++#include ++#include "../gcc/zifunc.h" ++ ++#define VX_MIN_LEN 64 ++#define VX_ALIGNMENT 16L ++#define VX_ALIGN_MASK (VX_ALIGNMENT - 1) ++ ++unsigned int crc32_le_vgfm_16(unsigned int crc, const unsigned char FAR *buf, z_size_t len); ++ ++local unsigned long s390_crc32_vx(unsigned long crc, const unsigned char FAR *buf, z_size_t len) ++{ ++ uintptr_t prealign, aligned, remaining; ++ ++ if (buf == Z_NULL) return 0UL; ++ ++ if (len < VX_MIN_LEN + VX_ALIGN_MASK) ++ return crc32_z_default(crc, buf, len); ++ ++ if ((uintptr_t)buf & VX_ALIGN_MASK) { ++ prealign = VX_ALIGNMENT - ((uintptr_t)buf & VX_ALIGN_MASK); ++ len -= prealign; ++ crc = crc32_z_default(crc, buf, prealign); ++ buf += prealign; ++ } ++ aligned = len & ~VX_ALIGN_MASK; ++ remaining = len & VX_ALIGN_MASK; ++ ++ crc = crc32_le_vgfm_16(crc ^ 0xffffffff, buf, (size_t)aligned) ^ 0xffffffff; ++ ++ if (remaining) ++ crc = crc32_z_default(crc, buf + aligned, remaining); ++ ++ return crc; ++} ++ ++Z_IFUNC(crc32_z) ++{ ++ if (hwcap & HWCAP_S390_VX) ++ 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) + #endif + + /* ========================================================================= */ +-#ifdef Z_POWER_OPT ++#if defined(Z_POWER_OPT) || defined(HAVE_S390X_VX) + /* Rename function so resolver can use its symbol. The default version will be + * returned by the resolver if the host has no support for an optimized version. + */ + #define crc32_z crc32_z_default +-#endif /* Z_POWER_OPT */ ++#endif /* defined(Z_POWER_OPT) || defined(HAVE_S390X_VX) */ + + unsigned long ZEXPORT crc32_z(crc, buf, len) + unsigned long crc; +@@ -1064,10 +1064,15 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) + return crc ^ 0xffffffff; + } + +-#ifdef Z_POWER_OPT ++#if defined(Z_POWER_OPT) || defined(HAVE_S390X_VX) + #undef crc32_z ++#ifdef Z_POWER_OPT + #include "contrib/power/crc32_z_resolver.c" + #endif /* Z_POWER_OPT */ ++#ifdef HAVE_S390X_VX ++#include "contrib/s390/crc32_z_resolver.c" ++#endif /* HAVE_S390X_VX */ ++#endif /* defined(Z_POWER_OPT) || defined(HAVE_S390X_VX) */ + + #endif + diff --git a/zlib-1.2.12.tar.gz b/zlib-1.2.12.tar.gz new file mode 100644 index 0000000..a572d32 --- /dev/null +++ b/zlib-1.2.12.tar.gz @@ -0,0 +1,3 @@ +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 new file mode 100644 index 0000000..a4c7be2 --- /dev/null +++ b/zlib-1.2.12.tar.gz.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Comment: GPGTools - http://gpgtools.org + +iF0EABECAB0WIQRe1GpnIdNlWHeR4qp4P82OWLyvugUCYkEexwAKCRB4P82OWLyv +ulGRAJ9CLw3LBVZKeIM2JY0MS3obrzTSzgCgqEHUCY42CMzYyrTLazKS6ymTC/4= +=mgXG +-----END PGP SIGNATURE----- diff --git a/zlib-1.2.5-minizip-fixuncrypt.patch b/zlib-1.2.5-minizip-fixuncrypt.patch new file mode 100644 index 0000000..2c6fa8e --- /dev/null +++ b/zlib-1.2.5-minizip-fixuncrypt.patch @@ -0,0 +1,24 @@ +From 9352e84c149d02ec0df78e19dad55b7f83185622 Mon Sep 17 00:00:00 2001 +From: Ilya Leoshkevich +Date: Wed, 27 Apr 2022 14:36:43 +0200 +Subject: [PATCH] zlib-1.2.5-minizip-fixuncrypt.patch + +--- + contrib/minizip/unzip.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/contrib/minizip/unzip.c b/contrib/minizip/unzip.c +index 5e12e4747..aa1a92d17 100644 +--- a/contrib/minizip/unzip.c ++++ b/contrib/minizip/unzip.c +@@ -68,10 +68,6 @@ + #include + #include + +-#ifndef NOUNCRYPT +- #define NOUNCRYPT +-#endif +- + #include "zlib.h" + #include "unzip.h" + diff --git a/zlib-format.patch b/zlib-format.patch index 7f6e0f9..18859fe 100644 --- a/zlib-format.patch +++ b/zlib-format.patch @@ -5,7 +5,7 @@ Index: zlib.h =================================================================== --- zlib.h.orig +++ zlib.h -@@ -1464,7 +1464,11 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((vo +@@ -1465,7 +1465,11 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((vo is returned, and the error state is set to Z_STREAM_ERROR. */ @@ -16,5 +16,5 @@ Index: zlib.h +#endif +; /* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of diff --git a/zlib-no-version-check.patch b/zlib-no-version-check.patch index 67a9661..95337d0 100644 --- a/zlib-no-version-check.patch +++ b/zlib-no-version-check.patch @@ -1,7 +1,7 @@ -Index: zlib-1.2.11/infback.c +Index: zlib-1.2.12/infback.c =================================================================== ---- zlib-1.2.11.orig/infback.c -+++ zlib-1.2.11/infback.c +--- zlib-1.2.12.orig/infback.c ++++ zlib-1.2.12/infback.c @@ -34,9 +34,6 @@ int stream_size; { struct inflate_state FAR *state; @@ -12,11 +12,11 @@ Index: zlib-1.2.11/infback.c if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) return Z_STREAM_ERROR; -Index: zlib-1.2.11/inflate.c +Index: zlib-1.2.12/inflate.c =================================================================== ---- zlib-1.2.11.orig/inflate.c -+++ zlib-1.2.11/inflate.c -@@ -219,9 +219,6 @@ int stream_size; +--- zlib-1.2.12.orig/inflate.c ++++ zlib-1.2.12/inflate.c +@@ -202,9 +202,6 @@ int stream_size; int ret; struct inflate_state FAR *state; @@ -26,21 +26,16 @@ Index: zlib-1.2.11/inflate.c if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { -Index: zlib-1.2.11/deflate.c +Index: zlib-1.2.12/deflate.c =================================================================== ---- zlib-1.2.11.orig/deflate.c -+++ zlib-1.2.11/deflate.c -@@ -263,17 +263,12 @@ int ZEXPORT deflateInit2_(strm, level, m +--- zlib-1.2.12.orig/deflate.c ++++ zlib-1.2.12/deflate.c +@@ -253,12 +253,7 @@ int ZEXPORT deflateInit2_(strm, level, m { deflate_state *s; int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; diff --git a/zlib-rpmlintrc b/zlib-rpmlintrc index 28cc7b9..0905c70 100644 --- a/zlib-rpmlintrc +++ b/zlib-rpmlintrc @@ -1,4 +1,2 @@ -# zlib-devel require libz1 - zlib produces libz, not libzlib -addFilter("zlib-devel.*: W: no-dependency-on zlib*/zlib-libs/libzlib") # used only if build --with profiling addFilter("zlib.src.*: W: make-check-outside-check-section time make check") diff --git a/zlib.changes b/zlib.changes index a7a3490..746e200 100644 --- a/zlib.changes +++ b/zlib.changes @@ -1,3 +1,37 @@ +------------------------------------------------------------------- +Tue Aug 23 16:22:59 UTC 2022 - Danilo Spinella + +- Update to 1.2.12: + * A lot of bug fixes + * Improve speed of crc32 functions + * Use ARM crc32 instructions if the ARM architecture has them + For the complete changes, see ChangeLog +- Fixes CVE-2022-37434, heap-based buffer over-read or buffer overflow in + inflate.c via a large gzip header extra field + (CVE-2022-37434, bsc#1202175) +- Added patches: + * zlib-1.2.11-covscan-issues-rhel9.patch + * zlib-1.2.11-covscan-issues.patch + * zlib-1.2.12-s390-vectorize-crc32.patch + * zlib-1.2.12-optimized-crc32-power8.patch + * zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch + * zlib-1.2.12-fix-configure.patch + * zlib-1.2.12-correct-inputs-provided-to-crc-func.patch + * zlib-1.2.12-fix-CVE-2022-37434.patch +- Removed patches: + * bsc1197459.patch (upstreamed) + * zlib-power8-fate325307.patch + (replaced by zlib-1.2.12-optimized-crc32-power8.patch) + * bsc1174736-DFLTCC_LEVEL_MASK-set-to-0x1ff.patch + (replaced by zlib-1.2.12-IBM-Z-hw-accelrated-deflate-s390x.patch) + * 410.patch + (replaced by zlib-1.2.12-IBM-Z-hw-accelrated-deflate-s390x.patch) +- Refreshed patches: + * zlib-format.patch + * zlib-no-version-check.patch +- Disable profiling since it breaks tests +- Update zlib-rpmlintrc + ------------------------------------------------------------------- Sat Jul 2 10:00:46 UTC 2022 - Marcus Meissner diff --git a/zlib.spec b/zlib.spec index c31a641..f74e6ad 100644 --- a/zlib.spec +++ b/zlib.spec @@ -17,7 +17,7 @@ Name: zlib -Version: 1.2.11 +Version: 1.2.12 Release: 0 Summary: Library implementing the DEFLATE compression algorithm License: Zlib @@ -28,24 +28,28 @@ Source2: %{name}.keyring Source4: LICENSE Source5: baselibs.conf Source6: zlib-rpmlintrc -#PATCH-FIX-SUSE: fate#314093, sent upstream by IBM -Patch0: zlib-1.2.11-optimized-s390.patch #PATCH-FIX-SUSE: compiler check of varguments passed to gzprintf Patch1: zlib-format.patch #PATCH-FIX-UPSTREAM do not store negative values in uInt Patch2: 0001-Do-not-try-to-store-negative-values-in-unsigned-int.patch -#PATCH-FIX-UPSTREAM https://github.com/madler/zlib/pull/335 -Patch3: zlib-power8-fate325307.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 -Patch5: zlib-no-version-check.patch -Patch6: bsc1174736-DFLTCC_LEVEL_MASK-set-to-0x1ff.patch +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 -Patch10: minizip-dont-install-crypt-header.patch -#PATCH-FIX-UPSTREAM https://github.com/madler/zlib/commit/5c44459c3b28a9bd3283aaceab7c615f8020c531 -Patch11: bsc1197459.patch -#PATCH-FIX-UPSTREAM https://github.com/madler/zlib/pull/410 -Patch101: 410.patch +Patch6: minizip-dont-install-crypt-header.patch +# The following patches are taken from https://github.com/iii-i/zlib/commits/crc32vx-v3 +Patch7: zlib-1.2.5-minizip-fixuncrypt.patch +Patch8: zlib-1.2.11-optimized-s390.patch +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 BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool @@ -130,15 +134,20 @@ It should exit 0 %prep %setup -q -%patch0 %patch1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 %patch5 -p1 %patch6 -p1 +%patch7 -p1 +%patch8 +%patch9 -p1 %patch10 -p1 %patch11 -p1 -%patch101 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 cp %{SOURCE4} . %build @@ -155,14 +164,16 @@ CC="cc" ./configure \ %endif %{nil} -%if %{do_profiling} - make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_generate}" - make check %{?_smp_mflags} - make %{?_smp_mflags} clean - make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_feedback}" -%else +# Profiling flags breaks tests, as of 1.2.12 +# In particular, gzseek does not work as intended +#%if %{do_profiling} +# #make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_generate}" +# make check %{?_smp_mflags} +# #make %{?_smp_mflags} clean +# #make %{?_smp_mflags} CFLAGS="%{optflags} %{cflags_profile_feedback}" +#%else make %{?_smp_mflags} -%endif +#%endif # And build minizip cd contrib/minizip