backport IBM Z updates to fedora

This commit is contained in:
Ondrej Dubaj 2020-11-18 11:18:50 +01:00
parent 4838139649
commit c440ac9c20
6 changed files with 931 additions and 1 deletions

View File

@ -0,0 +1,206 @@
Subject: [PATCH] Fixed DFLTCC compression level switching issues
---
configure | 4 +--
contrib/s390/dfltcc.c | 52 ++++++++++++++++++++++++++++++-----
contrib/s390/dfltcc_deflate.h | 2 ++
deflate.c | 12 ++++----
test/infcover.c | 2 +-
5 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/configure b/configure
index bfe4386..70ed86b 100755
--- a/configure
+++ b/configure
@@ -139,7 +139,7 @@ case "$1" in
-w* | --warn) warn=1; shift ;;
-d* | --debug) debug=1; shift ;;
--dfltcc)
- CFLAGS="$CFLAGS -DDFLTCC"
+ CFLAGS="$CFLAGS -DDFLTCC -DDFLTCC_LEVEL_MASK=0x7e"
OBJC="$OBJC dfltcc.o"
PIC_OBJC="$PIC_OBJC dfltcc.lo"
shift
@@ -838,7 +838,7 @@ cat > $test.c << EOF
#include <sys/sdt.h>
int main() { return 0; }
EOF
-if try ${CC} ${CFLAGS} $test.c; then
+ if try $CC -c $CFLAGS $test.c; then
echo "Checking for sys/sdt.h ... Yes." | tee -a configure.log
CFLAGS="$CFLAGS -DHAVE_SYS_SDT_H"
SFLAGS="$SFLAGS -DHAVE_SYS_SDT_H"
diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c
index d88a0d6..94a196f 100644
--- a/contrib/s390/dfltcc.c
+++ b/contrib/s390/dfltcc.c
@@ -350,8 +350,12 @@ int ZLIB_INTERNAL dfltcc_deflate(strm, flush, result)
int soft_bcc;
int no_flush;
- if (!dfltcc_can_deflate(strm))
+ if (!dfltcc_can_deflate(strm)) {
+ /* Clear history. */
+ if (flush == Z_FULL_FLUSH)
+ param->hl = 0;
return 0;
+ }
again:
masked_avail_in = 0;
@@ -376,7 +380,8 @@ again:
/* Clear history. */
if (flush == Z_FULL_FLUSH)
param->hl = 0;
- *result = need_more;
+ /* Trigger block post-processing if necessary. */
+ *result = no_flush ? need_more : block_done;
return 1;
}
@@ -403,13 +408,18 @@ again:
param->bcf = 0;
dfltcc_state->block_threshold =
strm->total_in + dfltcc_state->block_size;
- if (strm->avail_out == 0) {
- *result = need_more;
- return 1;
- }
}
}
+ /* No space for compressed data. If we proceed, dfltcc_cmpr() will return
+ * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still
+ * set BCF=1, which is wrong. Avoid complications and return early.
+ */
+ if (strm->avail_out == 0) {
+ *result = need_more;
+ return 1;
+ }
+
/* The caller gave us too much data. Pass only one block worth of
* uncompressed data to DFLTCC and mask the rest, so that on the next
* iteration we start a new block.
@@ -737,10 +747,15 @@ __attribute__((constructor)) local void init_globals(void)
* compiling with -m31, gcc defaults to ESA mode, however, since the kernel
* is 64-bit, it's always z/Architecture mode at runtime.
*/
- __asm__ volatile(".machinemode push\n"
+ __asm__ volatile(
+#ifndef __clang__
+ ".machinemode push\n"
".machinemode zarch\n"
+#endif
"stfle %[facilities]\n"
+#ifndef __clang__
".machinemode pop\n"
+#endif
: [facilities] "=Q" (cpu_facilities)
, [r0] "+r" (r0)
:
@@ -872,6 +887,28 @@ int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush)
return Z_OK;
}
+int ZLIB_INTERNAL dfltcc_deflate_done(strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
+
+ /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might
+ * close the block without resetting the compression state. Detect this
+ * situation and return that deflation is not done.
+ */
+ if (flush == Z_FULL_FLUSH && strm->avail_out == 0)
+ return 0;
+
+ /* Return that deflation is not done if DFLTCC is used and either it
+ * buffered some data (Continuation Flag is set), or has not written EOBS
+ * yet (Block-Continuation Flag is set).
+ */
+ return !dfltcc_can_deflate(strm) || (!param->cf && !param->bcf);
+}
+
/*
Preloading history.
*/
@@ -925,6 +962,7 @@ int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length)
append_history(param, state->window, dictionary, dict_length);
state->strstart = 1; /* Add FDICT to zlib header */
+ state->block_start = state->strstart; /* Make deflate_stored happy */
return Z_OK;
}
diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h
index de36784..914daa4 100644
--- a/contrib/s390/dfltcc_deflate.h
+++ b/contrib/s390/dfltcc_deflate.h
@@ -11,6 +11,7 @@ int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm,
int level,
int strategy,
int *flush));
+int ZLIB_INTERNAL dfltcc_deflate_done OF((z_streamp strm, int flush));
int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dict_length));
@@ -41,6 +42,7 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm,
if (err == Z_STREAM_ERROR) \
return err; \
} while (0)
+#define DEFLATE_DONE dfltcc_deflate_done
#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \
do { \
if (dfltcc_can_deflate((strm))) \
diff --git a/deflate.c b/deflate.c
index d907a1b..085abbe 100644
--- a/deflate.c
+++ b/deflate.c
@@ -75,6 +75,7 @@ const char deflate_copyright[] =
#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
#define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0)
+#define DEFLATE_DONE(strm, flush) 1
#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0)
#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0
#define DEFLATE_HOOK(strm, flush, bstate) 0
@@ -605,14 +606,15 @@ int ZEXPORT deflateParams(strm, level, strategy)
DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush);
func = configuration_table[s->level].func;
- if ((strategy != s->strategy || func != configuration_table[level].func ||
- hook_flush != Z_NO_FLUSH) && s->last_flush != -2) {
+ if (((strategy != s->strategy || func != configuration_table[level].func) &&
+ s->last_flush != -2) || hook_flush != Z_NO_FLUSH) {
/* Flush the last buffer: */
- int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ?
- hook_flush : Z_BLOCK);
+ int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK;
+ int err = deflate(strm, flush);
if (err == Z_STREAM_ERROR)
return err;
- if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead ||
+ !DEFLATE_DONE(strm, flush))
return Z_BUF_ERROR;
}
if (s->level != level) {
diff --git a/test/infcover.c b/test/infcover.c
index a34cd17..a208219 100644
--- a/test/infcover.c
+++ b/test/infcover.c
@@ -373,7 +373,7 @@ local void cover_support(void)
mem_setup(&strm);
strm.avail_in = 0;
strm.next_in = Z_NULL;
- ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
+ ret = inflateInit_(&strm, &ZLIB_VERSION[1], (int)sizeof(z_stream));
assert(ret == Z_VERSION_ERROR);
mem_done(&strm, "wrong version");
--
2.26.0

View File

@ -0,0 +1,516 @@
From 608b71008c16ce6fbf2305145c5ffb69cd88ef59 Mon Sep 17 00:00:00 2001
From: Ondrej Dubaj <odubaj@redhat.com>
Date: Fri, 7 Aug 2020 07:12:50 +0200
Subject: [PATCH] Fix for Z hardware-accelerated deflate for s390x
---
configure | 7 +
contrib/s390/dfltcc.c | 244 +++++++++++++++++++++-------------
contrib/s390/dfltcc_deflate.h | 10 +-
deflate.c | 21 +--
4 files changed, 177 insertions(+), 105 deletions(-)
diff --git a/configure b/configure
index 66caece..bfe4386 100755
--- a/configure
+++ b/configure
@@ -114,6 +114,7 @@ case "$1" in
echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log
echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
+ echo ' [--dfltcc]' | tee -a configure.log
exit 0 ;;
-p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
-e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
@@ -137,6 +138,12 @@ case "$1" in
-c* | --const) zconst=1; shift ;;
-w* | --warn) warn=1; shift ;;
-d* | --debug) debug=1; shift ;;
+ --dfltcc)
+ CFLAGS="$CFLAGS -DDFLTCC"
+ OBJC="$OBJC dfltcc.o"
+ PIC_OBJC="$PIC_OBJC dfltcc.lo"
+ shift
+ ;;
*)
echo "unknown option: $1" | tee -a configure.log
echo "$0 --help for help" | tee -a configure.log
diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c
index d187796..d88a0d6 100644
--- a/contrib/s390/dfltcc.c
+++ b/contrib/s390/dfltcc.c
@@ -2,12 +2,13 @@
/*
Use the following commands to build zlib with DFLTCC support:
- $ CFLAGS=-DDFLTCC ./configure
- $ make OBJA=dfltcc.o PIC_OBJA=dfltcc.lo
+ $ ./configure --dfltcc
+ $ make
*/
#define _GNU_SOURCE
#include <ctype.h>
+#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
@@ -230,31 +231,28 @@ struct dfltcc_state {
/*
Compress.
*/
-local inline int dfltcc_are_params_ok(int level,
- uInt window_bits,
- int strategy,
- uLong level_mask);
-local inline int dfltcc_are_params_ok(level, window_bits, strategy, level_mask)
+local inline int dfltcc_can_deflate_with_params(z_streamp strm,
+ int level,
+ uInt window_bits,
+ int strategy);
+local inline int dfltcc_can_deflate_with_params(strm,
+ level,
+ window_bits,
+ strategy)
+ z_streamp strm;
int level;
uInt window_bits;
int strategy;
- uLong level_mask;
-{
- return (level_mask & (1 << level)) != 0 &&
- (window_bits == HB_BITS) &&
- (strategy == Z_FIXED || strategy == Z_DEFAULT_STRATEGY);
-}
-
-
-int ZLIB_INTERNAL dfltcc_can_deflate(strm)
- z_streamp strm;
{
deflate_state FAR *state = (deflate_state FAR *)strm->state;
struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
/* Unsupported compression settings */
- if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy,
- dfltcc_state->level_mask))
+ if ((dfltcc_state->level_mask & (1 << level)) == 0)
+ return 0;
+ if (window_bits != HB_BITS)
+ return 0;
+ if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY)
return 0;
/* Unsupported hardware */
@@ -266,6 +264,17 @@ int ZLIB_INTERNAL dfltcc_can_deflate(strm)
return 1;
}
+int ZLIB_INTERNAL dfltcc_can_deflate(strm)
+ z_streamp strm;
+{
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
+
+ return dfltcc_can_deflate_with_params(strm,
+ state->level,
+ state->w_bits,
+ state->strategy);
+}
+
local void dfltcc_gdht OF((z_streamp strm));
local void dfltcc_gdht(strm)
z_streamp strm;
@@ -349,22 +358,24 @@ again:
soft_bcc = 0;
no_flush = flush == Z_NO_FLUSH;
- /* Trailing empty block. Switch to software, except when Continuation Flag
- * is set, which means that DFLTCC has buffered some output in the
- * parameter block and needs to be called again in order to flush it.
+ /* No input data. Return, except when Continuation Flag is set, which means
+ * that DFLTCC has buffered some output in the parameter block and needs to
+ * be called again in order to flush it.
*/
- if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) {
- if (param->bcf) {
- /* A block is still open, and the hardware does not support closing
- * blocks without adding data. Thus, close it manually.
- */
+ if (strm->avail_in == 0 && !param->cf) {
+ /* A block is still open, and the hardware does not support closing
+ * blocks without adding data. Thus, close it manually.
+ */
+ if (!no_flush && param->bcf) {
send_eobs(strm, param);
param->bcf = 0;
}
- return 0;
- }
-
- if (strm->avail_in == 0 && !param->cf) {
+ /* Let one of deflate_* functions write a trailing empty block. */
+ if (flush == Z_FINISH)
+ return 0;
+ /* Clear history. */
+ if (flush == Z_FULL_FLUSH)
+ param->hl = 0;
*result = need_more;
return 1;
}
@@ -418,7 +429,7 @@ again:
param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32;
if (!no_flush)
/* We need to close a block. Always do this in software - when there is
- * no input data, the hardware will not nohor BCC. */
+ * no input data, the hardware will not honor BCC. */
soft_bcc = 1;
if (flush == Z_FINISH && !param->bcf)
/* We are about to open a BFINAL block, set Block Header Final bit
@@ -433,8 +444,8 @@ again:
param->sbb = (unsigned int)state->bi_valid;
if (param->sbb > 0)
*strm->next_out = (Bytef)state->bi_buf;
- if (param->hl)
- param->nt = 0; /* Honor history */
+ /* Honor history and check value */
+ param->nt = 0;
param->cv = state->wrap == 2 ? ZSWAP32(strm->adler) : strm->adler;
/* When opening a block, choose a Huffman-Table Type */
@@ -642,27 +653,86 @@ int ZLIB_INTERNAL dfltcc_inflate_disable(strm)
return 0;
}
-/*
- Memory management.
- DFLTCC requires parameter blocks and window to be aligned. zlib allows
- users to specify their own allocation functions, so using e.g.
- `posix_memalign' is not an option. Thus, we overallocate and take the
- aligned portion of the buffer.
-*/
+local int env_dfltcc_disabled;
+local int env_source_date_epoch;
+local unsigned long env_level_mask;
+local unsigned long env_block_size;
+local unsigned long env_block_threshold;
+local unsigned long env_dht_threshold;
+local unsigned long env_ribm;
+local uint64_t cpu_facilities[(DFLTCC_FACILITY / 64) + 1];
+local struct dfltcc_qaf_param cpu_af __attribute__((aligned(8)));
+
local inline int is_dfltcc_enabled OF((void));
local inline int is_dfltcc_enabled(void)
+{
+ if (env_dfltcc_disabled)
+ /* User has explicitly disabled DFLTCC. */
+ return 0;
+
+ return is_bit_set((const char *)cpu_facilities, DFLTCC_FACILITY);
+}
+
+local unsigned long xstrtoul OF((const char *s, unsigned long _default));
+local unsigned long xstrtoul(s, _default)
+ const char *s;
+ unsigned long _default;
+{
+ char *endptr;
+ unsigned long result;
+
+ if (!(s && *s))
+ return _default;
+ errno = 0;
+ result = strtoul(s, &endptr, 0);
+ return (errno || *endptr) ? _default : result;
+}
+
+__attribute__((constructor)) local void init_globals OF((void));
+__attribute__((constructor)) local void init_globals(void)
{
const char *env;
- uint64_t facilities[(DFLTCC_FACILITY / 64) + 1];
register char r0 __asm__("r0");
env = secure_getenv("DFLTCC");
- if (env && !strcmp(env, "0"))
- /* User has explicitly disabled DFLTCC. */
- return 0;
+
+
+ env_dfltcc_disabled = env && !strcmp(env, "0");
+
+ env = secure_getenv("SOURCE_DATE_EPOCH");
+ env_source_date_epoch = !!env;
+
+#ifndef DFLTCC_LEVEL_MASK
+#define DFLTCC_LEVEL_MASK 0x2
+#endif
+ env_level_mask = xstrtoul(secure_getenv("DFLTCC_LEVEL_MASK"),
+ DFLTCC_LEVEL_MASK);
+
+#ifndef DFLTCC_BLOCK_SIZE
+#define DFLTCC_BLOCK_SIZE 1048576
+#endif
+ env_block_size = xstrtoul(secure_getenv("DFLTCC_BLOCK_SIZE"),
+ DFLTCC_BLOCK_SIZE);
- memset(facilities, 0, sizeof(facilities));
- r0 = sizeof(facilities) / sizeof(facilities[0]) - 1;
+#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE
+#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096
+#endif
+ env_block_threshold = xstrtoul(secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE"),
+ DFLTCC_FIRST_FHT_BLOCK_SIZE);
+
+#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE
+#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096
+#endif
+ env_dht_threshold = xstrtoul(secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE"),
+ DFLTCC_DHT_MIN_SAMPLE_SIZE);
+
+#ifndef DFLTCC_RIBM
+#define DFLTCC_RIBM 0
+#endif
+ env_ribm = xstrtoul(secure_getenv("DFLTCC_RIBM"), DFLTCC_RIBM);
+
+ memset(cpu_facilities, 0, sizeof(cpu_facilities));
+ r0 = sizeof(cpu_facilities) / sizeof(cpu_facilities[0]) - 1;
/* STFLE is supported since z9-109 and only in z/Architecture mode. When
* compiling with -m31, gcc defaults to ESA mode, however, since the kernel
* is 64-bit, it's always z/Architecture mode at runtime.
@@ -671,31 +741,35 @@ local inline int is_dfltcc_enabled(void)
".machinemode zarch\n"
"stfle %[facilities]\n"
".machinemode pop\n"
- : [facilities] "=Q" (facilities)
+ : [facilities] "=Q" (cpu_facilities)
, [r0] "+r" (r0)
:
: "cc");
- return is_bit_set((const char *)facilities, DFLTCC_FACILITY);
+ /* Initialize available functions */
+ if (is_dfltcc_enabled())
+ dfltcc(DFLTCC_QAF, &cpu_af, NULL, NULL, NULL, NULL, NULL);
+ else
+ memset(&cpu_af, 0, sizeof(cpu_af));
}
+/*
+ Memory management.
+
+ DFLTCC requires parameter blocks and window to be aligned. zlib allows
+ users to specify their own allocation functions, so using e.g.
+ `posix_memalign' is not an option. Thus, we overallocate and take the
+ aligned portion of the buffer.
+*/
void ZLIB_INTERNAL dfltcc_reset(strm, size)
z_streamp strm;
uInt size;
{
struct dfltcc_state *dfltcc_state =
(struct dfltcc_state *)((char FAR *)strm->state + ALIGN_UP(size, 8));
- struct dfltcc_qaf_param *param =
- (struct dfltcc_qaf_param *)&dfltcc_state->param;
- const char *s;
- /* Initialize available functions */
- if (is_dfltcc_enabled()) {
- dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL);
- memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af));
- } else
- memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
+ memcpy(&dfltcc_state->af, &cpu_af, sizeof(dfltcc_state->af));
- if (secure_getenv("SOURCE_DATE_EPOCH"))
+ if (env_source_date_epoch)
/* User needs reproducible results, but the output of DFLTCC_CMPR
* depends on buffers' page offsets.
*/
@@ -706,36 +780,11 @@ void ZLIB_INTERNAL dfltcc_reset(strm, size)
dfltcc_state->param.nt = 1;
/* Initialize tuning parameters */
-#ifndef DFLTCC_LEVEL_MASK
-#define DFLTCC_LEVEL_MASK 0x2
-#endif
- s = secure_getenv("DFLTCC_LEVEL_MASK");
- dfltcc_state->level_mask = (s && *s) ? strtoul(s, NULL, 0) :
- DFLTCC_LEVEL_MASK;
-#ifndef DFLTCC_BLOCK_SIZE
-#define DFLTCC_BLOCK_SIZE 1048576
-#endif
- s = secure_getenv("DFLTCC_BLOCK_SIZE");
- dfltcc_state->block_size = (s && *s) ? strtoul(s, NULL, 0) :
- DFLTCC_BLOCK_SIZE;
-#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE
-#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096
-#endif
- s = secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE");
- dfltcc_state->block_threshold = (s && *s) ? strtoul(s, NULL, 0) :
- DFLTCC_FIRST_FHT_BLOCK_SIZE;
-#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE
-#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096
-#endif
- s = secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE");
- dfltcc_state->dht_threshold = (s && *s) ? strtoul(s, NULL, 0) :
- DFLTCC_DHT_MIN_SAMPLE_SIZE;
-#ifndef DFLTCC_RIBM
-#define DFLTCC_RIBM 0
-#endif
- s = secure_getenv("DFLTCC_RIBM");
- dfltcc_state->param.ribm = (s && *s) ? strtoul(s, NULL, 0) :
- DFLTCC_RIBM;
+ dfltcc_state->level_mask = env_level_mask;
+ dfltcc_state->block_size = env_block_size;
+ dfltcc_state->block_threshold = env_block_threshold;
+ dfltcc_state->dht_threshold = env_dht_threshold;
+ dfltcc_state->param.ribm = env_ribm;
}
voidpf ZLIB_INTERNAL dfltcc_alloc_state(strm, items, size)
@@ -787,22 +836,26 @@ void ZLIB_INTERNAL dfltcc_free_window(strm, w)
/*
Switching between hardware and software compression.
+
DFLTCC does not support all zlib settings, e.g. generation of non-compressed
blocks or alternative window sizes. When such settings are applied on the
fly with deflateParams, we need to convert between hardware and software
window formats.
*/
-int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy)
+int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush)
z_streamp strm;
int level;
int strategy;
+ int *flush;
{
deflate_state FAR *state = (deflate_state FAR *)strm->state;
struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
int could_deflate = dfltcc_can_deflate(strm);
- int can_deflate = dfltcc_are_params_ok(level, state->w_bits, strategy,
- dfltcc_state->level_mask);
+ int can_deflate = dfltcc_can_deflate_with_params(strm,
+ level,
+ state->w_bits,
+ strategy);
if (can_deflate == could_deflate)
/* We continue to work in the same mode - no changes needed */
@@ -812,8 +865,11 @@ int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy)
/* DFLTCC was not used yet - no changes needed */
return Z_OK;
- /* Switching between hardware and software is not implemented */
- return Z_STREAM_ERROR;
+ /* For now, do not convert between window formats - simply get rid of the
+ * old data instead.
+ */
+ *flush = Z_FULL_FLUSH;
+ return Z_OK;
}
/*
diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h
index a129a91..de36784 100644
--- a/contrib/s390/dfltcc_deflate.h
+++ b/contrib/s390/dfltcc_deflate.h
@@ -9,7 +9,8 @@ int ZLIB_INTERNAL dfltcc_deflate OF((z_streamp strm,
block_state *result));
int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm,
int level,
- int strategy));
+ int strategy,
+ int *flush));
int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dict_length));
@@ -29,11 +30,14 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm,
} while (0)
#define DEFLATE_RESET_KEEP_HOOK(strm) \
dfltcc_reset((strm), sizeof(deflate_state))
-#define DEFLATE_PARAMS_HOOK(strm, level, strategy) \
+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \
do { \
int err; \
\
- err = dfltcc_deflate_params((strm), (level), (strategy)); \
+ err = dfltcc_deflate_params((strm), \
+ (level), \
+ (strategy), \
+ (hook_flush)); \
if (err == Z_STREAM_ERROR) \
return err; \
} while (0)
diff --git a/deflate.c b/deflate.c
index b17a7dd..a80bd3e 100644
--- a/deflate.c
+++ b/deflate.c
@@ -74,7 +74,7 @@ const char deflate_copyright[] =
#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
#define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
-#define DEFLATE_PARAMS_HOOK(strm, level, strategy) do {} while (0)
+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0)
#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0)
#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0
#define DEFLATE_HOOK(strm, flush, bstate) 0
@@ -589,6 +589,7 @@ int ZEXPORT deflateParams(strm, level, strategy)
{
deflate_state *s;
compress_func func;
+ int hook_flush = Z_NO_FLUSH;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
@@ -601,13 +602,14 @@ int ZEXPORT deflateParams(strm, level, strategy)
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
- DEFLATE_PARAMS_HOOK(strm, level, strategy);
+ DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush);
func = configuration_table[s->level].func;
- if ((strategy != s->strategy || func != configuration_table[level].func) &&
- s->high_water) {
+ if ((strategy != s->strategy || func != configuration_table[level].func ||
+ hook_flush != Z_NO_FLUSH) && s->high_water) {
/* Flush the last buffer: */
- int err = deflate(strm, Z_BLOCK);
+ int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ?
+ hook_flush : Z_BLOCK);
if (err == Z_STREAM_ERROR)
return err;
if (strm->avail_out == 0)
@@ -1065,7 +1067,6 @@ int ZEXPORT deflate (strm, flush)
}
if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
/* Write the trailer */
#ifdef GZIP
@@ -1081,7 +1082,7 @@ int ZEXPORT deflate (strm, flush)
}
else
#endif
- {
+ if (s->wrap == 1) {
putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(s, (uInt)(strm->adler & 0xffff));
}
@@ -1090,7 +1091,11 @@ int ZEXPORT deflate (strm, flush)
* to flush the rest.
*/
if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
+ if (s->pending == 0) {
+ Assert(s->bi_valid == 0, "bi_buf not flushed");
+ return Z_STREAM_END;
+ }
+ return Z_OK;
}
/* ========================================================================= */
--
2.26.0

