summaryrefslogtreecommitdiff
path: root/libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch
diff options
context:
space:
mode:
authorAndreas Grapentin <andreas@grapentin.org>2019-10-12 23:31:44 +0200
committerAndreas Grapentin <andreas@grapentin.org>2019-10-12 23:31:44 +0200
commitf860e31adb9cf3726780a04aaa856c1ab0606a84 (patch)
treefc87e695fc5fb18d8b35acc759181385a62a5d08 /libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch
parentdea2d20dd08a66dce1df2627f473a6b068893832 (diff)
downloadabslibre-f860e31adb9cf3726780a04aaa856c1ab0606a84.tar.gz
abslibre-f860e31adb9cf3726780a04aaa856c1ab0606a84.tar.bz2
abslibre-f860e31adb9cf3726780a04aaa856c1ab0606a84.zip
added kernel package for c201 (veyron)
Diffstat (limited to 'libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch')
-rw-r--r--libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch1974
1 files changed, 1974 insertions, 0 deletions
diff --git a/libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch b/libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch
new file mode 100644
index 000000000..98edaff1c
--- /dev/null
+++ b/libre-testing/linux-libre-veyron/linux-4.19.8_lzip-0.patch
@@ -0,0 +1,1974 @@
+diff -urdN linux-4.19.8/Documentation/00-INDEX linux-4.19.8.new/Documentation/00-INDEX
+--- linux-4.19.8/Documentation/00-INDEX 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/Documentation/00-INDEX 2018-12-09 18:01:59.000000000 +0100
+@@ -242,6 +242,8 @@
+ - info on creator of above logo & site to get additional images from.
+ lsm.txt
+ - Linux Security Modules: General Security Hooks for Linux
++lzip.txt
++ - info on lzip compression for the linux kernel.
+ lzo.txt
+ - kernel LZO decompressor input formats
+ m68k/
+diff -urdN linux-4.19.8/Documentation/dontdiff linux-4.19.8.new/Documentation/dontdiff
+--- linux-4.19.8/Documentation/dontdiff 2018-12-08 19:33:27.000000000 +0100
++++ linux-4.19.8.new/Documentation/dontdiff 2018-12-09 18:01:59.000000000 +0100
+@@ -26,6 +26,7 @@
+ *.ll
+ *.log
+ *.lst
++*.lz
+ *.lzma
+ *.lzo
+ *.mo
+diff -urdN linux-4.19.8/Documentation/filesystems/squashfs.txt linux-4.19.8.new/Documentation/filesystems/squashfs.txt
+--- linux-4.19.8/Documentation/filesystems/squashfs.txt 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/Documentation/filesystems/squashfs.txt 2018-12-09 18:01:59.000000000 +0100
+@@ -2,7 +2,7 @@
+ =======================
+
+ Squashfs is a compressed read-only filesystem for Linux.
+-It uses zlib, lz4, lzo, or xz compression to compress files, inodes and
++It uses zlib, lz4, lzip, lzo, or xz compression to compress files, inodes and
+ directories. Inodes in the system are very small and all blocks are packed to
+ minimise data overhead. Block sizes greater than 4K are supported up to a
+ maximum of 1Mbytes (default block size 128K).
+diff -urdN linux-4.19.8/Documentation/lzip.txt linux-4.19.8.new/Documentation/lzip.txt
+--- linux-4.19.8/Documentation/lzip.txt 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.19.8.new/Documentation/lzip.txt 2018-12-09 19:07:33.000000000 +0100
+@@ -0,0 +1,59 @@
++==============================
++Lzip data compression in Linux
++==============================
++
++Introduction
++============
++
++Lzip is a lossless data compressor with a user interface similar to the
++one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)
++or compress most files more than bzip2 (lzip -9). Decompression speed is
++intermediate between gzip and bzip2. Lzip implements the LZMA algorithm.
++
++Lzip has been designed, written and tested with great care to be the
++standard general-purpose compressor for unix-like systems. The lzip
++format is as simple as possible (but not simpler). It provides accurate
++and robust 3 factor integrity checking.
++
++Learn more about lzip at http://www.nongnu.org/lzip/lzip.html
++
++Lzip related components in the kernel
++=====================================
++
++The lzip_decompress module in lib/lzip_decompress.c provides a versatile
++lzip decompression function able to do buffer to buffer decompression or
++stream decompression with fill and flush callback functions. The usage
++of the function is documented in include/linux/lzip.h.
++
++For decompressing the kernel image, initramfs, and initrd, there is a
++wrapper function in lib/decompress_lunzip.c providing the same common
++interface as the other decompress_*.c files, which is defined in
++include/linux/decompress/generic.h.
++
++For kernel makefiles, two commands are provided in scripts/Makefile.lib
++for use with $(call if_changed). The kernel image must be compressed
++with $(call if_changed,klzip) which will append a four-byte trailer
++containing the size of the uncompressed data, which is needed by the
++boot code. Other things should be compressed with $(call if_changed,lzip).
++
++Testing
++=======
++
++Lzip-compressed kernel images of multiple linux versions since 2.6.30.10
++have been built and tested, even on machines as modest as an AMD 486-DX2
++at 66 MHz with 64 MiB of RAM. In the worst case (on the slow machine
++above), lzip just increased the boot time a 15% compared with gzip. On
++more modern machines, lzip may boot slightly faster than gzip. It just
++takes 0.2 seconds for lzip to decompress vmlinuz-4.4.16 on my machine.
++
++Decompression time is usually a small fraction of the total boot time.
++For example, using lz4 on a desktop machine in order to save 0.05
++seconds of a total boot time of 20 seconds is probably not worth the
++increased image size.
++
++Xlunzip is a test tool for the lzip_decompress module. It is similar to
++lunzip, but it uses the lzip_decompress module as a backend. The xlunzip
++home page is at http://www.nongnu.org/lzip/xlunzip.html
++
++Author: Antonio Diaz Diaz
++Updated: 2018-12-09
+diff -urdN linux-4.19.8/Documentation/x86/boot.txt linux-4.19.8.new/Documentation/x86/boot.txt
+--- linux-4.19.8/Documentation/x86/boot.txt 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/Documentation/x86/boot.txt 2018-12-09 18:01:59.000000000 +0100
+@@ -665,10 +665,10 @@
+ The payload may be compressed. The format of both the compressed and
+ uncompressed data should be determined using the standard magic
+ numbers. The currently supported compression formats are gzip
+- (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA
+- (magic number 5D 00), XZ (magic number FD 37), and LZ4 (magic number
+- 02 21). The uncompressed payload is currently always ELF (magic
+- number 7F 45 4C 46).
++ (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), lzip
++ (magic number 4C 5A), LZMA (magic number 5D 00), XZ (magic number FD
++ 37), and LZ4 (magic number 02 21). The uncompressed payload is
++ currently always ELF (magic number 7F 45 4C 46).
+
+ Field name: payload_length
+ Type: read
+diff -urdN linux-4.19.8/Makefile linux-4.19.8.new/Makefile
+--- linux-4.19.8/Makefile 2018-12-08 19:31:53.000000000 +0100
++++ linux-4.19.8.new/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -912,14 +912,17 @@
+ export mod_strip_cmd
+
+ # CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed
+-# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP
+-# or CONFIG_MODULE_COMPRESS_XZ.
++# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP,
++# CONFIG_MODULE_COMPRESS_LZIP or CONFIG_MODULE_COMPRESS_XZ.
+
+ mod_compress_cmd = true
+ ifdef CONFIG_MODULE_COMPRESS
+ ifdef CONFIG_MODULE_COMPRESS_GZIP
+ mod_compress_cmd = gzip -n -f
+ endif # CONFIG_MODULE_COMPRESS_GZIP
++ ifdef CONFIG_MODULE_COMPRESS_LZIP
++ mod_compress_cmd = lzip -f
++ endif # CONFIG_MODULE_COMPRESS_LZIP
+ ifdef CONFIG_MODULE_COMPRESS_XZ
+ mod_compress_cmd = xz -f
+ endif # CONFIG_MODULE_COMPRESS_XZ
+@@ -931,6 +934,7 @@
+ #
+ INITRD_COMPRESS-y := gzip
+ INITRD_COMPRESS-$(CONFIG_RD_BZIP2) := bzip2
++INITRD_COMPRESS-$(CONFIG_RD_LZIP) := lzip
+ INITRD_COMPRESS-$(CONFIG_RD_LZMA) := lzma
+ INITRD_COMPRESS-$(CONFIG_RD_XZ) := xz
+ INITRD_COMPRESS-$(CONFIG_RD_LZO) := lzo
+diff -urdN linux-4.19.8/arch/arm/Kconfig linux-4.19.8.new/arch/arm/Kconfig
+--- linux-4.19.8/arch/arm/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/arm/Kconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -77,6 +77,7 @@
+ select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_LZ4
++ select HAVE_KERNEL_LZIP
+ select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
+ select HAVE_KERNEL_XZ
+diff -urdN linux-4.19.8/arch/arm/boot/compressed/Makefile linux-4.19.8.new/arch/arm/boot/compressed/Makefile
+--- linux-4.19.8/arch/arm/boot/compressed/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/arm/boot/compressed/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -71,6 +71,7 @@
+ CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)"
+
+ compress-$(CONFIG_KERNEL_GZIP) = gzip
++compress-$(CONFIG_KERNEL_LZIP) = klzip
+ compress-$(CONFIG_KERNEL_LZO) = lzo
+ compress-$(CONFIG_KERNEL_LZMA) = lzma
+ compress-$(CONFIG_KERNEL_XZ) = xzkern
+diff -urdN linux-4.19.8/arch/arm/boot/compressed/decompress.c linux-4.19.8.new/arch/arm/boot/compressed/decompress.c
+--- linux-4.19.8/arch/arm/boot/compressed/decompress.c 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/arm/boot/compressed/decompress.c 2018-12-09 18:01:59.000000000 +0100
+@@ -37,6 +37,10 @@
+ #include "../../../../lib/decompress_inflate.c"
+ #endif
+
++#ifdef CONFIG_KERNEL_LZIP
++#include "../../../../lib/decompress_lunzip.c"
++#endif
++
+ #ifdef CONFIG_KERNEL_LZO
+ #include "../../../../lib/decompress_unlzo.c"
+ #endif
+diff -urdN linux-4.19.8/arch/sh/Kconfig linux-4.19.8.new/arch/sh/Kconfig
+--- linux-4.19.8/arch/sh/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/sh/Kconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -25,6 +25,7 @@
+ select HAVE_KERNEL_GZIP
+ select CPU_NO_EFFICIENT_FFS
+ select HAVE_KERNEL_BZIP2
++ select HAVE_KERNEL_LZIP
+ select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_XZ
+ select HAVE_KERNEL_LZO
+diff -urdN linux-4.19.8/arch/sh/Makefile linux-4.19.8.new/arch/sh/Makefile
+--- linux-4.19.8/arch/sh/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/sh/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -209,9 +209,9 @@
+ libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
+ libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y)
+
+-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
+- uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
+- romImage
++BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lz uImage.lzma uImage.xz \
++ uImage.lzo uImage.srec uImage.bin zImage vmlinux.bin \
++ vmlinux.srec romImage
+ PHONY += $(BOOT_TARGETS)
+
+ all: $(notdir $(KBUILD_IMAGE))
+@@ -238,6 +238,7 @@
+ @echo ' uImage.bin - Kernel-only image for U-Boot (bin)'
+ @echo '* uImage.gz - Kernel-only image for U-Boot (gzip)'
+ @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)'
++ @echo ' uImage.lz - Kernel-only image for U-Boot (lzip)'
+ @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)'
+ @echo ' uImage.xz - Kernel-only image for U-Boot (xz)'
+ @echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)'
+diff -urdN linux-4.19.8/arch/sh/boot/Makefile linux-4.19.8.new/arch/sh/boot/Makefile
+--- linux-4.19.8/arch/sh/boot/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/sh/boot/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -22,14 +22,15 @@
+ suffix-y := bin
+ suffix-$(CONFIG_KERNEL_GZIP) := gz
+ suffix-$(CONFIG_KERNEL_BZIP2) := bz2
++suffix-$(CONFIG_KERNEL_LZIP) := lz
+ suffix-$(CONFIG_KERNEL_LZMA) := lzma
+ suffix-$(CONFIG_KERNEL_XZ) := xz
+ suffix-$(CONFIG_KERNEL_LZO) := lzo
+
+ targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
+- uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin
+-extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+- vmlinux.bin.xz vmlinux.bin.lzo
++ uImage.bz2 uImage.lz uImage.lzma uImage.xz uImage.lzo uImage.bin
++extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
++ vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo
+ subdir- := compressed romimage
+
+ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+@@ -71,6 +72,9 @@
+ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,bzip2)
+
++$(obj)/vmlinux.bin.lz: $(obj)/vmlinux.bin FORCE
++ $(call if_changed,klzip)
++
+ $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,lzma)
+
+@@ -86,6 +90,9 @@
+ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
+ $(call if_changed,uimage,gzip)
+
++$(obj)/uImage.lz: $(obj)/vmlinux.bin.lz
++ $(call if_changed,uimage,lzip)
++
+ $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
+ $(call if_changed,uimage,lzma)
+
+diff -urdN linux-4.19.8/arch/sh/boot/compressed/Makefile linux-4.19.8.new/arch/sh/boot/compressed/Makefile
+--- linux-4.19.8/arch/sh/boot/compressed/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/sh/boot/compressed/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -5,10 +5,9 @@
+ # create a compressed vmlinux image from the original vmlinux
+ #
+
+-targets := vmlinux vmlinux.bin vmlinux.bin.gz \
+- vmlinux.bin.bz2 vmlinux.bin.lzma \
+- vmlinux.bin.xz vmlinux.bin.lzo \
+- head_$(BITS).o misc.o piggy.o
++targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
++ vmlinux.bin.lz vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo \
++ head_$(BITS).o misc.o piggy.o
+
+ OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
+
+@@ -66,6 +65,8 @@
+ $(call if_changed,gzip)
+ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
+ $(call if_changed,bzip2)
++$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
++ $(call if_changed,klzip)
+ $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
+ $(call if_changed,lzma)
+ $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
+diff -urdN linux-4.19.8/arch/sh/boot/compressed/misc.c linux-4.19.8.new/arch/sh/boot/compressed/misc.c
+--- linux-4.19.8/arch/sh/boot/compressed/misc.c 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/sh/boot/compressed/misc.c 2018-12-09 18:01:59.000000000 +0100
+@@ -58,6 +58,10 @@
+ #include "../../../../lib/decompress_bunzip2.c"
+ #endif
+
++#ifdef CONFIG_KERNEL_LZIP
++#include "../../../../lib/decompress_lunzip.c"
++#endif
++
+ #ifdef CONFIG_KERNEL_LZMA
+ #include "../../../../lib/decompress_unlzma.c"
+ #endif
+diff -urdN linux-4.19.8/arch/x86/Kconfig linux-4.19.8.new/arch/x86/Kconfig
+--- linux-4.19.8/arch/x86/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/x86/Kconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -158,6 +158,7 @@
+ select HAVE_KERNEL_BZIP2
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_LZ4
++ select HAVE_KERNEL_LZIP
+ select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
+ select HAVE_KERNEL_XZ
+diff -urdN linux-4.19.8/arch/x86/boot/compressed/Makefile linux-4.19.8.new/arch/x86/boot/compressed/Makefile
+--- linux-4.19.8/arch/x86/boot/compressed/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/x86/boot/compressed/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -23,8 +23,8 @@
+ # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
+ KCOV_INSTRUMENT := n
+
+-targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
+- vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
++targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lz \
++ vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
+
+ KBUILD_CFLAGS := -m$(BITS) -O2
+ KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
+@@ -134,6 +134,8 @@
+ $(call if_changed,gzip)
+ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
+ $(call if_changed,bzip2)
++$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
++ $(call if_changed,klzip)
+ $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
+ $(call if_changed,lzma)
+ $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
+@@ -145,6 +147,7 @@
+
+ suffix-$(CONFIG_KERNEL_GZIP) := gz
+ suffix-$(CONFIG_KERNEL_BZIP2) := bz2
++suffix-$(CONFIG_KERNEL_LZIP) := lz
+ suffix-$(CONFIG_KERNEL_LZMA) := lzma
+ suffix-$(CONFIG_KERNEL_XZ) := xz
+ suffix-$(CONFIG_KERNEL_LZO) := lzo
+diff -urdN linux-4.19.8/arch/x86/boot/compressed/misc.c linux-4.19.8.new/arch/x86/boot/compressed/misc.c
+--- linux-4.19.8/arch/x86/boot/compressed/misc.c 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/arch/x86/boot/compressed/misc.c 2018-12-09 18:01:59.000000000 +0100
+@@ -61,6 +61,10 @@
+ #include "../../../../lib/decompress_bunzip2.c"
+ #endif
+
++#ifdef CONFIG_KERNEL_LZIP
++#include "../../../../lib/decompress_lunzip.c"
++#endif
++
+ #ifdef CONFIG_KERNEL_LZMA
+ #include "../../../../lib/decompress_unlzma.c"
+ #endif
+diff -urdN linux-4.19.8/fs/squashfs/Kconfig linux-4.19.8.new/fs/squashfs/Kconfig
+--- linux-4.19.8/fs/squashfs/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/fs/squashfs/Kconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -4,7 +4,7 @@
+ help
+ Saying Y here includes support for SquashFS 4.0 (a Compressed
+ Read-Only File System). Squashfs is a highly compressed read-only
+- filesystem for Linux. It uses zlib, lzo or xz compression to
++ filesystem for Linux. It uses zlib, lzip, lzo or xz compression to
+ compress both files, inodes and directories. Inodes in the system
+ are very small and all blocks are packed to minimise data overhead.
+ Block sizes greater than 4K are supported up to a maximum of 1 Mbytes
+@@ -134,6 +134,21 @@
+ file systems will be readable without selecting this option.
+
+ If unsure, say N.
++
++config SQUASHFS_LZIP
++ bool "Include support for LZIP compressed file systems"
++ depends on SQUASHFS
++ select LZIP_DECOMPRESS
++ help
++ Saying Y here includes support for reading Squashfs file systems
++ compressed with LZIP compression. LZIP gives better compression
++ than the default zlib compression, at the expense of greater CPU
++ and memory overhead.
++
++ LZIP is not the standard compression used in Squashfs and so most
++ file systems will be readable without selecting this option.
++
++ If unsure, say N.
+
+ config SQUASHFS_LZO
+ bool "Include support for LZO compressed file systems"
+diff -urdN linux-4.19.8/fs/squashfs/Makefile linux-4.19.8.new/fs/squashfs/Makefile
+--- linux-4.19.8/fs/squashfs/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/fs/squashfs/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -13,6 +13,7 @@
+ squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
+ squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
+ squashfs-$(CONFIG_SQUASHFS_LZ4) += lz4_wrapper.o
++squashfs-$(CONFIG_SQUASHFS_LZIP) += lzip_wrapper.o
+ squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
+ squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
+ squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o
+diff -urdN linux-4.19.8/fs/squashfs/decompressor.c linux-4.19.8.new/fs/squashfs/decompressor.c
+--- linux-4.19.8/fs/squashfs/decompressor.c 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/fs/squashfs/decompressor.c 2018-12-09 18:01:59.000000000 +0100
+@@ -47,6 +47,12 @@
+ };
+ #endif
+
++#ifndef CONFIG_SQUASHFS_LZIP
++static const struct squashfs_decompressor squashfs_lzip_comp_ops = {
++ NULL, NULL, NULL, NULL, LZIP_COMPRESSION, "lzip", 0
++};
++#endif
++
+ #ifndef CONFIG_SQUASHFS_LZO
+ static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
+ NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
+@@ -78,6 +84,7 @@
+ static const struct squashfs_decompressor *decompressor[] = {
+ &squashfs_zlib_comp_ops,
+ &squashfs_lz4_comp_ops,
++ &squashfs_lzip_comp_ops,
+ &squashfs_lzo_comp_ops,
+ &squashfs_xz_comp_ops,
+ &squashfs_lzma_unsupported_comp_ops,
+diff -urdN linux-4.19.8/fs/squashfs/decompressor.h linux-4.19.8.new/fs/squashfs/decompressor.h
+--- linux-4.19.8/fs/squashfs/decompressor.h 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/fs/squashfs/decompressor.h 2018-12-09 18:01:59.000000000 +0100
+@@ -50,6 +50,10 @@
+ extern const struct squashfs_decompressor squashfs_lz4_comp_ops;
+ #endif
+
++#ifdef CONFIG_SQUASHFS_LZIP
++extern const struct squashfs_decompressor squashfs_lzip_comp_ops;
++#endif
++
+ #ifdef CONFIG_SQUASHFS_LZO
+ extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
+ #endif
+diff -urdN linux-4.19.8/fs/squashfs/lzip_wrapper.c linux-4.19.8.new/fs/squashfs/lzip_wrapper.c
+--- linux-4.19.8/fs/squashfs/lzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.19.8.new/fs/squashfs/lzip_wrapper.c 2018-12-09 18:01:59.000000000 +0100
+@@ -0,0 +1,129 @@
++/*
++ * Squashfs - a compressed read only filesystem for Linux
++ *
++ * Copyright (c) 2014
++ * Phillip Lougher <phillip@squashfs.org.uk>
++ * Copyright (C) 2018 Antonio Diaz Diaz
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2,
++ * or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see <http://www.gnu.org/licenses/>.
++ *
++ * lzip_wrapper.c
++ */
++
++#include <linux/buffer_head.h>
++#include <linux/mutex.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/lzip.h>
++
++#include "squashfs_fs.h"
++#include "squashfs_fs_sb.h"
++#include "squashfs.h"
++#include "decompressor.h"
++#include "page_actor.h"
++
++struct squashfs_lzip {
++ void *input;
++ void *output;
++};
++
++
++static void *lzip_init(struct squashfs_sb_info *msblk, void *buff)
++{
++ int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
++ struct squashfs_lzip *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
++ if (stream == NULL)
++ goto failed;
++ stream->input = vmalloc(block_size);
++ if (stream->input == NULL)
++ goto failed2;
++ stream->output = vmalloc(block_size);
++ if (stream->output == NULL)
++ goto failed3;
++
++ return stream;
++
++failed3:
++ vfree(stream->input);
++failed2:
++ kfree(stream);
++failed:
++ ERROR("Failed to initialise LZIP decompressor\n");
++ return ERR_PTR(-ENOMEM);
++}
++
++
++static void lzip_free(void *strm)
++{
++ struct squashfs_lzip *stream = strm;
++
++ if (stream) {
++ vfree(stream->input);
++ vfree(stream->output);
++ }
++ kfree(stream);
++}
++
++
++static int lzip_uncompress(struct squashfs_sb_info *msblk, void *strm,
++ struct buffer_head **bh, int b, int offset, int length,
++ struct squashfs_page_actor *output)
++{
++ struct squashfs_lzip *stream = strm;
++ void *buff = stream->input, *data;
++ long out_pos;
++ int avail, i, bytes = length, res;
++
++ for (i = 0; i < b; i++) {
++ avail = min(bytes, msblk->devblksize - offset);
++ memcpy(buff, bh[i]->b_data + offset, avail);
++ buff += avail;
++ bytes -= avail;
++ offset = 0;
++ put_bh(bh[i]);
++ }
++
++ res = lzip_decompress(stream->input, length, 0, 0, stream->output,
++ output->length, 0, &out_pos);
++ if (res < 0) {
++ ERROR("LZIP error code %d\n", res);
++ return -EIO;
++ }
++ bytes = out_pos;
++ data = squashfs_first_page(output);
++ buff = stream->output;
++ while (data) {
++ if (bytes <= PAGE_SIZE) {
++ memcpy(data, buff, bytes);
++ break;
++ }
++ memcpy(data, buff, PAGE_SIZE);
++ buff += PAGE_SIZE;
++ bytes -= PAGE_SIZE;
++ data = squashfs_next_page(output);
++ }
++ squashfs_finish_page(output);
++
++ return out_pos;
++}
++
++
++const struct squashfs_decompressor squashfs_lzip_comp_ops = {
++ .init = lzip_init,
++ .free = lzip_free,
++ .decompress = lzip_uncompress,
++ .id = LZIP_COMPRESSION,
++ .name = "lzip",
++ .supported = 1
++};
+diff -urdN linux-4.19.8/fs/squashfs/squashfs_fs.h linux-4.19.8.new/fs/squashfs/squashfs_fs.h
+--- linux-4.19.8/fs/squashfs/squashfs_fs.h 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/fs/squashfs/squashfs_fs.h 2018-12-09 18:01:59.000000000 +0100
+@@ -248,6 +248,7 @@
+ #define XZ_COMPRESSION 4
+ #define LZ4_COMPRESSION 5
+ #define ZSTD_COMPRESSION 6
++#define LZIP_COMPRESSION 7
+
+ struct squashfs_super_block {
+ __le32 s_magic;
+diff -urdN linux-4.19.8/include/linux/decompress/lunzip.h linux-4.19.8.new/include/linux/decompress/lunzip.h
+--- linux-4.19.8/include/linux/decompress/lunzip.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.19.8.new/include/linux/decompress/lunzip.h 2018-12-09 18:01:59.000000000 +0100
+@@ -0,0 +1,11 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef LINUX_DECOMPRESS_LUNZIP_H
++#define LINUX_DECOMPRESS_LUNZIP_H
++
++int lunzip(unsigned char *inbuf, long in_len,
++ long (*fill)(void*, unsigned long),
++ long (*flush)(void*, unsigned long),
++ unsigned char *outbuf,
++ long *in_posp,
++ void (*error)(char *x));
++#endif
+diff -urdN linux-4.19.8/include/linux/lzip.h linux-4.19.8.new/include/linux/lzip.h
+--- linux-4.19.8/include/linux/lzip.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.19.8.new/include/linux/lzip.h 2018-12-09 18:01:59.000000000 +0100
+@@ -0,0 +1,53 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __LZIP_H__
++#define __LZIP_H__
++/*
++ * LZIP decompressor
++ *
++ * Copyright (C) 2016-2018 Antonio Diaz Diaz.
++ */
++
++/* Return values (< 0 = Error) */
++enum {
++ LZIP_OOM_INBUF = -1,
++ LZIP_HEADER1_EOF = -2,
++ LZIP_HEADER2_EOF = -3,
++ LZIP_BAD_MAGIC1 = -4,
++ LZIP_BAD_MAGIC2 = -5,
++ LZIP_BAD_VERSION = -6,
++ LZIP_BAD_DICT_SIZE = -7,
++ LZIP_OOM_OUTBUF = -8,
++ LZIP_WRITE_ERROR = -9,
++ LZIP_BAD_DATA = -10,
++ LZIP_DATA_EOF = -11,
++ LZIP_BAD_CRC = -12
++};
++
++int lzip_decompress(unsigned char *inbuf, long in_len,
++ long (*fill)(void*, unsigned long),
++ long (*flush)(void*, unsigned long),
++ unsigned char *outbuf, long out_size,
++ long *in_posp, long *out_posp);
++
++/* inbuf - input buffer. If null or in_len <= 0, fill must be non-null
++ * in_len - len of pre-read data in inbuf if inbuf is non-null
++ * fill - if non-null, function to fill inbuf when empty
++ * flush - if non-null, function to write out outbuf when full
++ * outbuf - output buffer. If null or out_size <= 0, flush must be non-null
++ * out_size - size of outbuf if outbuf is non-null
++ * in_posp - if non-null, the number of bytes consumed will be returned here
++ * out_posp - if non-null, the number of bytes produced will be returned here
++ *
++ * fill will be called (repeatedly) to read data. in_len bytes will be read
++ * per call (or 16384 bytes per call if inbuf is null or in_len <= 0).
++ *
++ * If flush is null, outbuf must be large enough to buffer all the expected
++ * output. Else the flush function will be called to flush the output buffer
++ * at the appropriate time (stream dependent).
++ * If out_size > 0 but is not large enough to buffer all the expected output,
++ * it must be at least as large as the dictionary size of the data.
++ *
++ * inbuf and outbuf may overlap (in-place decompression).
++ */
++
++#endif
+diff -urdN linux-4.19.8/init/Kconfig linux-4.19.8.new/init/Kconfig
+--- linux-4.19.8/init/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/init/Kconfig 2018-12-09 19:01:32.000000000 +0100
+@@ -122,6 +122,9 @@
+ config HAVE_KERNEL_BZIP2
+ bool
+
++config HAVE_KERNEL_LZIP
++ bool
++
+ config HAVE_KERNEL_LZMA
+ bool
+
+@@ -140,7 +143,7 @@
+ choice
+ prompt "Kernel compression mode"
+ default KERNEL_GZIP
+- depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4 || HAVE_KERNEL_UNCOMPRESSED
++ 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
+ help
+ The linux kernel is a kind of self-extracting executable.
+ Several compression algorithms are available, which differ
+@@ -176,6 +179,15 @@
+ Bzip2 uses a large amount of memory. For modern kernels you
+ will need at least 8MB RAM or more for booting.
+
++config KERNEL_LZIP
++ bool "Lzip"
++ depends on HAVE_KERNEL_LZIP
++ help
++ Lzip's compression ratio is better than that of gzip and bzip2.
++ Decompression speed is between gzip and bzip2. Compression can
++ be as fast as gzip or slower than bzip2 depending on compression
++ level. Lzip can produce a kernel about a 16% smaller than gzip.
++
+ config KERNEL_LZMA
+ bool "LZMA"
+ depends on HAVE_KERNEL_LZMA
+@@ -1919,8 +1931,8 @@
+ depends on MODULES
+ help
+
+- Compresses kernel modules when 'make modules_install' is run; gzip or
+- xz depending on "Compression algorithm" below.
++ Compresses kernel modules when 'make modules_install' is run; gzip,
++ lzip or xz are used depending on "Compression algorithm" below.
+
+ module-init-tools MAY support gzip, and kmod MAY support gzip and xz.
+
+@@ -1942,11 +1954,14 @@
+ This determines which sort of compression will be used during
+ 'make modules_install'.
+
+- GZIP (default) and XZ are supported.
++ GZIP (default), LZIP and XZ are supported.
+
+ config MODULE_COMPRESS_GZIP
+ bool "GZIP"
+
++config MODULE_COMPRESS_LZIP
++ bool "LZIP"
++
+ config MODULE_COMPRESS_XZ
+ bool "XZ"
+
+diff -urdN linux-4.19.8/init/do_mounts_rd.c linux-4.19.8.new/init/do_mounts_rd.c
+--- linux-4.19.8/init/do_mounts_rd.c 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/init/do_mounts_rd.c 2018-12-09 18:01:59.000000000 +0100
+@@ -49,6 +49,7 @@
+ * squashfs
+ * gzip
+ * bzip2
++ * lzip
+ * lzma
+ * xz
+ * lzo
+diff -urdN linux-4.19.8/lib/Kconfig linux-4.19.8.new/lib/Kconfig
+--- linux-4.19.8/lib/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/lib/Kconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -253,6 +253,12 @@
+ tristate
+ select BITREVERSE
+
++config LZIP_DECOMPRESS
++ tristate "LZIP decompression support"
++ help
++ LZMA compression algorithm is supported using the .lz file format.
++ See Documentation/lzip.txt for more information.
++
+ config LZO_COMPRESS
+ tristate
+
+@@ -289,6 +295,10 @@
+ config DECOMPRESS_BZIP2
+ tristate
+
++config DECOMPRESS_LZIP
++ select LZIP_DECOMPRESS
++ tristate
++
+ config DECOMPRESS_LZMA
+ tristate
+
+diff -urdN linux-4.19.8/lib/Makefile linux-4.19.8.new/lib/Makefile
+--- linux-4.19.8/lib/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/lib/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -119,6 +119,7 @@
+ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
+ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
+ obj-$(CONFIG_BCH) += bch.o
++obj-$(CONFIG_LZIP_DECOMPRESS) += lzip_decompress.o
+ obj-$(CONFIG_LZO_COMPRESS) += lzo/
+ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
+ obj-$(CONFIG_LZ4_COMPRESS) += lz4/
+@@ -131,6 +132,7 @@
+
+ lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
+ lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
++lib-$(CONFIG_DECOMPRESS_LZIP) += decompress_lunzip.o
+ lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
+ lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
+ lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
+diff -urdN linux-4.19.8/lib/decompress.c linux-4.19.8.new/lib/decompress.c
+--- linux-4.19.8/lib/decompress.c 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/lib/decompress.c 2018-12-09 18:01:59.000000000 +0100
+@@ -8,6 +8,7 @@
+ #include <linux/decompress/generic.h>
+
+ #include <linux/decompress/bunzip2.h>
++#include <linux/decompress/lunzip.h>
+ #include <linux/decompress/unlzma.h>
+ #include <linux/decompress/unxz.h>
+ #include <linux/decompress/inflate.h>
+@@ -25,6 +26,9 @@
+ #ifndef CONFIG_DECOMPRESS_BZIP2
+ # define bunzip2 NULL
+ #endif
++#ifndef CONFIG_DECOMPRESS_LZIP
++# define lunzip NULL
++#endif
+ #ifndef CONFIG_DECOMPRESS_LZMA
+ # define unlzma NULL
+ #endif
+@@ -48,6 +52,7 @@
+ { {0x1f, 0x8b}, "gzip", gunzip },
+ { {0x1f, 0x9e}, "gzip", gunzip },
+ { {0x42, 0x5a}, "bzip2", bunzip2 },
++ { {0x4c, 0x5a}, "lzip", lunzip },
+ { {0x5d, 0x00}, "lzma", unlzma },
+ { {0xfd, 0x37}, "xz", unxz },
+ { {0x89, 0x4c}, "lzo", unlzo },
+diff -urdN linux-4.19.8/lib/decompress_lunzip.c linux-4.19.8.new/lib/decompress_lunzip.c
+--- linux-4.19.8/lib/decompress_lunzip.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.19.8.new/lib/decompress_lunzip.c 2018-12-09 18:01:59.000000000 +0100
+@@ -0,0 +1,100 @@
++/*
++ * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
++ *
++ * Copyright (C) 2016-2018 Antonio Diaz Diaz.
++ *
++ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
++ */
++
++#ifdef STATIC
++#define PREBOOT
++#include "lzip_decompress.c"
++#else
++#include <linux/lzip.h>
++#include <linux/decompress/lunzip.h>
++#include <linux/decompress/mm.h>
++#endif
++
++STATIC int INIT __lunzip(unsigned char *inbuf, long in_len,
++ long (*fill)(void*, unsigned long),
++ long (*flush)(void*, unsigned long),
++ unsigned char *outbuf, long out_size,
++ long *in_posp, long *out_posp,
++ void (*error)(char *x))
++{
++ const int retval = lzip_decompress(inbuf, in_len, fill, flush,
++ outbuf, out_size, in_posp, out_posp);
++ switch (retval) {
++ case 0: break;
++ case LZIP_OOM_INBUF:
++ error("Out of memory while allocating input buffer.");
++ break;
++ case LZIP_HEADER1_EOF:
++ error("File ends unexpectedly at member header.");
++ break;
++ case LZIP_HEADER2_EOF:
++ error("Truncated header in multimember file.");
++ break;
++ case LZIP_BAD_MAGIC1:
++ error("Bad magic number (file not in lzip format).");
++ break;
++ case LZIP_BAD_MAGIC2:
++ error("Corrupt header in multimember file.");
++ break;
++ case LZIP_BAD_VERSION:
++ error("Version of lzip member format not supported.");
++ break;
++ case LZIP_BAD_DICT_SIZE:
++ error("Invalid dictionary size in member header.");
++ break;
++ case LZIP_OOM_OUTBUF:
++ error("Out of memory while allocating output buffer.");
++ break;
++ case LZIP_WRITE_ERROR:
++ error("Write error.");
++ break;
++ case LZIP_BAD_DATA:
++ error("LZIP-compressed data is corrupt.");
++ break;
++ case LZIP_DATA_EOF:
++ error("LZIP-compressed data ends unexpectedly.");
++ break;
++ case LZIP_BAD_CRC:
++ error("CRC mismatch in LZIP-compressed data.");
++ break;
++ default:
++ error("Bug in the LZIP decompressor.");
++ }
++ return retval;
++}
++
++#ifndef PREBOOT
++/* decompress_fn (see include/linux/decompress/generic.h) should have an
++ * out_size argument to prevent overflowing outbuf in case of corruption
++ * of the compressed data.
++ */
++STATIC int INIT lunzip(unsigned char *inbuf, long in_len,
++ long (*fill)(void*, unsigned long),
++ long (*flush)(void*, unsigned long),
++ unsigned char *outbuf,
++ long *in_posp,
++ void (*error)(char *x))
++{
++ return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX,
++ in_posp, 0, error);
++}
++#else
++STATIC int INIT __decompress(unsigned char *inbuf, long in_len,
++ long (*fill)(void*, unsigned long),
++ long (*flush)(void*, unsigned long),
++ unsigned char *outbuf, long out_size,
++ long *in_posp,
++ void (*error)(char *x))
++{
++/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe
++ * in case of corruption of the compressed data.
++ */
++ return __lunzip(inbuf, in_len - 4, fill, flush, outbuf,
++ out_size ? out_size : LONG_MAX, in_posp, 0, error);
++}
++#endif
+diff -urdN linux-4.19.8/lib/lzip_decompress.c linux-4.19.8.new/lib/lzip_decompress.c
+--- linux-4.19.8/lib/lzip_decompress.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-4.19.8.new/lib/lzip_decompress.c 2018-12-09 18:01:59.000000000 +0100
+@@ -0,0 +1,882 @@
++/*
++ * LZIP decompressor
++ *
++ * Copyright (C) 2016-2018 Antonio Diaz Diaz.
++ *
++ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
++ */
++
++#include <linux/module.h>
++#include <linux/lzip.h>
++#include <linux/decompress/mm.h>
++
++/*
++ * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
++ * See include/linux/decompress/mm.h for details.
++ */
++#ifndef STATIC_RW_DATA
++#define STATIC_RW_DATA static
++#endif
++
++typedef int State;
++
++enum { states = 12 };
++
++static inline bool St_is_char(const State st) { return st < 7; }
++
++static inline State St_set_char(const State st)
++{
++ STATIC_RW_DATA const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
++ return next[st];
++}
++
++static inline State St_set_match(const State st)
++{
++ return ((st < 7) ? 7 : 10);
++}
++
++static inline State St_set_rep(const State st)
++{
++ return ((st < 7) ? 8 : 11);
++}
++
++static inline State St_set_short_rep(const State st)
++{
++ return ((st < 7) ? 9 : 11);
++}
++
++
++enum {
++ min_dictionary_bits = 12,
++ min_dictionary_size = 1 << min_dictionary_bits,
++ max_dictionary_bits = 29,
++ max_dictionary_size = 1 << max_dictionary_bits,
++ literal_context_bits = 3,
++ pos_state_bits = 2,
++ pos_states = 1 << pos_state_bits,
++ pos_state_mask = pos_states - 1,
++
++ len_states = 4,
++ dis_slot_bits = 6,
++ start_dis_model = 4,
++ end_dis_model = 14,
++ modeled_distances = 1 << (end_dis_model / 2), /* 128 */
++ dis_align_bits = 4,
++ dis_align_size = 1 << dis_align_bits,
++
++ len_low_bits = 3,
++ len_mid_bits = 3,
++ len_high_bits = 8,
++ len_low_symbols = 1 << len_low_bits,
++ len_mid_symbols = 1 << len_mid_bits,
++ len_high_symbols = 1 << len_high_bits,
++ max_len_symbols = len_low_symbols + len_mid_symbols + len_high_symbols,
++
++ min_match_len = 2, /* must be 2 */
++ max_match_len = min_match_len + max_len_symbols - 1, /* 273 */
++ min_match_len_limit = 5
++};
++
++static inline int get_len_state(const int len)
++{
++ return min(len - min_match_len, len_states - 1);
++}
++
++static inline int get_lit_state(const uint8_t prev_byte)
++{
++ return (prev_byte >> (8 - literal_context_bits));
++}
++
++
++enum { bit_model_move_bits = 5,
++ bit_model_total_bits = 11,
++ bit_model_total = 1 << bit_model_total_bits
++};
++
++typedef int Bit_model;
++
++static inline void Bm_init(Bit_model * const probability)
++{
++ *probability = bit_model_total / 2;
++}
++
++static inline void Bm_array_init(Bit_model bm[], const int size)
++{
++ int i;
++
++ for (i = 0; i < size; ++i)
++ Bm_init(&bm[i]);
++}
++
++struct Len_model {
++ Bit_model choice1;
++ Bit_model choice2;
++ Bit_model bm_low[pos_states][len_low_symbols];
++ Bit_model bm_mid[pos_states][len_mid_symbols];
++ Bit_model bm_high[len_high_symbols];
++};
++
++static inline void Lm_init(struct Len_model * const lm)
++{
++ Bm_init(&lm->choice1);
++ Bm_init(&lm->choice2);
++ Bm_array_init(lm->bm_low[0], pos_states * len_low_symbols);
++ Bm_array_init(lm->bm_mid[0], pos_states * len_mid_symbols);
++ Bm_array_init(lm->bm_high, len_high_symbols);
++}
++
++
++/* Table of CRCs of all 8-bit messages. */
++STATIC_RW_DATA const uint32_t crc32[256] =
++ {
++ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
++ 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
++ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
++ 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
++ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
++ 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
++ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
++ 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
++ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
++ 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
++ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
++ 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
++ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
++ 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
++ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
++ 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
++ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
++ 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
++ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
++ 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
++ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
++ 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
++ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
++ 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
++ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
++ 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
++ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
++ 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
++ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
++ 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
++ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
++ 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
++ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
++ 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
++ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
++ 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
++ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
++ 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
++ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
++ 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
++ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
++ 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
++ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
++
++
++static inline void CRC32_update_buf(uint32_t * const crc,
++ const uint8_t * const buffer,
++ const long size)
++{
++ long i;
++ uint32_t c = *crc;
++
++ for (i = 0; i < size; ++i)
++ c = crc32[(c^buffer[i])&0xFF] ^ (c >> 8);
++ *crc = c;
++}
++
++
++STATIC_RW_DATA const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
++
++typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
++ /* 4 version */
++ /* 5 coded_dict_size */
++enum { Lh_size = 6 };
++
++static inline bool Lh_verify_magic(const Lzip_header data)
++{
++ int i;
++
++ for (i = 0; i < 4; ++i)
++ if (data[i] != lzip_magic[i])
++ return false;
++ return true;
++}
++
++/* detect (truncated) header */
++static inline bool Lh_verify_prefix(const Lzip_header data, const int sz)
++{
++ int i;
++ for (i = 0; i < sz && i < 4; ++i)
++ if (data[i] != lzip_magic[i])
++ return false;
++ return (sz > 0);
++}
++
++/* detect corrupt header */
++static inline bool Lh_verify_corrupt(const Lzip_header data)
++{
++ int matches = 0;
++ int i;
++ for (i = 0; i < 4; ++i)
++ if (data[i] == lzip_magic[i])
++ ++matches;
++ return (matches > 1 && matches < 4);
++}
++
++static inline bool Lh_verify_version(const Lzip_header data)
++{
++ return (data[4] == 1);
++}
++
++static inline unsigned Lh_get_dictionary_size(const Lzip_header data)
++{
++ unsigned sz = (1 << (data[5] & 0x1F));
++
++ if (sz > min_dictionary_size)
++ sz -= (sz / 16) * ((data[5] >> 5) & 7);
++ return sz;
++}
++
++
++typedef uint8_t Lzip_trailer[20];
++ /* 0-3 CRC32 of the uncompressed data */
++ /* 4-11 size of the uncompressed data */
++ /* 12-19 member size including header and trailer */
++enum { Lt_size = 20 };
++
++static inline unsigned Lt_get_data_crc(const Lzip_trailer data)
++{
++ unsigned tmp = 0;
++ int i;
++
++ for (i = 3; i >= 0; --i) {
++ tmp <<= 8;
++ tmp += data[i];
++ }
++ return tmp;
++}
++
++static inline unsigned long long Lt_get_data_size(const Lzip_trailer data)
++{
++ unsigned long long tmp = 0;
++ int i;
++
++ for (i = 11; i >= 4; --i) {
++ tmp <<= 8;
++ tmp += data[i];
++ }
++ return tmp;
++}
++
++static inline unsigned long long Lt_get_member_size(const Lzip_trailer data)
++{
++ unsigned long long tmp = 0;
++ int i;
++
++ for (i = 19; i >= 12; --i) {
++ tmp <<= 8;
++ tmp += data[i];
++ }
++ return tmp;
++}
++
++
++struct Range_decoder {
++ unsigned long long partial_member_pos;
++ uint8_t *buffer; /* input buffer */
++ long buffer_size;
++ long pos; /* current pos in buffer */
++ long stream_pos; /* when reached, a new block must be read */
++ uint32_t code;
++ uint32_t range;
++ long (*fill)(void*, unsigned long);
++ bool at_stream_end;
++ bool buffer_given;
++};
++
++
++static bool Rd_read_block(struct Range_decoder * const rdec)
++{
++ if (!rdec->at_stream_end) {
++ rdec->stream_pos = rdec->fill ?
++ rdec->fill(rdec->buffer, rdec->buffer_size) : 0;
++ rdec->at_stream_end = (rdec->stream_pos < rdec->buffer_size);
++ rdec->partial_member_pos += rdec->pos;
++ rdec->pos = 0;
++ }
++ return rdec->pos < rdec->stream_pos;
++}
++
++
++static inline bool Rd_init(struct Range_decoder * const rdec,
++ uint8_t * const inbuf, const long in_len,
++ long (*fill)(void*, unsigned long))
++{
++ rdec->partial_member_pos = 0;
++ rdec->buffer_given = (inbuf && in_len > 0);
++ rdec->buffer_size = rdec->buffer_given ? in_len : 16384;
++ rdec->buffer = rdec->buffer_given ? inbuf : malloc(rdec->buffer_size);
++ if (!rdec->buffer)
++ return false;
++ rdec->pos = 0;
++ rdec->stream_pos = rdec->buffer_given ? in_len : 0;
++ rdec->code = 0;
++ rdec->range = 0xFFFFFFFFU;
++ rdec->fill = fill;
++ rdec->at_stream_end = false;
++ return true;
++}
++
++static inline void Rd_free(struct Range_decoder * const rdec)
++{
++ if (!rdec->buffer_given)
++ free(rdec->buffer);
++}
++
++static inline bool Rd_finished(struct Range_decoder * const rdec)
++{
++ return rdec->pos >= rdec->stream_pos && !Rd_read_block(rdec);
++}
++
++static inline unsigned long long
++Rd_member_position(const struct Range_decoder * const rdec)
++{
++ return rdec->partial_member_pos + rdec->pos;
++}
++
++static inline void Rd_reset_member_position(struct Range_decoder * const rdec)
++{
++ rdec->partial_member_pos = 0; rdec->partial_member_pos -= rdec->pos;
++}
++
++static inline uint8_t Rd_get_byte(struct Range_decoder * const rdec)
++{
++ /* 0xFF avoids decoder error if member is truncated at EOS marker */
++ if (Rd_finished(rdec))
++ return 0xFF;
++ return rdec->buffer[rdec->pos++];
++}
++
++static inline void Rd_load(struct Range_decoder * const rdec)
++{
++ int i;
++
++ rdec->code = 0;
++ for (i = 0; i < 5; ++i)
++ rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
++ rdec->range = 0xFFFFFFFFU;
++}
++
++static inline void Rd_normalize(struct Range_decoder * const rdec)
++{
++ if (rdec->range <= 0x00FFFFFFU) {
++ rdec->range <<= 8;
++ rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
++ }
++}
++
++static inline unsigned Rd_decode(struct Range_decoder * const rdec,
++ const int num_bits)
++{
++ unsigned symbol = 0;
++ int i;
++
++ for (i = num_bits; i > 0; --i) {
++ bool bit;
++
++ Rd_normalize(rdec);
++ rdec->range >>= 1;
++ /* symbol <<= 1; */
++ /* if(rdec->code >= rdec->range) { rdec->code -= rdec->range; symbol |= 1; } */
++ bit = (rdec->code >= rdec->range);
++ symbol = (symbol << 1) + bit;
++ rdec->code -= rdec->range & (0U - bit);
++ }
++ return symbol;
++}
++
++static inline unsigned Rd_decode_bit(struct Range_decoder * const rdec,
++ Bit_model * const probability)
++{
++ uint32_t bound;
++
++ Rd_normalize(rdec);
++ bound = (rdec->range >> bit_model_total_bits) * *probability;
++ if (rdec->code < bound) {
++ rdec->range = bound;
++ *probability += (bit_model_total - *probability) >> bit_model_move_bits;
++ return 0;
++ } else {
++ rdec->range -= bound;
++ rdec->code -= bound;
++ *probability -= *probability >> bit_model_move_bits;
++ return 1;
++ }
++}
++
++static inline unsigned Rd_decode_tree3(struct Range_decoder * const rdec,
++ Bit_model bm[])
++{
++ unsigned symbol = 1;
++
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ return symbol & 7;
++}
++
++static inline unsigned Rd_decode_tree6(struct Range_decoder * const rdec,
++ Bit_model bm[])
++{
++ unsigned symbol = 1;
++
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ return symbol & 0x3F;
++}
++
++static inline unsigned Rd_decode_tree8(struct Range_decoder * const rdec,
++ Bit_model bm[])
++{
++ unsigned symbol = 1;
++ int i;
++
++ for (i = 0; i < 8; ++i)
++ symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
++ return symbol & 0xFF;
++}
++
++static inline unsigned
++Rd_decode_tree_reversed(struct Range_decoder * const rdec,
++ Bit_model bm[], const int num_bits)
++{
++ unsigned model = 1;
++ unsigned symbol = 0;
++ int i;
++
++ for (i = 0; i < num_bits; ++i) {
++ const unsigned bit = Rd_decode_bit(rdec, &bm[model]);
++
++ model = (model << 1) + bit;
++ symbol |= (bit << i);
++ }
++ return symbol;
++}
++
++static inline unsigned
++Rd_decode_tree_reversed4(struct Range_decoder * const rdec, Bit_model bm[])
++{
++ unsigned symbol = Rd_decode_bit(rdec, &bm[1]);
++ unsigned model = 2 + symbol;
++ unsigned bit = Rd_decode_bit(rdec, &bm[model]);
++
++ model = (model << 1) + bit; symbol |= (bit << 1);
++ bit = Rd_decode_bit(rdec, &bm[model]);
++ model = (model << 1) + bit; symbol |= (bit << 2);
++ symbol |= (Rd_decode_bit(rdec, &bm[model]) << 3);
++ return symbol;
++}
++
++static inline unsigned Rd_decode_matched(struct Range_decoder * const rdec,
++ Bit_model bm[], unsigned match_byte)
++{
++ unsigned symbol = 1;
++ unsigned mask = 0x100;
++
++ while (true) {
++ const unsigned match_bit = (match_byte <<= 1) & mask;
++ const unsigned bit = Rd_decode_bit(rdec, &bm[symbol+match_bit+mask]);
++
++ symbol = (symbol << 1) + bit;
++ if (symbol > 0xFF)
++ return symbol & 0xFF;
++ mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
++ }
++}
++
++static inline unsigned Rd_decode_len(struct Range_decoder * const rdec,
++ struct Len_model * const lm,
++ const int pos_state)
++{
++ if (Rd_decode_bit(rdec, &lm->choice1) == 0)
++ return Rd_decode_tree3(rdec, lm->bm_low[pos_state]);
++ if (Rd_decode_bit(rdec, &lm->choice2) == 0)
++ return len_low_symbols +
++ Rd_decode_tree3(rdec, lm->bm_mid[pos_state]);
++ return len_low_symbols + len_mid_symbols +
++ Rd_decode_tree8(rdec, lm->bm_high);
++}
++
++
++struct LZ_decoder {
++ unsigned long long partial_data_pos;
++ struct Range_decoder *rdec;
++ /* Don't move bm_* to LZd_decode_member; makes frame too large. */
++ Bit_model bm_literal[1 << literal_context_bits][0x300];
++ Bit_model bm_match[states][pos_states];
++ Bit_model bm_rep[states];
++ Bit_model bm_rep0[states];
++ Bit_model bm_rep1[states];
++ Bit_model bm_rep2[states];
++ Bit_model bm_len[states][pos_states];
++ Bit_model bm_dis_slot[len_states][1 << dis_slot_bits];
++ Bit_model bm_dis[modeled_distances-end_dis_model+1];
++ Bit_model bm_align[dis_align_size];
++ struct Len_model match_len_model;
++ struct Len_model rep_len_model;
++
++ unsigned long buffer_size;
++ unsigned dictionary_size;
++ uint8_t *buffer; /* output buffer */
++ unsigned long pos; /* current pos in buffer */
++ unsigned long stream_pos; /* first byte not yet written to file */
++ uint32_t crc;
++ long (*flush)(void*, unsigned long);
++ bool pos_wrapped;
++ bool buffer_given;
++ bool write_error;
++};
++
++static void LZd_flush_data(struct LZ_decoder * const d)
++{
++ if (d->pos > d->stream_pos) {
++ const long size = d->pos - d->stream_pos;
++
++ CRC32_update_buf(&d->crc, d->buffer + d->stream_pos, size);
++ if ((d->flush &&
++ d->flush(d->buffer + d->stream_pos, size) != size) ||
++ (!d->flush && d->pos_wrapped))
++ d->write_error = true;
++ if (d->pos >= d->buffer_size) {
++ d->partial_data_pos += d->pos;
++ d->pos = 0;
++ d->pos_wrapped = true;
++ }
++ d->stream_pos = d->pos;
++ }
++}
++
++static inline uint8_t LZd_peek_prev(const struct LZ_decoder * const d)
++{
++ if (d->pos > 0)
++ return d->buffer[d->pos-1];
++ if (d->pos_wrapped)
++ return d->buffer[d->buffer_size-1];
++ return 0; /* prev_byte of first byte */
++}
++
++static inline uint8_t LZd_peek(const struct LZ_decoder * const d,
++ const unsigned distance)
++{
++ const unsigned long i = ((d->pos > distance) ? 0 : d->buffer_size) +
++ d->pos - distance - 1;
++ return d->buffer[i];
++}
++
++static inline void LZd_put_byte(struct LZ_decoder * const d, const uint8_t b)
++{
++ d->buffer[d->pos] = b;
++ if (++d->pos >= d->buffer_size)
++ LZd_flush_data(d);
++}
++
++static inline void LZd_copy_block(struct LZ_decoder * const d,
++ const unsigned distance, unsigned len)
++{
++ unsigned long lpos = d->pos, i = lpos - distance - 1;
++ bool fast, fast2;
++
++ if (lpos > distance) {
++ fast = (len < d->buffer_size - lpos);
++ fast2 = (fast && len <= lpos - i);
++ } else {
++ i += d->buffer_size;
++ fast = (len < d->buffer_size - i); /* (i == pos) may happen */
++ fast2 = (fast && len <= i - lpos);
++ }
++ if (fast) { /* no wrap */
++ d->pos += len;
++ if (fast2) /* no wrap, no overlap */
++ memcpy(d->buffer + lpos, d->buffer + i, len);
++ else
++ for (; len > 0; --len)
++ d->buffer[lpos++] = d->buffer[i++];
++ } else
++ for (; len > 0; --len) {
++ d->buffer[d->pos] = d->buffer[i];
++ if (++d->pos >= d->buffer_size)
++ LZd_flush_data(d);
++ if (++i >= d->buffer_size)
++ i = 0;
++ }
++}
++
++static inline bool LZd_init(struct LZ_decoder * const d,
++ struct Range_decoder * const rde,
++ const unsigned dict_size, uint8_t * const outbuf,
++ long out_size, long (*flush)(void*, unsigned long))
++{
++ d->partial_data_pos = 0;
++ d->rdec = rde;
++ Bm_array_init(d->bm_literal[0], (1 << literal_context_bits) * 0x300);
++ Bm_array_init(d->bm_match[0], states * pos_states);
++ Bm_array_init(d->bm_rep, states);
++ Bm_array_init(d->bm_rep0, states);
++ Bm_array_init(d->bm_rep1, states);
++ Bm_array_init(d->bm_rep2, states);
++ Bm_array_init(d->bm_len[0], states * pos_states);
++ Bm_array_init(d->bm_dis_slot[0], len_states * (1 << dis_slot_bits));
++ Bm_array_init(d->bm_dis, modeled_distances - end_dis_model + 1);
++ Bm_array_init(d->bm_align, dis_align_size);
++ Lm_init(&d->match_len_model);
++ Lm_init(&d->rep_len_model);
++
++ d->buffer_given = (outbuf && out_size > 0);
++ d->buffer_size = d->buffer_given ? (unsigned long)out_size : dict_size;
++ d->dictionary_size = min_t(unsigned long, d->buffer_size, dict_size);
++ d->buffer = d->buffer_given ? outbuf : large_malloc(d->buffer_size);
++ if (!d->buffer)
++ return false;
++ d->pos = 0;
++ d->stream_pos = 0;
++ d->crc = 0xFFFFFFFFU;
++ d->flush = flush;
++ d->pos_wrapped = false;
++ d->write_error = false;
++ /* prev_byte of first byte; also for LZd_peek( 0 ) on corrupt file */
++ if (!d->buffer_given) /* inbuf and outbuf may overlap */
++ d->buffer[d->buffer_size-1] = 0;
++ return true;
++}
++
++static inline void LZd_free(struct LZ_decoder * const d)
++{
++ if (!d->buffer_given)
++ large_free(d->buffer);
++}
++
++static inline unsigned LZd_crc(const struct LZ_decoder * const d)
++{
++ return d->crc ^ 0xFFFFFFFFU;
++}
++
++static inline unsigned long long
++LZd_data_position(const struct LZ_decoder * const d)
++{
++ return d->partial_data_pos + d->pos;
++}
++
++
++static bool LZd_verify_trailer(struct LZ_decoder * const d)
++{
++ Lzip_trailer trailer;
++ int i = 0;
++
++ while (i < Lt_size)
++ trailer[i++] = Rd_get_byte(d->rdec);
++
++ return (Lt_get_data_crc(trailer) == LZd_crc(d) &&
++ Lt_get_data_size(trailer) == LZd_data_position(d) &&
++ Lt_get_member_size(trailer) == Rd_member_position(d->rdec));
++}
++
++
++/* Return value: 0 = OK, < 0 = error (see include/linux/lzip.h). */
++static int LZd_decode_member(struct LZ_decoder * const d)
++{
++ struct Range_decoder * const rdec = d->rdec;
++ unsigned rep0 = 0; /* rep[0-3] latest four distances */
++ unsigned rep1 = 0; /* used for efficient coding of */
++ unsigned rep2 = 0; /* repeated distances */
++ unsigned rep3 = 0;
++ State state = 0;
++
++ Rd_load(rdec);
++ while (!Rd_finished(rdec)) {
++ int len;
++ const int pos_state = LZd_data_position(d) & pos_state_mask;
++
++ if (Rd_decode_bit(rdec, &d->bm_match[state][pos_state]) == 0) {
++ /* literal byte */
++ Bit_model * const bm = d->bm_literal[get_lit_state(LZd_peek_prev(d))];
++
++ if (St_is_char(state)) {
++ state -= (state < 4) ? state : 3;
++ LZd_put_byte(d, Rd_decode_tree8(rdec, bm));
++ } else {
++ state -= (state < 10) ? 3 : 6;
++ LZd_put_byte(d, Rd_decode_matched(rdec, bm, LZd_peek(d, rep0)));
++ }
++ continue;
++ }
++ /* match or repeated match */
++ if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) {
++ if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) {
++ if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) {
++ state = St_set_short_rep(state);
++ LZd_put_byte(d, LZd_peek(d, rep0));
++ continue;
++ }
++ } else {
++ unsigned distance;
++
++ if (Rd_decode_bit(rdec, &d->bm_rep1[state]) == 0)
++ distance = rep1;
++ else {
++ if (Rd_decode_bit(rdec, &d->bm_rep2[state]) == 0)
++ distance = rep2;
++ else {
++ distance = rep3;
++ rep3 = rep2;
++ }
++ rep2 = rep1;
++ }
++ rep1 = rep0;
++ rep0 = distance;
++ }
++ state = St_set_rep(state);
++ len = min_match_len + Rd_decode_len(rdec, &d->rep_len_model, pos_state);
++ } else { /* match */
++ unsigned distance;
++
++ len = min_match_len + Rd_decode_len(rdec, &d->match_len_model, pos_state);
++ distance = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]);
++ if (distance >= start_dis_model) {
++ const unsigned dis_slot = distance;
++ const int direct_bits = (dis_slot >> 1) - 1;
++
++ distance = (2 | (dis_slot & 1)) << direct_bits;
++ if (dis_slot < end_dis_model)
++ distance += Rd_decode_tree_reversed(rdec,
++ d->bm_dis + (distance - dis_slot), direct_bits);
++ else {
++ distance +=
++ Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits;
++ distance += Rd_decode_tree_reversed4(rdec, d->bm_align);
++ if (distance == 0xFFFFFFFFU) { /* marker found */
++ Rd_normalize(rdec);
++ LZd_flush_data(d);
++ if (d->write_error)
++ return LZIP_WRITE_ERROR;
++ if (len == min_match_len) { /* End Of Stream marker */
++ if (LZd_verify_trailer(d))
++ return 0;
++ else
++ return LZIP_BAD_CRC;
++ }
++ if (len == min_match_len + 1) { /* Sync Flush marker */
++ Rd_load(rdec);
++ continue;
++ }
++ return LZIP_BAD_DATA; /* unknown marker */
++ }
++ }
++ }
++ rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
++ state = St_set_match(state);
++ if (rep0 >= d->dictionary_size ||
++ (rep0 >= d->pos && !d->pos_wrapped)) {
++ LZd_flush_data(d);
++ return LZIP_BAD_DATA;
++ }
++ }
++ LZd_copy_block(d, rep0, len);
++ }
++ LZd_flush_data(d);
++ return LZIP_DATA_EOF;
++}
++
++
++int lzip_decompress(unsigned char *inbuf, long in_len,
++ long (*fill)(void*, unsigned long),
++ long (*flush)(void*, unsigned long),
++ unsigned char *outbuf, long out_size,
++ long *in_posp, long *out_posp)
++{
++ unsigned char *outptr = outbuf;
++ struct Range_decoder rdec;
++ struct LZ_decoder *decoder = 0;
++ int retval = 0;
++ bool first_member;
++
++ if (in_posp)
++ *in_posp = 0;
++ if (out_posp)
++ *out_posp = 0;
++
++ if (!Rd_init(&rdec, inbuf, in_len, fill))
++ return LZIP_OOM_INBUF;
++
++ for (first_member = true;; first_member = false) {
++ long data_pos;
++ int size;
++ unsigned dictionary_size;
++ Lzip_header header;
++
++ Rd_reset_member_position(&rdec);
++ for (size = 0; size < Lh_size && !Rd_finished(&rdec); ++size)
++ header[size] = Rd_get_byte(&rdec);
++ if (Rd_finished(&rdec)) { /* End Of File */
++ if (first_member)
++ retval = LZIP_HEADER1_EOF;
++ else if (Lh_verify_prefix(header, size))
++ retval = LZIP_HEADER2_EOF;
++ break;
++ }
++ if (!Lh_verify_magic(header)) {
++ if (first_member)
++ retval = LZIP_BAD_MAGIC1;
++ else if (Lh_verify_corrupt(header))
++ retval = LZIP_BAD_MAGIC2;
++ break;
++ }
++ if (!Lh_verify_version(header)) {
++ retval = LZIP_BAD_VERSION;
++ break;
++ }
++ dictionary_size = Lh_get_dictionary_size(header);
++ if (dictionary_size < min_dictionary_size ||
++ dictionary_size > max_dictionary_size) {
++ retval = LZIP_BAD_DICT_SIZE;
++ break;
++ }
++
++ if (!decoder)
++ decoder = malloc(sizeof *decoder);
++ if (!decoder || !LZd_init(decoder, &rdec, dictionary_size,
++ outptr, out_size, flush)) {
++ retval = LZIP_OOM_OUTBUF;
++ break;
++ }
++ retval = LZd_decode_member(decoder);
++ if (in_posp)
++ *in_posp += Rd_member_position(&rdec);
++ data_pos = LZd_data_position(decoder);
++ if (outptr)
++ outptr += data_pos;
++ if (out_posp)
++ *out_posp += data_pos;
++ if (out_size > 0)
++ out_size -= data_pos;
++ LZd_free(decoder);
++ if (retval != 0)
++ break;
++ }
++ if (decoder)
++ free(decoder);
++ Rd_free(&rdec);
++ return retval;
++}
++
++#ifndef STATIC
++EXPORT_SYMBOL_GPL(lzip_decompress);
++#endif
++MODULE_DESCRIPTION("LZIP Decompressor");
++MODULE_AUTHOR("Antonio Diaz Diaz <antonio@gnu.org>");
++MODULE_LICENSE("GPL");
+diff -urdN linux-4.19.8/scripts/Makefile.lib linux-4.19.8.new/scripts/Makefile.lib
+--- linux-4.19.8/scripts/Makefile.lib 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/scripts/Makefile.lib 2018-12-09 18:01:59.000000000 +0100
+@@ -319,6 +319,21 @@
+ bzip2 -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
+ (rm -f $@ ; false)
+
++# Lzip
++# ---------------------------------------------------------------------------
++# The .lz format has the uncompressed size available at the end of the
++# file, but at offset (member_size - 16). So we append a gzip-style size.
++# Use klzip to compress the kernel image and lzip to compress other things.
++
++quiet_cmd_klzip = LZIP $@
++cmd_klzip = (cat $(filter-out FORCE,$^) | \
++ lzip -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
++ (rm -f $@ ; false)
++
++quiet_cmd_lzip = LZIP $@
++cmd_lzip = (cat $(filter-out FORCE,$^) | lzip -9) > $@ || \
++ (rm -f $@ ; false)
++
+ # Lzma
+ # ---------------------------------------------------------------------------
+
+diff -urdN linux-4.19.8/scripts/extract-ikconfig linux-4.19.8.new/scripts/extract-ikconfig
+--- linux-4.19.8/scripts/extract-ikconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/scripts/extract-ikconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -59,6 +59,7 @@
+ try_decompress '\037\213\010' xy gunzip
+ try_decompress '\3757zXZ\000' abcde unxz
+ try_decompress 'BZh' xy bunzip2
++try_decompress 'LZIP' xyz 'lzip -d'
+ try_decompress '\135\0\0\0' xxx unlzma
+ try_decompress '\211\114\132' xy 'lzop -d'
+ try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
+diff -urdN linux-4.19.8/scripts/extract-vmlinux linux-4.19.8.new/scripts/extract-vmlinux
+--- linux-4.19.8/scripts/extract-vmlinux 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/scripts/extract-vmlinux 2018-12-09 18:01:59.000000000 +0100
+@@ -55,6 +55,7 @@
+ try_decompress '\037\213\010' xy gunzip
+ try_decompress '\3757zXZ\000' abcde unxz
+ try_decompress 'BZh' xy bunzip2
++try_decompress 'LZIP' xyz 'lzip -d'
+ try_decompress '\135\0\0\0' xxx unlzma
+ try_decompress '\211\114\132' xy 'lzop -d'
+ try_decompress '\002!L\030' xxx 'lz4 -d'
+diff -urdN linux-4.19.8/scripts/package/Makefile linux-4.19.8.new/scripts/package/Makefile
+--- linux-4.19.8/scripts/package/Makefile 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/scripts/package/Makefile 2018-12-09 18:01:59.000000000 +0100
+@@ -129,8 +129,9 @@
+ $(if $(findstring tar-src,$@),, \
+ $(if $(findstring bz2,$@),bzip2, \
+ $(if $(findstring gz,$@),gzip, \
++$(if $(findstring lz,$@),lzip, \
+ $(if $(findstring xz,$@),xz, \
+-$(error unknown target $@)))) \
++$(error unknown target $@))))) \
+ -f -9 $(perf-tar).tar)
+
+ perf-%pkg: FORCE
+@@ -147,8 +148,10 @@
+ @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
+ @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
+ @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball'
++ @echo ' tarlz-pkg - Build the kernel as a lzip compressed tarball'
+ @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball'
+ @echo ' perf-tar-src-pkg - Build $(perf-tar).tar source tarball'
+ @echo ' perf-targz-src-pkg - Build $(perf-tar).tar.gz source tarball'
+ @echo ' perf-tarbz2-src-pkg - Build $(perf-tar).tar.bz2 source tarball'
++ @echo ' perf-tarlz-src-pkg - Build $(perf-tar).tar.lz source tarball'
+ @echo ' perf-tarxz-src-pkg - Build $(perf-tar).tar.xz source tarball'
+diff -urdN linux-4.19.8/scripts/package/buildtar linux-4.19.8.new/scripts/package/buildtar
+--- linux-4.19.8/scripts/package/buildtar 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/scripts/package/buildtar 2018-12-09 18:01:59.000000000 +0100
+@@ -35,6 +35,10 @@
+ opts=--bzip2
+ tarball=${tarball}.bz2
+ ;;
++ tarlz-pkg)
++ opts=--lzip
++ tarball=${tarball}.lz
++ ;;
+ tarxz-pkg)
+ opts=--xz
+ tarball=${tarball}.xz
+diff -urdN linux-4.19.8/scripts/patch-kernel linux-4.19.8.new/scripts/patch-kernel
+--- linux-4.19.8/scripts/patch-kernel 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/scripts/patch-kernel 2018-12-09 18:01:59.000000000 +0100
+@@ -117,6 +117,10 @@
+ ext=".bz2"
+ name="bzip2"
+ uncomp="bunzip2 -dc"
++ elif [ -r ${filebase}.lz ]; then
++ ext=".lz"
++ name="lzip"
++ uncomp="lzip -dc"
+ elif [ -r ${filebase}.xz ]; then
+ ext=".xz"
+ name="xz"
+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
+--- linux-4.19.8/tools/testing/selftests/gen_kselftest_tar.sh 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/tools/testing/selftests/gen_kselftest_tar.sh 2018-12-09 18:01:59.000000000 +0100
+@@ -27,6 +27,10 @@
+ copts="cvjf"
+ ext=".tar.bz2"
+ ;;
++ tarlz)
++ copts="cv --lzip -f"
++ ext=".tar.lz"
++ ;;
+ tarxz)
+ copts="cvJf"
+ ext=".tar.xz"
+diff -urdN linux-4.19.8/usr/.gitignore linux-4.19.8.new/usr/.gitignore
+--- linux-4.19.8/usr/.gitignore 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/usr/.gitignore 2018-12-09 18:01:59.000000000 +0100
+@@ -5,6 +5,7 @@
+ initramfs_data.cpio
+ initramfs_data.cpio.gz
+ initramfs_data.cpio.bz2
++initramfs_data.cpio.lz
+ initramfs_data.cpio.lzma
+ initramfs_list
+ include
+diff -urdN linux-4.19.8/usr/Kconfig linux-4.19.8.new/usr/Kconfig
+--- linux-4.19.8/usr/Kconfig 2018-12-08 12:59:10.000000000 +0100
++++ linux-4.19.8.new/usr/Kconfig 2018-12-09 18:01:59.000000000 +0100
+@@ -70,6 +70,15 @@
+ Support loading of a bzip2 encoded initial ramdisk or cpio buffer
+ If unsure, say N.
+
++config RD_LZIP
++ bool "Support initial ramdisk/ramfs compressed using lzip"
++ default y
++ depends on BLK_DEV_INITRD
++ select DECOMPRESS_LZIP
++ help
++ Support loading of a lzip encoded initial ramdisk or cpio buffer.
++ If unsure, say N.
++
+ config RD_LZMA
+ bool "Support initial ramdisk/ramfs compressed using LZMA"
+ default y
+@@ -165,6 +174,18 @@
+ If you choose this, keep in mind that you need to have the bzip2 tool
+ available to be able to compress the initram.
+
++config INITRAMFS_COMPRESSION_LZIP
++ bool "Lzip"
++ depends on RD_LZIP
++ help
++ Lzip's compression ratio is better than that of gzip and bzip2.
++ Decompression speed is between gzip and bzip2. Compression can
++ be as fast as gzip or slower than bzip2 depending on compression
++ level. Lzip can produce a initramfs about a 16% smaller than gzip.
++
++ If you choose this, keep in mind that you need to have the lzip tool
++ available to be able to compress the initram.
++
+ config INITRAMFS_COMPRESSION_LZMA
+ bool "LZMA"
+ depends on RD_LZMA
+@@ -222,12 +243,14 @@
+ default "" if INITRAMFS_COMPRESSION_NONE
+ default ".gz" if INITRAMFS_COMPRESSION_GZIP
+ default ".bz2" if INITRAMFS_COMPRESSION_BZIP2
++ default ".lz" if INITRAMFS_COMPRESSION_LZIP
+ default ".lzma" if INITRAMFS_COMPRESSION_LZMA
+ default ".xz" if INITRAMFS_COMPRESSION_XZ
+ default ".lzo" if INITRAMFS_COMPRESSION_LZO
+ default ".lz4" if INITRAMFS_COMPRESSION_LZ4
+ default ".gz" if RD_GZIP
+ default ".lz4" if RD_LZ4
++ default ".lz" if RD_LZIP
+ default ".lzo" if RD_LZO
+ default ".xz" if RD_XZ
+ default ".lzma" if RD_LZMA