qi: clarify the order in which qi looks for a recipe
[dragora.git] / patches / kernel / linux-4.19.8_lzip-0.diff
blob98edaff1cea2e369b57175b472091841cea8c6e9
1 diff -urdN linux-4.19.8/Documentation/00-INDEX linux-4.19.8.new/Documentation/00-INDEX
2 --- linux-4.19.8/Documentation/00-INDEX 2018-12-08 12:59:10.000000000 +0100
3 +++ linux-4.19.8.new/Documentation/00-INDEX 2018-12-09 18:01:59.000000000 +0100
4 @@ -242,6 +242,8 @@
5 - info on creator of above logo & site to get additional images from.
6 lsm.txt
7 - Linux Security Modules: General Security Hooks for Linux
8 +lzip.txt
9 + - info on lzip compression for the linux kernel.
10 lzo.txt
11 - kernel LZO decompressor input formats
12 m68k/
13 diff -urdN linux-4.19.8/Documentation/dontdiff linux-4.19.8.new/Documentation/dontdiff
14 --- linux-4.19.8/Documentation/dontdiff 2018-12-08 19:33:27.000000000 +0100
15 +++ linux-4.19.8.new/Documentation/dontdiff 2018-12-09 18:01:59.000000000 +0100
16 @@ -26,6 +26,7 @@
17 *.ll
18 *.log
19 *.lst
20 +*.lz
21 *.lzma
22 *.lzo
23 *.mo
24 diff -urdN linux-4.19.8/Documentation/filesystems/squashfs.txt linux-4.19.8.new/Documentation/filesystems/squashfs.txt
25 --- linux-4.19.8/Documentation/filesystems/squashfs.txt 2018-12-08 12:59:10.000000000 +0100
26 +++ linux-4.19.8.new/Documentation/filesystems/squashfs.txt 2018-12-09 18:01:59.000000000 +0100
27 @@ -2,7 +2,7 @@
28 =======================
30 Squashfs is a compressed read-only filesystem for Linux.
31 -It uses zlib, lz4, lzo, or xz compression to compress files, inodes and
32 +It uses zlib, lz4, lzip, lzo, or xz compression to compress files, inodes and
33 directories. Inodes in the system are very small and all blocks are packed to
34 minimise data overhead. Block sizes greater than 4K are supported up to a
35 maximum of 1Mbytes (default block size 128K).
36 diff -urdN linux-4.19.8/Documentation/lzip.txt linux-4.19.8.new/Documentation/lzip.txt
37 --- linux-4.19.8/Documentation/lzip.txt 1970-01-01 01:00:00.000000000 +0100
38 +++ linux-4.19.8.new/Documentation/lzip.txt 2018-12-09 19:07:33.000000000 +0100
39 @@ -0,0 +1,59 @@
40 +==============================
41 +Lzip data compression in Linux
42 +==============================
44 +Introduction
45 +============
47 +Lzip is a lossless data compressor with a user interface similar to the
48 +one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)
49 +or compress most files more than bzip2 (lzip -9). Decompression speed is
50 +intermediate between gzip and bzip2. Lzip implements the LZMA algorithm.
52 +Lzip has been designed, written and tested with great care to be the
53 +standard general-purpose compressor for unix-like systems. The lzip
54 +format is as simple as possible (but not simpler). It provides accurate
55 +and robust 3 factor integrity checking.
57 +Learn more about lzip at http://www.nongnu.org/lzip/lzip.html
59 +Lzip related components in the kernel
60 +=====================================
62 +The lzip_decompress module in lib/lzip_decompress.c provides a versatile
63 +lzip decompression function able to do buffer to buffer decompression or
64 +stream decompression with fill and flush callback functions. The usage
65 +of the function is documented in include/linux/lzip.h.
67 +For decompressing the kernel image, initramfs, and initrd, there is a
68 +wrapper function in lib/decompress_lunzip.c providing the same common
69 +interface as the other decompress_*.c files, which is defined in
70 +include/linux/decompress/generic.h.
72 +For kernel makefiles, two commands are provided in scripts/Makefile.lib
73 +for use with $(call if_changed). The kernel image must be compressed
74 +with $(call if_changed,klzip) which will append a four-byte trailer
75 +containing the size of the uncompressed data, which is needed by the
76 +boot code. Other things should be compressed with $(call if_changed,lzip).
78 +Testing
79 +=======
81 +Lzip-compressed kernel images of multiple linux versions since 2.6.30.10
82 +have been built and tested, even on machines as modest as an AMD 486-DX2
83 +at 66 MHz with 64 MiB of RAM. In the worst case (on the slow machine
84 +above), lzip just increased the boot time a 15% compared with gzip. On
85 +more modern machines, lzip may boot slightly faster than gzip. It just
86 +takes 0.2 seconds for lzip to decompress vmlinuz-4.4.16 on my machine.
88 +Decompression time is usually a small fraction of the total boot time.
89 +For example, using lz4 on a desktop machine in order to save 0.05
90 +seconds of a total boot time of 20 seconds is probably not worth the
91 +increased image size.
93 +Xlunzip is a test tool for the lzip_decompress module. It is similar to
94 +lunzip, but it uses the lzip_decompress module as a backend. The xlunzip
95 +home page is at http://www.nongnu.org/lzip/xlunzip.html
97 +Author: Antonio Diaz Diaz
98 +Updated: 2018-12-09
99 diff -urdN linux-4.19.8/Documentation/x86/boot.txt linux-4.19.8.new/Documentation/x86/boot.txt
100 --- linux-4.19.8/Documentation/x86/boot.txt 2018-12-08 12:59:10.000000000 +0100
101 +++ linux-4.19.8.new/Documentation/x86/boot.txt 2018-12-09 18:01:59.000000000 +0100
102 @@ -665,10 +665,10 @@
103 The payload may be compressed. The format of both the compressed and
104 uncompressed data should be determined using the standard magic
105 numbers. The currently supported compression formats are gzip
106 - (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
107 - (magic number 5D 00), XZ (magic number FD 37), and LZ4 (magic number
108 - 02 21). The uncompressed payload is currently always ELF (magic
109 - number 7F 45 4C 46).
110 + (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), lzip
111 + (magic number 4C 5A), LZMA (magic number 5D 00), XZ (magic number FD
112 + 37), and LZ4 (magic number 02 21). The uncompressed payload is
113 + currently always ELF (magic number 7F 45 4C 46).
115 Field name: payload_length
116 Type: read
117 diff -urdN linux-4.19.8/Makefile linux-4.19.8.new/Makefile
118 --- linux-4.19.8/Makefile 2018-12-08 19:31:53.000000000 +0100
119 +++ linux-4.19.8.new/Makefile 2018-12-09 18:01:59.000000000 +0100
120 @@ -912,14 +912,17 @@
121 export mod_strip_cmd
123 # CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed
124 -# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP
125 -# or CONFIG_MODULE_COMPRESS_XZ.
126 +# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP,
127 +# CONFIG_MODULE_COMPRESS_LZIP or CONFIG_MODULE_COMPRESS_XZ.
129 mod_compress_cmd = true
130 ifdef CONFIG_MODULE_COMPRESS
131 ifdef CONFIG_MODULE_COMPRESS_GZIP
132 mod_compress_cmd = gzip -n -f
133 endif # CONFIG_MODULE_COMPRESS_GZIP
134 + ifdef CONFIG_MODULE_COMPRESS_LZIP
135 + mod_compress_cmd = lzip -f
136 + endif # CONFIG_MODULE_COMPRESS_LZIP
137 ifdef CONFIG_MODULE_COMPRESS_XZ
138 mod_compress_cmd = xz -f
139 endif # CONFIG_MODULE_COMPRESS_XZ
140 @@ -931,6 +934,7 @@
142 INITRD_COMPRESS-y := gzip
143 INITRD_COMPRESS-$(CONFIG_RD_BZIP2) := bzip2
144 +INITRD_COMPRESS-$(CONFIG_RD_LZIP) := lzip
145 INITRD_COMPRESS-$(CONFIG_RD_LZMA) := lzma
146 INITRD_COMPRESS-$(CONFIG_RD_XZ) := xz
147 INITRD_COMPRESS-$(CONFIG_RD_LZO) := lzo
148 diff -urdN linux-4.19.8/arch/arm/Kconfig linux-4.19.8.new/arch/arm/Kconfig
149 --- linux-4.19.8/arch/arm/Kconfig 2018-12-08 12:59:10.000000000 +0100
150 +++ linux-4.19.8.new/arch/arm/Kconfig 2018-12-09 18:01:59.000000000 +0100
151 @@ -77,6 +77,7 @@
152 select HAVE_IRQ_TIME_ACCOUNTING
153 select HAVE_KERNEL_GZIP
154 select HAVE_KERNEL_LZ4
155 + select HAVE_KERNEL_LZIP
156 select HAVE_KERNEL_LZMA
157 select HAVE_KERNEL_LZO
158 select HAVE_KERNEL_XZ
159 diff -urdN linux-4.19.8/arch/arm/boot/compressed/Makefile linux-4.19.8.new/arch/arm/boot/compressed/Makefile
160 --- linux-4.19.8/arch/arm/boot/compressed/Makefile 2018-12-08 12:59:10.000000000 +0100
161 +++ linux-4.19.8.new/arch/arm/boot/compressed/Makefile 2018-12-09 18:01:59.000000000 +0100
162 @@ -71,6 +71,7 @@
163 CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
165 compress-$(CONFIG_KERNEL_GZIP) = gzip
166 +compress-$(CONFIG_KERNEL_LZIP) = klzip
167 compress-$(CONFIG_KERNEL_LZO) = lzo
168 compress-$(CONFIG_KERNEL_LZMA) = lzma
169 compress-$(CONFIG_KERNEL_XZ) = xzkern
170 diff -urdN linux-4.19.8/arch/arm/boot/compressed/decompress.c linux-4.19.8.new/arch/arm/boot/compressed/decompress.c
171 --- linux-4.19.8/arch/arm/boot/compressed/decompress.c 2018-12-08 12:59:10.000000000 +0100
172 +++ linux-4.19.8.new/arch/arm/boot/compressed/decompress.c 2018-12-09 18:01:59.000000000 +0100
173 @@ -37,6 +37,10 @@
174 #include "../../../../lib/decompress_inflate.c"
175 #endif
177 +#ifdef CONFIG_KERNEL_LZIP
178 +#include "../../../../lib/decompress_lunzip.c"
179 +#endif
181 #ifdef CONFIG_KERNEL_LZO
182 #include "../../../../lib/decompress_unlzo.c"
183 #endif
184 diff -urdN linux-4.19.8/arch/sh/Kconfig linux-4.19.8.new/arch/sh/Kconfig
185 --- linux-4.19.8/arch/sh/Kconfig 2018-12-08 12:59:10.000000000 +0100
186 +++ linux-4.19.8.new/arch/sh/Kconfig 2018-12-09 18:01:59.000000000 +0100
187 @@ -25,6 +25,7 @@
188 select HAVE_KERNEL_GZIP
189 select CPU_NO_EFFICIENT_FFS
190 select HAVE_KERNEL_BZIP2
191 + select HAVE_KERNEL_LZIP
192 select HAVE_KERNEL_LZMA
193 select HAVE_KERNEL_XZ
194 select HAVE_KERNEL_LZO
195 diff -urdN linux-4.19.8/arch/sh/Makefile linux-4.19.8.new/arch/sh/Makefile
196 --- linux-4.19.8/arch/sh/Makefile 2018-12-08 12:59:10.000000000 +0100
197 +++ linux-4.19.8.new/arch/sh/Makefile 2018-12-09 18:01:59.000000000 +0100
198 @@ -209,9 +209,9 @@
199 libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
200 libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
202 -BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
203 - uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
204 - romImage
205 +BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lz uImage.lzma uImage.xz \
206 + uImage.lzo uImage.srec uImage.bin zImage vmlinux.bin \
207 + vmlinux.srec romImage
208 PHONY += $(BOOT_TARGETS)
210 all: $(notdir $(KBUILD_IMAGE))
211 @@ -238,6 +238,7 @@
212 @echo ' uImage.bin - Kernel-only image for U-Boot (bin)'
213 @echo '* uImage.gz - Kernel-only image for U-Boot (gzip)'
214 @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
215 + @echo ' uImage.lz - Kernel-only image for U-Boot (lzip)'
216 @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)'
217 @echo ' uImage.xz - Kernel-only image for U-Boot (xz)'
218 @echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)'
219 diff -urdN linux-4.19.8/arch/sh/boot/Makefile linux-4.19.8.new/arch/sh/boot/Makefile
220 --- linux-4.19.8/arch/sh/boot/Makefile 2018-12-08 12:59:10.000000000 +0100
221 +++ linux-4.19.8.new/arch/sh/boot/Makefile 2018-12-09 18:01:59.000000000 +0100
222 @@ -22,14 +22,15 @@
223 suffix-y := bin
224 suffix-$(CONFIG_KERNEL_GZIP) := gz
225 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
226 +suffix-$(CONFIG_KERNEL_LZIP) := lz
227 suffix-$(CONFIG_KERNEL_LZMA) := lzma
228 suffix-$(CONFIG_KERNEL_XZ) := xz
229 suffix-$(CONFIG_KERNEL_LZO) := lzo
231 targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
232 - uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin
233 -extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
234 - vmlinux.bin.xz vmlinux.bin.lzo
235 + uImage.bz2 uImage.lz uImage.lzma uImage.xz uImage.lzo uImage.bin
236 +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
237 + vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo
238 subdir- := compressed romimage
240 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
241 @@ -71,6 +72,9 @@
242 $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
243 $(call if_changed,bzip2)
245 +$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
246 + $(call if_changed,klzip)
248 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
249 $(call if_changed,lzma)
251 @@ -86,6 +90,9 @@
252 $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
253 $(call if_changed,uimage,gzip)
255 +$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz
256 + $(call if_changed,uimage,lzip)
258 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
259 $(call if_changed,uimage,lzma)
261 diff -urdN linux-4.19.8/arch/sh/boot/compressed/Makefile linux-4.19.8.new/arch/sh/boot/compressed/Makefile
262 --- linux-4.19.8/arch/sh/boot/compressed/Makefile 2018-12-08 12:59:10.000000000 +0100
263 +++ linux-4.19.8.new/arch/sh/boot/compressed/Makefile 2018-12-09 18:01:59.000000000 +0100
264 @@ -5,10 +5,9 @@
265 # create a compressed vmlinux image from the original vmlinux
268 -targets := vmlinux vmlinux.bin vmlinux.bin.gz \
269 - vmlinux.bin.bz2 vmlinux.bin.lzma \
270 - vmlinux.bin.xz vmlinux.bin.lzo \
271 - head_$(BITS).o misc.o piggy.o
272 +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
273 + vmlinux.bin.lz vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo \
274 + head_$(BITS).o misc.o piggy.o
276 OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
278 @@ -66,6 +65,8 @@
279 $(call if_changed,gzip)
280 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
281 $(call if_changed,bzip2)
282 +$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
283 + $(call if_changed,klzip)
284 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
285 $(call if_changed,lzma)
286 $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
287 diff -urdN linux-4.19.8/arch/sh/boot/compressed/misc.c linux-4.19.8.new/arch/sh/boot/compressed/misc.c
288 --- linux-4.19.8/arch/sh/boot/compressed/misc.c 2018-12-08 12:59:10.000000000 +0100
289 +++ linux-4.19.8.new/arch/sh/boot/compressed/misc.c 2018-12-09 18:01:59.000000000 +0100
290 @@ -58,6 +58,10 @@
291 #include "../../../../lib/decompress_bunzip2.c"
292 #endif
294 +#ifdef CONFIG_KERNEL_LZIP
295 +#include "../../../../lib/decompress_lunzip.c"
296 +#endif
298 #ifdef CONFIG_KERNEL_LZMA
299 #include "../../../../lib/decompress_unlzma.c"
300 #endif
301 diff -urdN linux-4.19.8/arch/x86/Kconfig linux-4.19.8.new/arch/x86/Kconfig
302 --- linux-4.19.8/arch/x86/Kconfig 2018-12-08 12:59:10.000000000 +0100
303 +++ linux-4.19.8.new/arch/x86/Kconfig 2018-12-09 18:01:59.000000000 +0100
304 @@ -158,6 +158,7 @@
305 select HAVE_KERNEL_BZIP2
306 select HAVE_KERNEL_GZIP
307 select HAVE_KERNEL_LZ4
308 + select HAVE_KERNEL_LZIP
309 select HAVE_KERNEL_LZMA
310 select HAVE_KERNEL_LZO
311 select HAVE_KERNEL_XZ
312 diff -urdN linux-4.19.8/arch/x86/boot/compressed/Makefile linux-4.19.8.new/arch/x86/boot/compressed/Makefile
313 --- linux-4.19.8/arch/x86/boot/compressed/Makefile 2018-12-08 12:59:10.000000000 +0100
314 +++ linux-4.19.8.new/arch/x86/boot/compressed/Makefile 2018-12-09 18:01:59.000000000 +0100
315 @@ -23,8 +23,8 @@
316 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
317 KCOV_INSTRUMENT := n
319 -targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
320 - vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
321 +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
322 + vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
324 KBUILD_CFLAGS := -m$(BITS) -O2
325 KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
326 @@ -134,6 +134,8 @@
327 $(call if_changed,gzip)
328 $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
329 $(call if_changed,bzip2)
330 +$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
331 + $(call if_changed,klzip)
332 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
333 $(call if_changed,lzma)
334 $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
335 @@ -145,6 +147,7 @@
337 suffix-$(CONFIG_KERNEL_GZIP) := gz
338 suffix-$(CONFIG_KERNEL_BZIP2) := bz2
339 +suffix-$(CONFIG_KERNEL_LZIP) := lz
340 suffix-$(CONFIG_KERNEL_LZMA) := lzma
341 suffix-$(CONFIG_KERNEL_XZ) := xz
342 suffix-$(CONFIG_KERNEL_LZO) := lzo
343 diff -urdN linux-4.19.8/arch/x86/boot/compressed/misc.c linux-4.19.8.new/arch/x86/boot/compressed/misc.c
344 --- linux-4.19.8/arch/x86/boot/compressed/misc.c 2018-12-08 12:59:10.000000000 +0100
345 +++ linux-4.19.8.new/arch/x86/boot/compressed/misc.c 2018-12-09 18:01:59.000000000 +0100
346 @@ -61,6 +61,10 @@
347 #include "../../../../lib/decompress_bunzip2.c"
348 #endif
350 +#ifdef CONFIG_KERNEL_LZIP
351 +#include "../../../../lib/decompress_lunzip.c"
352 +#endif
354 #ifdef CONFIG_KERNEL_LZMA
355 #include "../../../../lib/decompress_unlzma.c"
356 #endif
357 diff -urdN linux-4.19.8/fs/squashfs/Kconfig linux-4.19.8.new/fs/squashfs/Kconfig
358 --- linux-4.19.8/fs/squashfs/Kconfig 2018-12-08 12:59:10.000000000 +0100
359 +++ linux-4.19.8.new/fs/squashfs/Kconfig 2018-12-09 18:01:59.000000000 +0100
360 @@ -4,7 +4,7 @@
361 help
362 Saying Y here includes support for SquashFS 4.0 (a Compressed
363 Read-Only File System). Squashfs is a highly compressed read-only
364 - filesystem for Linux. It uses zlib, lzo or xz compression to
365 + filesystem for Linux. It uses zlib, lzip, lzo or xz compression to
366 compress both files, inodes and directories. Inodes in the system
367 are very small and all blocks are packed to minimise data overhead.
368 Block sizes greater than 4K are supported up to a maximum of 1 Mbytes
369 @@ -134,6 +134,21 @@
370 file systems will be readable without selecting this option.
372 If unsure, say N.
374 +config SQUASHFS_LZIP
375 + bool "Include support for LZIP compressed file systems"
376 + depends on SQUASHFS
377 + select LZIP_DECOMPRESS
378 + help
379 + Saying Y here includes support for reading Squashfs file systems
380 + compressed with LZIP compression. LZIP gives better compression
381 + than the default zlib compression, at the expense of greater CPU
382 + and memory overhead.
384 + LZIP is not the standard compression used in Squashfs and so most
385 + file systems will be readable without selecting this option.
387 + If unsure, say N.
389 config SQUASHFS_LZO
390 bool "Include support for LZO compressed file systems"
391 diff -urdN linux-4.19.8/fs/squashfs/Makefile linux-4.19.8.new/fs/squashfs/Makefile
392 --- linux-4.19.8/fs/squashfs/Makefile 2018-12-08 12:59:10.000000000 +0100
393 +++ linux-4.19.8.new/fs/squashfs/Makefile 2018-12-09 18:01:59.000000000 +0100
394 @@ -13,6 +13,7 @@
395 squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
396 squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
397 squashfs-$(CONFIG_SQUASHFS_LZ4) += lz4_wrapper.o
398 +squashfs-$(CONFIG_SQUASHFS_LZIP) += lzip_wrapper.o
399 squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
400 squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
401 squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o
402 diff -urdN linux-4.19.8/fs/squashfs/decompressor.c linux-4.19.8.new/fs/squashfs/decompressor.c
403 --- linux-4.19.8/fs/squashfs/decompressor.c 2018-12-08 12:59:10.000000000 +0100
404 +++ linux-4.19.8.new/fs/squashfs/decompressor.c 2018-12-09 18:01:59.000000000 +0100
405 @@ -47,6 +47,12 @@
407 #endif
409 +#ifndef CONFIG_SQUASHFS_LZIP
410 +static const struct squashfs_decompressor squashfs_lzip_comp_ops = {
411 + NULL, NULL, NULL, NULL, LZIP_COMPRESSION, "lzip", 0
413 +#endif
415 #ifndef CONFIG_SQUASHFS_LZO
416 static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
417 NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
418 @@ -78,6 +84,7 @@
419 static const struct squashfs_decompressor *decompressor[] = {
420 &squashfs_zlib_comp_ops,
421 &squashfs_lz4_comp_ops,
422 + &squashfs_lzip_comp_ops,
423 &squashfs_lzo_comp_ops,
424 &squashfs_xz_comp_ops,
425 &squashfs_lzma_unsupported_comp_ops,
426 diff -urdN linux-4.19.8/fs/squashfs/decompressor.h linux-4.19.8.new/fs/squashfs/decompressor.h
427 --- linux-4.19.8/fs/squashfs/decompressor.h 2018-12-08 12:59:10.000000000 +0100
428 +++ linux-4.19.8.new/fs/squashfs/decompressor.h 2018-12-09 18:01:59.000000000 +0100
429 @@ -50,6 +50,10 @@
430 extern const struct squashfs_decompressor squashfs_lz4_comp_ops;
431 #endif
433 +#ifdef CONFIG_SQUASHFS_LZIP
434 +extern const struct squashfs_decompressor squashfs_lzip_comp_ops;
435 +#endif
437 #ifdef CONFIG_SQUASHFS_LZO
438 extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
439 #endif
440 diff -urdN linux-4.19.8/fs/squashfs/lzip_wrapper.c linux-4.19.8.new/fs/squashfs/lzip_wrapper.c
441 --- linux-4.19.8/fs/squashfs/lzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
442 +++ linux-4.19.8.new/fs/squashfs/lzip_wrapper.c 2018-12-09 18:01:59.000000000 +0100
443 @@ -0,0 +1,129 @@
445 + * Squashfs - a compressed read only filesystem for Linux
447 + * Copyright (c) 2014
448 + * Phillip Lougher <phillip@squashfs.org.uk>
449 + * Copyright (C) 2018 Antonio Diaz Diaz
451 + * This program is free software; you can redistribute it and/or
452 + * modify it under the terms of the GNU General Public License
453 + * as published by the Free Software Foundation; either version 2,
454 + * or (at your option) any later version.
456 + * This program is distributed in the hope that it will be useful,
457 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
458 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
459 + * GNU General Public License for more details.
461 + * You should have received a copy of the GNU General Public License
462 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
464 + * lzip_wrapper.c
465 + */
467 +#include <linux/buffer_head.h>
468 +#include <linux/mutex.h>
469 +#include <linux/slab.h>
470 +#include <linux/vmalloc.h>
471 +#include <linux/lzip.h>
473 +#include "squashfs_fs.h"
474 +#include "squashfs_fs_sb.h"
475 +#include "squashfs.h"
476 +#include "decompressor.h"
477 +#include "page_actor.h"
479 +struct squashfs_lzip {
480 + void *input;
481 + void *output;
485 +static void *lzip_init(struct squashfs_sb_info *msblk, void *buff)
487 + int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
488 + struct squashfs_lzip *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
489 + if (stream == NULL)
490 + goto failed;
491 + stream->input = vmalloc(block_size);
492 + if (stream->input == NULL)
493 + goto failed2;
494 + stream->output = vmalloc(block_size);
495 + if (stream->output == NULL)
496 + goto failed3;
498 + return stream;
500 +failed3:
501 + vfree(stream->input);
502 +failed2:
503 + kfree(stream);
504 +failed:
505 + ERROR("Failed to initialise LZIP decompressor\n");
506 + return ERR_PTR(-ENOMEM);
510 +static void lzip_free(void *strm)
512 + struct squashfs_lzip *stream = strm;
514 + if (stream) {
515 + vfree(stream->input);
516 + vfree(stream->output);
518 + kfree(stream);
522 +static int lzip_uncompress(struct squashfs_sb_info *msblk, void *strm,
523 + struct buffer_head **bh, int b, int offset, int length,
524 + struct squashfs_page_actor *output)
526 + struct squashfs_lzip *stream = strm;
527 + void *buff = stream->input, *data;
528 + long out_pos;
529 + int avail, i, bytes = length, res;
531 + for (i = 0; i < b; i++) {
532 + avail = min(bytes, msblk->devblksize - offset);
533 + memcpy(buff, bh[i]->b_data + offset, avail);
534 + buff += avail;
535 + bytes -= avail;
536 + offset = 0;
537 + put_bh(bh[i]);
540 + res = lzip_decompress(stream->input, length, 0, 0, stream->output,
541 + output->length, 0, &out_pos);
542 + if (res < 0) {
543 + ERROR("LZIP error code %d\n", res);
544 + return -EIO;
546 + bytes = out_pos;
547 + data = squashfs_first_page(output);
548 + buff = stream->output;
549 + while (data) {
550 + if (bytes <= PAGE_SIZE) {
551 + memcpy(data, buff, bytes);
552 + break;
554 + memcpy(data, buff, PAGE_SIZE);
555 + buff += PAGE_SIZE;
556 + bytes -= PAGE_SIZE;
557 + data = squashfs_next_page(output);
559 + squashfs_finish_page(output);
561 + return out_pos;
565 +const struct squashfs_decompressor squashfs_lzip_comp_ops = {
566 + .init = lzip_init,
567 + .free = lzip_free,
568 + .decompress = lzip_uncompress,
569 + .id = LZIP_COMPRESSION,
570 + .name = "lzip",
571 + .supported = 1
573 diff -urdN linux-4.19.8/fs/squashfs/squashfs_fs.h linux-4.19.8.new/fs/squashfs/squashfs_fs.h
574 --- linux-4.19.8/fs/squashfs/squashfs_fs.h 2018-12-08 12:59:10.000000000 +0100
575 +++ linux-4.19.8.new/fs/squashfs/squashfs_fs.h 2018-12-09 18:01:59.000000000 +0100
576 @@ -248,6 +248,7 @@
577 #define XZ_COMPRESSION 4
578 #define LZ4_COMPRESSION 5
579 #define ZSTD_COMPRESSION 6
580 +#define LZIP_COMPRESSION 7
582 struct squashfs_super_block {
583 __le32 s_magic;
584 diff -urdN linux-4.19.8/include/linux/decompress/lunzip.h linux-4.19.8.new/include/linux/decompress/lunzip.h
585 --- linux-4.19.8/include/linux/decompress/lunzip.h 1970-01-01 01:00:00.000000000 +0100
586 +++ linux-4.19.8.new/include/linux/decompress/lunzip.h 2018-12-09 18:01:59.000000000 +0100
587 @@ -0,0 +1,11 @@
588 +/* SPDX-License-Identifier: GPL-2.0 */
589 +#ifndef LINUX_DECOMPRESS_LUNZIP_H
590 +#define LINUX_DECOMPRESS_LUNZIP_H
592 +int lunzip(unsigned char *inbuf, long in_len,
593 + long (*fill)(void*, unsigned long),
594 + long (*flush)(void*, unsigned long),
595 + unsigned char *outbuf,
596 + long *in_posp,
597 + void (*error)(char *x));
598 +#endif
599 diff -urdN linux-4.19.8/include/linux/lzip.h linux-4.19.8.new/include/linux/lzip.h
600 --- linux-4.19.8/include/linux/lzip.h 1970-01-01 01:00:00.000000000 +0100
601 +++ linux-4.19.8.new/include/linux/lzip.h 2018-12-09 18:01:59.000000000 +0100
602 @@ -0,0 +1,53 @@
603 +/* SPDX-License-Identifier: GPL-2.0 */
604 +#ifndef __LZIP_H__
605 +#define __LZIP_H__
607 + * LZIP decompressor
609 + * Copyright (C) 2016-2018 Antonio Diaz Diaz.
610 + */
612 +/* Return values (< 0 = Error) */
613 +enum {
614 + LZIP_OOM_INBUF = -1,
615 + LZIP_HEADER1_EOF = -2,
616 + LZIP_HEADER2_EOF = -3,
617 + LZIP_BAD_MAGIC1 = -4,
618 + LZIP_BAD_MAGIC2 = -5,
619 + LZIP_BAD_VERSION = -6,
620 + LZIP_BAD_DICT_SIZE = -7,
621 + LZIP_OOM_OUTBUF = -8,
622 + LZIP_WRITE_ERROR = -9,
623 + LZIP_BAD_DATA = -10,
624 + LZIP_DATA_EOF = -11,
625 + LZIP_BAD_CRC = -12
628 +int lzip_decompress(unsigned char *inbuf, long in_len,
629 + long (*fill)(void*, unsigned long),
630 + long (*flush)(void*, unsigned long),
631 + unsigned char *outbuf, long out_size,
632 + long *in_posp, long *out_posp);
634 +/* inbuf - input buffer. If null or in_len <= 0, fill must be non-null
635 + * in_len - len of pre-read data in inbuf if inbuf is non-null
636 + * fill - if non-null, function to fill inbuf when empty
637 + * flush - if non-null, function to write out outbuf when full
638 + * outbuf - output buffer. If null or out_size <= 0, flush must be non-null
639 + * out_size - size of outbuf if outbuf is non-null
640 + * in_posp - if non-null, the number of bytes consumed will be returned here
641 + * out_posp - if non-null, the number of bytes produced will be returned here
643 + * fill will be called (repeatedly) to read data. in_len bytes will be read
644 + * per call (or 16384 bytes per call if inbuf is null or in_len <= 0).
646 + * If flush is null, outbuf must be large enough to buffer all the expected
647 + * output. Else the flush function will be called to flush the output buffer
648 + * at the appropriate time (stream dependent).
649 + * If out_size > 0 but is not large enough to buffer all the expected output,
650 + * it must be at least as large as the dictionary size of the data.
652 + * inbuf and outbuf may overlap (in-place decompression).
653 + */
655 +#endif
656 diff -urdN linux-4.19.8/init/Kconfig linux-4.19.8.new/init/Kconfig
657 --- linux-4.19.8/init/Kconfig 2018-12-08 12:59:10.000000000 +0100
658 +++ linux-4.19.8.new/init/Kconfig 2018-12-09 19:01:32.000000000 +0100
659 @@ -122,6 +122,9 @@
660 config HAVE_KERNEL_BZIP2
661 bool
663 +config HAVE_KERNEL_LZIP
664 + bool
666 config HAVE_KERNEL_LZMA
667 bool
669 @@ -140,7 +143,7 @@
670 choice
671 prompt "Kernel compression mode"
672 default KERNEL_GZIP
673 - depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4 || HAVE_KERNEL_UNCOMPRESSED
674 + 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
675 help
676 The linux kernel is a kind of self-extracting executable.
677 Several compression algorithms are available, which differ
678 @@ -176,6 +179,15 @@
679 Bzip2 uses a large amount of memory. For modern kernels you
680 will need at least 8MB RAM or more for booting.
682 +config KERNEL_LZIP
683 + bool "Lzip"
684 + depends on HAVE_KERNEL_LZIP
685 + help
686 + Lzip's compression ratio is better than that of gzip and bzip2.
687 + Decompression speed is between gzip and bzip2. Compression can
688 + be as fast as gzip or slower than bzip2 depending on compression
689 + level. Lzip can produce a kernel about a 16% smaller than gzip.
691 config KERNEL_LZMA
692 bool "LZMA"
693 depends on HAVE_KERNEL_LZMA
694 @@ -1919,8 +1931,8 @@
695 depends on MODULES
696 help
698 - Compresses kernel modules when 'make modules_install' is run; gzip or
699 - xz depending on "Compression algorithm" below.
700 + Compresses kernel modules when 'make modules_install' is run; gzip,
701 + lzip or xz are used depending on "Compression algorithm" below.
703 module-init-tools MAY support gzip, and kmod MAY support gzip and xz.
705 @@ -1942,11 +1954,14 @@
706 This determines which sort of compression will be used during
707 'make modules_install'.
709 - GZIP (default) and XZ are supported.
710 + GZIP (default), LZIP and XZ are supported.
712 config MODULE_COMPRESS_GZIP
713 bool "GZIP"
715 +config MODULE_COMPRESS_LZIP
716 + bool "LZIP"
718 config MODULE_COMPRESS_XZ
719 bool "XZ"
721 diff -urdN linux-4.19.8/init/do_mounts_rd.c linux-4.19.8.new/init/do_mounts_rd.c
722 --- linux-4.19.8/init/do_mounts_rd.c 2018-12-08 12:59:10.000000000 +0100
723 +++ linux-4.19.8.new/init/do_mounts_rd.c 2018-12-09 18:01:59.000000000 +0100
724 @@ -49,6 +49,7 @@
725 * squashfs
726 * gzip
727 * bzip2
728 + * lzip
729 * lzma
730 * xz
731 * lzo
732 diff -urdN linux-4.19.8/lib/Kconfig linux-4.19.8.new/lib/Kconfig
733 --- linux-4.19.8/lib/Kconfig 2018-12-08 12:59:10.000000000 +0100
734 +++ linux-4.19.8.new/lib/Kconfig 2018-12-09 18:01:59.000000000 +0100
735 @@ -253,6 +253,12 @@
736 tristate
737 select BITREVERSE
739 +config LZIP_DECOMPRESS
740 + tristate "LZIP decompression support"
741 + help
742 + LZMA compression algorithm is supported using the .lz file format.
743 + See Documentation/lzip.txt for more information.
745 config LZO_COMPRESS
746 tristate
748 @@ -289,6 +295,10 @@
749 config DECOMPRESS_BZIP2
750 tristate
752 +config DECOMPRESS_LZIP
753 + select LZIP_DECOMPRESS
754 + tristate
756 config DECOMPRESS_LZMA
757 tristate
759 diff -urdN linux-4.19.8/lib/Makefile linux-4.19.8.new/lib/Makefile
760 --- linux-4.19.8/lib/Makefile 2018-12-08 12:59:10.000000000 +0100
761 +++ linux-4.19.8.new/lib/Makefile 2018-12-09 18:01:59.000000000 +0100
762 @@ -119,6 +119,7 @@
763 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
764 obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
765 obj-$(CONFIG_BCH) += bch.o
766 +obj-$(CONFIG_LZIP_DECOMPRESS) += lzip_decompress.o
767 obj-$(CONFIG_LZO_COMPRESS) += lzo/
768 obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
769 obj-$(CONFIG_LZ4_COMPRESS) += lz4/
770 @@ -131,6 +132,7 @@
772 lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
773 lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
774 +lib-$(CONFIG_DECOMPRESS_LZIP) += decompress_lunzip.o
775 lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
776 lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
777 lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
778 diff -urdN linux-4.19.8/lib/decompress.c linux-4.19.8.new/lib/decompress.c
779 --- linux-4.19.8/lib/decompress.c 2018-12-08 12:59:10.000000000 +0100
780 +++ linux-4.19.8.new/lib/decompress.c 2018-12-09 18:01:59.000000000 +0100
781 @@ -8,6 +8,7 @@
782 #include <linux/decompress/generic.h>
784 #include <linux/decompress/bunzip2.h>
785 +#include <linux/decompress/lunzip.h>
786 #include <linux/decompress/unlzma.h>
787 #include <linux/decompress/unxz.h>
788 #include <linux/decompress/inflate.h>
789 @@ -25,6 +26,9 @@
790 #ifndef CONFIG_DECOMPRESS_BZIP2
791 # define bunzip2 NULL
792 #endif
793 +#ifndef CONFIG_DECOMPRESS_LZIP
794 +# define lunzip NULL
795 +#endif
796 #ifndef CONFIG_DECOMPRESS_LZMA
797 # define unlzma NULL
798 #endif
799 @@ -48,6 +52,7 @@
800 { {0x1f, 0x8b}, "gzip", gunzip },
801 { {0x1f, 0x9e}, "gzip", gunzip },
802 { {0x42, 0x5a}, "bzip2", bunzip2 },
803 + { {0x4c, 0x5a}, "lzip", lunzip },
804 { {0x5d, 0x00}, "lzma", unlzma },
805 { {0xfd, 0x37}, "xz", unxz },
806 { {0x89, 0x4c}, "lzo", unlzo },
807 diff -urdN linux-4.19.8/lib/decompress_lunzip.c linux-4.19.8.new/lib/decompress_lunzip.c
808 --- linux-4.19.8/lib/decompress_lunzip.c 1970-01-01 01:00:00.000000000 +0100
809 +++ linux-4.19.8.new/lib/decompress_lunzip.c 2018-12-09 18:01:59.000000000 +0100
810 @@ -0,0 +1,100 @@
812 + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
814 + * Copyright (C) 2016-2018 Antonio Diaz Diaz.
816 + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
817 + */
819 +#ifdef STATIC
820 +#define PREBOOT
821 +#include "lzip_decompress.c"
822 +#else
823 +#include <linux/lzip.h>
824 +#include <linux/decompress/lunzip.h>
825 +#include <linux/decompress/mm.h>
826 +#endif
828 +STATIC int INIT __lunzip(unsigned char *inbuf, long in_len,
829 + long (*fill)(void*, unsigned long),
830 + long (*flush)(void*, unsigned long),
831 + unsigned char *outbuf, long out_size,
832 + long *in_posp, long *out_posp,
833 + void (*error)(char *x))
835 + const int retval = lzip_decompress(inbuf, in_len, fill, flush,
836 + outbuf, out_size, in_posp, out_posp);
837 + switch (retval) {
838 + case 0: break;
839 + case LZIP_OOM_INBUF:
840 + error("Out of memory while allocating input buffer.");
841 + break;
842 + case LZIP_HEADER1_EOF:
843 + error("File ends unexpectedly at member header.");
844 + break;
845 + case LZIP_HEADER2_EOF:
846 + error("Truncated header in multimember file.");
847 + break;
848 + case LZIP_BAD_MAGIC1:
849 + error("Bad magic number (file not in lzip format).");
850 + break;
851 + case LZIP_BAD_MAGIC2:
852 + error("Corrupt header in multimember file.");
853 + break;
854 + case LZIP_BAD_VERSION:
855 + error("Version of lzip member format not supported.");
856 + break;
857 + case LZIP_BAD_DICT_SIZE:
858 + error("Invalid dictionary size in member header.");
859 + break;
860 + case LZIP_OOM_OUTBUF:
861 + error("Out of memory while allocating output buffer.");
862 + break;
863 + case LZIP_WRITE_ERROR:
864 + error("Write error.");
865 + break;
866 + case LZIP_BAD_DATA:
867 + error("LZIP-compressed data is corrupt.");
868 + break;
869 + case LZIP_DATA_EOF:
870 + error("LZIP-compressed data ends unexpectedly.");
871 + break;
872 + case LZIP_BAD_CRC:
873 + error("CRC mismatch in LZIP-compressed data.");
874 + break;
875 + default:
876 + error("Bug in the LZIP decompressor.");
878 + return retval;
881 +#ifndef PREBOOT
882 +/* decompress_fn (see include/linux/decompress/generic.h) should have an
883 + * out_size argument to prevent overflowing outbuf in case of corruption
884 + * of the compressed data.
885 + */
886 +STATIC int INIT lunzip(unsigned char *inbuf, long in_len,
887 + long (*fill)(void*, unsigned long),
888 + long (*flush)(void*, unsigned long),
889 + unsigned char *outbuf,
890 + long *in_posp,
891 + void (*error)(char *x))
893 + return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX,
894 + in_posp, 0, error);
896 +#else
897 +STATIC int INIT __decompress(unsigned char *inbuf, long in_len,
898 + long (*fill)(void*, unsigned long),
899 + long (*flush)(void*, unsigned long),
900 + unsigned char *outbuf, long out_size,
901 + long *in_posp,
902 + void (*error)(char *x))
904 +/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe
905 + * in case of corruption of the compressed data.
906 + */
907 + return __lunzip(inbuf, in_len - 4, fill, flush, outbuf,
908 + out_size ? out_size : LONG_MAX, in_posp, 0, error);
910 +#endif
911 diff -urdN linux-4.19.8/lib/lzip_decompress.c linux-4.19.8.new/lib/lzip_decompress.c
912 --- linux-4.19.8/lib/lzip_decompress.c 1970-01-01 01:00:00.000000000 +0100
913 +++ linux-4.19.8.new/lib/lzip_decompress.c 2018-12-09 18:01:59.000000000 +0100
914 @@ -0,0 +1,882 @@
916 + * LZIP decompressor
918 + * Copyright (C) 2016-2018 Antonio Diaz Diaz.
920 + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
921 + */
923 +#include <linux/module.h>
924 +#include <linux/lzip.h>
925 +#include <linux/decompress/mm.h>
928 + * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
929 + * See include/linux/decompress/mm.h for details.
930 + */
931 +#ifndef STATIC_RW_DATA
932 +#define STATIC_RW_DATA static
933 +#endif
935 +typedef int State;
937 +enum { states = 12 };
939 +static inline bool St_is_char(const State st) { return st < 7; }
941 +static inline State St_set_char(const State st)
943 + STATIC_RW_DATA const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
944 + return next[st];
947 +static inline State St_set_match(const State st)
949 + return ((st < 7) ? 7 : 10);
952 +static inline State St_set_rep(const State st)
954 + return ((st < 7) ? 8 : 11);
957 +static inline State St_set_short_rep(const State st)
959 + return ((st < 7) ? 9 : 11);
963 +enum {
964 + min_dictionary_bits = 12,
965 + min_dictionary_size = 1 << min_dictionary_bits,
966 + max_dictionary_bits = 29,
967 + max_dictionary_size = 1 << max_dictionary_bits,
968 + literal_context_bits = 3,
969 + pos_state_bits = 2,
970 + pos_states = 1 << pos_state_bits,
971 + pos_state_mask = pos_states - 1,
973 + len_states = 4,
974 + dis_slot_bits = 6,
975 + start_dis_model = 4,
976 + end_dis_model = 14,
977 + modeled_distances = 1 << (end_dis_model / 2), /* 128 */
978 + dis_align_bits = 4,
979 + dis_align_size = 1 << dis_align_bits,
981 + len_low_bits = 3,
982 + len_mid_bits = 3,
983 + len_high_bits = 8,
984 + len_low_symbols = 1 << len_low_bits,
985 + len_mid_symbols = 1 << len_mid_bits,
986 + len_high_symbols = 1 << len_high_bits,
987 + max_len_symbols = len_low_symbols + len_mid_symbols + len_high_symbols,
989 + min_match_len = 2, /* must be 2 */
990 + max_match_len = min_match_len + max_len_symbols - 1, /* 273 */
991 + min_match_len_limit = 5
994 +static inline int get_len_state(const int len)
996 + return min(len - min_match_len, len_states - 1);
999 +static inline int get_lit_state(const uint8_t prev_byte)
1001 + return (prev_byte >> (8 - literal_context_bits));
1005 +enum { bit_model_move_bits = 5,
1006 + bit_model_total_bits = 11,
1007 + bit_model_total = 1 << bit_model_total_bits
1010 +typedef int Bit_model;
1012 +static inline void Bm_init(Bit_model * const probability)
1014 + *probability = bit_model_total / 2;
1017 +static inline void Bm_array_init(Bit_model bm[], const int size)
1019 + int i;
1021 + for (i = 0; i < size; ++i)
1022 + Bm_init(&bm[i]);
1025 +struct Len_model {
1026 + Bit_model choice1;
1027 + Bit_model choice2;
1028 + Bit_model bm_low[pos_states][len_low_symbols];
1029 + Bit_model bm_mid[pos_states][len_mid_symbols];
1030 + Bit_model bm_high[len_high_symbols];
1033 +static inline void Lm_init(struct Len_model * const lm)
1035 + Bm_init(&lm->choice1);
1036 + Bm_init(&lm->choice2);
1037 + Bm_array_init(lm->bm_low[0], pos_states * len_low_symbols);
1038 + Bm_array_init(lm->bm_mid[0], pos_states * len_mid_symbols);
1039 + Bm_array_init(lm->bm_high, len_high_symbols);
1043 +/* Table of CRCs of all 8-bit messages. */
1044 +STATIC_RW_DATA const uint32_t crc32[256] =
1046 + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
1047 + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
1048 + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
1049 + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
1050 + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
1051 + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
1052 + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
1053 + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
1054 + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
1055 + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
1056 + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
1057 + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
1058 + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
1059 + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
1060 + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
1061 + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
1062 + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1063 + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
1064 + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
1065 + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
1066 + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1067 + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
1068 + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
1069 + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
1070 + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1071 + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
1072 + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
1073 + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
1074 + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1075 + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
1076 + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
1077 + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1078 + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1079 + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
1080 + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
1081 + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1082 + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1083 + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
1084 + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
1085 + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1086 + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1087 + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
1088 + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
1091 +static inline void CRC32_update_buf(uint32_t * const crc,
1092 + const uint8_t * const buffer,
1093 + const long size)
1095 + long i;
1096 + uint32_t c = *crc;
1098 + for (i = 0; i < size; ++i)
1099 + c = crc32[(c^buffer[i])&0xFF] ^ (c >> 8);
1100 + *crc = c;
1104 +STATIC_RW_DATA const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
1106 +typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
1107 + /* 4 version */
1108 + /* 5 coded_dict_size */
1109 +enum { Lh_size = 6 };
1111 +static inline bool Lh_verify_magic(const Lzip_header data)
1113 + int i;
1115 + for (i = 0; i < 4; ++i)
1116 + if (data[i] != lzip_magic[i])
1117 + return false;
1118 + return true;
1121 +/* detect (truncated) header */
1122 +static inline bool Lh_verify_prefix(const Lzip_header data, const int sz)
1124 + int i;
1125 + for (i = 0; i < sz && i < 4; ++i)
1126 + if (data[i] != lzip_magic[i])
1127 + return false;
1128 + return (sz > 0);
1131 +/* detect corrupt header */
1132 +static inline bool Lh_verify_corrupt(const Lzip_header data)
1134 + int matches = 0;
1135 + int i;
1136 + for (i = 0; i < 4; ++i)
1137 + if (data[i] == lzip_magic[i])
1138 + ++matches;
1139 + return (matches > 1 && matches < 4);
1142 +static inline bool Lh_verify_version(const Lzip_header data)
1144 + return (data[4] == 1);
1147 +static inline unsigned Lh_get_dictionary_size(const Lzip_header data)
1149 + unsigned sz = (1 << (data[5] & 0x1F));
1151 + if (sz > min_dictionary_size)
1152 + sz -= (sz / 16) * ((data[5] >> 5) & 7);
1153 + return sz;
1157 +typedef uint8_t Lzip_trailer[20];
1158 + /* 0-3 CRC32 of the uncompressed data */
1159 + /* 4-11 size of the uncompressed data */
1160 + /* 12-19 member size including header and trailer */
1161 +enum { Lt_size = 20 };
1163 +static inline unsigned Lt_get_data_crc(const Lzip_trailer data)
1165 + unsigned tmp = 0;
1166 + int i;
1168 + for (i = 3; i >= 0; --i) {
1169 + tmp <<= 8;
1170 + tmp += data[i];
1172 + return tmp;
1175 +static inline unsigned long long Lt_get_data_size(const Lzip_trailer data)
1177 + unsigned long long tmp = 0;
1178 + int i;
1180 + for (i = 11; i >= 4; --i) {
1181 + tmp <<= 8;
1182 + tmp += data[i];
1184 + return tmp;
1187 +static inline unsigned long long Lt_get_member_size(const Lzip_trailer data)
1189 + unsigned long long tmp = 0;
1190 + int i;
1192 + for (i = 19; i >= 12; --i) {
1193 + tmp <<= 8;
1194 + tmp += data[i];
1196 + return tmp;
1200 +struct Range_decoder {
1201 + unsigned long long partial_member_pos;
1202 + uint8_t *buffer; /* input buffer */
1203 + long buffer_size;
1204 + long pos; /* current pos in buffer */
1205 + long stream_pos; /* when reached, a new block must be read */
1206 + uint32_t code;
1207 + uint32_t range;
1208 + long (*fill)(void*, unsigned long);
1209 + bool at_stream_end;
1210 + bool buffer_given;
1214 +static bool Rd_read_block(struct Range_decoder * const rdec)
1216 + if (!rdec->at_stream_end) {
1217 + rdec->stream_pos = rdec->fill ?
1218 + rdec->fill(rdec->buffer, rdec->buffer_size) : 0;
1219 + rdec->at_stream_end = (rdec->stream_pos < rdec->buffer_size);
1220 + rdec->partial_member_pos += rdec->pos;
1221 + rdec->pos = 0;
1223 + return rdec->pos < rdec->stream_pos;
1227 +static inline bool Rd_init(struct Range_decoder * const rdec,
1228 + uint8_t * const inbuf, const long in_len,
1229 + long (*fill)(void*, unsigned long))
1231 + rdec->partial_member_pos = 0;
1232 + rdec->buffer_given = (inbuf && in_len > 0);
1233 + rdec->buffer_size = rdec->buffer_given ? in_len : 16384;
1234 + rdec->buffer = rdec->buffer_given ? inbuf : malloc(rdec->buffer_size);
1235 + if (!rdec->buffer)
1236 + return false;
1237 + rdec->pos = 0;
1238 + rdec->stream_pos = rdec->buffer_given ? in_len : 0;
1239 + rdec->code = 0;
1240 + rdec->range = 0xFFFFFFFFU;
1241 + rdec->fill = fill;
1242 + rdec->at_stream_end = false;
1243 + return true;
1246 +static inline void Rd_free(struct Range_decoder * const rdec)
1248 + if (!rdec->buffer_given)
1249 + free(rdec->buffer);
1252 +static inline bool Rd_finished(struct Range_decoder * const rdec)
1254 + return rdec->pos >= rdec->stream_pos && !Rd_read_block(rdec);
1257 +static inline unsigned long long
1258 +Rd_member_position(const struct Range_decoder * const rdec)
1260 + return rdec->partial_member_pos + rdec->pos;
1263 +static inline void Rd_reset_member_position(struct Range_decoder * const rdec)
1265 + rdec->partial_member_pos = 0; rdec->partial_member_pos -= rdec->pos;
1268 +static inline uint8_t Rd_get_byte(struct Range_decoder * const rdec)
1270 + /* 0xFF avoids decoder error if member is truncated at EOS marker */
1271 + if (Rd_finished(rdec))
1272 + return 0xFF;
1273 + return rdec->buffer[rdec->pos++];
1276 +static inline void Rd_load(struct Range_decoder * const rdec)
1278 + int i;
1280 + rdec->code = 0;
1281 + for (i = 0; i < 5; ++i)
1282 + rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
1283 + rdec->range = 0xFFFFFFFFU;
1286 +static inline void Rd_normalize(struct Range_decoder * const rdec)
1288 + if (rdec->range <= 0x00FFFFFFU) {
1289 + rdec->range <<= 8;
1290 + rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
1294 +static inline unsigned Rd_decode(struct Range_decoder * const rdec,
1295 + const int num_bits)
1297 + unsigned symbol = 0;
1298 + int i;
1300 + for (i = num_bits; i > 0; --i) {
1301 + bool bit;
1303 + Rd_normalize(rdec);
1304 + rdec->range >>= 1;
1305 + /* symbol <<= 1; */
1306 + /* if(rdec->code >= rdec->range) { rdec->code -= rdec->range; symbol |= 1; } */
1307 + bit = (rdec->code >= rdec->range);
1308 + symbol = (symbol << 1) + bit;
1309 + rdec->code -= rdec->range & (0U - bit);
1311 + return symbol;
1314 +static inline unsigned Rd_decode_bit(struct Range_decoder * const rdec,
1315 + Bit_model * const probability)
1317 + uint32_t bound;
1319 + Rd_normalize(rdec);
1320 + bound = (rdec->range >> bit_model_total_bits) * *probability;
1321 + if (rdec->code < bound) {
1322 + rdec->range = bound;
1323 + *probability += (bit_model_total - *probability) >> bit_model_move_bits;
1324 + return 0;
1325 + } else {
1326 + rdec->range -= bound;
1327 + rdec->code -= bound;
1328 + *probability -= *probability >> bit_model_move_bits;
1329 + return 1;
1333 +static inline unsigned Rd_decode_tree3(struct Range_decoder * const rdec,
1334 + Bit_model bm[])
1336 + unsigned symbol = 1;
1338 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1339 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1340 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1341 + return symbol & 7;
1344 +static inline unsigned Rd_decode_tree6(struct Range_decoder * const rdec,
1345 + Bit_model bm[])
1347 + unsigned symbol = 1;
1349 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1350 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1351 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1352 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1353 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1354 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1355 + return symbol & 0x3F;
1358 +static inline unsigned Rd_decode_tree8(struct Range_decoder * const rdec,
1359 + Bit_model bm[])
1361 + unsigned symbol = 1;
1362 + int i;
1364 + for (i = 0; i < 8; ++i)
1365 + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
1366 + return symbol & 0xFF;
1369 +static inline unsigned
1370 +Rd_decode_tree_reversed(struct Range_decoder * const rdec,
1371 + Bit_model bm[], const int num_bits)
1373 + unsigned model = 1;
1374 + unsigned symbol = 0;
1375 + int i;
1377 + for (i = 0; i < num_bits; ++i) {
1378 + const unsigned bit = Rd_decode_bit(rdec, &bm[model]);
1380 + model = (model << 1) + bit;
1381 + symbol |= (bit << i);
1383 + return symbol;
1386 +static inline unsigned
1387 +Rd_decode_tree_reversed4(struct Range_decoder * const rdec, Bit_model bm[])
1389 + unsigned symbol = Rd_decode_bit(rdec, &bm[1]);
1390 + unsigned model = 2 + symbol;
1391 + unsigned bit = Rd_decode_bit(rdec, &bm[model]);
1393 + model = (model << 1) + bit; symbol |= (bit << 1);
1394 + bit = Rd_decode_bit(rdec, &bm[model]);
1395 + model = (model << 1) + bit; symbol |= (bit << 2);
1396 + symbol |= (Rd_decode_bit(rdec, &bm[model]) << 3);
1397 + return symbol;
1400 +static inline unsigned Rd_decode_matched(struct Range_decoder * const rdec,
1401 + Bit_model bm[], unsigned match_byte)
1403 + unsigned symbol = 1;
1404 + unsigned mask = 0x100;
1406 + while (true) {
1407 + const unsigned match_bit = (match_byte <<= 1) & mask;
1408 + const unsigned bit = Rd_decode_bit(rdec, &bm[symbol+match_bit+mask]);
1410 + symbol = (symbol << 1) + bit;
1411 + if (symbol > 0xFF)
1412 + return symbol & 0xFF;
1413 + mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
1417 +static inline unsigned Rd_decode_len(struct Range_decoder * const rdec,
1418 + struct Len_model * const lm,
1419 + const int pos_state)
1421 + if (Rd_decode_bit(rdec, &lm->choice1) == 0)
1422 + return Rd_decode_tree3(rdec, lm->bm_low[pos_state]);
1423 + if (Rd_decode_bit(rdec, &lm->choice2) == 0)
1424 + return len_low_symbols +
1425 + Rd_decode_tree3(rdec, lm->bm_mid[pos_state]);
1426 + return len_low_symbols + len_mid_symbols +
1427 + Rd_decode_tree8(rdec, lm->bm_high);
1431 +struct LZ_decoder {
1432 + unsigned long long partial_data_pos;
1433 + struct Range_decoder *rdec;
1434 + /* Don't move bm_* to LZd_decode_member; makes frame too large. */
1435 + Bit_model bm_literal[1 << literal_context_bits][0x300];
1436 + Bit_model bm_match[states][pos_states];
1437 + Bit_model bm_rep[states];
1438 + Bit_model bm_rep0[states];
1439 + Bit_model bm_rep1[states];
1440 + Bit_model bm_rep2[states];
1441 + Bit_model bm_len[states][pos_states];
1442 + Bit_model bm_dis_slot[len_states][1 << dis_slot_bits];
1443 + Bit_model bm_dis[modeled_distances-end_dis_model+1];
1444 + Bit_model bm_align[dis_align_size];
1445 + struct Len_model match_len_model;
1446 + struct Len_model rep_len_model;
1448 + unsigned long buffer_size;
1449 + unsigned dictionary_size;
1450 + uint8_t *buffer; /* output buffer */
1451 + unsigned long pos; /* current pos in buffer */
1452 + unsigned long stream_pos; /* first byte not yet written to file */
1453 + uint32_t crc;
1454 + long (*flush)(void*, unsigned long);
1455 + bool pos_wrapped;
1456 + bool buffer_given;
1457 + bool write_error;
1460 +static void LZd_flush_data(struct LZ_decoder * const d)
1462 + if (d->pos > d->stream_pos) {
1463 + const long size = d->pos - d->stream_pos;
1465 + CRC32_update_buf(&d->crc, d->buffer + d->stream_pos, size);
1466 + if ((d->flush &&
1467 + d->flush(d->buffer + d->stream_pos, size) != size) ||
1468 + (!d->flush && d->pos_wrapped))
1469 + d->write_error = true;
1470 + if (d->pos >= d->buffer_size) {
1471 + d->partial_data_pos += d->pos;
1472 + d->pos = 0;
1473 + d->pos_wrapped = true;
1475 + d->stream_pos = d->pos;
1479 +static inline uint8_t LZd_peek_prev(const struct LZ_decoder * const d)
1481 + if (d->pos > 0)
1482 + return d->buffer[d->pos-1];
1483 + if (d->pos_wrapped)
1484 + return d->buffer[d->buffer_size-1];
1485 + return 0; /* prev_byte of first byte */
1488 +static inline uint8_t LZd_peek(const struct LZ_decoder * const d,
1489 + const unsigned distance)
1491 + const unsigned long i = ((d->pos > distance) ? 0 : d->buffer_size) +
1492 + d->pos - distance - 1;
1493 + return d->buffer[i];
1496 +static inline void LZd_put_byte(struct LZ_decoder * const d, const uint8_t b)
1498 + d->buffer[d->pos] = b;
1499 + if (++d->pos >= d->buffer_size)
1500 + LZd_flush_data(d);
1503 +static inline void LZd_copy_block(struct LZ_decoder * const d,
1504 + const unsigned distance, unsigned len)
1506 + unsigned long lpos = d->pos, i = lpos - distance - 1;
1507 + bool fast, fast2;
1509 + if (lpos > distance) {
1510 + fast = (len < d->buffer_size - lpos);
1511 + fast2 = (fast && len <= lpos - i);
1512 + } else {
1513 + i += d->buffer_size;
1514 + fast = (len < d->buffer_size - i); /* (i == pos) may happen */
1515 + fast2 = (fast && len <= i - lpos);
1517 + if (fast) { /* no wrap */
1518 + d->pos += len;
1519 + if (fast2) /* no wrap, no overlap */
1520 + memcpy(d->buffer + lpos, d->buffer + i, len);
1521 + else
1522 + for (; len > 0; --len)
1523 + d->buffer[lpos++] = d->buffer[i++];
1524 + } else
1525 + for (; len > 0; --len) {
1526 + d->buffer[d->pos] = d->buffer[i];
1527 + if (++d->pos >= d->buffer_size)
1528 + LZd_flush_data(d);
1529 + if (++i >= d->buffer_size)
1530 + i = 0;
1534 +static inline bool LZd_init(struct LZ_decoder * const d,
1535 + struct Range_decoder * const rde,
1536 + const unsigned dict_size, uint8_t * const outbuf,
1537 + long out_size, long (*flush)(void*, unsigned long))
1539 + d->partial_data_pos = 0;
1540 + d->rdec = rde;
1541 + Bm_array_init(d->bm_literal[0], (1 << literal_context_bits) * 0x300);
1542 + Bm_array_init(d->bm_match[0], states * pos_states);
1543 + Bm_array_init(d->bm_rep, states);
1544 + Bm_array_init(d->bm_rep0, states);
1545 + Bm_array_init(d->bm_rep1, states);
1546 + Bm_array_init(d->bm_rep2, states);
1547 + Bm_array_init(d->bm_len[0], states * pos_states);
1548 + Bm_array_init(d->bm_dis_slot[0], len_states * (1 << dis_slot_bits));
1549 + Bm_array_init(d->bm_dis, modeled_distances - end_dis_model + 1);
1550 + Bm_array_init(d->bm_align, dis_align_size);
1551 + Lm_init(&d->match_len_model);
1552 + Lm_init(&d->rep_len_model);
1554 + d->buffer_given = (outbuf && out_size > 0);
1555 + d->buffer_size = d->buffer_given ? (unsigned long)out_size : dict_size;
1556 + d->dictionary_size = min_t(unsigned long, d->buffer_size, dict_size);
1557 + d->buffer = d->buffer_given ? outbuf : large_malloc(d->buffer_size);
1558 + if (!d->buffer)
1559 + return false;
1560 + d->pos = 0;
1561 + d->stream_pos = 0;
1562 + d->crc = 0xFFFFFFFFU;
1563 + d->flush = flush;
1564 + d->pos_wrapped = false;
1565 + d->write_error = false;
1566 + /* prev_byte of first byte; also for LZd_peek( 0 ) on corrupt file */
1567 + if (!d->buffer_given) /* inbuf and outbuf may overlap */
1568 + d->buffer[d->buffer_size-1] = 0;
1569 + return true;
1572 +static inline void LZd_free(struct LZ_decoder * const d)
1574 + if (!d->buffer_given)
1575 + large_free(d->buffer);
1578 +static inline unsigned LZd_crc(const struct LZ_decoder * const d)
1580 + return d->crc ^ 0xFFFFFFFFU;
1583 +static inline unsigned long long
1584 +LZd_data_position(const struct LZ_decoder * const d)
1586 + return d->partial_data_pos + d->pos;
1590 +static bool LZd_verify_trailer(struct LZ_decoder * const d)
1592 + Lzip_trailer trailer;
1593 + int i = 0;
1595 + while (i < Lt_size)
1596 + trailer[i++] = Rd_get_byte(d->rdec);
1598 + return (Lt_get_data_crc(trailer) == LZd_crc(d) &&
1599 + Lt_get_data_size(trailer) == LZd_data_position(d) &&
1600 + Lt_get_member_size(trailer) == Rd_member_position(d->rdec));
1604 +/* Return value: 0 = OK, < 0 = error (see include/linux/lzip.h). */
1605 +static int LZd_decode_member(struct LZ_decoder * const d)
1607 + struct Range_decoder * const rdec = d->rdec;
1608 + unsigned rep0 = 0; /* rep[0-3] latest four distances */
1609 + unsigned rep1 = 0; /* used for efficient coding of */
1610 + unsigned rep2 = 0; /* repeated distances */
1611 + unsigned rep3 = 0;
1612 + State state = 0;
1614 + Rd_load(rdec);
1615 + while (!Rd_finished(rdec)) {
1616 + int len;
1617 + const int pos_state = LZd_data_position(d) & pos_state_mask;
1619 + if (Rd_decode_bit(rdec, &d->bm_match[state][pos_state]) == 0) {
1620 + /* literal byte */
1621 + Bit_model * const bm = d->bm_literal[get_lit_state(LZd_peek_prev(d))];
1623 + if (St_is_char(state)) {
1624 + state -= (state < 4) ? state : 3;
1625 + LZd_put_byte(d, Rd_decode_tree8(rdec, bm));
1626 + } else {
1627 + state -= (state < 10) ? 3 : 6;
1628 + LZd_put_byte(d, Rd_decode_matched(rdec, bm, LZd_peek(d, rep0)));
1630 + continue;
1632 + /* match or repeated match */
1633 + if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) {
1634 + if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) {
1635 + if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) {
1636 + state = St_set_short_rep(state);
1637 + LZd_put_byte(d, LZd_peek(d, rep0));
1638 + continue;
1640 + } else {
1641 + unsigned distance;
1643 + if (Rd_decode_bit(rdec, &d->bm_rep1[state]) == 0)
1644 + distance = rep1;
1645 + else {
1646 + if (Rd_decode_bit(rdec, &d->bm_rep2[state]) == 0)
1647 + distance = rep2;
1648 + else {
1649 + distance = rep3;
1650 + rep3 = rep2;
1652 + rep2 = rep1;
1654 + rep1 = rep0;
1655 + rep0 = distance;
1657 + state = St_set_rep(state);
1658 + len = min_match_len + Rd_decode_len(rdec, &d->rep_len_model, pos_state);
1659 + } else { /* match */
1660 + unsigned distance;
1662 + len = min_match_len + Rd_decode_len(rdec, &d->match_len_model, pos_state);
1663 + distance = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]);
1664 + if (distance >= start_dis_model) {
1665 + const unsigned dis_slot = distance;
1666 + const int direct_bits = (dis_slot >> 1) - 1;
1668 + distance = (2 | (dis_slot & 1)) << direct_bits;
1669 + if (dis_slot < end_dis_model)
1670 + distance += Rd_decode_tree_reversed(rdec,
1671 + d->bm_dis + (distance - dis_slot), direct_bits);
1672 + else {
1673 + distance +=
1674 + Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits;
1675 + distance += Rd_decode_tree_reversed4(rdec, d->bm_align);
1676 + if (distance == 0xFFFFFFFFU) { /* marker found */
1677 + Rd_normalize(rdec);
1678 + LZd_flush_data(d);
1679 + if (d->write_error)
1680 + return LZIP_WRITE_ERROR;
1681 + if (len == min_match_len) { /* End Of Stream marker */
1682 + if (LZd_verify_trailer(d))
1683 + return 0;
1684 + else
1685 + return LZIP_BAD_CRC;
1687 + if (len == min_match_len + 1) { /* Sync Flush marker */
1688 + Rd_load(rdec);
1689 + continue;
1691 + return LZIP_BAD_DATA; /* unknown marker */
1695 + rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
1696 + state = St_set_match(state);
1697 + if (rep0 >= d->dictionary_size ||
1698 + (rep0 >= d->pos && !d->pos_wrapped)) {
1699 + LZd_flush_data(d);
1700 + return LZIP_BAD_DATA;
1703 + LZd_copy_block(d, rep0, len);
1705 + LZd_flush_data(d);
1706 + return LZIP_DATA_EOF;
1710 +int lzip_decompress(unsigned char *inbuf, long in_len,
1711 + long (*fill)(void*, unsigned long),
1712 + long (*flush)(void*, unsigned long),
1713 + unsigned char *outbuf, long out_size,
1714 + long *in_posp, long *out_posp)
1716 + unsigned char *outptr = outbuf;
1717 + struct Range_decoder rdec;
1718 + struct LZ_decoder *decoder = 0;
1719 + int retval = 0;
1720 + bool first_member;
1722 + if (in_posp)
1723 + *in_posp = 0;
1724 + if (out_posp)
1725 + *out_posp = 0;
1727 + if (!Rd_init(&rdec, inbuf, in_len, fill))
1728 + return LZIP_OOM_INBUF;
1730 + for (first_member = true;; first_member = false) {
1731 + long data_pos;
1732 + int size;
1733 + unsigned dictionary_size;
1734 + Lzip_header header;
1736 + Rd_reset_member_position(&rdec);
1737 + for (size = 0; size < Lh_size && !Rd_finished(&rdec); ++size)
1738 + header[size] = Rd_get_byte(&rdec);
1739 + if (Rd_finished(&rdec)) { /* End Of File */
1740 + if (first_member)
1741 + retval = LZIP_HEADER1_EOF;
1742 + else if (Lh_verify_prefix(header, size))
1743 + retval = LZIP_HEADER2_EOF;
1744 + break;
1746 + if (!Lh_verify_magic(header)) {
1747 + if (first_member)
1748 + retval = LZIP_BAD_MAGIC1;
1749 + else if (Lh_verify_corrupt(header))
1750 + retval = LZIP_BAD_MAGIC2;
1751 + break;
1753 + if (!Lh_verify_version(header)) {
1754 + retval = LZIP_BAD_VERSION;
1755 + break;
1757 + dictionary_size = Lh_get_dictionary_size(header);
1758 + if (dictionary_size < min_dictionary_size ||
1759 + dictionary_size > max_dictionary_size) {
1760 + retval = LZIP_BAD_DICT_SIZE;
1761 + break;
1764 + if (!decoder)
1765 + decoder = malloc(sizeof *decoder);
1766 + if (!decoder || !LZd_init(decoder, &rdec, dictionary_size,
1767 + outptr, out_size, flush)) {
1768 + retval = LZIP_OOM_OUTBUF;
1769 + break;
1771 + retval = LZd_decode_member(decoder);
1772 + if (in_posp)
1773 + *in_posp += Rd_member_position(&rdec);
1774 + data_pos = LZd_data_position(decoder);
1775 + if (outptr)
1776 + outptr += data_pos;
1777 + if (out_posp)
1778 + *out_posp += data_pos;
1779 + if (out_size > 0)
1780 + out_size -= data_pos;
1781 + LZd_free(decoder);
1782 + if (retval != 0)
1783 + break;
1785 + if (decoder)
1786 + free(decoder);
1787 + Rd_free(&rdec);
1788 + return retval;
1791 +#ifndef STATIC
1792 +EXPORT_SYMBOL_GPL(lzip_decompress);
1793 +#endif
1794 +MODULE_DESCRIPTION("LZIP Decompressor");
1795 +MODULE_AUTHOR("Antonio Diaz Diaz <antonio@gnu.org>");
1796 +MODULE_LICENSE("GPL");
1797 diff -urdN linux-4.19.8/scripts/Makefile.lib linux-4.19.8.new/scripts/Makefile.lib
1798 --- linux-4.19.8/scripts/Makefile.lib 2018-12-08 12:59:10.000000000 +0100
1799 +++ linux-4.19.8.new/scripts/Makefile.lib 2018-12-09 18:01:59.000000000 +0100
1800 @@ -319,6 +319,21 @@
1801 bzip2 -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
1802 (rm -f $@ ; false)
1804 +# Lzip
1805 +# ---------------------------------------------------------------------------
1806 +# The .lz format has the uncompressed size available at the end of the
1807 +# file, but at offset (member_size - 16). So we append a gzip-style size.
1808 +# Use klzip to compress the kernel image and lzip to compress other things.
1810 +quiet_cmd_klzip = LZIP $@
1811 +cmd_klzip = (cat $(filter-out FORCE,$^) | \
1812 + lzip -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
1813 + (rm -f $@ ; false)
1815 +quiet_cmd_lzip = LZIP $@
1816 +cmd_lzip = (cat $(filter-out FORCE,$^) | lzip -9) > $@ || \
1817 + (rm -f $@ ; false)
1819 # Lzma
1820 # ---------------------------------------------------------------------------
1822 diff -urdN linux-4.19.8/scripts/extract-ikconfig linux-4.19.8.new/scripts/extract-ikconfig
1823 --- linux-4.19.8/scripts/extract-ikconfig 2018-12-08 12:59:10.000000000 +0100
1824 +++ linux-4.19.8.new/scripts/extract-ikconfig 2018-12-09 18:01:59.000000000 +0100
1825 @@ -59,6 +59,7 @@
1826 try_decompress '\037\213\010' xy gunzip
1827 try_decompress '\3757zXZ\000' abcde unxz
1828 try_decompress 'BZh' xy bunzip2
1829 +try_decompress 'LZIP' xyz 'lzip -d'
1830 try_decompress '\135\0\0\0' xxx unlzma
1831 try_decompress '\211\114\132' xy 'lzop -d'
1832 try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
1833 diff -urdN linux-4.19.8/scripts/extract-vmlinux linux-4.19.8.new/scripts/extract-vmlinux
1834 --- linux-4.19.8/scripts/extract-vmlinux 2018-12-08 12:59:10.000000000 +0100
1835 +++ linux-4.19.8.new/scripts/extract-vmlinux 2018-12-09 18:01:59.000000000 +0100
1836 @@ -55,6 +55,7 @@
1837 try_decompress '\037\213\010' xy gunzip
1838 try_decompress '\3757zXZ\000' abcde unxz
1839 try_decompress 'BZh' xy bunzip2
1840 +try_decompress 'LZIP' xyz 'lzip -d'
1841 try_decompress '\135\0\0\0' xxx unlzma
1842 try_decompress '\211\114\132' xy 'lzop -d'
1843 try_decompress '\002!L\030' xxx 'lz4 -d'
1844 diff -urdN linux-4.19.8/scripts/package/Makefile linux-4.19.8.new/scripts/package/Makefile
1845 --- linux-4.19.8/scripts/package/Makefile 2018-12-08 12:59:10.000000000 +0100
1846 +++ linux-4.19.8.new/scripts/package/Makefile 2018-12-09 18:01:59.000000000 +0100
1847 @@ -129,8 +129,9 @@
1848 $(if $(findstring tar-src,$@),, \
1849 $(if $(findstring bz2,$@),bzip2, \
1850 $(if $(findstring gz,$@),gzip, \
1851 +$(if $(findstring lz,$@),lzip, \
1852 $(if $(findstring xz,$@),xz, \
1853 -$(error unknown target $@)))) \
1854 +$(error unknown target $@))))) \
1855 -f -9 $(perf-tar).tar)
1857 perf-%pkg: FORCE
1858 @@ -147,8 +148,10 @@
1859 @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
1860 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
1861 @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball'
1862 + @echo ' tarlz-pkg - Build the kernel as a lzip compressed tarball'
1863 @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball'
1864 @echo ' perf-tar-src-pkg - Build $(perf-tar).tar source tarball'
1865 @echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball'
1866 @echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
1867 + @echo ' perf-tarlz-src-pkg - Build $(perf-tar).tar.lz source tarball'
1868 @echo ' perf-tarxz-src-pkg - Build $(perf-tar).tar.xz source tarball'
1869 diff -urdN linux-4.19.8/scripts/package/buildtar linux-4.19.8.new/scripts/package/buildtar
1870 --- linux-4.19.8/scripts/package/buildtar 2018-12-08 12:59:10.000000000 +0100
1871 +++ linux-4.19.8.new/scripts/package/buildtar 2018-12-09 18:01:59.000000000 +0100
1872 @@ -35,6 +35,10 @@
1873 opts=--bzip2
1874 tarball=${tarball}.bz2
1876 + tarlz-pkg)
1877 + opts=--lzip
1878 + tarball=${tarball}.lz
1879 + ;;
1880 tarxz-pkg)
1881 opts=--xz
1882 tarball=${tarball}.xz
1883 diff -urdN linux-4.19.8/scripts/patch-kernel linux-4.19.8.new/scripts/patch-kernel
1884 --- linux-4.19.8/scripts/patch-kernel 2018-12-08 12:59:10.000000000 +0100
1885 +++ linux-4.19.8.new/scripts/patch-kernel 2018-12-09 18:01:59.000000000 +0100
1886 @@ -117,6 +117,10 @@
1887 ext=".bz2"
1888 name="bzip2"
1889 uncomp="bunzip2 -dc"
1890 + elif [ -r ${filebase}.lz ]; then
1891 + ext=".lz"
1892 + name="lzip"
1893 + uncomp="lzip -dc"
1894 elif [ -r ${filebase}.xz ]; then
1895 ext=".xz"
1896 name="xz"
1897 diff -urdN linux-4.19.8/tools/testing/selftests/gen_kselftest_tar.sh linux-4.19.8.new/tools/testing/selftests/gen_kselftest_tar.sh
1898 --- linux-4.19.8/tools/testing/selftests/gen_kselftest_tar.sh 2018-12-08 12:59:10.000000000 +0100
1899 +++ linux-4.19.8.new/tools/testing/selftests/gen_kselftest_tar.sh 2018-12-09 18:01:59.000000000 +0100
1900 @@ -27,6 +27,10 @@
1901 copts="cvjf"
1902 ext=".tar.bz2"
1904 + tarlz)
1905 + copts="cv --lzip -f"
1906 + ext=".tar.lz"
1907 + ;;
1908 tarxz)
1909 copts="cvJf"
1910 ext=".tar.xz"
1911 diff -urdN linux-4.19.8/usr/.gitignore linux-4.19.8.new/usr/.gitignore
1912 --- linux-4.19.8/usr/.gitignore 2018-12-08 12:59:10.000000000 +0100
1913 +++ linux-4.19.8.new/usr/.gitignore 2018-12-09 18:01:59.000000000 +0100
1914 @@ -5,6 +5,7 @@
1915 initramfs_data.cpio
1916 initramfs_data.cpio.gz
1917 initramfs_data.cpio.bz2
1918 +initramfs_data.cpio.lz
1919 initramfs_data.cpio.lzma
1920 initramfs_list
1921 include
1922 diff -urdN linux-4.19.8/usr/Kconfig linux-4.19.8.new/usr/Kconfig
1923 --- linux-4.19.8/usr/Kconfig 2018-12-08 12:59:10.000000000 +0100
1924 +++ linux-4.19.8.new/usr/Kconfig 2018-12-09 18:01:59.000000000 +0100
1925 @@ -70,6 +70,15 @@
1926 Support loading of a bzip2 encoded initial ramdisk or cpio buffer
1927 If unsure, say N.
1929 +config RD_LZIP
1930 + bool "Support initial ramdisk/ramfs compressed using lzip"
1931 + default y
1932 + depends on BLK_DEV_INITRD
1933 + select DECOMPRESS_LZIP
1934 + help
1935 + Support loading of a lzip encoded initial ramdisk or cpio buffer.
1936 + If unsure, say N.
1938 config RD_LZMA
1939 bool "Support initial ramdisk/ramfs compressed using LZMA"
1940 default y
1941 @@ -165,6 +174,18 @@
1942 If you choose this, keep in mind that you need to have the bzip2 tool
1943 available to be able to compress the initram.
1945 +config INITRAMFS_COMPRESSION_LZIP
1946 + bool "Lzip"
1947 + depends on RD_LZIP
1948 + help
1949 + Lzip's compression ratio is better than that of gzip and bzip2.
1950 + Decompression speed is between gzip and bzip2. Compression can
1951 + be as fast as gzip or slower than bzip2 depending on compression
1952 + level. Lzip can produce a initramfs about a 16% smaller than gzip.
1954 + If you choose this, keep in mind that you need to have the lzip tool
1955 + available to be able to compress the initram.
1957 config INITRAMFS_COMPRESSION_LZMA
1958 bool "LZMA"
1959 depends on RD_LZMA
1960 @@ -222,12 +243,14 @@
1961 default "" if INITRAMFS_COMPRESSION_NONE
1962 default ".gz" if INITRAMFS_COMPRESSION_GZIP
1963 default ".bz2" if INITRAMFS_COMPRESSION_BZIP2
1964 + default ".lz" if INITRAMFS_COMPRESSION_LZIP
1965 default ".lzma" if INITRAMFS_COMPRESSION_LZMA
1966 default ".xz" if INITRAMFS_COMPRESSION_XZ
1967 default ".lzo" if INITRAMFS_COMPRESSION_LZO
1968 default ".lz4" if INITRAMFS_COMPRESSION_LZ4
1969 default ".gz" if RD_GZIP
1970 default ".lz4" if RD_LZ4
1971 + default ".lz" if RD_LZIP
1972 default ".lzo" if RD_LZO
1973 default ".xz" if RD_XZ
1974 default ".lzma" if RD_LZMA