View File

@ -0,0 +1,74 @@
From f776e1609cc63bf486634ee9bc6226dac2c0d2f3 Mon Sep 17 00:00:00 2001
From: Ondrej Dubaj <odubaj@redhat.com>
Date: Tue, 15 Oct 2019 11:27:15 +0200
Subject: [PATCH] fixed covscan issues
---
crc32.c | 2 +-
deflate.c | 2 +-
test/crc32_test.c | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/crc32.c b/crc32.c
index 406d350..34132ea 100644
--- a/crc32.c
+++ b/crc32.c
@@ -302,7 +302,7 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
if (!crc32_func)
crc32_func = crc32_z_ifunc();
- return (*crc32_func)(crc, buf, len);
+ return (*crc32_func)(crc, buf, len);
}
#endif /* defined(Z_IFUNC_ASM) || defined(Z_IFUNC_NATIVE) */
diff --git a/deflate.c b/deflate.c
index 089285a..9b09718 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1015,7 +1015,7 @@ int ZEXPORT deflate (strm, flush)
*/
if (strm->avail_in != 0 || s->lookahead != 0 ||
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
+ block_state bstate = 0;
bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate :
s->level == 0 ? deflate_stored(s, flush) :
diff --git a/test/crc32_test.c b/test/crc32_test.c
index 5d73128..2d2a6c7 100644
--- a/test/crc32_test.c
+++ b/test/crc32_test.c
@@ -11,25 +11,25 @@
# include <stdlib.h>
#endif
-void test_crc32 OF((uLong crc, Byte* buf, z_size_t len, uLong chk, int line));
+void test_crc32 OF((uLong crc, char* buf, z_size_t len, uLong chk, int line));
int main OF((void));
typedef struct {
int line;
uLong crc;
- Byte* buf;
+ char* buf;
int len;
uLong expect;
} crc32_test;
void test_crc32(crc, buf, len, chk, line)
uLong crc;
- Byte *buf;
+ char *buf;
z_size_t len;
uLong chk;
int line;
{
- uLong res = crc32(crc, buf, len);
+ uLong res = crc32(crc, (Bytef *) buf, len);
if (res != chk) {
fprintf(stderr, "FAIL [%d]: crc32 returned 0x%08X expected 0x%08X\n",
line, (unsigned int)res, (unsigned int)chk);
--
2.19.1

View File

@ -0,0 +1,45 @@
Subject: [PATCH] Fixed inflateSyncPoint() bad return value on z15
---
contrib/s390/dfltcc.h | 4 ++++
inflate.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/contrib/s390/dfltcc.h b/contrib/s390/dfltcc.h
index 574e84c..7960626 100644
--- a/contrib/s390/dfltcc.h
+++ b/contrib/s390/dfltcc.h
@@ -51,5 +51,9 @@ int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm));
do { \
if (dfltcc_was_inflate_used((strm))) return -(1L << 16); \
} while (0)
+#define INFLATE_SYNC_POINT_HOOK(strm) \
+ do { \
+ if (dfltcc_was_inflate_used((strm))) return Z_STREAM_ERROR; \
+ } while (0)
#endif
\ No newline at end of file
diff --git a/inflate.c b/inflate.c
index f77c2ae..596034c 100644
--- a/inflate.c
+++ b/inflate.c
@@ -100,6 +100,7 @@
#define INFLATE_NEED_CHECKSUM(strm) 1
#define INFLATE_NEED_UPDATEWINDOW(strm) 1
#define INFLATE_MARK_HOOK(strm) do {} while (0)
+#define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0)
#endif
#ifdef MAKEFIXED
@@ -1483,6 +1484,7 @@ z_streamp strm;
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ INFLATE_SYNC_POINT_HOOK(strm);
state = (struct inflate_state FAR *)strm->state;
return state->mode == STORED && state->bits == 0;
}
--
2.26.0

