File 410.patch of Package zlib (Revision 0588b3898606bdee7cb196d720e8f551)
Currently displaying revision 0588b3898606bdee7cb196d720e8f551 , Show latest
xxxxxxxxxx
1
From 79ccd96ec69d2367291568c586aeaae941d2635c Mon Sep 17 00:00:00 2001
2
From: Ilya Leoshkevich <iii@linux.ibm.com>
3
Date: Wed, 18 Jul 2018 13:14:07 +0200
4
Subject: [PATCH] Add support for IBM Z hardware-accelerated deflate
5
6
IBM Z mainframes starting from version z15 provide DFLTCC instruction,
7
which implements deflate algorithm in hardware with estimated
8
compression and decompression performance orders of magnitude faster
9
than the current zlib and ratio comparable with that of level 1.
10
11
This patch adds DFLTCC support to zlib. In order to enable it, the
12
following build commands should be used:
13
14
$ ./configure --dfltcc
15
$ make
16
17
When built like this, zlib would compress in hardware on level 1, and in
18
software on all other levels. Decompression will always happen in
19
hardware. In order to enable DFLTCC compression for levels 1-6 (i.e. to
20
make it used by default) one could either add -DDFLTCC_LEVEL_MASK=0x7e
21
to CFLAGS at compile time, or set the environment variable
22
DFLTCC_LEVEL_MASK to 0x7e at run time.
23
24
Two DFLTCC compression calls produce the same results only when they
25
both are made on machines of the same generation, and when the
26
respective buffers have the same offset relative to the start of the
27
page. Therefore care should be taken when using hardware compression
28
when reproducible results are desired. One such use case - reproducible
29
software builds - is handled explicitly: when SOURCE_DATE_EPOCH
30
environment variable is set, the hardware compression is disabled.
31
32
DFLTCC does not support every single zlib feature, in particular:
33
34
* inflate(Z_BLOCK) and inflate(Z_TREES)
35
* inflateMark()
36
* inflatePrime()
37
38
When used, these functions will either switch to software, or, in case
39
this is not possible, gracefully fail.
40
41
This patch tries to add DFLTCC support in the least intrusive way.
42
All SystemZ-specific code is placed into a separate file, but
43
unfortunately there is still a noticeable amount of changes in the
44
main zlib code. Below is the summary of these changes.
45
46
DFLTCC takes as arguments a parameter block, an input buffer, an output
47
buffer and a window. Since DFLTCC requires parameter block to be
48
doubleword-aligned, and it's reasonable to allocate it alongside
49
deflate and inflate states, ZALLOC_STATE, ZFREE_STATE and ZCOPY_STATE
50
macros were introduced in order to encapsulate the allocation details.
51
The same is true for window, for which ZALLOC_WINDOW and
52
TRY_FREE_WINDOW macros were introduced.
53
54
While for inflate software and hardware window formats match, this is
55
not the case for deflate. Therefore, deflateSetDictionary and
56
deflateGetDictionary need special handling, which is triggered using the
57
new DEFLATE_SET_DICTIONARY_HOOK and DEFLATE_GET_DICTIONARY_HOOK macros.
58
59
deflateResetKeep() and inflateResetKeep() now update the DFLTCC
60
parameter block, which is allocated alongside zlib state, using
61
the new DEFLATE_RESET_KEEP_HOOK and INFLATE_RESET_KEEP_HOOK macros.
62
63
The new DEFLATE_PARAMS_HOOK switches between hardware and software
64
deflate implementations when deflateParams() arguments demand this.
65
66
In order to make unsupported inflatePrime() and inflateMark() calls
67
fail gracefully, the new INFLATE_PRIME_HOOK and INFLATE_MARK_HOOK macros
68
were introduced.
69
70
The algorithm implemented in hardware has different compression ratio
71
than the one implemented in software. In order for deflateBound() to
72
return the correct results for the hardware implementation, the new
73
DEFLATE_BOUND_ADJUST_COMPLEN and DEFLATE_NEED_CONSERVATIVE_BOUND macros
74
were introduced.
75
76
Actual compression and decompression are handled by the new DEFLATE_HOOK
77
and INFLATE_TYPEDO_HOOK macros. Since inflation with DFLTCC manages the
78
window on its own, calling updatewindow() is suppressed using the new
79
INFLATE_NEED_UPDATEWINDOW() macro.
80
81
In addition to compression, DFLTCC computes CRC-32 and Adler-32
82
checksums, therefore, whenever it's used, software checksumming needs to
83
be suppressed using the new DEFLATE_NEED_CHECKSUM and
84
INFLATE_NEED_CHECKSUM macros.
85
86
DFLTCC will refuse to write an End-of-block Symbol if there is no input
87
data, thus in some cases it is necessary to do this manually. In order
88
to achieve this, send_bits, bi_reverse, bi_windup and flush_pending
89
were promoted from local to ZLIB_INTERNAL. Furthermore, since block and
90
stream termination must be handled in software as well, block_state enum
91
was moved to deflate.h.
92
93
Since the first call to dfltcc_inflate already needs the window, and it
94
might be not allocated yet, inflate_ensure_window was factored out of
95
updatewindow and made ZLIB_INTERNAL.
96
---
97
Makefile.in | 8 +
98
configure | 20 +
99
contrib/README.contrib | 4 +
100
contrib/s390/dfltcc.c | 920 ++++++++++++++++++++++++++++++++++
101
contrib/s390/dfltcc.h | 55 ++
102
contrib/s390/dfltcc_deflate.h | 54 ++
103
deflate.c | 68 ++-
104
deflate.h | 12 +
105
gzguts.h | 4 +
106
inflate.c | 85 +++-
107
inflate.h | 2 +
108
test/infcover.c | 2 +-
109
test/minigzip.c | 4 +
110
trees.c | 13 +-
111
14 files changed, 1197 insertions(+), 54 deletions(-)
112
create mode 100644 contrib/s390/dfltcc.c
113
create mode 100644 contrib/s390/dfltcc.h
114
create mode 100644 contrib/s390/dfltcc_deflate.h
115
116
Index: zlib-1.2.11/Makefile.in
117
===================================================================
118
--- zlib-1.2.11.orig/Makefile.in
119
+++ zlib-1.2.11/Makefile.in
120
121
mv _match.o match.lo
122
rm -f _match.s
123
124
+dfltcc.o: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h
125
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)contrib/s390/dfltcc.c
126
+
127
+dfltcc.lo: $(SRCDIR)contrib/s390/dfltcc.c $(SRCDIR)zlib.h zconf.h
128
+ -@mkdir objs 2>/dev/null || test -d objs
129
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/dfltcc.o $(SRCDIR)contrib/s390/dfltcc.c
130
+ -@mv objs/dfltcc.o $@
131
+
132
example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
133
$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c
134
135
Index: zlib-1.2.11/configure
136
===================================================================
137
--- zlib-1.2.11.orig/configure
138
+++ zlib-1.2.11/configure
139
140
echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log
141
echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
142
echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
143
+ echo ' [--dfltcc]' | tee -a configure.log
144
exit 0 ;;
145
-p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
146
-e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
147
148
-c* | --const) zconst=1; shift ;;
149
-w* | --warn) warn=1; shift ;;
150
-d* | --debug) debug=1; shift ;;
151
+ --dfltcc)
152
+ CFLAGS="$CFLAGS -DDFLTCC"
153
+ OBJC="$OBJC dfltcc.o"
154
+ PIC_OBJC="$PIC_OBJC dfltcc.lo"
155
+ shift
156
+ ;;
157
*)
158
echo "unknown option: $1" | tee -a configure.log
159
echo "$0 --help for help" | tee -a configure.log
160
161
fi
162
fi
163
164
+# Check whether sys/sdt.h is available
165
+cat > $test.c << EOF
166
+#include <sys/sdt.h>
167
+int main() { return 0; }
168
+EOF
169
+if try ${CC} ${CFLAGS} $test.c; then
170
+ echo "Checking for sys/sdt.h ... Yes." | tee -a configure.log
171
+ CFLAGS="$CFLAGS -DHAVE_SYS_SDT_H"
172
+ SFLAGS="$SFLAGS -DHAVE_SYS_SDT_H"
173
+else
174
+ echo "Checking for sys/sdt.h ... No." | tee -a configure.log
175
+fi
176
+
177
# show the results in the log
178
echo >> configure.log
179
echo ALL = $ALL >> configure.log
180
Index: zlib-1.2.11/contrib/README.contrib
181
===================================================================
182
--- zlib-1.2.11.orig/contrib/README.contrib
183
+++ zlib-1.2.11/contrib/README.contrib
184
185
Small, low memory usage inflate. Also serves to provide an
186
unambiguous description of the deflate format.
187
188
+s390/ by Ilya Leoshkevich <iii@linux.ibm.com>
189
+ Hardware-accelerated deflate on IBM Z with DEFLATE CONVERSION CALL
190
+ instruction.
191
+
192
testzlib/ by Gilles Vollant <info@winimage.com>
193
Example of the use of zlib
194
195
Index: zlib-1.2.11/contrib/s390/dfltcc.c
196
===================================================================
197
--- /dev/null
198
+++ zlib-1.2.11/contrib/s390/dfltcc.c
199
200
+/* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */
201
+
202
+/*
203
+ Use the following commands to build zlib with DFLTCC support:
204
+
205
+ $ ./configure --dfltcc
206
+ $ make
207
+*/
208
+
209
+#define _GNU_SOURCE
210
+#include <ctype.h>
211
+#include <inttypes.h>
212
+#include <stddef.h>
213
+#include <stdio.h>
214
+#include <stdint.h>
215
+#include <stdlib.h>
216
+#include "../../zutil.h"
217
+#include "../../deflate.h"
218
+#include "../../inftrees.h"
219
+#include "../../inflate.h"
220
+#include "dfltcc.h"
221
+#include "dfltcc_deflate.h"
222
+#ifdef HAVE_SYS_SDT_H
223
+#include <sys/sdt.h>
224
+#endif
225
+
226
+/*
227
+ C wrapper for the DEFLATE CONVERSION CALL instruction.
228
+ */
229
+typedef enum {
230
+ DFLTCC_CC_OK = 0,
231
+ DFLTCC_CC_OP1_TOO_SHORT = 1,
232
+ DFLTCC_CC_OP2_TOO_SHORT = 2,
233
+ DFLTCC_CC_OP2_CORRUPT = 2,
234
+ DFLTCC_CC_AGAIN = 3,
235
+} dfltcc_cc;
236
+
237
+#define DFLTCC_QAF 0
238
+#define DFLTCC_GDHT 1
239
+#define DFLTCC_CMPR 2
240
+#define DFLTCC_XPND 4
241
+#define HBT_CIRCULAR (1 << 7)
242
+#define HB_BITS 15
243
+#define HB_SIZE (1 << HB_BITS)
244
+#define DFLTCC_FACILITY 151
245
+
246
+local inline dfltcc_cc dfltcc OF((int fn, void *param,
247
+ Bytef **op1, size_t *len1,
248
+ z_const Bytef **op2, size_t *len2,
249
+ void *hist));
250
+local inline dfltcc_cc dfltcc(fn, param, op1, len1, op2, len2, hist)
251
+ int fn;
252
+ void *param;
253
+ Bytef **op1;
254
+ size_t *len1;
255
+ z_const Bytef **op2;
256
+ size_t *len2;
257
+ void *hist;
258
+{
259
+ Bytef *t2 = op1 ? *op1 : NULL;
260
+ size_t t3 = len1 ? *len1 : 0;
261
+ z_const Bytef *t4 = op2 ? *op2 : NULL;
262
+ size_t t5 = len2 ? *len2 : 0;
263
+ register int r0 __asm__("r0") = fn;
264
+ register void *r1 __asm__("r1") = param;
265
+ register Bytef *r2 __asm__("r2") = t2;
266
+ register size_t r3 __asm__("r3") = t3;
267
+ register z_const Bytef *r4 __asm__("r4") = t4;
268
+ register size_t r5 __asm__("r5") = t5;
269
+ int cc;
270
+
271
+ __asm__ volatile(
272
+#ifdef HAVE_SYS_SDT_H
273
+ STAP_PROBE_ASM(zlib, dfltcc_entry,
274
+ STAP_PROBE_ASM_TEMPLATE(5))
275
+#endif
276
+ ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n"
277
+#ifdef HAVE_SYS_SDT_H
278
+ STAP_PROBE_ASM(zlib, dfltcc_exit,
279
+ STAP_PROBE_ASM_TEMPLATE(5))
280
+#endif
281
+ "ipm %[cc]\n"
282
+ : [r2] "+r" (r2)
283
+ , [r3] "+r" (r3)
284
+ , [r4] "+r" (r4)
285
+ , [r5] "+r" (r5)
286
+ , [cc] "=r" (cc)
287
+ : [r0] "r" (r0)
288
+ , [r1] "r" (r1)
289
+ , [hist] "r" (hist)
290
+#ifdef HAVE_SYS_SDT_H
291
+ , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist)
292
+#endif
293
+ : "cc", "memory");
294
+ t2 = r2; t3 = r3; t4 = r4; t5 = r5;
295
+
296
+ if (op1)
297
+ *op1 = t2;
298
+ if (len1)
299
+ *len1 = t3;
300
+ if (op2)
301
+ *op2 = t4;
302
+ if (len2)
303
+ *len2 = t5;
304
+ return (cc >> 28) & 3;
305
+}
306
+
307
+/*
308
+ Parameter Block for Query Available Functions.
309
+ */
310
+#define static_assert(c, msg) \
311
+ __attribute__((unused)) \
312
+ static char static_assert_failed_ ## msg[c ? 1 : -1]
313
+
314
+struct dfltcc_qaf_param {
315
+ char fns[16];
316
+ char reserved1[8];
317
+ char fmts[2];
318
+ char reserved2[6];
319
+};
320
+
321
+static_assert(sizeof(struct dfltcc_qaf_param) == 32,
322
+ sizeof_struct_dfltcc_qaf_param_is_32);
323
+
324
+local inline int is_bit_set OF((const char *bits, int n));
325
+local inline int is_bit_set(bits, n)
326
+ const char *bits;
327
+ int n;
328
+{
329
+ return bits[n / 8] & (1 << (7 - (n % 8)));
330
+}
331
+
332
+local inline void clear_bit OF((char *bits, int n));
333
+local inline void clear_bit(bits, n)
334
+ char *bits;
335
+ int n;
336
+{
337
+ bits[n / 8] &= ~(1 << (7 - (n % 8)));
338
+}
339
+
340
+#define DFLTCC_FMT0 0
341
+
342
+/*
343
+ Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand.
344
+ */
345
+#define CVT_CRC32 0
346
+#define CVT_ADLER32 1
347
+#define HTT_FIXED 0
348
+#define HTT_DYNAMIC 1
349
+
350
+struct dfltcc_param_v0 {
351
+ uint16_t pbvn; /* Parameter-Block-Version Number */
352
+ uint8_t mvn; /* Model-Version Number */
353
+ uint8_t ribm; /* Reserved for IBM use */
354
+ unsigned reserved32 : 31;
355
+ unsigned cf : 1; /* Continuation Flag */
356
+ uint8_t reserved64[8];
357
+ unsigned nt : 1; /* New Task */
358
+ unsigned reserved129 : 1;
359
+ unsigned cvt : 1; /* Check Value Type */
360
+ unsigned reserved131 : 1;
361
+ unsigned htt : 1; /* Huffman-Table Type */
362
+ unsigned bcf : 1; /* Block-Continuation Flag */
363
+ unsigned bcc : 1; /* Block Closing Control */
364
+ unsigned bhf : 1; /* Block Header Final */
365
+ unsigned reserved136 : 1;
366
+ unsigned reserved137 : 1;
367
+ unsigned dhtgc : 1; /* DHT Generation Control */
368
+ unsigned reserved139 : 5;
369
+ unsigned reserved144 : 5;
370
+ unsigned sbb : 3; /* Sub-Byte Boundary */
371
+ uint8_t oesc; /* Operation-Ending-Supplemental Code */
372
+ unsigned reserved160 : 12;
373
+ unsigned ifs : 4; /* Incomplete-Function Status */
374
+ uint16_t ifl; /* Incomplete-Function Length */
375
+ uint8_t reserved192[8];
376
+ uint8_t reserved256[8];
377
+ uint8_t reserved320[4];
378
+ uint16_t hl; /* History Length */
379
+ unsigned reserved368 : 1;
380
+ uint16_t ho : 15; /* History Offset */
381
+ uint32_t cv; /* Check Value */
382
+ unsigned eobs : 15; /* End-of-block Symbol */
383
+ unsigned reserved431: 1;
384
+ uint8_t eobl : 4; /* End-of-block Length */
385
+ unsigned reserved436 : 12;
386
+ unsigned reserved448 : 4;
387
+ uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table
388
+ Length */
389
+ uint8_t reserved464[6];
390
+ uint8_t cdht[288];
391
+ uint8_t reserved[32];
392
+ uint8_t csb[1152];
393
+};
394
+
395
+static_assert(sizeof(struct dfltcc_param_v0) == 1536,
396
+ sizeof_struct_dfltcc_param_v0_is_1536);
397
+
398
+local z_const char *oesc_msg OF((char *buf, int oesc));
399
+local z_const char *oesc_msg(buf, oesc)
400
+ char *buf;
401
+ int oesc;
402
+{
403
+ if (oesc == 0x00)
404
+ return NULL; /* Successful completion */
405
+ else {
406
+ sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc);
407
+ return buf;
408
+ }
409
+}
410
+
411
+/*
412
+ Extension of inflate_state and deflate_state. Must be doubleword-aligned.
413
+*/
414
+struct dfltcc_state {
415
+ struct dfltcc_param_v0 param; /* Parameter block. */
416
+ struct dfltcc_qaf_param af; /* Available functions. */
417
+ uLong level_mask; /* Levels on which to use DFLTCC */
418
+ uLong block_size; /* New block each X bytes */
419
+ uLong block_threshold; /* New block after total_in > X */
420
+ uLong dht_threshold; /* New block only if avail_in >= X */
421
+ char msg[64]; /* Buffer for strm->msg */
422
+};
423
+
424
+#define ALIGN_UP(p, size) \
425
+ (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1))
426
+
427
+#define GET_DFLTCC_STATE(state) ((struct dfltcc_state FAR *)( \
428
+ (char FAR *)(state) + ALIGN_UP(sizeof(*state), 8)))
429
+
430
+/*
431
+ Compress.
432
+ */
433
+local inline int dfltcc_can_deflate_with_params(z_streamp strm,
434
+ int level,
435
+ uInt window_bits,
436
+ int strategy);
437
+local inline int dfltcc_can_deflate_with_params(strm,
438
+ level,
439
+ window_bits,
440
+ strategy)
441
+ z_streamp strm;
442
+ int level;
443
+ uInt window_bits;
444
+ int strategy;
445
+{
446
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
447
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
448
+
449
+ /* Unsupported compression settings */
450
+ if ((dfltcc_state->level_mask & (1 << level)) == 0)
451
+ return 0;
452
+ if (window_bits != HB_BITS)
453
+ return 0;
454
+ if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY)
455
+ return 0;
456
+
457
+ /* Unsupported hardware */
458
+ if (!is_bit_set(dfltcc_state->af.fns, DFLTCC_GDHT) ||
459
+ !is_bit_set(dfltcc_state->af.fns, DFLTCC_CMPR) ||
460
+ !is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0))
461
+ return 0;
462
+
463
+ return 1;
464
+}
465
+
466
+int ZLIB_INTERNAL dfltcc_can_deflate(strm)
467
+ z_streamp strm;
468
+{
469
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
470
+
471
+ return dfltcc_can_deflate_with_params(strm,
472
+ state->level,
473
+ state->w_bits,
474
+ state->strategy);
475
+}
476
+
477
+local void dfltcc_gdht OF((z_streamp strm));
478
+local void dfltcc_gdht(strm)
479
+ z_streamp strm;
480
+{
481
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
482
+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param;
483
+ size_t avail_in = avail_in = strm->avail_in;
484
+
485
+ dfltcc(DFLTCC_GDHT,
486
+ param, NULL, NULL,
487
+ &strm->next_in, &avail_in, NULL);
488
+}
489
+
490
+local dfltcc_cc dfltcc_cmpr OF((z_streamp strm));
491
+local dfltcc_cc dfltcc_cmpr(strm)
492
+ z_streamp strm;
493
+{
494
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
495
+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param;
496
+ size_t avail_in = strm->avail_in;
497
+ size_t avail_out = strm->avail_out;
498
+ dfltcc_cc cc;
499
+
500
+ cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR,
501
+ param, &strm->next_out, &avail_out,
502
+ &strm->next_in, &avail_in, state->window);
503
+ strm->total_in += (strm->avail_in - avail_in);
504
+ strm->total_out += (strm->avail_out - avail_out);
505
+ strm->avail_in = avail_in;
506
+ strm->avail_out = avail_out;
507
+ return cc;
508
+}
509
+
510
+local void send_eobs OF((z_streamp strm,
511
+ z_const struct dfltcc_param_v0 FAR *param));
512
+local void send_eobs(strm, param)
513
+ z_streamp strm;
514
+ z_const struct dfltcc_param_v0 FAR *param;
515
+{
516
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
517
+
518
+ _tr_send_bits(
519
+ state,
520
+ bi_reverse(param->eobs >> (15 - param->eobl), param->eobl),
521
+ param->eobl);
522
+ flush_pending(strm);
523
+ if (state->pending != 0) {
524
+ /* The remaining data is located in pending_out[0:pending]. If someone
525
+ * calls put_byte() - this might happen in deflate() - the byte will be
526
+ * placed into pending_buf[pending], which is incorrect. Move the
527
+ * remaining data to the beginning of pending_buf so that put_byte() is
528
+ * usable again.
529
+ */
530
+ memmove(state->pending_buf, state->pending_out, state->pending);
531
+ state->pending_out = state->pending_buf;
532
+ }
533
+#ifdef ZLIB_DEBUG
534
+ state->compressed_len += param->eobl;
535
+#endif
536
+}
537
+
538
+int ZLIB_INTERNAL dfltcc_deflate(strm, flush, result)
539
+ z_streamp strm;
540
+ int flush;
541
+ block_state *result;
542
+{
543
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
544
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
545
+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
546
+ uInt masked_avail_in;
547
+ dfltcc_cc cc;
548
+ int need_empty_block;
549
+ int soft_bcc;
550
+ int no_flush;
551
+
552
+ if (!dfltcc_can_deflate(strm))
553
+ return 0;
554
+
555
+again:
556
+ masked_avail_in = 0;
557
+ soft_bcc = 0;
558
+ no_flush = flush == Z_NO_FLUSH;
559
+
560
+ /* No input data. Return, except when Continuation Flag is set, which means
561
+ * that DFLTCC has buffered some output in the parameter block and needs to
562
+ * be called again in order to flush it.
563
+ */
564
+ if (strm->avail_in == 0 && !param->cf) {
565
+ /* A block is still open, and the hardware does not support closing
566
+ * blocks without adding data. Thus, close it manually.
567
+ */
568
+ if (!no_flush && param->bcf) {
569
+ send_eobs(strm, param);
570
+ param->bcf = 0;
571
+ }
572
+ /* Let one of deflate_* functions write a trailing empty block. */
573
+ if (flush == Z_FINISH)
574
+ return 0;
575
+ /* Clear history. */
576
+ if (flush == Z_FULL_FLUSH)
577
+ param->hl = 0;
578
+ *result = need_more;
579
+ return 1;
580
+ }
581
+
582
+ /* There is an open non-BFINAL block, we are not going to close it just
583
+ * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see
584
+ * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new
585
+ * DHT in order to adapt to a possibly changed input data distribution.
586
+ */
587
+ if (param->bcf && no_flush &&
588
+ strm->total_in > dfltcc_state->block_threshold &&
589
+ strm->avail_in >= dfltcc_state->dht_threshold) {
590
+ if (param->cf) {
591
+ /* We need to flush the DFLTCC buffer before writing the
592
+ * End-of-block Symbol. Mask the input data and proceed as usual.
593
+ */
594
+ masked_avail_in += strm->avail_in;
595
+ strm->avail_in = 0;
596
+ no_flush = 0;
597
+ } else {
598
+ /* DFLTCC buffer is empty, so we can manually write the
599
+ * End-of-block Symbol right away.
600
+ */
601
+ send_eobs(strm, param);
602
+ param->bcf = 0;
603
+ dfltcc_state->block_threshold =
604
+ strm->total_in + dfltcc_state->block_size;
605
+ if (strm->avail_out == 0) {
606
+ *result = need_more;
607
+ return 1;
608
+ }
609
+ }
610
+ }
611
+
612
+ /* The caller gave us too much data. Pass only one block worth of
613
+ * uncompressed data to DFLTCC and mask the rest, so that on the next
614
+ * iteration we start a new block.
615
+ */
616
+ if (no_flush && strm->avail_in > dfltcc_state->block_size) {
617
+ masked_avail_in += (strm->avail_in - dfltcc_state->block_size);
618
+ strm->avail_in = dfltcc_state->block_size;
619
+ }
620
+
621
+ /* When we have an open non-BFINAL deflate block and caller indicates that
622
+ * the stream is ending, we need to close an open deflate block and open a
623
+ * BFINAL one.
624
+ */
625
+ need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf;
626
+
627
+ /* Translate stream to parameter block */
628
+ param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32;
629
+ if (!no_flush)
630
+ /* We need to close a block. Always do this in software - when there is
631
+ * no input data, the hardware will not honor BCC. */
632
+ soft_bcc = 1;
633
+ if (flush == Z_FINISH && !param->bcf)
634
+ /* We are about to open a BFINAL block, set Block Header Final bit
635
+ * until the stream ends.
636
+ */
637
+ param->bhf = 1;
638
+ /* DFLTCC-CMPR will write to next_out, so make sure that buffers with
639
+ * higher precedence are empty.
640
+ */
641
+ Assert(state->pending == 0, "There must be no pending bytes");
642
+ Assert(state->bi_valid < 8, "There must be less than 8 pending bits");
643
+ param->sbb = (unsigned int)state->bi_valid;
644
+ if (param->sbb > 0)
645
+ *strm->next_out = (Bytef)state->bi_buf;
646
+ /* Honor history and check value */
647
+ param->nt = 0;
648
+ param->cv = state->wrap == 2 ? ZSWAP32(strm->adler) : strm->adler;
649
+
650
+ /* When opening a block, choose a Huffman-Table Type */
651
+ if (!param->bcf) {
652
+ if (state->strategy == Z_FIXED ||
653
+ (strm->total_in == 0 && dfltcc_state->block_threshold > 0))
654
+ param->htt = HTT_FIXED;
655
+ else {
656
+ param->htt = HTT_DYNAMIC;
657
+ dfltcc_gdht(strm);
658
+ }
659
+ }
660
+
661
+ /* Deflate */
662
+ do {
663
+ cc = dfltcc_cmpr(strm);
664
+ if (strm->avail_in < 4096 && masked_avail_in > 0)
665
+ /* We are about to call DFLTCC with a small input buffer, which is
666
+ * inefficient. Since there is masked data, there will be at least
667
+ * one more DFLTCC call, so skip the current one and make the next
668
+ * one handle more data.
669
+ */
670
+ break;
671
+ } while (cc == DFLTCC_CC_AGAIN);
672
+
673
+ /* Translate parameter block to stream */
674
+ strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
675
+ state->bi_valid = param->sbb;
676
+ if (state->bi_valid == 0)
677
+ state->bi_buf = 0; /* Avoid accessing next_out */
678
+ else
679
+ state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1);
680
+ strm->adler = state->wrap == 2 ? ZSWAP32(param->cv) : param->cv;
681
+
682
+ /* Unmask the input data */
683
+ strm->avail_in += masked_avail_in;
684
+ masked_avail_in = 0;
685
+
686
+ /* If we encounter an error, it means there is a bug in DFLTCC call */
687
+ Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG");
688
+
689
+ /* Update Block-Continuation Flag. It will be used to check whether to call
690
+ * GDHT the next time.
691
+ */
692
+ if (cc == DFLTCC_CC_OK) {
693
+ if (soft_bcc) {
694
+ send_eobs(strm, param);
695
+ param->bcf = 0;
696
+ dfltcc_state->block_threshold =
697
+ strm->total_in + dfltcc_state->block_size;
698
+ } else
699
+ param->bcf = 1;
700
+ if (flush == Z_FINISH) {
701
+ if (need_empty_block)
702
+ /* Make the current deflate() call also close the stream */
703
+ return 0;
704
+ else {
705
+ bi_windup(state);
706
+ *result = finish_done;
707
+ }
708
+ } else {
709
+ if (flush == Z_FULL_FLUSH)
710
+ param->hl = 0; /* Clear history */
711
+ *result = flush == Z_NO_FLUSH ? need_more : block_done;
712
+ }
713
+ } else {
714
+ param->bcf = 1;
715
+ *result = need_more;
716
+ }
717
+ if (strm->avail_in != 0 && strm->avail_out != 0)
718
+ goto again; /* deflate() must use all input or all output */
719
+ return 1;
720
+}
721
+
722
+/*
723
+ Expand.
724
+ */
725
+int ZLIB_INTERNAL dfltcc_can_inflate(strm)
726
+ z_streamp strm;
727
+{
728
+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
729
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
730
+
731
+ /* Unsupported compression settings */
732
+ if (state->wbits != HB_BITS)
733
+ return 0;
734
+
735
+ /* Unsupported hardware */
736
+ return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) &&
737
+ is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0);
738
+}
739
+
740
+local dfltcc_cc dfltcc_xpnd OF((z_streamp strm));
741
+local dfltcc_cc dfltcc_xpnd(strm)
742
+ z_streamp strm;
743
+{
744
+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
745
+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param;
746
+ size_t avail_in = strm->avail_in;
747
+ size_t avail_out = strm->avail_out;
748
+ dfltcc_cc cc;
749
+
750
+ cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR,
751
+ param, &strm->next_out, &avail_out,
752
+ &strm->next_in, &avail_in, state->window);
753
+ strm->avail_in = avail_in;
754
+ strm->avail_out = avail_out;
755
+ return cc;
756
+}
757
+
758
+dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate(strm, flush, ret)
759
+ z_streamp strm;
760
+ int flush;
761
+ int *ret;
762
+{
763
+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
764
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
765
+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
766
+ dfltcc_cc cc;
767
+
768
+ if (flush == Z_BLOCK || flush == Z_TREES) {
769
+ /* DFLTCC does not support stopping on block boundaries */
770
+ if (dfltcc_inflate_disable(strm)) {
771
+ *ret = Z_STREAM_ERROR;
772
+ return DFLTCC_INFLATE_BREAK;
773
+ } else
774
+ return DFLTCC_INFLATE_SOFTWARE;
775
+ }
776
+
777
+ if (state->last) {
778
+ if (state->bits != 0) {
779
+ strm->next_in++;
780
+ strm->avail_in--;
781
+ state->bits = 0;
782
+ }
783
+ state->mode = CHECK;
784
+ return DFLTCC_INFLATE_CONTINUE;
785
+ }
786
+
787
+ if (strm->avail_in == 0 && !param->cf)
788
+ return DFLTCC_INFLATE_BREAK;
789
+
790
+ if (inflate_ensure_window(state)) {
791
+ state->mode = MEM;
792
+ return DFLTCC_INFLATE_CONTINUE;
793
+ }
794
+
795
+ /* Translate stream to parameter block */
796
+ param->cvt = state->flags ? CVT_CRC32 : CVT_ADLER32;
797
+ param->sbb = state->bits;
798
+ param->hl = state->whave; /* Software and hardware history formats match */
799
+ param->ho = (state->wnext - state->whave) & ((1 << HB_BITS) - 1);
800
+ if (param->hl)
801
+ param->nt = 0; /* Honor history for the first block */
802
+ param->cv = state->flags ? ZSWAP32(state->check) : state->check;
803
+
804
+ /* Inflate */
805
+ do {
806
+ cc = dfltcc_xpnd(strm);
807
+ } while (cc == DFLTCC_CC_AGAIN);
808
+
809
+ /* Translate parameter block to stream */
810
+ strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
811
+ state->last = cc == DFLTCC_CC_OK;
812
+ state->bits = param->sbb;
813
+ state->whave = param->hl;
814
+ state->wnext = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
815
+ state->check = state->flags ? ZSWAP32(param->cv) : param->cv;
816
+ if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
817
+ /* Report an error if stream is corrupted */
818
+ state->mode = BAD;
819
+ return DFLTCC_INFLATE_CONTINUE;
820
+ }
821
+ state->mode = TYPEDO;
822
+ /* Break if operands are exhausted, otherwise continue looping */
823
+ return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ?
824
+ DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE;
825
+}
826
+
827
+int ZLIB_INTERNAL dfltcc_was_inflate_used(strm)
828
+ z_streamp strm;
829
+{
830
+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
831
+ struct dfltcc_param_v0 FAR *param = &GET_DFLTCC_STATE(state)->param;
832
+
833
+ return !param->nt;
834
+}
835
+
836
+int ZLIB_INTERNAL dfltcc_inflate_disable(strm)
837
+ z_streamp strm;
838
+{
839
+ struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state;
840
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
841
+
842
+ if (!dfltcc_can_inflate(strm))
843
+ return 0;
844
+ if (dfltcc_was_inflate_used(strm))
845
+ /* DFLTCC has already decompressed some data. Since there is not
846
+ * enough information to resume decompression in software, the call
847
+ * must fail.
848
+ */
849
+ return 1;
850
+ /* DFLTCC was not used yet - decompress in software */
851
+ memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
852
+ return 0;
853
+}
854
+
855
+/*
856
+ Memory management.
857
+
858
+ DFLTCC requires parameter blocks and window to be aligned. zlib allows
859
+ users to specify their own allocation functions, so using e.g.
860
+ `posix_memalign' is not an option. Thus, we overallocate and take the
861
+ aligned portion of the buffer.
862
+*/
863
+local inline int is_dfltcc_enabled OF((void));
864
+local inline int is_dfltcc_enabled(void)
865
+{
866
+ const char *env;
867
+ uint64_t facilities[(DFLTCC_FACILITY / 64) + 1];
868
+ register char r0 __asm__("r0");
869
+
870
+ env = secure_getenv("DFLTCC");
871
+ if (env && !strcmp(env, "0"))
872
+ /* User has explicitly disabled DFLTCC. */
873
+ return 0;
874
+
875
+ memset(facilities, 0, sizeof(facilities));
876
+ r0 = sizeof(facilities) / sizeof(facilities[0]) - 1;
877
+ /* STFLE is supported since z9-109 and only in z/Architecture mode. When
878
+ * compiling with -m31, gcc defaults to ESA mode, however, since the kernel
879
+ * is 64-bit, it's always z/Architecture mode at runtime.
880
+ */
881
+ __asm__ volatile(".machinemode push\n"
882
+ ".machinemode zarch\n"
883
+ "stfle %[facilities]\n"
884
+ ".machinemode pop\n"
885
+ : [facilities] "=Q" (facilities)
886
+ , [r0] "+r" (r0)
887
+ :
888
+ : "cc");
889
+ return is_bit_set((const char *)facilities, DFLTCC_FACILITY);
890
+}
891
+
892
+void ZLIB_INTERNAL dfltcc_reset(strm, size)
893
+ z_streamp strm;
894
+ uInt size;
895
+{
896
+ struct dfltcc_state *dfltcc_state =
897
+ (struct dfltcc_state *)((char FAR *)strm->state + ALIGN_UP(size, 8));
898
+ struct dfltcc_qaf_param *param =
899
+ (struct dfltcc_qaf_param *)&dfltcc_state->param;
900
+ const char *s;
901
+
902
+ /* Initialize available functions */
903
+ if (is_dfltcc_enabled()) {
904
+ dfltcc(DFLTCC_QAF, param, NULL, NULL, NULL, NULL, NULL);
905
+ memmove(&dfltcc_state->af, param, sizeof(dfltcc_state->af));
906
+ } else
907
+ memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af));
908
+
909
+ if (secure_getenv("SOURCE_DATE_EPOCH"))
910
+ /* User needs reproducible results, but the output of DFLTCC_CMPR
911
+ * depends on buffers' page offsets.
912
+ */
913
+ clear_bit(dfltcc_state->af.fns, DFLTCC_CMPR);
914
+
915
+ /* Initialize parameter block */
916
+ memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param));
917
+ dfltcc_state->param.nt = 1;
918
+
919
+ /* Initialize tuning parameters */
920
+#ifndef DFLTCC_LEVEL_MASK
921
+#define DFLTCC_LEVEL_MASK 0x2
922
+#endif
923
+ s = secure_getenv("DFLTCC_LEVEL_MASK");
924
+ dfltcc_state->level_mask = (s && *s) ? strtoul(s, NULL, 0) :
925
+ DFLTCC_LEVEL_MASK;
926
+#ifndef DFLTCC_BLOCK_SIZE
927
+#define DFLTCC_BLOCK_SIZE 1048576
928
+#endif
929
+ s = secure_getenv("DFLTCC_BLOCK_SIZE");
930
+ dfltcc_state->block_size = (s && *s) ? strtoul(s, NULL, 0) :
931
+ DFLTCC_BLOCK_SIZE;
932
+#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE
933
+#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096
934
+#endif
935
+ s = secure_getenv("DFLTCC_FIRST_FHT_BLOCK_SIZE");
936
+ dfltcc_state->block_threshold = (s && *s) ? strtoul(s, NULL, 0) :
937
+ DFLTCC_FIRST_FHT_BLOCK_SIZE;
938
+#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE
939
+#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096
940
+#endif
941
+ s = secure_getenv("DFLTCC_DHT_MIN_SAMPLE_SIZE");
942
+ dfltcc_state->dht_threshold = (s && *s) ? strtoul(s, NULL, 0) :
943
+ DFLTCC_DHT_MIN_SAMPLE_SIZE;
944
+#ifndef DFLTCC_RIBM
945
+#define DFLTCC_RIBM 0
946
+#endif
947
+ s = secure_getenv("DFLTCC_RIBM");
948
+ dfltcc_state->param.ribm = (s && *s) ? strtoul(s, NULL, 0) :
949
+ DFLTCC_RIBM;
950
+}
951
+
952
+voidpf ZLIB_INTERNAL dfltcc_alloc_state(strm, items, size)
953
+ z_streamp strm;
954
+ uInt items;
955
+ uInt size;
956
+{
957
+ return ZALLOC(strm,
958
+ ALIGN_UP(items * size, 8) + sizeof(struct dfltcc_state),
959
+ sizeof(unsigned char));
960
+}
961
+
962
+void ZLIB_INTERNAL dfltcc_copy_state(dst, src, size)
963
+ voidpf dst;
964
+ const voidpf src;
965
+ uInt size;
966
+{
967
+ zmemcpy(dst, src, ALIGN_UP(size, 8) + sizeof(struct dfltcc_state));
968
+}
969
+
970
+static const int PAGE_ALIGN = 0x1000;
971
+
972
+voidpf ZLIB_INTERNAL dfltcc_alloc_window(strm, items, size)
973
+ z_streamp strm;
974
+ uInt items;
975
+ uInt size;
976
+{
977
+ voidpf p, w;
978
+
979
+ /* To simplify freeing, we store the pointer to the allocated buffer right
980
+ * before the window.
981
+ */
982
+ p = ZALLOC(strm, sizeof(voidpf) + items * size + PAGE_ALIGN,
983
+ sizeof(unsigned char));
984
+ if (p == NULL)
985
+ return NULL;
986
+ w = ALIGN_UP((char FAR *)p + sizeof(voidpf), PAGE_ALIGN);
987
+ *(voidpf *)((char FAR *)w - sizeof(voidpf)) = p;
988
+ return w;
989
+}
990
+
991
+void ZLIB_INTERNAL dfltcc_free_window(strm, w)
992
+ z_streamp strm;
993
+ voidpf w;
994
+{
995
+ if (w)
996
+ ZFREE(strm, *(voidpf *)((unsigned char FAR *)w - sizeof(voidpf)));
997
+}
998
+
999
+/*
1000
+ Switching between hardware and software compression.
1001
+
1002
+ DFLTCC does not support all zlib settings, e.g. generation of non-compressed
1003
+ blocks or alternative window sizes. When such settings are applied on the
1004
+ fly with deflateParams, we need to convert between hardware and software
1005
+ window formats.
1006
+*/
1007
+int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush)
1008
+ z_streamp strm;
1009
+ int level;
1010
+ int strategy;
1011
+ int *flush;
1012
+{
1013
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
1014
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
1015
+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
1016
+ int could_deflate = dfltcc_can_deflate(strm);
1017
+ int can_deflate = dfltcc_can_deflate_with_params(strm,
1018
+ level,
1019
+ state->w_bits,
1020
+ strategy);
1021
+
1022
+ if (can_deflate == could_deflate)
1023
+ /* We continue to work in the same mode - no changes needed */
1024
+ return Z_OK;
1025
+
1026
+ if (strm->total_in == 0 && param->nt == 1 && param->hl == 0)
1027
+ /* DFLTCC was not used yet - no changes needed */
1028
+ return Z_OK;
1029
+
1030
+ /* For now, do not convert between window formats - simply get rid of the
1031
+ * old data instead.
1032
+ */
1033
+ *flush = Z_FULL_FLUSH;
1034
+ return Z_OK;
1035
+}
1036
+
1037
+/*
1038
+ Preloading history.
1039
+*/
1040
+local void append_history OF((struct dfltcc_param_v0 FAR *param,
1041
+ Bytef *history,
1042
+ const Bytef *buf,
1043
+ uInt count));
1044
+local void append_history(param, history, buf, count)
1045
+ struct dfltcc_param_v0 FAR *param;
1046
+ Bytef *history;
1047
+ const Bytef *buf;
1048
+ uInt count;
1049
+{
1050
+ size_t offset;
1051
+ size_t n;
1052
+
1053
+ /* Do not use more than 32K */
1054
+ if (count > HB_SIZE) {
1055
+ buf += count - HB_SIZE;
1056
+ count = HB_SIZE;
1057
+ }
1058
+ offset = (param->ho + param->hl) % HB_SIZE;
1059
+ if (offset + count <= HB_SIZE)
1060
+ /* Circular history buffer does not wrap - copy one chunk */
1061
+ zmemcpy(history + offset, buf, count);
1062
+ else {
1063
+ /* Circular history buffer wraps - copy two chunks */
1064
+ n = HB_SIZE - offset;
1065
+ zmemcpy(history + offset, buf, n);
1066
+ zmemcpy(history, buf + n, count - n);
1067
+ }
1068
+ n = param->hl + count;
1069
+ if (n <= HB_SIZE)
1070
+ /* All history fits into buffer - no need to discard anything */
1071
+ param->hl = n;
1072
+ else {
1073
+ /* History does not fit into buffer - discard extra bytes */
1074
+ param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE;
1075
+ param->hl = HB_SIZE;
1076
+ }
1077
+}
1078
+
1079
+int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length)
1080
+ z_streamp strm;
1081
+ const Bytef *dictionary;
1082
+ uInt dict_length;
1083
+{
1084
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
1085
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
1086
+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
1087
+
1088
+ append_history(param, state->window, dictionary, dict_length);
1089
+ state->strstart = 1; /* Add FDICT to zlib header */
1090
+ return Z_OK;
1091
+}
1092
+
1093
+int ZLIB_INTERNAL dfltcc_deflate_get_dictionary(strm, dictionary, dict_length)
1094
+ z_streamp strm;
1095
+ Bytef *dictionary;
1096
+ uInt *dict_length;
1097
+{
1098
+ deflate_state FAR *state = (deflate_state FAR *)strm->state;
1099
+ struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
1100
+ struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
1101
+
1102
+ if (dictionary) {
1103
+ if (param->ho + param->hl <= HB_SIZE)
1104
+ /* Circular history buffer does not wrap - copy one chunk */
1105
+ zmemcpy(dictionary, state->window + param->ho, param->hl);
1106
+ else {
1107
+ /* Circular history buffer wraps - copy two chunks */
1108
+ zmemcpy(dictionary,
1109
+ state->window + param->ho,
1110
+ HB_SIZE - param->ho);
1111
+ zmemcpy(dictionary + HB_SIZE - param->ho,
1112
+ state->window,
1113
+ param->ho + param->hl - HB_SIZE);
1114
+ }
1115
+ }
1116
+ if (dict_length)
1117
+ *dict_length = param->hl;
1118
+ return Z_OK;
1119
+}
1120
Index: zlib-1.2.11/contrib/s390/dfltcc.h
1121
===================================================================
1122
--- /dev/null
1123
+++ zlib-1.2.11/contrib/s390/dfltcc.h
1124
1125
+#ifndef DFLTCC_H
1126
+#define DFLTCC_H
1127
+
1128
+#include "../../zlib.h"
1129
+#include "../../zutil.h"
1130
+
1131
+voidpf ZLIB_INTERNAL dfltcc_alloc_state OF((z_streamp strm, uInt items,
1132
+ uInt size));
1133
+void ZLIB_INTERNAL dfltcc_copy_state OF((voidpf dst, const voidpf src,
1134
+ uInt size));
1135
+void ZLIB_INTERNAL dfltcc_reset OF((z_streamp strm, uInt size));
1136
+voidpf ZLIB_INTERNAL dfltcc_alloc_window OF((z_streamp strm, uInt items,
1137
+ uInt size));
1138
+void ZLIB_INTERNAL dfltcc_free_window OF((z_streamp strm, voidpf w));
1139
+int ZLIB_INTERNAL dfltcc_can_inflate OF((z_streamp strm));
1140
+typedef enum {
1141
+ DFLTCC_INFLATE_CONTINUE,
1142
+ DFLTCC_INFLATE_BREAK,
1143
+ DFLTCC_INFLATE_SOFTWARE,
1144
+} dfltcc_inflate_action;
1145
+dfltcc_inflate_action ZLIB_INTERNAL dfltcc_inflate OF((z_streamp strm,
1146
+ int flush, int *ret));
1147
+int ZLIB_INTERNAL dfltcc_was_inflate_used OF((z_streamp strm));
1148
+int ZLIB_INTERNAL dfltcc_inflate_disable OF((z_streamp strm));
1149
+
1150
+#define ZALLOC_STATE dfltcc_alloc_state
1151
+#define ZFREE_STATE ZFREE
1152
+#define ZCOPY_STATE dfltcc_copy_state
1153
+#define ZALLOC_WINDOW dfltcc_alloc_window
1154
+#define ZFREE_WINDOW dfltcc_free_window
1155
+#define TRY_FREE_WINDOW dfltcc_free_window
1156
+#define INFLATE_RESET_KEEP_HOOK(strm) \
1157
+ dfltcc_reset((strm), sizeof(struct inflate_state))
1158
+#define INFLATE_PRIME_HOOK(strm, bits, value) \
1159
+ do { if (dfltcc_inflate_disable((strm))) return Z_STREAM_ERROR; } while (0)
1160
+#define INFLATE_TYPEDO_HOOK(strm, flush) \
1161
+ if (dfltcc_can_inflate((strm))) { \
1162
+ dfltcc_inflate_action action; \
1163
+\
1164
+ RESTORE(); \
1165
+ action = dfltcc_inflate((strm), (flush), &ret); \
1166
+ LOAD(); \
1167
+ if (action == DFLTCC_INFLATE_CONTINUE) \
1168
+ break; \
1169
+ else if (action == DFLTCC_INFLATE_BREAK) \
1170
+ goto inf_leave; \
1171
+ }
1172
+#define INFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_inflate((strm)))
1173
+#define INFLATE_NEED_UPDATEWINDOW(strm) (!dfltcc_can_inflate((strm)))
1174
+#define INFLATE_MARK_HOOK(strm) \
1175
+ do { \
1176
+ if (dfltcc_was_inflate_used((strm))) return -(1L << 16); \
1177
+ } while (0)
1178
+
1179
+#endif
1180
Index: zlib-1.2.11/contrib/s390/dfltcc_deflate.h
1181
===================================================================
1182
--- /dev/null
1183
+++ zlib-1.2.11/contrib/s390/dfltcc_deflate.h
1184
1185
+#ifndef DFLTCC_DEFLATE_H
1186
+#define DFLTCC_DEFLATE_H
1187
+
1188
+#include "dfltcc.h"
1189
+
1190
+int ZLIB_INTERNAL dfltcc_can_deflate OF((z_streamp strm));
1191
+int ZLIB_INTERNAL dfltcc_deflate OF((z_streamp strm,
1192
+ int flush,
1193
+ block_state *result));
1194
+int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm,
1195
+ int level,
1196
+ int strategy,
1197
+ int *flush));
1198
+int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm,
1199
+ const Bytef *dictionary,
1200
+ uInt dict_length));
1201
+int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm,
1202
+ Bytef *dictionary,
1203
+ uInt* dict_length));
1204
+
1205
+#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \
1206
+ do { \
1207
+ if (dfltcc_can_deflate((strm))) \
1208
+ return dfltcc_deflate_set_dictionary((strm), (dict), (dict_len)); \
1209
+ } while (0)
1210
+#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \
1211
+ do { \
1212
+ if (dfltcc_can_deflate((strm))) \
1213
+ return dfltcc_deflate_get_dictionary((strm), (dict), (dict_len)); \
1214
+ } while (0)
1215
+#define DEFLATE_RESET_KEEP_HOOK(strm) \
1216
+ dfltcc_reset((strm), sizeof(deflate_state))
1217
+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \
1218
+ do { \
1219
+ int err; \
1220
+\
1221
+ err = dfltcc_deflate_params((strm), \
1222
+ (level), \
1223
+ (strategy), \
1224
+ (hook_flush)); \
1225
+ if (err == Z_STREAM_ERROR) \
1226
+ return err; \
1227
+ } while (0)
1228
+#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \
1229
+ do { \
1230
+ if (dfltcc_can_deflate((strm))) \
1231
+ (complen) = (3 + 5 + 5 + 4 + 19 * 3 + (286 + 30) * 7 + \
1232
+ (source_len) * 16 + 15 + 7) >> 3; \
1233
+ } while (0)
1234
+#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (dfltcc_can_deflate((strm)))
1235
+#define DEFLATE_HOOK dfltcc_deflate
1236
+#define DEFLATE_NEED_CHECKSUM(strm) (!dfltcc_can_deflate((strm)))
1237
+
1238
+#endif
1239
Index: zlib-1.2.11/deflate.c
1240
===================================================================
1241
--- zlib-1.2.11.orig/deflate.c
1242
+++ zlib-1.2.11/deflate.c
1243
1244
*/
1245
1246
/* ===========================================================================
1247
- * Function prototypes.
1248
+ * Architecture-specific bits.
1249
*/
1250
-typedef enum {
1251
- need_more, /* block not completed, need more input or more output */
1252
- block_done, /* block flush performed */
1253
- finish_started, /* finish started, need only more output at next deflate */
1254
- finish_done /* finish done, accept no more input or output */
1255
-} block_state;
1256
+#ifdef DFLTCC
1257
+# include "contrib/s390/dfltcc_deflate.h"
1258
+#else
1259
+#define ZALLOC_STATE ZALLOC
1260
+#define ZFREE_STATE ZFREE
1261
+#define ZCOPY_STATE zmemcpy
1262
+#define ZALLOC_WINDOW ZALLOC
1263
+#define TRY_FREE_WINDOW TRY_FREE
1264
+#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
1265
+#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
1266
+#define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
1267
+#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0)
1268
+#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0)
1269
+#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0
1270
+#define DEFLATE_HOOK(strm, flush, bstate) 0
1271
+#define DEFLATE_NEED_CHECKSUM(strm) 1
1272
+#endif
1273
1274
+/* ===========================================================================
1275
+ * Function prototypes.
1276
+ */
1277
typedef block_state (*compress_func) OF((deflate_state *s, int flush));
1278
/* Compression function. Returns the block state after the call. */
1279
1280
1281
local block_state deflate_huff OF((deflate_state *s, int flush));
1282
local void lm_init OF((deflate_state *s));
1283
local void putShortMSB OF((deflate_state *s, uInt b));
1284
-local void flush_pending OF((z_streamp strm));
1285
local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
1286
#ifdef ASMV
1287
# pragma message("Assembler code may have bugs -- use at your own risk")
1288
1289
return Z_STREAM_ERROR;
1290
}
1291
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
1292
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
1293
+ s = (deflate_state *) ZALLOC_STATE(strm, 1, sizeof(deflate_state));
1294
if (s == Z_NULL) return Z_MEM_ERROR;
1295
strm->state = (struct internal_state FAR *)s;
1296
s->strm = strm;
1297
1298
s->hash_mask = s->hash_size - 1;
1299
s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
1300
1301
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
1302
+ s->window = (Bytef *) ZALLOC_WINDOW(strm, s->w_size, 2*sizeof(Byte));
1303
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
1304
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
1305
1306
1307
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
1308
if (wrap == 1)
1309
strm->adler = adler32(strm->adler, dictionary, dictLength);
1310
+ DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength);
1311
s->wrap = 0; /* avoid computing Adler-32 in read_buf */
1312
1313
/* if dictionary would fill window, just replace the history */
1314
1315
1316
if (deflateStateCheck(strm))
1317
return Z_STREAM_ERROR;
1318
+ DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength);
1319
s = strm->state;
1320
len = s->strstart + s->lookahead;
1321
if (len > s->w_size)
1322
1323
1324
_tr_init(s);
1325
1326
+ DEFLATE_RESET_KEEP_HOOK(strm);
1327
+
1328
return Z_OK;
1329
}
1330
1331
1332
{
1333
deflate_state *s;
1334
compress_func func;
1335
+ int hook_flush = Z_NO_FLUSH;
1336
1337
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
1338
s = strm->state;
1339
1340
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
1341
return Z_STREAM_ERROR;
1342
}
1343
+ DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush);
1344
func = configuration_table[s->level].func;
1345
1346
- if ((strategy != s->strategy || func != configuration_table[level].func) &&
1347
- s->high_water) {
1348
+ if ((strategy != s->strategy || func != configuration_table[level].func ||
1349
+ hook_flush != Z_NO_FLUSH) && s->high_water) {
1350
/* Flush the last buffer: */
1351
- int err = deflate(strm, Z_BLOCK);
1352
+ int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ?
1353
+ hook_flush : Z_BLOCK);
1354
if (err == Z_STREAM_ERROR)
1355
return err;
1356
if (strm->avail_out == 0)
1357
1358
/* conservative upper bound for compressed data */
1359
complen = sourceLen +
1360
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
1361
+ DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen);
1362
1363
/* if can't get parameters, return conservative bound plus zlib wrapper */
1364
if (deflateStateCheck(strm))
1365
1366
}
1367
1368
/* if not default parameters, return conservative bound */
1369
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
1370
+ if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) ||
1371
+ s->w_bits != 15 || s->hash_bits != 8 + 7)
1372
return complen + wraplen;
1373
1374
/* default settings: return tight bound for that case */
1375
1376
* applications may wish to modify it to avoid allocating a large
1377
* strm->next_out buffer and copying into it. (See also read_buf()).
1378
*/
1379
-local void flush_pending(strm)
1380
+void ZLIB_INTERNAL flush_pending(strm)
1381
z_streamp strm;
1382
{
1383
unsigned len;
1384
1385
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
1386
block_state bstate;
1387
1388
- bstate = s->level == 0 ? deflate_stored(s, flush) :
1389
+ bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate :
1390
+ s->level == 0 ? deflate_stored(s, flush) :
1391
s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
1392
s->strategy == Z_RLE ? deflate_rle(s, flush) :
1393
(*(configuration_table[s->level].func))(s, flush);
1394
1395
TRY_FREE(strm, strm->state->pending_buf);
1396
TRY_FREE(strm, strm->state->head);
1397
TRY_FREE(strm, strm->state->prev);
1398
- TRY_FREE(strm, strm->state->window);
1399
+ TRY_FREE_WINDOW(strm, strm->state->window);
1400
1401
- ZFREE(strm, strm->state);
1402
+ ZFREE_STATE(strm, strm->state);
1403
strm->state = Z_NULL;
1404
1405
return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
1406
1407
1408
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
1409
1410
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
1411
+ ds = (deflate_state *) ZALLOC_STATE(dest, 1, sizeof(deflate_state));
1412
if (ds == Z_NULL) return Z_MEM_ERROR;
1413
dest->state = (struct internal_state FAR *) ds;
1414
- zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
1415
+ ZCOPY_STATE((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
1416
ds->strm = dest;
1417
1418
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
1419
+ ds->window = (Bytef *) ZALLOC_WINDOW(dest, ds->w_size, 2*sizeof(Byte));
1420
ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
1421
ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
1422
overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
1423
1424
strm->avail_in -= len;
1425
1426
zmemcpy(buf, strm->next_in, len);
1427
- if (strm->state->wrap == 1) {
1428
+ if (!DEFLATE_NEED_CHECKSUM(strm)) {}
1429
+ else if (strm->state->wrap == 1) {
1430
strm->adler = adler32(strm->adler, buf, len);
1431
}
1432
#ifdef GZIP
1433
Index: zlib-1.2.11/deflate.h
1434
===================================================================
1435
--- zlib-1.2.11.orig/deflate.h
1436
+++ zlib-1.2.11/deflate.h
1437
1438
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
1439
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
1440
ulg stored_len, int last));
1441
+void ZLIB_INTERNAL _tr_send_bits OF((deflate_state *s, int value, int length));
1442
1443
#define d_code(dist) \
1444
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
1445
1446
flush = _tr_tally(s, distance, length)
1447
#endif
1448
1449
+typedef enum {
1450
+ need_more, /* block not completed, need more input or more output */
1451
+ block_done, /* block flush performed */
1452
+ finish_started, /* finish started, need only more output at next deflate */
1453
+ finish_done /* finish done, accept no more input or output */
1454
+} block_state;
1455
+
1456
+unsigned ZLIB_INTERNAL bi_reverse OF((unsigned code, int len));
1457
+void ZLIB_INTERNAL bi_windup OF((deflate_state *s));
1458
+void ZLIB_INTERNAL flush_pending OF((z_streamp strm));
1459
+
1460
#endif /* DEFLATE_H */
1461
Index: zlib-1.2.11/gzguts.h
1462
===================================================================
1463
--- zlib-1.2.11.orig/gzguts.h
1464
+++ zlib-1.2.11/gzguts.h
1465
1466
1467
/* default i/o buffer size -- double this for output when reading (this and
1468
twice this must be able to fit in an unsigned type) */
1469
+#ifdef DFLTCC
1470
+#define GZBUFSIZE 131072
1471
+#else
1472
#define GZBUFSIZE 8192
1473
+#endif
1474
1475
/* gzip modes, also provide a little integrity check on the passed structure */
1476
#define GZ_NONE 0
1477
Index: zlib-1.2.11/inflate.c
1478
===================================================================
1479
--- zlib-1.2.11.orig/inflate.c
1480
+++ zlib-1.2.11/inflate.c
1481
1482
#include "inflate.h"
1483
#include "inffast.h"
1484
1485
+/* architecture-specific bits */
1486
+#ifdef DFLTCC
1487
+# include "contrib/s390/dfltcc.h"
1488
+#else
1489
+#define ZALLOC_STATE ZALLOC
1490
+#define ZFREE_STATE ZFREE
1491
+#define ZCOPY_STATE zmemcpy
1492
+#define ZALLOC_WINDOW ZALLOC
1493
+#define ZFREE_WINDOW ZFREE
1494
+#define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
1495
+#define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0)
1496
+#define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
1497
+#define INFLATE_NEED_CHECKSUM(strm) 1
1498
+#define INFLATE_NEED_UPDATEWINDOW(strm) 1
1499
+#define INFLATE_MARK_HOOK(strm) do {} while (0)
1500
+#endif
1501
+
1502
#ifdef MAKEFIXED
1503
# ifndef BUILDFIXED
1504
# define BUILDFIXED
1505
1506
state->lencode = state->distcode = state->next = state->codes;
1507
state->sane = 1;
1508
state->back = -1;
1509
+ INFLATE_RESET_KEEP_HOOK(strm);
1510
Tracev((stderr, "inflate: reset\n"));
1511
return Z_OK;
1512
}
1513
1514
if (windowBits && (windowBits < 8 || windowBits > 15))
1515
return Z_STREAM_ERROR;
1516
if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
1517
- ZFREE(strm, state->window);
1518
+ ZFREE_WINDOW(strm, state->window);
1519
state->window = Z_NULL;
1520
}
1521
1522
1523
strm->zfree = zcfree;
1524
#endif
1525
state = (struct inflate_state FAR *)
1526
- ZALLOC(strm, 1, sizeof(struct inflate_state));
1527
+ ZALLOC_STATE(strm, 1, sizeof(struct inflate_state));
1528
if (state == Z_NULL) return Z_MEM_ERROR;
1529
Tracev((stderr, "inflate: allocated\n"));
1530
strm->state = (struct internal_state FAR *)state;
1531
1532
state->mode = HEAD; /* to pass state test in inflateReset2() */
1533
ret = inflateReset2(strm, windowBits);
1534
if (ret != Z_OK) {
1535
- ZFREE(strm, state);
1536
+ ZFREE_STATE(strm, state);
1537
strm->state = Z_NULL;
1538
}
1539
return ret;
1540
1541
struct inflate_state FAR *state;
1542
1543
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1544
+ INFLATE_PRIME_HOOK(strm, bits, value);
1545
state = (struct inflate_state FAR *)strm->state;
1546
if (bits < 0) {
1547
state->hold = 0;
1548
1549
}
1550
#endif /* MAKEFIXED */
1551
1552
+int ZLIB_INTERNAL inflate_ensure_window(state)
1553
+ struct inflate_state *state;
1554
+{
1555
+ /* if it hasn't been done already, allocate space for the window */
1556
+ if (state->window == Z_NULL) {
1557
+ state->window = (unsigned char FAR *)
1558
+ ZALLOC_WINDOW(state->strm, 1U << state->wbits,
1559
+ sizeof(unsigned char));
1560
+ if (state->window == Z_NULL) return 1;
1561
+ }
1562
+
1563
+ /* if window not in use yet, initialize */
1564
+ if (state->wsize == 0) {
1565
+ state->wsize = 1U << state->wbits;
1566
+ state->wnext = 0;
1567
+ state->whave = 0;
1568
+ }
1569
+
1570
+ return 0;
1571
+}
1572
+
1573
/*
1574
Update the window with the last wsize (normally 32K) bytes written before
1575
returning. If window does not exist yet, create it. This is only called
1576
1577
1578
state = (struct inflate_state FAR *)strm->state;
1579
1580
- /* if it hasn't been done already, allocate space for the window */
1581
- if (state->window == Z_NULL) {
1582
- state->window = (unsigned char FAR *)
1583
- ZALLOC(strm, 1U << state->wbits,
1584
- sizeof(unsigned char));
1585
- if (state->window == Z_NULL) return 1;
1586
- }
1587
-
1588
- /* if window not in use yet, initialize */
1589
- if (state->wsize == 0) {
1590
- state->wsize = 1U << state->wbits;
1591
- state->wnext = 0;
1592
- state->whave = 0;
1593
- }
1594
+ if (inflate_ensure_window(state)) return 1;
1595
1596
/* copy state->wsize or less output bytes into the circular window */
1597
if (copy >= state->wsize) {
1598
1599
case TYPE:
1600
if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
1601
case TYPEDO:
1602
+ INFLATE_TYPEDO_HOOK(strm, flush);
1603
if (state->last) {
1604
BYTEBITS();
1605
state->mode = CHECK;
1606
1607
out -= left;
1608
strm->total_out += out;
1609
state->total += out;
1610
- if ((state->wrap & 4) && out)
1611
+ if (INFLATE_NEED_CHECKSUM(strm) && (state->wrap & 4) && out)
1612
strm->adler = state->check =
1613
UPDATE(state->check, put - out, out);
1614
out = left;
1615
1616
*/
1617
inf_leave:
1618
RESTORE();
1619
- if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
1620
- (state->mode < CHECK || flush != Z_FINISH)))
1621
+ if (INFLATE_NEED_UPDATEWINDOW(strm) &&
1622
+ (state->wsize || (out != strm->avail_out && state->mode < BAD &&
1623
+ (state->mode < CHECK || flush != Z_FINISH))))
1624
if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
1625
state->mode = MEM;
1626
return Z_MEM_ERROR;
1627
1628
strm->total_in += in;
1629
strm->total_out += out;
1630
state->total += out;
1631
- if ((state->wrap & 4) && out)
1632
+ if (INFLATE_NEED_CHECKSUM(strm) && (state->wrap & 4) && out)
1633
strm->adler = state->check =
1634
UPDATE(state->check, strm->next_out - out, out);
1635
strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
1636
1637
if (inflateStateCheck(strm))
1638
return Z_STREAM_ERROR;
1639
state = (struct inflate_state FAR *)strm->state;
1640
- if (state->window != Z_NULL) ZFREE(strm, state->window);
1641
- ZFREE(strm, strm->state);
1642
+ if (state->window != Z_NULL) ZFREE_WINDOW(strm, state->window);
1643
+ ZFREE_STATE(strm, strm->state);
1644
strm->state = Z_NULL;
1645
Tracev((stderr, "inflate: end\n"));
1646
return Z_OK;
1647
1648
1649
/* allocate space */
1650
copy = (struct inflate_state FAR *)
1651
- ZALLOC(source, 1, sizeof(struct inflate_state));
1652
+ ZALLOC_STATE(source, 1, sizeof(struct inflate_state));
1653
if (copy == Z_NULL) return Z_MEM_ERROR;
1654
window = Z_NULL;
1655
if (state->window != Z_NULL) {
1656
window = (unsigned char FAR *)
1657
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
1658
+ ZALLOC_WINDOW(source, 1U << state->wbits,
1659
+ sizeof(unsigned char));
1660
if (window == Z_NULL) {
1661
- ZFREE(source, copy);
1662
+ ZFREE_STATE(source, copy);
1663
return Z_MEM_ERROR;
1664
}
1665
}
1666
1667
/* copy state */
1668
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
1669
- zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
1670
+ ZCOPY_STATE((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
1671
copy->strm = dest;
1672
if (state->lencode >= state->codes &&
1673
state->lencode <= state->codes + ENOUGH - 1) {
1674
1675
1676
if (inflateStateCheck(strm))
1677
return -(1L << 16);
1678
+ INFLATE_MARK_HOOK(strm);
1679
state = (struct inflate_state FAR *)strm->state;
1680
return (long)(((unsigned long)((long)state->back)) << 16) +
1681
(state->mode == COPY ? state->length :
1682
Index: zlib-1.2.11/inflate.h
1683
===================================================================
1684
--- zlib-1.2.11.orig/inflate.h
1685
+++ zlib-1.2.11/inflate.h
1686
1687
int back; /* bits back of last unprocessed length/lit */
1688
unsigned was; /* initial length of match */
1689
};
1690
+
1691
+int ZLIB_INTERNAL inflate_ensure_window OF((struct inflate_state *state));
1692
Index: zlib-1.2.11/test/infcover.c
1693
===================================================================
1694
--- zlib-1.2.11.orig/test/infcover.c
1695
+++ zlib-1.2.11/test/infcover.c
1696
1697
}
1698
1699
/* input and output functions for inflateBack() */
1700
-local unsigned pull(void *desc, unsigned char **buf)
1701
+local unsigned pull(void *desc, z_const unsigned char **buf)
1702
{
1703
static unsigned int next = 0;
1704
static unsigned char dat[] = {0x63, 0, 2, 0};
1705
Index: zlib-1.2.11/test/minigzip.c
1706
===================================================================
1707
--- zlib-1.2.11.orig/test/minigzip.c
1708
+++ zlib-1.2.11/test/minigzip.c
1709
1710
#endif
1711
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
1712
1713
+#ifdef DFLTCC
1714
+#define BUFLEN 262144
1715
+#else
1716
#define BUFLEN 16384
1717
+#endif
1718
#define MAX_NAME_LEN 1024
1719
1720
#ifdef MAXSEG_64K
1721
Index: zlib-1.2.11/trees.c
1722
===================================================================
1723
--- zlib-1.2.11.orig/trees.c
1724
+++ zlib-1.2.11/trees.c
1725
1726
local void compress_block OF((deflate_state *s, const ct_data *ltree,
1727
const ct_data *dtree));
1728
local int detect_data_type OF((deflate_state *s));
1729
-local unsigned bi_reverse OF((unsigned value, int length));
1730
-local void bi_windup OF((deflate_state *s));
1731
local void bi_flush OF((deflate_state *s));
1732
1733
#ifdef GEN_TREES_H
1734
1735
}
1736
#endif /* ZLIB_DEBUG */
1737
1738
+void ZLIB_INTERNAL _tr_send_bits(s, value, length)
1739
+ deflate_state *s;
1740
+ int value;
1741
+ int length;
1742
+{
1743
+ send_bits(s, value, length);
1744
+}
1745
1746
/* the arguments must not have side effects */
1747
1748
1749
* method would use a table)
1750
* IN assertion: 1 <= len <= 15
1751
*/
1752
-local unsigned bi_reverse(code, len)
1753
+unsigned ZLIB_INTERNAL bi_reverse(code, len)
1754
unsigned code; /* the value to invert */
1755
int len; /* its bit length */
1756
{
1757
1758
/* ===========================================================================
1759
* Flush the bit buffer and align the output on a byte boundary
1760
*/
1761
-local void bi_windup(s)
1762
+void ZLIB_INTERNAL bi_windup(s)
1763
deflate_state *s;
1764
{
1765
if (s->bi_valid > 8) {
1766