Upgraded GCC to snapshot 9-20200229, and Linux-libre to the version 5.4.23 (config...
[dragora.git] / patches / kernel / linux-5.4.18_lzip-0.diff
blob3b4c6d9ff513ee16996dc3c90f77eeb000efa99a
1 diff -urdN linux-5.4.18/Documentation/lzip.txt linux-5.4.18.new/Documentation/lzip.txt
2 --- linux-5.4.18/Documentation/lzip.txt 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-5.4.18.new/Documentation/lzip.txt 2020-02-10 15:55:57.000000000 +0100
4 @@ -0,0 +1,59 @@
5 +==============================
6 +Lzip data compression in Linux
7 +==============================
9 +Introduction
10 +============
12 +Lzip is a lossless data compressor with a user interface similar to the
13 +one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)
14 +or compress most files more than bzip2 (lzip -9). Decompression speed is
15 +intermediate between gzip and bzip2. Lzip implements the LZMA algorithm.
17 +Lzip has been designed, written and tested with great care to be the
18 +standard general-purpose compressor for unix-like systems. The lzip
19 +format is as simple as possible (but not simpler). It provides accurate
20 +and robust 3 factor integrity checking.
22 +Learn more about lzip at http://www.nongnu.org/lzip/lzip.html
24 +Lzip related components in the kernel
25 +=====================================
27 +The lzip_decompress module in lib/lzip_decompress.c provides a versatile
28 +lzip decompression function able to do buffer to buffer decompression or
29 +stream decompression with fill and flush callback functions. The usage
30 +of the function is documented in include/linux/lzip.h.
32 +For decompressing the kernel image, initramfs, and initrd, there is a
33 +wrapper function in lib/decompress_lunzip.c providing the same common
34 +interface as the other decompress_*.c files, which is defined in
35 +include/linux/decompress/generic.h.
37 +For kernel makefiles, two commands are provided in scripts/Makefile.lib
38 +for use with $(call if_changed). The kernel image must be compressed
39 +with $(call if_changed,klzip) which will append a four-byte trailer
40 +containing the size of the uncompressed data, which is needed by the
41 +boot code. Other things should be compressed with $(call if_changed,lzip).
43 +Testing
44 +=======
46 +Lzip-compressed kernel images of multiple linux versions since 2.6.30.10
47 +have been built and tested, even on machines as modest as an AMD 486-DX2
48 +at 66 MHz with 64 MiB of RAM. In the worst case (on the slow machine
49 +above), lzip just increased the boot time a 15% compared with gzip. On
50 +more modern machines, lzip may boot slightly faster than gzip. It just
51 +takes 0.2 seconds for lzip to decompress vmlinuz-4.4.16 on my machine.
53 +Decompression time is usually a small fraction of the total boot time.
54 +For example, using lz4 on a desktop machine in order to save 0.05
55 +seconds of a total boot time of 20 seconds is probably not worth the
56 +increased image size.
58 +Xlunzip is a test tool for the lzip_decompress module. It is similar to
59 +lunzip, but it uses the lzip_decompress module as a backend. The xlunzip
60 +home page is at http://www.nongnu.org/lzip/xlunzip.html
62 +Author: Antonio Diaz Diaz
63 +Updated: 2018-12-09
64 diff -urdN linux-5.4.18/Makefile linux-5.4.18.new/Makefile
65 --- linux-5.4.18/Makefile 2020-02-05 23:18:13.000000000 +0100
66 +++ linux-5.4.18.new/Makefile 2020-02-10 15:55:57.000000000 +0100
67 @@ -972,14 +972,17 @@
68 export mod_strip_cmd
70 # CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed
71 -# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP
72 -# or CONFIG_MODULE_COMPRESS_XZ.
73 +# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP,
74 +# CONFIG_MODULE_COMPRESS_LZIP or CONFIG_MODULE_COMPRESS_XZ.
76 mod_compress_cmd = true
77 ifdef CONFIG_MODULE_COMPRESS
78 ifdef CONFIG_MODULE_COMPRESS_GZIP
79 mod_compress_cmd = gzip -n -f
80 endif # CONFIG_MODULE_COMPRESS_GZIP
81 + ifdef CONFIG_MODULE_COMPRESS_LZIP
82 + mod_compress_cmd = lzip -f
83 + endif # CONFIG_MODULE_COMPRESS_LZIP
84 ifdef CONFIG_MODULE_COMPRESS_XZ
85 mod_compress_cmd = xz -f
86 endif # CONFIG_MODULE_COMPRESS_XZ
87 diff -urdN linux-5.4.18/arch/arm/Kconfig linux-5.4.18.new/arch/arm/Kconfig
88 --- linux-5.4.18/arch/arm/Kconfig 2020-02-05 22:22:53.000000000 +0100
89 +++ linux-5.4.18.new/arch/arm/Kconfig 2020-02-10 15:55:57.000000000 +0100
90 @@ -91,6 +91,7 @@
91 select HAVE_IRQ_TIME_ACCOUNTING
92 select HAVE_KERNEL_GZIP
93 select HAVE_KERNEL_LZ4
94 + select HAVE_KERNEL_LZIP
95 select HAVE_KERNEL_LZMA
96 select HAVE_KERNEL_LZO
97 select HAVE_KERNEL_XZ
98 diff -urdN linux-5.4.18/arch/arm/boot/compressed/Makefile linux-5.4.18.new/arch/arm/boot/compressed/Makefile
99 --- linux-5.4.18/arch/arm/boot/compressed/Makefile 2020-02-05 22:22:53.000000000 +0100
100 +++ linux-5.4.18.new/arch/arm/boot/compressed/Makefile 2020-02-10 15:55:57.000000000 +0100
101 @@ -71,6 +71,7 @@
102 CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
104 compress-$(CONFIG_KERNEL_GZIP) = gzip
105 +compress-$(CONFIG_KERNEL_LZIP) = klzip
106 compress-$(CONFIG_KERNEL_LZO) = lzo
107 compress-$(CONFIG_KERNEL_LZMA) = lzma
108 compress-$(CONFIG_KERNEL_XZ) = xzkern
109 diff -urdN linux-5.4.18/arch/arm/boot/compressed/decompress.c linux-5.4.18.new/arch/arm/boot/compressed/decompress.c
110 --- linux-5.4.18/arch/arm/boot/compressed/decompress.c 2020-02-05 22:22:53.000000000 +0100
111 +++ linux-5.4.18.new/arch/arm/boot/compressed/decompress.c 2020-02-10 15:55:57.000000000 +0100
112 @@ -38,6 +38,10 @@
113 #include "../../../../lib/decompress_inflate.c"
114 #endif
116 +#ifdef CONFIG_KERNEL_LZIP
117 +#include "../../../../lib/decompress_lunzip.c"
118 +#endif
120 #ifdef CONFIG_KERNEL_LZO
121 #include "../../../../lib/decompress_unlzo.c"
122 #endif
123 diff -urdN linux-5.4.18/arch/sh/Kconfig linux-5.4.18.new/arch/sh/Kconfig
124 --- linux-5.4.18/arch/sh/Kconfig 2020-02-05 22:22:53.000000000 +0100
125 +++ linux-5.4.18.new/arch/sh/Kconfig 2020-02-10 15:55:57.000000000 +0100
126 @@ -23,6 +23,7 @@
127 select HAVE_KERNEL_GZIP
128 select CPU_NO_EFFICIENT_FFS
129 select HAVE_KERNEL_BZIP2
130 + select HAVE_KERNEL_LZIP
131 select HAVE_KERNEL_LZMA
132 select HAVE_KERNEL_XZ
133 select HAVE_KERNEL_LZO
134 diff -urdN linux-5.4.18/arch/sh/Makefile linux-5.4.18.new/arch/sh/Makefile
135 --- linux-5.4.18/arch/sh/Makefile 2020-02-05 22:22:53.000000000 +0100
136 +++ linux-5.4.18.new/arch/sh/Makefile 2020-02-10 15:55:57.000000000 +0100
137 @@ -209,9 +209,9 @@
138 libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
139 libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
141 -BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
142 - uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
143 - romImage
144 +BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lz uImage.lzma uImage.xz \
145 + uImage.lzo uImage.srec uImage.bin zImage vmlinux.bin \
146 + vmlinux.srec romImage
147 PHONY += $(BOOT_TARGETS)
149 all: $(notdir $(KBUILD_IMAGE))
150 @@ -241,6 +241,7 @@
151 @echo ' uImage.bin - Kernel-only image for U-Boot (bin)'
152 @echo '* uImage.gz - Kernel-only image for U-Boot (gzip)'
153 @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
154 + @echo ' uImage.lz - Kernel-only image for U-Boot (lzip)'
155 @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)'
156 @echo ' uImage.xz - Kernel-only image for U-Boot (xz)'
157 @echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)'
158 diff -urdN linux-5.4.18/arch/sh/boot/Makefile linux-5.4.18.new/arch/sh/boot/Makefile
159 --- linux-5.4.18/arch/sh/boot/Makefile 2020-02-05 22:22:53.000000000 +0100
160 +++ linux-5.4.18.new/arch/sh/boot/Makefile 2020-02-10 15:55:57.000000000 +0100
161 @@ -22,14 +22,15 @@
162 suffix-y := bin
163 suffix-$(CONFIG_KERNEL_GZIP) := gz
164 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
165 +suffix-$(CONFIG_KERNEL_LZIP) := lz
166 suffix-$(CONFIG_KERNEL_LZMA) := lzma
167 suffix-$(CONFIG_KERNEL_XZ) := xz
168 suffix-$(CONFIG_KERNEL_LZO) := lzo
170 targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
171 - uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin
172 -extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
173 - vmlinux.bin.xz vmlinux.bin.lzo
174 + uImage.bz2 uImage.lz uImage.lzma uImage.xz uImage.lzo uImage.bin
175 +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
176 + vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo
177 subdir- := compressed romimage
179 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
180 @@ -71,6 +72,9 @@
181 $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
182 $(call if_changed,bzip2)
184 +$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
185 + $(call if_changed,klzip)
187 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
188 $(call if_changed,lzma)
190 @@ -86,6 +90,9 @@
191 $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
192 $(call if_changed,uimage,gzip)
194 +$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz
195 + $(call if_changed,uimage,lzip)
197 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
198 $(call if_changed,uimage,lzma)
200 diff -urdN linux-5.4.18/arch/sh/boot/compressed/Makefile linux-5.4.18.new/arch/sh/boot/compressed/Makefile
201 --- linux-5.4.18/arch/sh/boot/compressed/Makefile 2020-02-05 22:22:53.000000000 +0100
202 +++ linux-5.4.18.new/arch/sh/boot/compressed/Makefile 2020-02-10 15:55:57.000000000 +0100
203 @@ -5,10 +5,9 @@
204 # create a compressed vmlinux image from the original vmlinux
207 -targets := vmlinux vmlinux.bin vmlinux.bin.gz \
208 - vmlinux.bin.bz2 vmlinux.bin.lzma \
209 - vmlinux.bin.xz vmlinux.bin.lzo \
210 - head_$(BITS).o misc.o piggy.o
211 +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
212 + vmlinux.bin.lz vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo \
213 + head_$(BITS).o misc.o piggy.o
215 OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
217 @@ -66,6 +65,8 @@
218 $(call if_changed,gzip)
219 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
220 $(call if_changed,bzip2)
221 +$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
222 + $(call if_changed,klzip)
223 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
224 $(call if_changed,lzma)
225 $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
226 diff -urdN linux-5.4.18/arch/sh/boot/compressed/misc.c linux-5.4.18.new/arch/sh/boot/compressed/misc.c
227 --- linux-5.4.18/arch/sh/boot/compressed/misc.c 2020-02-05 22:22:53.000000000 +0100
228 +++ linux-5.4.18.new/arch/sh/boot/compressed/misc.c 2020-02-10 15:55:57.000000000 +0100
229 @@ -58,6 +58,10 @@
230 #include "../../../../lib/decompress_bunzip2.c"
231 #endif
233 +#ifdef CONFIG_KERNEL_LZIP
234 +#include "../../../../lib/decompress_lunzip.c"
235 +#endif
237 #ifdef CONFIG_KERNEL_LZMA
238 #include "../../../../lib/decompress_unlzma.c"
239 #endif
240 diff -urdN linux-5.4.18/arch/x86/Kconfig linux-5.4.18.new/arch/x86/Kconfig
241 --- linux-5.4.18/arch/x86/Kconfig 2020-02-05 22:22:53.000000000 +0100
242 +++ linux-5.4.18.new/arch/x86/Kconfig 2020-02-10 15:55:57.000000000 +0100
243 @@ -176,6 +176,7 @@
244 select HAVE_KERNEL_BZIP2
245 select HAVE_KERNEL_GZIP
246 select HAVE_KERNEL_LZ4
247 + select HAVE_KERNEL_LZIP
248 select HAVE_KERNEL_LZMA
249 select HAVE_KERNEL_LZO
250 select HAVE_KERNEL_XZ
251 diff -urdN linux-5.4.18/arch/x86/boot/compressed/Makefile linux-5.4.18.new/arch/x86/boot/compressed/Makefile
252 --- linux-5.4.18/arch/x86/boot/compressed/Makefile 2020-02-05 22:22:53.000000000 +0100
253 +++ linux-5.4.18.new/arch/x86/boot/compressed/Makefile 2020-02-10 15:55:57.000000000 +0100
254 @@ -23,8 +23,8 @@
255 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
256 KCOV_INSTRUMENT := n
258 -targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
259 - vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
260 +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
261 + vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
263 KBUILD_CFLAGS := -m$(BITS) -O2
264 KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
265 @@ -136,6 +136,8 @@
266 $(call if_changed,gzip)
267 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
268 $(call if_changed,bzip2)
269 +$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
270 + $(call if_changed,klzip)
271 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
272 $(call if_changed,lzma)
273 $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
274 @@ -147,6 +149,7 @@
276 suffix-$(CONFIG_KERNEL_GZIP) := gz
277 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
278 +suffix-$(CONFIG_KERNEL_LZIP) := lz
279 suffix-$(CONFIG_KERNEL_LZMA) := lzma
280 suffix-$(CONFIG_KERNEL_XZ) := xz
281 suffix-$(CONFIG_KERNEL_LZO) := lzo
282 diff -urdN linux-5.4.18/arch/x86/boot/compressed/misc.c linux-5.4.18.new/arch/x86/boot/compressed/misc.c
283 --- linux-5.4.18/arch/x86/boot/compressed/misc.c 2020-02-05 22:22:53.000000000 +0100
284 +++ linux-5.4.18.new/arch/x86/boot/compressed/misc.c 2020-02-10 15:55:57.000000000 +0100
285 @@ -62,6 +62,10 @@
286 #include "../../../../lib/decompress_bunzip2.c"
287 #endif
289 +#ifdef CONFIG_KERNEL_LZIP
290 +#include "../../../../lib/decompress_lunzip.c"
291 +#endif
293 #ifdef CONFIG_KERNEL_LZMA
294 #include "../../../../lib/decompress_unlzma.c"
295 #endif
296 diff -urdN linux-5.4.18/fs/squashfs/Kconfig linux-5.4.18.new/fs/squashfs/Kconfig
297 --- linux-5.4.18/fs/squashfs/Kconfig 2020-02-05 22:22:53.000000000 +0100
298 +++ linux-5.4.18.new/fs/squashfs/Kconfig 2020-02-10 15:55:57.000000000 +0100
299 @@ -5,7 +5,7 @@
300 help
301 Saying Y here includes support for SquashFS 4.0 (a Compressed
302 Read-Only File System). Squashfs is a highly compressed read-only
303 - filesystem for Linux. It uses zlib, lzo or xz compression to
304 + filesystem for Linux. It uses zlib, lzip, lzo or xz compression to
305 compress both files, inodes and directories. Inodes in the system
306 are very small and all blocks are packed to minimise data overhead.
307 Block sizes greater than 4K are supported up to a maximum of 1 Mbytes
308 @@ -135,6 +135,21 @@
309 file systems will be readable without selecting this option.
311 If unsure, say N.
313 +config SQUASHFS_LZIP
314 + bool "Include support for LZIP compressed file systems"
315 + depends on SQUASHFS
316 + select LZIP_DECOMPRESS
317 + help
318 + Saying Y here includes support for reading Squashfs file systems
319 + compressed with LZIP compression. LZIP gives better compression
320 + than the default zlib compression, at the expense of greater CPU
321 + and memory overhead.
323 + LZIP is not the standard compression used in Squashfs and so most
324 + file systems will be readable without selecting this option.
326 + If unsure, say N.
328 config SQUASHFS_LZO
329 bool "Include support for LZO compressed file systems"
330 diff -urdN linux-5.4.18/fs/squashfs/Makefile linux-5.4.18.new/fs/squashfs/Makefile
331 --- linux-5.4.18/fs/squashfs/Makefile 2020-02-05 22:22:53.000000000 +0100
332 +++ linux-5.4.18.new/fs/squashfs/Makefile 2020-02-10 15:55:57.000000000 +0100
333 @@ -13,6 +13,7 @@
334 squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
335 squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
336 squashfs-$(CONFIG_SQUASHFS_LZ4) += lz4_wrapper.o
337 +squashfs-$(CONFIG_SQUASHFS_LZIP) += lzip_wrapper.o
338 squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
339 squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
340 squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o
341 diff -urdN linux-5.4.18/fs/squashfs/decompressor.c linux-5.4.18.new/fs/squashfs/decompressor.c
342 --- linux-5.4.18/fs/squashfs/decompressor.c 2020-02-05 22:22:53.000000000 +0100
343 +++ linux-5.4.18.new/fs/squashfs/decompressor.c 2020-02-10 15:55:57.000000000 +0100
344 @@ -34,6 +34,12 @@
346 #endif
348 +#ifndef CONFIG_SQUASHFS_LZIP
349 +static const struct squashfs_decompressor squashfs_lzip_comp_ops = {
350 + NULL, NULL, NULL, NULL, LZIP_COMPRESSION, "lzip", 0
352 +#endif
354 #ifndef CONFIG_SQUASHFS_LZO
355 static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
356 NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
357 @@ -65,6 +71,7 @@
358 static const struct squashfs_decompressor *decompressor[] = {
359 &squashfs_zlib_comp_ops,
360 &squashfs_lz4_comp_ops,
361 + &squashfs_lzip_comp_ops,
362 &squashfs_lzo_comp_ops,
363 &squashfs_xz_comp_ops,
364 &squashfs_lzma_unsupported_comp_ops,
365 diff -urdN linux-5.4.18/fs/squashfs/decompressor.h linux-5.4.18.new/fs/squashfs/decompressor.h
366 --- linux-5.4.18/fs/squashfs/decompressor.h 2020-02-05 22:22:53.000000000 +0100
367 +++ linux-5.4.18.new/fs/squashfs/decompressor.h 2020-02-10 15:55:57.000000000 +0100
368 @@ -37,6 +37,10 @@
369 extern const struct squashfs_decompressor squashfs_lz4_comp_ops;
370 #endif
372 +#ifdef CONFIG_SQUASHFS_LZIP
373 +extern const struct squashfs_decompressor squashfs_lzip_comp_ops;
374 +#endif
376 #ifdef CONFIG_SQUASHFS_LZO
377 extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
378 #endif
379 diff -urdN linux-5.4.18/fs/squashfs/lzip_wrapper.c linux-5.4.18.new/fs/squashfs/lzip_wrapper.c
380 --- linux-5.4.18/fs/squashfs/lzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
381 +++ linux-5.4.18.new/fs/squashfs/lzip_wrapper.c 2020-02-10 15:55:57.000000000 +0100
382 @@ -0,0 +1,129 @@
384 + * Squashfs - a compressed read only filesystem for Linux
386 + * Copyright (c) 2014
387 + * Phillip Lougher <phillip@squashfs.org.uk>
388 + * Copyright (C) 2018-2020 Antonio Diaz Diaz
390 + * This program is free software; you can redistribute it and/or
391 + * modify it under the terms of the GNU General Public License
392 + * as published by the Free Software Foundation; either version 2,
393 + * or (at your option) any later version.
395 + * This program is distributed in the hope that it will be useful,
396 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
397 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
398 + * GNU General Public License for more details.
400 + * You should have received a copy of the GNU General Public License
401 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
403 + * lzip_wrapper.c
404 + */
406 +#include <linux/buffer_head.h>
407 +#include <linux/mutex.h>
408 +#include <linux/slab.h>
409 +#include <linux/vmalloc.h>
410 +#include <linux/lzip.h>
412 +#include "squashfs_fs.h"
413 +#include "squashfs_fs_sb.h"
414 +#include "squashfs.h"
415 +#include "decompressor.h"
416 +#include "page_actor.h"
418 +struct squashfs_lzip {
419 + void *input;
420 + void *output;
424 +static void *lzip_init(struct squashfs_sb_info *msblk, void *buff)
426 + int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
427 + struct squashfs_lzip *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
428 + if (stream == NULL)
429 + goto failed;
430 + stream->input = vmalloc(block_size);
431 + if (stream->input == NULL)
432 + goto failed2;
433 + stream->output = vmalloc(block_size);
434 + if (stream->output == NULL)
435 + goto failed3;
437 + return stream;
439 +failed3:
440 + vfree(stream->input);
441 +failed2:
442 + kfree(stream);
443 +failed:
444 + ERROR("Failed to initialise LZIP decompressor\n");
445 + return ERR_PTR(-ENOMEM);
449 +static void lzip_free(void *strm)
451 + struct squashfs_lzip *stream = strm;
453 + if (stream) {
454 + vfree(stream->input);
455 + vfree(stream->output);
457 + kfree(stream);
461 +static int lzip_uncompress(struct squashfs_sb_info *msblk, void *strm,
462 + struct buffer_head **bh, int b, int offset, int length,
463 + struct squashfs_page_actor *output)
465 + struct squashfs_lzip *stream = strm;
466 + void *buff = stream->input, *data;
467 + long out_pos;
468 + int avail, i, bytes = length, res;
470 + for (i = 0; i < b; i++) {
471 + avail = min(bytes, msblk->devblksize - offset);
472 + memcpy(buff, bh[i]->b_data + offset, avail);
473 + buff += avail;
474 + bytes -= avail;
475 + offset = 0;
476 + put_bh(bh[i]);
479 + res = lzip_decompress(stream->input, length, 0, 0, stream->output,
480 + output->length, 0, &out_pos);
481 + if (res < 0) {
482 + ERROR("LZIP error code %d\n", res);
483 + return -EIO;
485 + bytes = out_pos;
486 + data = squashfs_first_page(output);
487 + buff = stream->output;
488 + while (data) {
489 + if (bytes <= PAGE_SIZE) {
490 + memcpy(data, buff, bytes);
491 + break;
493 + memcpy(data, buff, PAGE_SIZE);
494 + buff += PAGE_SIZE;
495 + bytes -= PAGE_SIZE;
496 + data = squashfs_next_page(output);
498 + squashfs_finish_page(output);
500 + return out_pos;
504 +const struct squashfs_decompressor squashfs_lzip_comp_ops = {
505 + .init = lzip_init,
506 + .free = lzip_free,
507 + .decompress = lzip_uncompress,
508 + .id = LZIP_COMPRESSION,
509 + .name = "lzip",
510 + .supported = 1
512 diff -urdN linux-5.4.18/fs/squashfs/squashfs_fs.h linux-5.4.18.new/fs/squashfs/squashfs_fs.h
513 --- linux-5.4.18/fs/squashfs/squashfs_fs.h 2020-02-05 22:22:53.000000000 +0100
514 +++ linux-5.4.18.new/fs/squashfs/squashfs_fs.h 2020-02-10 15:55:57.000000000 +0100
515 @@ -235,6 +235,7 @@
516 #define XZ_COMPRESSION 4
517 #define LZ4_COMPRESSION 5
518 #define ZSTD_COMPRESSION 6
519 +#define LZIP_COMPRESSION 7
521 struct squashfs_super_block {
522 __le32 s_magic;
523 diff -urdN linux-5.4.18/include/linux/decompress/lunzip.h linux-5.4.18.new/include/linux/decompress/lunzip.h
524 --- linux-5.4.18/include/linux/decompress/lunzip.h 1970-01-01 01:00:00.000000000 +0100
525 +++ linux-5.4.18.new/include/linux/decompress/lunzip.h 2020-02-10 15:55:57.000000000 +0100
526 @@ -0,0 +1,11 @@
527 +/* SPDX-License-Identifier: GPL-2.0 */
528 +#ifndef LINUX_DECOMPRESS_LUNZIP_H
529 +#define LINUX_DECOMPRESS_LUNZIP_H
531 +int lunzip(unsigned char *inbuf, long in_len,
532 + long (*fill)(void*, unsigned long),
533 + long (*flush)(void*, unsigned long),
534 + unsigned char *outbuf,
535 + long *in_posp,
536 + void (*error)(char *x));
537 +#endif
538 diff -urdN linux-5.4.18/include/linux/lzip.h linux-5.4.18.new/include/linux/lzip.h
539 --- linux-5.4.18/include/linux/lzip.h 1970-01-01 01:00:00.000000000 +0100
540 +++ linux-5.4.18.new/include/linux/lzip.h 2020-02-10 15:55:57.000000000 +0100
541 @@ -0,0 +1,53 @@
542 +/* SPDX-License-Identifier: GPL-2.0 */
543 +#ifndef __LZIP_H__
544 +#define __LZIP_H__
546 + * LZIP decompressor
548 + * Copyright (C) 2016-2020 Antonio Diaz Diaz.
549 + */
551 +/* Return values (< 0 = Error) */
552 +enum {
553 + LZIP_OOM_INBUF = -1,
554 + LZIP_HEADER1_EOF = -2,
555 + LZIP_HEADER2_EOF = -3,
556 + LZIP_BAD_MAGIC1 = -4,
557 + LZIP_BAD_MAGIC2 = -5,
558 + LZIP_BAD_VERSION = -6,
559 + LZIP_BAD_DICT_SIZE = -7,
560 + LZIP_OOM_OUTBUF = -8,
561 + LZIP_WRITE_ERROR = -9,
562 + LZIP_BAD_DATA = -10,
563 + LZIP_DATA_EOF = -11,
564 + LZIP_BAD_CRC = -12
567 +int lzip_decompress(unsigned char *inbuf, long in_len,
568 + long (*fill)(void*, unsigned long),
569 + long (*flush)(void*, unsigned long),
570 + unsigned char *outbuf, long out_size,
571 + long *in_posp, long *out_posp);
573 +/* inbuf - input buffer. If null or in_len <= 0, fill must be non-null
574 + * in_len - len of pre-read data in inbuf if inbuf is non-null
575 + * fill - if non-null, function to fill inbuf when empty
576 + * flush - if non-null, function to write out outbuf when full
577 + * outbuf - output buffer. If null or out_size <= 0, flush must be non-null
578 + * out_size - size of outbuf if outbuf is non-null
579 + * in_posp - if non-null, the number of bytes consumed will be returned here
580 + * out_posp - if non-null, the number of bytes produced will be returned here
582 + * fill will be called (repeatedly) to read data. in_len bytes will be read
583 + * per call (or 16384 bytes per call if inbuf is null or in_len <= 0).
585 + * If flush is null, outbuf must be large enough to buffer all the expected
586 + * output. Else the flush function will be called to flush the output buffer
587 + * at the appropriate time (stream dependent).
588 + * If out_size > 0 but is not large enough to buffer all the expected output,
589 + * it must be at least as large as the dictionary size of the data.
591 + * inbuf and outbuf may overlap (in-place decompression).
592 + */
594 +#endif
595 diff -urdN linux-5.4.18/init/Kconfig linux-5.4.18.new/init/Kconfig
596 --- linux-5.4.18/init/Kconfig 2020-02-05 22:22:53.000000000 +0100
597 +++ linux-5.4.18.new/init/Kconfig 2020-02-10 15:55:57.000000000 +0100
598 @@ -181,6 +181,9 @@
599 config HAVE_KERNEL_BZIP2
600 bool
602 +config HAVE_KERNEL_LZIP
603 + bool
605 config HAVE_KERNEL_LZMA
606 bool
608 @@ -199,7 +202,7 @@
609 choice
610 prompt "Kernel compression mode"
611 default KERNEL_GZIP
612 - depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4 || HAVE_KERNEL_UNCOMPRESSED
613 + depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZIP || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4 || HAVE_KERNEL_UNCOMPRESSED
614 help
615 The linux kernel is a kind of self-extracting executable.
616 Several compression algorithms are available, which differ
617 @@ -235,6 +238,15 @@
618 Bzip2 uses a large amount of memory. For modern kernels you
619 will need at least 8MB RAM or more for booting.
621 +config KERNEL_LZIP
622 + bool "Lzip"
623 + depends on HAVE_KERNEL_LZIP
624 + help
625 + Lzip's compression ratio is better than that of gzip and bzip2.
626 + Decompression speed is between gzip and bzip2. Compression can
627 + be as fast as gzip or slower than bzip2 depending on compression
628 + level. Lzip can produce a kernel about a 16% smaller than gzip.
630 config KERNEL_LZMA
631 bool "LZMA"
632 depends on HAVE_KERNEL_LZMA
633 @@ -2135,8 +2147,8 @@
634 bool "Compress modules on installation"
635 help
637 - Compresses kernel modules when 'make modules_install' is run; gzip or
638 - xz depending on "Compression algorithm" below.
639 + Compresses kernel modules when 'make modules_install' is run; gzip,
640 + lzip, or xz are used depending on "Compression algorithm" below.
642 module-init-tools MAY support gzip, and kmod MAY support gzip and xz.
644 @@ -2158,11 +2170,14 @@
645 This determines which sort of compression will be used during
646 'make modules_install'.
648 - GZIP (default) and XZ are supported.
649 + GZIP (default), LZIP, and XZ are supported.
651 config MODULE_COMPRESS_GZIP
652 bool "GZIP"
654 +config MODULE_COMPRESS_LZIP
655 + bool "LZIP"
657 config MODULE_COMPRESS_XZ
658 bool "XZ"
660 diff -urdN linux-5.4.18/init/do_mounts_rd.c linux-5.4.18.new/init/do_mounts_rd.c
661 --- linux-5.4.18/init/do_mounts_rd.c 2020-02-05 22:22:53.000000000 +0100
662 +++ linux-5.4.18.new/init/do_mounts_rd.c 2020-02-10 15:55:57.000000000 +0100
663 @@ -49,6 +49,7 @@
664 * squashfs
665 * gzip
666 * bzip2
667 + * lzip
668 * lzma
669 * xz
670 * lzo
671 diff -urdN linux-5.4.18/lib/Kconfig linux-5.4.18.new/lib/Kconfig
672 --- linux-5.4.18/lib/Kconfig 2020-02-05 22:22:53.000000000 +0100
673 +++ linux-5.4.18.new/lib/Kconfig 2020-02-10 15:55:57.000000000 +0100
674 @@ -278,6 +278,12 @@
675 tristate
676 select BITREVERSE
678 +config LZIP_DECOMPRESS
679 + tristate "LZIP decompression support"
680 + help
681 + LZMA compression algorithm is supported using the .lz file format.
682 + See Documentation/lzip.txt for more information.
684 config LZO_COMPRESS
685 tristate
687 @@ -314,6 +320,10 @@
688 config DECOMPRESS_BZIP2
689 tristate
691 +config DECOMPRESS_LZIP
692 + select LZIP_DECOMPRESS
693 + tristate
695 config DECOMPRESS_LZMA
696 tristate
698 diff -urdN linux-5.4.18/lib/Makefile linux-5.4.18.new/lib/Makefile
699 --- linux-5.4.18/lib/Makefile 2020-02-05 22:22:53.000000000 +0100
700 +++ linux-5.4.18.new/lib/Makefile 2020-02-10 15:55:57.000000000 +0100
701 @@ -141,6 +141,7 @@
702 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
703 obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
704 obj-$(CONFIG_BCH) += bch.o
705 +obj-$(CONFIG_LZIP_DECOMPRESS) += lzip_decompress.o
706 obj-$(CONFIG_LZO_COMPRESS) += lzo/
707 obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
708 obj-$(CONFIG_LZ4_COMPRESS) += lz4/
709 @@ -153,6 +154,7 @@
711 lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
712 lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
713 +lib-$(CONFIG_DECOMPRESS_LZIP) += decompress_lunzip.o
714 lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
715 lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
716 lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
717 diff -urdN linux-5.4.18/lib/decompress.c linux-5.4.18.new/lib/decompress.c
718 --- linux-5.4.18/lib/decompress.c 2020-02-05 22:22:53.000000000 +0100
719 +++ linux-5.4.18.new/lib/decompress.c 2020-02-10 15:55:57.000000000 +0100
720 @@ -8,6 +8,7 @@
721 #include <linux/decompress/generic.h>
723 #include <linux/decompress/bunzip2.h>
724 +#include <linux/decompress/lunzip.h>
725 #include <linux/decompress/unlzma.h>
726 #include <linux/decompress/unxz.h>
727 #include <linux/decompress/inflate.h>
728 @@ -25,6 +26,9 @@
729 #ifndef CONFIG_DECOMPRESS_BZIP2
730 # define bunzip2 NULL
731 #endif
732 +#ifndef CONFIG_DECOMPRESS_LZIP
733 +# define lunzip NULL
734 +#endif
735 #ifndef CONFIG_DECOMPRESS_LZMA
736 # define unlzma NULL
737 #endif
738 @@ -48,6 +52,7 @@
739 { {0x1f, 0x8b}, "gzip", gunzip },
740 { {0x1f, 0x9e}, "gzip", gunzip },
741 { {0x42, 0x5a}, "bzip2", bunzip2 },
742 + { {0x4c, 0x5a}, "lzip", lunzip },
743 { {0x5d, 0x00}, "lzma", unlzma },
744 { {0xfd, 0x37}, "xz", unxz },
745 { {0x89, 0x4c}, "lzo", unlzo },
746 diff -urdN linux-5.4.18/lib/decompress_lunzip.c linux-5.4.18.new/lib/decompress_lunzip.c
747 --- linux-5.4.18/lib/decompress_lunzip.c 1970-01-01 01:00:00.000000000 +0100
748 +++ linux-5.4.18.new/lib/decompress_lunzip.c 2020-02-10 15:55:57.000000000 +0100
749 @@ -0,0 +1,100 @@
751 + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
753 + * Copyright (C) 2016-2020 Antonio Diaz Diaz.
755 + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
756 + */
758 +#ifdef STATIC
759 +#define PREBOOT
760 +#include "lzip_decompress.c"
761 +#else
762 +#include <linux/lzip.h>
763 +#include <linux/decompress/lunzip.h>
764 +#include <linux/decompress/mm.h>
765 +#endif
767 +STATIC int INIT __lunzip(unsigned char *inbuf, long in_len,
768 + long (*fill)(void*, unsigned long),
769 + long (*flush)(void*, unsigned long),
770 + unsigned char *outbuf, long out_size,
771 + long *in_posp, long *out_posp,
772 + void (*error)(char *x))
774 + const int retval = lzip_decompress(inbuf, in_len, fill, flush,
775 + outbuf, out_size, in_posp, out_posp);
776 + switch (retval) {
777 + case 0: break;
778 + case LZIP_OOM_INBUF:
779 + error("Out of memory while allocating input buffer.");
780 + break;
781 + case LZIP_HEADER1_EOF:
782 + error("File ends unexpectedly at member header.");
783 + break;
784 + case LZIP_HEADER2_EOF:
785 + error("Truncated header in multimember file.");
786 + break;
787 + case LZIP_BAD_MAGIC1:
788 + error("Bad magic number (file not in lzip format).");
789 + break;
790 + case LZIP_BAD_MAGIC2:
791 + error("Corrupt header in multimember file.");
792 + break;
793 + case LZIP_BAD_VERSION:
794 + error("Version of lzip member format not supported.");
795 + break;
796 + case LZIP_BAD_DICT_SIZE:
797 + error("Invalid dictionary size in member header.");
798 + break;
799 + case LZIP_OOM_OUTBUF:
800 + error("Out of memory while allocating output buffer.");
801 + break;
802 + case LZIP_WRITE_ERROR:
803 + error("Write error.");
804 + break;
805 + case LZIP_BAD_DATA:
806 + error("LZIP-compressed data is corrupt.");
807 + break;
808 + case LZIP_DATA_EOF:
809 + error("LZIP-compressed data ends unexpectedly.");
810 + break;
811 + case LZIP_BAD_CRC:
812 + error("CRC mismatch in LZIP-compressed data.");
813 + break;
814 + default:
815 + error("Bug in the LZIP decompressor.");
817 + return retval;
820 +#ifndef PREBOOT
821 +/* decompress_fn (see include/linux/decompress/generic.h) should have an
822 + * out_size argument to prevent overflowing outbuf in case of corruption
823 + * of the compressed data.
824 + */
825 +STATIC int INIT lunzip(unsigned char *inbuf, long in_len,
826 + long (*fill)(void*, unsigned long),
827 + long (*flush)(void*, unsigned long),
828 + unsigned char *outbuf,
829 + long *in_posp,
830 + void (*error)(char *x))
832 + return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX,
833 + in_posp, 0, error);
835 +#else
836 +STATIC int INIT __decompress(unsigned char *inbuf, long in_len,
837 + long (*fill)(void*, unsigned long),
838 + long (*flush)(void*, unsigned long),
839 + unsigned char *outbuf, long out_size,
840 + long *in_posp,
841 + void (*error)(char *x))
843 +/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe
844 + * in case of corruption of the compressed data.
845 + */
846 + return __lunzip(inbuf, in_len - 4, fill, flush, outbuf,
847 + out_size ? out_size : LONG_MAX, in_posp, 0, error);
849 +#endif
850 diff -urdN linux-5.4.18/lib/lzip_decompress.c linux-5.4.18.new/lib/lzip_decompress.c
851 --- linux-5.4.18/lib/lzip_decompress.c 1970-01-01 01:00:00.000000000 +0100
852 +++ linux-5.4.18.new/lib/lzip_decompress.c 2020-02-10 16:58:14.000000000 +0100
853 @@ -0,0 +1,877 @@
855 + * LZIP decompressor
857 + * Copyright (C) 2016-2020 Antonio Diaz Diaz.
859 + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
860 + */
862 +#include <linux/module.h>
863 +#include <linux/lzip.h>
864 +#include <linux/decompress/mm.h>
867 + * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
868 + * See include/linux/decompress/mm.h for details.
869 + */
870 +#ifndef STATIC_RW_DATA
871 +#define STATIC_RW_DATA static
872 +#endif
874 +typedef int State;
876 +enum { states = 12 };
878 +static inline bool St_is_char(const State st) { return st < 7; }
880 +static inline State St_set_char(const State st)
882 + STATIC_RW_DATA const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
883 + return next[st];
886 +static inline State St_set_match(const State st)
888 + return ((st < 7) ? 7 : 10);
891 +static inline State St_set_rep(const State st)
893 + return ((st < 7) ? 8 : 11);
896 +static inline State St_set_short_rep(const State st)
898 + return ((st < 7) ? 9 : 11);
902 +enum {
903 + min_dictionary_bits = 12,
904 + min_dictionary_size = 1 << min_dictionary_bits,
905 + max_dictionary_bits = 29,
906 + max_dictionary_size = 1 << max_dictionary_bits,
907 + literal_context_bits = 3,
908 + pos_state_bits = 2,
909 + pos_states = 1 << pos_state_bits,
910 + pos_state_mask = pos_states - 1,
912 + len_states = 4,
913 + dis_slot_bits = 6,
914 + start_dis_model = 4,
915 + end_dis_model = 14,
916 + modeled_distances = 1 << (end_dis_model / 2), /* 128 */
917 + dis_align_bits = 4,
918 + dis_align_size = 1 << dis_align_bits,
920 + len_low_bits = 3,
921 + len_mid_bits = 3,
922 + len_high_bits = 8,
923 + len_low_symbols = 1 << len_low_bits,
924 + len_mid_symbols = 1 << len_mid_bits,
925 + len_high_symbols = 1 << len_high_bits,
926 + max_len_symbols = len_low_symbols + len_mid_symbols + len_high_symbols,
928 + min_match_len = 2, /* must be 2 */
929 + max_match_len = min_match_len + max_len_symbols - 1, /* 273 */
930 + min_match_len_limit = 5
933 +static inline int get_len_state(const int len)
935 + return min(len - min_match_len, len_states - 1);
938 +static inline int get_lit_state(const uint8_t prev_byte)
940 + return prev_byte >> (8 - literal_context_bits);
944 +enum { bit_model_move_bits = 5,
945 + bit_model_total_bits = 11,
946 + bit_model_total = 1 << bit_model_total_bits
949 +typedef int Bit_model;
951 +static inline void Bm_init(Bit_model * const probability)
953 + *probability = bit_model_total / 2;
956 +static inline void Bm_array_init(Bit_model bm[], const int size)
958 + int i;
960 + for (i = 0; i < size; ++i)
961 + Bm_init(&bm[i]);
964 +struct Len_model {
965 + Bit_model choice1;
966 + Bit_model choice2;
967 + Bit_model bm_low[pos_states][len_low_symbols];
968 + Bit_model bm_mid[pos_states][len_mid_symbols];
969 + Bit_model bm_high[len_high_symbols];
972 +static inline void Lm_init(struct Len_model * const lm)
974 + Bm_init(&lm->choice1);
975 + Bm_init(&lm->choice2);
976 + Bm_array_init(lm->bm_low[0], pos_states * len_low_symbols);
977 + Bm_array_init(lm->bm_mid[0], pos_states * len_mid_symbols);
978 + Bm_array_init(lm->bm_high, len_high_symbols);
982 +/* Table of CRCs of all 8-bit messages. */
983 +STATIC_RW_DATA const uint32_t crc32[256] =
985 + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
986 + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
987 + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
988 + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
989 + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
990 + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
991 + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
992 + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
993 + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
994 + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
995 + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
996 + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
997 + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
998 + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
999 + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
1000 + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
1001 + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1002 + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
1003 + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
1004 + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
1005 + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1006 + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
1007 + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
1008 + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
1009 + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1010 + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
1011 + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
1012 + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
1013 + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1014 + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
1015 + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
1016 + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1017 + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1018 + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
1019 + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
1020 + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1021 + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1022 + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
1023 + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
1024 + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1025 + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1026 + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
1027 + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
1030 +static inline void CRC32_update_buf(uint32_t * const crc,
1031 + const uint8_t * const buffer,
1032 + const long size)
1034 + long i;
1035 + uint32_t c = *crc;
1037 + for (i = 0; i < size; ++i)
1038 + c = crc32[(c^buffer[i])&0xFF] ^ (c >> 8);
1039 + *crc = c;
1043 +STATIC_RW_DATA const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
1045 +typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
1046 + /* 4 version */
1047 + /* 5 coded_dict_size */
1048 +enum { Lh_size = 6 };
1050 +static inline bool Lh_verify_magic(const Lzip_header data)
1052 + int i;
1054 + for (i = 0; i < 4; ++i)
1055 + if (data[i] != lzip_magic[i])
1056 + return false;
1057 + return true;
1060 +/* detect (truncated) header */
1061 +static inline bool Lh_verify_prefix(const Lzip_header data, const int sz)
1063 + int i;
1064 + for (i = 0; i < sz && i < 4; ++i)
1065 + if (data[i] != lzip_magic[i])
1066 + return false;
1067 + return (sz > 0);
1070 +/* detect corrupt header */
1071 +static inline bool Lh_verify_corrupt(const Lzip_header data)
1073 + int matches = 0;
1074 + int i;
1075 + for (i = 0; i < 4; ++i)
1076 + if (data[i] == lzip_magic[i])
1077 + ++matches;
1078 + return (matches > 1 && matches < 4);
1081 +static inline bool Lh_verify_version(const Lzip_header data)
1083 + return (data[4] == 1);
1086 +static inline unsigned Lh_get_dictionary_size(const Lzip_header data)
1088 + unsigned sz = (1 << (data[5] & 0x1F));
1090 + if (sz > min_dictionary_size)
1091 + sz -= (sz / 16) * ((data[5] >> 5) & 7);
1092 + return sz;
1096 +typedef uint8_t Lzip_trailer[20];
1097 + /* 0-3 CRC32 of the uncompressed data */
1098 + /* 4-11 size of the uncompressed data */
1099 + /* 12-19 member size including header and trailer */
1100 +enum { Lt_size = 20 };
1102 +static inline unsigned Lt_get_data_crc(const Lzip_trailer data)
1104 + unsigned tmp = 0;
1105 + int i;
1107 + for (i = 3; i >= 0; --i) {
1108 + tmp <<= 8;
1109 + tmp += data[i];
1111 + return tmp;
1114 +static inline unsigned long long Lt_get_data_size(const Lzip_trailer data)
1116 + unsigned long long tmp = 0;
1117 + int i;
1119 + for (i = 11; i >= 4; --i) {
1120 + tmp <<= 8;
1121 + tmp += data[i];
1123 + return tmp;
1126 +static inline unsigned long long Lt_get_member_size(const Lzip_trailer data)
1128 + unsigned long long tmp = 0;
1129 + int i;
1131 + for (i = 19; i >= 12; --i) {
1132 + tmp <<= 8;
1133 + tmp += data[i];
1135 + return tmp;
1139 +struct Range_decoder {
1140 + unsigned long long partial_member_pos;
1141 + uint8_t *buffer; /* input buffer */
1142 + long buffer_size;
1143 + long pos; /* current pos in buffer */
1144 + long stream_pos; /* when reached, a new block must be read */
1145 + uint32_t code;
1146 + uint32_t range;
1147 + long (*fill)(void*, unsigned long);
1148 + bool at_stream_end;
1149 + bool buffer_given;
1153 +static bool Rd_read_block(struct Range_decoder * const rdec)
1155 + if (!rdec->at_stream_end) {
1156 + rdec->stream_pos = rdec->fill ?
1157 + rdec->fill(rdec->buffer, rdec->buffer_size) : 0;
1158 + rdec->at_stream_end = (rdec->stream_pos < rdec->buffer_size);
1159 + rdec->partial_member_pos += rdec->pos;
1160 + rdec->pos = 0;
1162 + return rdec->pos < rdec->stream_pos;
1166 +static inline bool Rd_init(struct Range_decoder * const rdec,
1167 + uint8_t * const inbuf, const long in_len,
1168 + long (*fill)(void*, unsigned long))
1170 + rdec->partial_member_pos = 0;
1171 + rdec->buffer_given = (inbuf && in_len > 0);
1172 + rdec->buffer_size = rdec->buffer_given ? in_len : 16384;
1173 + rdec->buffer = rdec->buffer_given ? inbuf : malloc(rdec->buffer_size);
1174 + if (!rdec->buffer)
1175 + return false;
1176 + rdec->pos = 0;
1177 + rdec->stream_pos = rdec->buffer_given ? in_len : 0;
1178 + rdec->code = 0;
1179 + rdec->range = 0xFFFFFFFFU;
1180 + rdec->fill = fill;
1181 + rdec->at_stream_end = false;
1182 + return true;
1185 +static inline void Rd_free(struct Range_decoder * const rdec)
1187 + if (!rdec->buffer_given)
1188 + free(rdec->buffer);
1191 +static inline bool Rd_finished(struct Range_decoder * const rdec)
1193 + return rdec->pos >= rdec->stream_pos && !Rd_read_block(rdec);
1196 +static inline unsigned long long
1197 +Rd_member_position(const struct Range_decoder * const rdec)
1199 + return rdec->partial_member_pos + rdec->pos;
1202 +static inline void Rd_reset_member_position(struct Range_decoder * const rdec)
1204 + rdec->partial_member_pos = 0; rdec->partial_member_pos -= rdec->pos;
1207 +static inline uint8_t Rd_get_byte(struct Range_decoder * const rdec)
1209 + /* 0xFF avoids decoder error if member is truncated at EOS marker */
1210 + if (Rd_finished(rdec))
1211 + return 0xFF;
1212 + return rdec->buffer[rdec->pos++];
1215 +static inline void Rd_load(struct Range_decoder * const rdec)
1217 + int i;
1219 + rdec->code = 0;
1220 + for (i = 0; i < 5; ++i)
1221 + rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
1222 + rdec->range = 0xFFFFFFFFU;
1225 +static inline void Rd_normalize(struct Range_decoder * const rdec)
1227 + if (rdec->range <= 0x00FFFFFFU) {
1228 + rdec->range <<= 8;
1229 + rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
1233 +static inline unsigned Rd_decode(struct Range_decoder * const rdec,
1234 + const int num_bits)
1236 + unsigned symbol = 0;
1237 + int i;
1239 + for (i = num_bits; i > 0; --i) {
1240 + bool bit;
1242 + Rd_normalize(rdec);
1243 + rdec->range >>= 1;
1244 + /* symbol <<= 1; */
1245 + /* if(rdec->code >= rdec->range) { rdec->code -= rdec->range; symbol |= 1; } */
1246 + bit = (rdec->code >= rdec->range);
1247 + symbol <<= 1; symbol += bit;
1248 + rdec->code -= rdec->range & (0U - bit);
1250 + return symbol;
1253 +static inline unsigned Rd_decode_bit(struct Range_decoder * const rdec,
1254 + Bit_model * const probability)
1256 + uint32_t bound;
1258 + Rd_normalize(rdec);
1259 + bound = (rdec->range >> bit_model_total_bits) * *probability;
1260 + if (rdec->code < bound) {
1261 + rdec->range = bound;
1262 + *probability += (bit_model_total - *probability) >> bit_model_move_bits;
1263 + return 0;
1264 + } else {
1265 + rdec->range -= bound;
1266 + rdec->code -= bound;
1267 + *probability -= *probability >> bit_model_move_bits;
1268 + return 1;
1272 +static inline unsigned Rd_decode_tree3(struct Range_decoder * const rdec,
1273 + Bit_model bm[])
1275 + unsigned symbol = 2 | Rd_decode_bit(rdec, &bm[1]);
1277 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1278 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1279 + return symbol & 7;
1282 +static inline unsigned Rd_decode_tree6(struct Range_decoder * const rdec,
1283 + Bit_model bm[])
1285 + unsigned symbol = 2 | Rd_decode_bit(rdec, &bm[1]);
1287 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1288 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1289 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1290 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1291 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1292 + return symbol & 0x3F;
1295 +static inline unsigned Rd_decode_tree8(struct Range_decoder * const rdec,
1296 + Bit_model bm[])
1298 + unsigned symbol = 1;
1299 + int i;
1301 + for (i = 0; i < 8; ++i)
1302 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1303 + return symbol & 0xFF;
1306 +static inline unsigned
1307 +Rd_decode_tree_reversed(struct Range_decoder * const rdec,
1308 + Bit_model bm[], const int num_bits)
1310 + unsigned model = 1;
1311 + unsigned symbol = 0;
1312 + int i;
1314 + for (i = 0; i < num_bits; ++i) {
1315 + const unsigned bit = Rd_decode_bit(rdec, &bm[model]);
1317 + model <<= 1; model += bit;
1318 + symbol |= (bit << i);
1320 + return symbol;
1323 +static inline unsigned
1324 +Rd_decode_tree_reversed4(struct Range_decoder * const rdec, Bit_model bm[])
1326 + unsigned symbol = Rd_decode_bit(rdec, &bm[1]);
1328 + symbol += Rd_decode_bit( rdec, &bm[2+symbol] ) << 1;
1329 + symbol += Rd_decode_bit( rdec, &bm[4+symbol] ) << 2;
1330 + symbol += Rd_decode_bit( rdec, &bm[8+symbol] ) << 3;
1331 + return symbol;
1334 +static inline unsigned Rd_decode_matched(struct Range_decoder * const rdec,
1335 + Bit_model bm[], unsigned match_byte)
1337 + unsigned symbol = 1;
1338 + unsigned mask = 0x100;
1340 + while (true) {
1341 + const unsigned match_bit = (match_byte <<= 1) & mask;
1342 + const unsigned bit = Rd_decode_bit(rdec, &bm[symbol+match_bit+mask]);
1344 + symbol <<= 1; symbol += bit;
1345 + if (symbol > 0xFF)
1346 + return symbol & 0xFF;
1347 + mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
1351 +static inline unsigned Rd_decode_len(struct Range_decoder * const rdec,
1352 + struct Len_model * const lm,
1353 + const int pos_state)
1355 + if (Rd_decode_bit(rdec, &lm->choice1) == 0)
1356 + return Rd_decode_tree3(rdec, lm->bm_low[pos_state]);
1357 + if (Rd_decode_bit(rdec, &lm->choice2) == 0)
1358 + return len_low_symbols +
1359 + Rd_decode_tree3(rdec, lm->bm_mid[pos_state]);
1360 + return len_low_symbols + len_mid_symbols +
1361 + Rd_decode_tree8(rdec, lm->bm_high);
1365 +struct LZ_decoder {
1366 + unsigned long long partial_data_pos;
1367 + struct Range_decoder *rdec;
1368 + /* Don't move bm_* to LZd_decode_member; makes frame too large. */
1369 + Bit_model bm_literal[1 << literal_context_bits][0x300];
1370 + Bit_model bm_match[states][pos_states];
1371 + Bit_model bm_rep[states];
1372 + Bit_model bm_rep0[states];
1373 + Bit_model bm_rep1[states];
1374 + Bit_model bm_rep2[states];
1375 + Bit_model bm_len[states][pos_states];
1376 + Bit_model bm_dis_slot[len_states][1 << dis_slot_bits];
1377 + Bit_model bm_dis[modeled_distances-end_dis_model+1];
1378 + Bit_model bm_align[dis_align_size];
1379 + struct Len_model match_len_model;
1380 + struct Len_model rep_len_model;
1382 + unsigned long buffer_size;
1383 + unsigned dictionary_size;
1384 + uint8_t *buffer; /* output buffer */
1385 + unsigned long pos; /* current pos in buffer */
1386 + unsigned long stream_pos; /* first byte not yet written to file */
1387 + uint32_t crc;
1388 + long (*flush)(void*, unsigned long);
1389 + bool pos_wrapped;
1390 + bool buffer_given;
1391 + bool write_error;
1394 +static void LZd_flush_data(struct LZ_decoder * const d)
1396 + if (d->pos > d->stream_pos) {
1397 + const long size = d->pos - d->stream_pos;
1399 + CRC32_update_buf(&d->crc, d->buffer + d->stream_pos, size);
1400 + if ((d->flush &&
1401 + d->flush(d->buffer + d->stream_pos, size) != size) ||
1402 + (!d->flush && d->pos_wrapped))
1403 + d->write_error = true;
1404 + if (d->pos >= d->buffer_size) {
1405 + d->partial_data_pos += d->pos;
1406 + d->pos = 0;
1407 + d->pos_wrapped = true;
1409 + d->stream_pos = d->pos;
1413 +static inline uint8_t LZd_peek_prev(const struct LZ_decoder * const d)
1415 + if (d->pos > 0)
1416 + return d->buffer[d->pos-1];
1417 + if (d->pos_wrapped)
1418 + return d->buffer[d->buffer_size-1];
1419 + return 0; /* prev_byte of first byte */
1422 +static inline uint8_t LZd_peek(const struct LZ_decoder * const d,
1423 + const unsigned distance)
1425 + const unsigned long i = ((d->pos > distance) ? 0 : d->buffer_size) +
1426 + d->pos - distance - 1;
1427 + return d->buffer[i];
1430 +static inline void LZd_put_byte(struct LZ_decoder * const d, const uint8_t b)
1432 + d->buffer[d->pos] = b;
1433 + if (++d->pos >= d->buffer_size)
1434 + LZd_flush_data(d);
1437 +static inline void LZd_copy_block(struct LZ_decoder * const d,
1438 + const unsigned distance, unsigned len)
1440 + unsigned long lpos = d->pos, i = lpos - distance - 1;
1441 + bool fast, fast2;
1443 + if (lpos > distance) {
1444 + fast = (len < d->buffer_size - lpos);
1445 + fast2 = (fast && len <= lpos - i);
1446 + } else {
1447 + i += d->buffer_size;
1448 + fast = (len < d->buffer_size - i); /* (i == pos) may happen */
1449 + fast2 = (fast && len <= i - lpos);
1451 + if (fast) { /* no wrap */
1452 + d->pos += len;
1453 + if (fast2) /* no wrap, no overlap */
1454 + memcpy(d->buffer + lpos, d->buffer + i, len);
1455 + else
1456 + for (; len > 0; --len)
1457 + d->buffer[lpos++] = d->buffer[i++];
1458 + } else
1459 + for (; len > 0; --len) {
1460 + d->buffer[d->pos] = d->buffer[i];
1461 + if (++d->pos >= d->buffer_size)
1462 + LZd_flush_data(d);
1463 + if (++i >= d->buffer_size)
1464 + i = 0;
1468 +static inline bool LZd_init(struct LZ_decoder * const d,
1469 + struct Range_decoder * const rde,
1470 + const unsigned dict_size, uint8_t * const outbuf,
1471 + long out_size, long (*flush)(void*, unsigned long))
1473 + d->partial_data_pos = 0;
1474 + d->rdec = rde;
1475 + Bm_array_init(d->bm_literal[0], (1 << literal_context_bits) * 0x300);
1476 + Bm_array_init(d->bm_match[0], states * pos_states);
1477 + Bm_array_init(d->bm_rep, states);
1478 + Bm_array_init(d->bm_rep0, states);
1479 + Bm_array_init(d->bm_rep1, states);
1480 + Bm_array_init(d->bm_rep2, states);
1481 + Bm_array_init(d->bm_len[0], states * pos_states);
1482 + Bm_array_init(d->bm_dis_slot[0], len_states * (1 << dis_slot_bits));
1483 + Bm_array_init(d->bm_dis, modeled_distances - end_dis_model + 1);
1484 + Bm_array_init(d->bm_align, dis_align_size);
1485 + Lm_init(&d->match_len_model);
1486 + Lm_init(&d->rep_len_model);
1488 + d->buffer_given = (outbuf && out_size > 0);
1489 + d->buffer_size = d->buffer_given ? (unsigned long)out_size : dict_size;
1490 + d->dictionary_size = min_t(unsigned long, d->buffer_size, dict_size);
1491 + d->buffer = d->buffer_given ? outbuf : large_malloc(d->buffer_size);
1492 + if (!d->buffer)
1493 + return false;
1494 + d->pos = 0;
1495 + d->stream_pos = 0;
1496 + d->crc = 0xFFFFFFFFU;
1497 + d->flush = flush;
1498 + d->pos_wrapped = false;
1499 + d->write_error = false;
1500 + /* prev_byte of first byte; also for LZd_peek( 0 ) on corrupt file */
1501 + if (!d->buffer_given) /* inbuf and outbuf may overlap */
1502 + d->buffer[d->buffer_size-1] = 0;
1503 + return true;
1506 +static inline void LZd_free(struct LZ_decoder * const d)
1508 + if (!d->buffer_given)
1509 + large_free(d->buffer);
1512 +static inline unsigned LZd_crc(const struct LZ_decoder * const d)
1514 + return d->crc ^ 0xFFFFFFFFU;
1517 +static inline unsigned long long
1518 +LZd_data_position(const struct LZ_decoder * const d)
1520 + return d->partial_data_pos + d->pos;
1524 +static bool LZd_verify_trailer(struct LZ_decoder * const d)
1526 + Lzip_trailer trailer;
1527 + int i = 0;
1529 + while (i < Lt_size)
1530 + trailer[i++] = Rd_get_byte(d->rdec);
1532 + return (Lt_get_data_crc(trailer) == LZd_crc(d) &&
1533 + Lt_get_data_size(trailer) == LZd_data_position(d) &&
1534 + Lt_get_member_size(trailer) == Rd_member_position(d->rdec));
1538 +/* Return value: 0 = OK, < 0 = error (see include/linux/lzip.h). */
1539 +static int LZd_decode_member(struct LZ_decoder * const d)
1541 + struct Range_decoder * const rdec = d->rdec;
1542 + unsigned rep0 = 0; /* rep[0-3] latest four distances */
1543 + unsigned rep1 = 0; /* used for efficient coding of */
1544 + unsigned rep2 = 0; /* repeated distances */
1545 + unsigned rep3 = 0;
1546 + State state = 0;
1548 + Rd_load(rdec);
1549 + while (!Rd_finished(rdec)) {
1550 + int len;
1551 + const int pos_state = LZd_data_position(d) & pos_state_mask;
1553 + if (Rd_decode_bit(rdec, &d->bm_match[state][pos_state]) == 0) {
1554 + /* literal byte */
1555 + Bit_model * const bm = d->bm_literal[get_lit_state(LZd_peek_prev(d))];
1557 + if (St_is_char(state)) {
1558 + state -= (state < 4) ? state : 3;
1559 + LZd_put_byte(d, Rd_decode_tree8(rdec, bm));
1560 + } else {
1561 + state -= (state < 10) ? 3 : 6;
1562 + LZd_put_byte(d, Rd_decode_matched(rdec, bm, LZd_peek(d, rep0)));
1564 + continue;
1566 + /* match or repeated match */
1567 + if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) {
1568 + if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) {
1569 + if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) {
1570 + state = St_set_short_rep(state);
1571 + LZd_put_byte(d, LZd_peek(d, rep0));
1572 + continue;
1574 + } else {
1575 + unsigned distance;
1577 + if (Rd_decode_bit(rdec, &d->bm_rep1[state]) == 0)
1578 + distance = rep1;
1579 + else {
1580 + if (Rd_decode_bit(rdec, &d->bm_rep2[state]) == 0)
1581 + distance = rep2;
1582 + else {
1583 + distance = rep3;
1584 + rep3 = rep2;
1586 + rep2 = rep1;
1588 + rep1 = rep0;
1589 + rep0 = distance;
1591 + state = St_set_rep(state);
1592 + len = min_match_len + Rd_decode_len(rdec, &d->rep_len_model, pos_state);
1593 + } else { /* match */
1594 + unsigned distance;
1596 + len = min_match_len + Rd_decode_len(rdec, &d->match_len_model, pos_state);
1597 + distance = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]);
1598 + if (distance >= start_dis_model) {
1599 + const unsigned dis_slot = distance;
1600 + const int direct_bits = (dis_slot >> 1) - 1;
1602 + distance = (2 | (dis_slot & 1)) << direct_bits;
1603 + if (dis_slot < end_dis_model)
1604 + distance += Rd_decode_tree_reversed(rdec,
1605 + d->bm_dis + (distance - dis_slot), direct_bits);
1606 + else {
1607 + distance +=
1608 + Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits;
1609 + distance += Rd_decode_tree_reversed4(rdec, d->bm_align);
1610 + if (distance == 0xFFFFFFFFU) { /* marker found */
1611 + Rd_normalize(rdec);
1612 + LZd_flush_data(d);
1613 + if (d->write_error)
1614 + return LZIP_WRITE_ERROR;
1615 + if (len == min_match_len) { /* End Of Stream marker */
1616 + if (LZd_verify_trailer(d))
1617 + return 0;
1618 + else
1619 + return LZIP_BAD_CRC;
1621 + if (len == min_match_len + 1) { /* Sync Flush marker */
1622 + Rd_load(rdec);
1623 + continue;
1625 + return LZIP_BAD_DATA; /* unknown marker */
1629 + rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
1630 + state = St_set_match(state);
1631 + if (rep0 >= d->dictionary_size ||
1632 + (rep0 >= d->pos && !d->pos_wrapped)) {
1633 + LZd_flush_data(d);
1634 + return LZIP_BAD_DATA;
1637 + LZd_copy_block(d, rep0, len);
1639 + LZd_flush_data(d);
1640 + return LZIP_DATA_EOF;
1644 +int lzip_decompress(unsigned char *inbuf, long in_len,
1645 + long (*fill)(void*, unsigned long),
1646 + long (*flush)(void*, unsigned long),
1647 + unsigned char *outbuf, long out_size,
1648 + long *in_posp, long *out_posp)
1650 + unsigned char *outptr = outbuf;
1651 + struct Range_decoder rdec;
1652 + struct LZ_decoder *decoder = 0;
1653 + int retval = 0;
1654 + bool first_member;
1656 + if (in_posp)
1657 + *in_posp = 0;
1658 + if (out_posp)
1659 + *out_posp = 0;
1661 + if (!Rd_init(&rdec, inbuf, in_len, fill))
1662 + return LZIP_OOM_INBUF;
1664 + for (first_member = true;; first_member = false) {
1665 + long data_pos;
1666 + int size;
1667 + unsigned dictionary_size;
1668 + Lzip_header header;
1670 + Rd_reset_member_position(&rdec);
1671 + for (size = 0; size < Lh_size && !Rd_finished(&rdec); ++size)
1672 + header[size] = Rd_get_byte(&rdec);
1673 + if (Rd_finished(&rdec)) { /* End Of File */
1674 + if (first_member)
1675 + retval = LZIP_HEADER1_EOF;
1676 + else if (Lh_verify_prefix(header, size))
1677 + retval = LZIP_HEADER2_EOF;
1678 + break;
1680 + if (!Lh_verify_magic(header)) {
1681 + if (first_member)
1682 + retval = LZIP_BAD_MAGIC1;
1683 + else if (Lh_verify_corrupt(header))
1684 + retval = LZIP_BAD_MAGIC2;
1685 + break;
1687 + if (!Lh_verify_version(header)) {
1688 + retval = LZIP_BAD_VERSION;
1689 + break;
1691 + dictionary_size = Lh_get_dictionary_size(header);
1692 + if (dictionary_size < min_dictionary_size ||
1693 + dictionary_size > max_dictionary_size) {
1694 + retval = LZIP_BAD_DICT_SIZE;
1695 + break;
1698 + if (!decoder)
1699 + decoder = malloc(sizeof *decoder);
1700 + if (!decoder || !LZd_init(decoder, &rdec, dictionary_size,
1701 + outptr, out_size, flush)) {
1702 + retval = LZIP_OOM_OUTBUF;
1703 + break;
1705 + retval = LZd_decode_member(decoder);
1706 + if (in_posp)
1707 + *in_posp += Rd_member_position(&rdec);
1708 + data_pos = LZd_data_position(decoder);
1709 + if (outptr)
1710 + outptr += data_pos;
1711 + if (out_posp)
1712 + *out_posp += data_pos;
1713 + if (out_size > 0)
1714 + out_size -= data_pos;
1715 + LZd_free(decoder);
1716 + if (retval != 0)
1717 + break;
1719 + if (decoder)
1720 + free(decoder);
1721 + Rd_free(&rdec);
1722 + return retval;
1725 +#ifndef STATIC
1726 +EXPORT_SYMBOL_GPL(lzip_decompress);
1727 +#endif
1728 +MODULE_DESCRIPTION("LZIP Decompressor");
1729 +MODULE_AUTHOR("Antonio Diaz Diaz <antonio@gnu.org>");
1730 +MODULE_LICENSE("GPL");
1731 diff -urdN linux-5.4.18/scripts/Makefile.lib linux-5.4.18.new/scripts/Makefile.lib
1732 --- linux-5.4.18/scripts/Makefile.lib 2020-02-05 22:22:53.000000000 +0100
1733 +++ linux-5.4.18.new/scripts/Makefile.lib 2020-02-10 15:55:57.000000000 +0100
1734 @@ -338,6 +338,18 @@
1735 quiet_cmd_bzip2 = BZIP2 $@
1736 cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9; $(size_append); } > $@
1738 +# Lzip
1739 +# ---------------------------------------------------------------------------
1740 +# The .lz format has the uncompressed size available at the end of the
1741 +# file, but at offset (member_size - 16). So we append a gzip-style size.
1742 +# Use klzip to compress the kernel image and lzip to compress other things.
1744 +quiet_cmd_klzip = LZIP $@
1745 + cmd_klzip = { cat $(real-prereqs) | lzip -9; $(size_append); } > $@
1747 +quiet_cmd_lzip = LZIP $@
1748 + cmd_lzip = cat $(real-prereqs) | lzip -9 > $@
1750 # Lzma
1751 # ---------------------------------------------------------------------------
1753 diff -urdN linux-5.4.18/scripts/extract-ikconfig linux-5.4.18.new/scripts/extract-ikconfig
1754 --- linux-5.4.18/scripts/extract-ikconfig 2020-02-05 22:22:53.000000000 +0100
1755 +++ linux-5.4.18.new/scripts/extract-ikconfig 2020-02-10 15:55:57.000000000 +0100
1756 @@ -59,6 +59,7 @@
1757 try_decompress '\037\213\010' xy gunzip
1758 try_decompress '\3757zXZ\000' abcde unxz
1759 try_decompress 'BZh' xy bunzip2
1760 +try_decompress 'LZIP' xyz 'lzip -d'
1761 try_decompress '\135\0\0\0' xxx unlzma
1762 try_decompress '\211\114\132' xy 'lzop -d'
1763 try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
1764 diff -urdN linux-5.4.18/scripts/extract-vmlinux linux-5.4.18.new/scripts/extract-vmlinux
1765 --- linux-5.4.18/scripts/extract-vmlinux 2020-02-05 22:22:53.000000000 +0100
1766 +++ linux-5.4.18.new/scripts/extract-vmlinux 2020-02-10 15:55:57.000000000 +0100
1767 @@ -52,6 +52,7 @@
1768 try_decompress '\037\213\010' xy gunzip
1769 try_decompress '\3757zXZ\000' abcde unxz
1770 try_decompress 'BZh' xy bunzip2
1771 +try_decompress 'LZIP' xyz 'lzip -d'
1772 try_decompress '\135\0\0\0' xxx unlzma
1773 try_decompress '\211\114\132' xy 'lzop -d'
1774 try_decompress '\002!L\030' xxx 'lz4 -d'
1775 diff -urdN linux-5.4.18/scripts/package/buildtar linux-5.4.18.new/scripts/package/buildtar
1776 --- linux-5.4.18/scripts/package/buildtar 2020-02-05 22:22:53.000000000 +0100
1777 +++ linux-5.4.18.new/scripts/package/buildtar 2020-02-10 15:55:57.000000000 +0100
1778 @@ -35,6 +35,10 @@
1779 opts=--bzip2
1780 tarball=${tarball}.bz2
1782 + tarlz-pkg)
1783 + opts=--lzip
1784 + tarball=${tarball}.lz
1785 + ;;
1786 tarxz-pkg)
1787 opts=--xz
1788 tarball=${tarball}.xz
1789 diff -urdN linux-5.4.18/scripts/patch-kernel linux-5.4.18.new/scripts/patch-kernel
1790 --- linux-5.4.18/scripts/patch-kernel 2020-02-05 22:22:53.000000000 +0100
1791 +++ linux-5.4.18.new/scripts/patch-kernel 2020-02-10 15:55:57.000000000 +0100
1792 @@ -117,6 +117,10 @@
1793 ext=".bz2"
1794 name="bzip2"
1795 uncomp="bunzip2 -dc"
1796 + elif [ -r ${filebase}.lz ]; then
1797 + ext=".lz"
1798 + name="lzip"
1799 + uncomp="lzip -dc"
1800 elif [ -r ${filebase}.xz ]; then
1801 ext=".xz"
1802 name="xz"
1803 diff -urdN linux-5.4.18/tools/testing/selftests/gen_kselftest_tar.sh linux-5.4.18.new/tools/testing/selftests/gen_kselftest_tar.sh
1804 --- linux-5.4.18/tools/testing/selftests/gen_kselftest_tar.sh 2020-02-05 22:22:53.000000000 +0100
1805 +++ linux-5.4.18.new/tools/testing/selftests/gen_kselftest_tar.sh 2020-02-10 15:55:57.000000000 +0100
1806 @@ -27,6 +27,10 @@
1807 copts="cvjf"
1808 ext=".tar.bz2"
1810 + tarlz)
1811 + copts="cv --lzip -f"
1812 + ext=".tar.lz"
1813 + ;;
1814 tarxz)
1815 copts="cvJf"
1816 ext=".tar.xz"
1817 diff -urdN linux-5.4.18/usr/.gitignore linux-5.4.18.new/usr/.gitignore
1818 --- linux-5.4.18/usr/.gitignore 2020-02-05 22:22:53.000000000 +0100
1819 +++ linux-5.4.18.new/usr/.gitignore 2020-02-10 15:55:57.000000000 +0100
1820 @@ -5,5 +5,6 @@
1821 initramfs_data.cpio
1822 initramfs_data.cpio.gz
1823 initramfs_data.cpio.bz2
1824 +initramfs_data.cpio.lz
1825 initramfs_data.cpio.lzma
1826 initramfs_list
1827 diff -urdN linux-5.4.18/usr/Kconfig linux-5.4.18.new/usr/Kconfig
1828 --- linux-5.4.18/usr/Kconfig 2020-02-05 22:22:53.000000000 +0100
1829 +++ linux-5.4.18.new/usr/Kconfig 2020-02-10 15:55:57.000000000 +0100
1830 @@ -70,6 +70,15 @@
1831 Support loading of a bzip2 encoded initial ramdisk or cpio buffer
1832 If unsure, say N.
1834 +config RD_LZIP
1835 + bool "Support initial ramdisk/ramfs compressed using lzip"
1836 + default y
1837 + depends on BLK_DEV_INITRD
1838 + select DECOMPRESS_LZIP
1839 + help
1840 + Support loading of a lzip encoded initial ramdisk or cpio buffer.
1841 + If unsure, say N.
1843 config RD_LZMA
1844 bool "Support initial ramdisk/ramfs compressed using LZMA"
1845 default y
1846 @@ -165,6 +174,18 @@
1847 If you choose this, keep in mind that you need to have the bzip2 tool
1848 available to be able to compress the initram.
1850 +config INITRAMFS_COMPRESSION_LZIP
1851 + bool "Lzip"
1852 + depends on RD_LZIP
1853 + help
1854 + Lzip's compression ratio is better than that of gzip and bzip2.
1855 + Decompression speed is between gzip and bzip2. Compression can
1856 + be as fast as gzip or slower than bzip2 depending on compression
1857 + level. Lzip can produce a initramfs about a 16% smaller than gzip.
1859 + If you choose this, keep in mind that you need to have the lzip tool
1860 + available to be able to compress the initram.
1862 config INITRAMFS_COMPRESSION_LZMA
1863 bool "LZMA"
1864 depends on RD_LZMA
1865 @@ -222,12 +243,14 @@
1866 default "" if INITRAMFS_COMPRESSION_NONE
1867 default ".gz" if INITRAMFS_COMPRESSION_GZIP
1868 default ".bz2" if INITRAMFS_COMPRESSION_BZIP2
1869 + default ".lz" if INITRAMFS_COMPRESSION_LZIP
1870 default ".lzma" if INITRAMFS_COMPRESSION_LZMA
1871 default ".xz" if INITRAMFS_COMPRESSION_XZ
1872 default ".lzo" if INITRAMFS_COMPRESSION_LZO
1873 default ".lz4" if INITRAMFS_COMPRESSION_LZ4
1874 default ".gz" if RD_GZIP
1875 default ".lz4" if RD_LZ4
1876 + default ".lz" if RD_LZIP
1877 default ".lzo" if RD_LZO
1878 default ".xz" if RD_XZ
1879 default ".lzma" if RD_LZMA