View File

@ -0,0 +1,70 @@
From d09bb1ab8ef9bb91457c0ead09589e8807489260 Mon Sep 17 00:00:00 2001
From: Ondrej Dubaj <odubaj@redhat.com>
Date: Thu, 6 Aug 2020 08:09:53 +0200
Subject: [PATCH] Permit a deflateParams() parameter change.
This change allows a parameter change even if the input data has
not all been compressed and copied to the application output
buffer, so long as all of the input data has been compressed to
the internal pending output buffer. This also allows an immediate
deflateParams change so long as there have been no deflate calls
since initialization or reset.
---
deflate.c | 6 +++---
zlib.h | 11 ++++++-----
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/deflate.c b/deflate.c
index 9705c1c..f3c9924 100644
--- a/deflate.c
+++ b/deflate.c
@@ -509,7 +509,7 @@ int ZEXPORT deflateResetKeep (strm)
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
#endif
adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
+ s->last_flush = -2;
_tr_init(s);
@@ -606,13 +606,13 @@ int ZEXPORT deflateParams(strm, level, strategy)
func = configuration_table[s->level].func;
if ((strategy != s->strategy || func != configuration_table[level].func ||
- hook_flush != Z_NO_FLUSH) && s->high_water) {
+ hook_flush != Z_NO_FLUSH) && s->last_flush != -2) {
/* Flush the last buffer: */
int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ?
hook_flush : Z_BLOCK);
if (err == Z_STREAM_ERROR)
return err;
- if (strm->avail_out == 0)
+ if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
return Z_BUF_ERROR;
}
if (s->level != level) {
diff --git a/zlib.h b/zlib.h
index f09cdaf..001624e 100644
--- a/zlib.h
+++ b/zlib.h
@@ -712,11 +712,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
used to switch between compression and straight copy of the input data, or
to switch to a different kind of input data requiring a different strategy.
If the compression approach (which is a function of the level) or the
- strategy is changed, and if any input has been consumed in a previous
- deflate() call, then the input available so far is compressed with the old
- level and strategy using deflate(strm, Z_BLOCK). There are three approaches
- for the compression levels 0, 1..3, and 4..9 respectively. The new level
- and strategy will take effect at the next call of deflate().
+ strategy is changed, and if there have been any deflate() calls since the
+ state was initialized or reset, then the input available so far is
+ compressed with the old level and strategy using deflate(strm, Z_BLOCK).
+ There are three approaches for the compression levels 0, 1..3, and 4..9
+ respectively. The new level and strategy will take effect at the next call
+ of deflate().
If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
not have enough output space to complete, then the parameter change will not
--
2.26.0

View File

@ -2,7 +2,7 @@
Name: zlib
Version: 1.2.11
Release: 22%{?dist}
Release: 23%{?dist}
Summary: The compression and decompression library
# /contrib/dotzlib/ have Boost license
License: zlib and Boost
@ -23,6 +23,17 @@ Patch7: zlib-1.2.11-IBM-Z-hw-accelrated-deflate-s390x.patch
Patch8: zlib-1.2.11-optimized-CRC32-framework.patch
# fixed firefox crash + added test case
Patch9: zlib-1.2.11-firefox-crash-fix.patch
# fixed covscan issues
Patch10: zlib-1.2.11-covscan-issues.patch
# fix for IBM Z optimalizations
Patch11: zlib-1.2.11-IBM-Z-hw-accelrated-deflate-fix.patch
# permit a deflateParams() parameter change
Patch12: zlib-1.2.11-permit-deflateParams-change.patch
# fixed DFLTCC compression level switching issues
# enabled HW compression for compression levels 1 through 6
Patch13: zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch
# fixed inflateSyncPoint() bad return value on z15
Patch14: zlib-1.2.11-inflateSyncPoint-return-value-fix.patch
BuildRequires: automake, autoconf, libtool
@ -88,6 +99,11 @@ developing applications which use minizip.
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
iconv -f iso-8859-2 -t utf-8 < ChangeLog > ChangeLog.tmp
@ -175,6 +191,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete
%changelog
* Wed Nov 18 2020 Ondrej Dubaj <odubaj@redhat.com> - 1.2.11-23
- backport IBM Z updates to fedora
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.2.11-22
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild