1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750 |
- diff -urdN linux-5.16.11/Documentation/lzip.txt linux-5.16.11.new/Documentation/lzip.txt
- --- linux-5.16.11/Documentation/lzip.txt 1970-01-01 01:00:00.000000000 +0100
- +++ linux-5.16.11.new/Documentation/lzip.txt 2022-02-28 22:10:45.790400069 +0100
- @@ -0,0 +1,58 @@
- +==============================
- +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 uses a simplified form of the 'Lempel-Ziv-Markov
- +chain-Algorithm' (LZMA) stream format, chosen to maximize safety and
- +interoperability. 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 is better than gzip and bzip2 from
- +a data recovery perspective. Lzip has been designed, written, and tested
- +with great care to replace gzip and bzip2 as the standard general-purpose
- +compressed format for unix-like systems, especially for long-term archiving.
- +
- +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 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: 2021-03-22
- diff -urdN linux-5.16.11/Makefile linux-5.16.11.new/Makefile
- --- linux-5.16.11/Makefile 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/Makefile 2022-02-28 22:22:19.180431558 +0100
- @@ -474,6 +474,7 @@
- BASH = bash
- KGZIP = gzip
- KBZIP2 = bzip2
- +KLZIP = lzip
- KLZOP = lzop
- LZMA = lzma
- LZ4 = lz4c
- @@ -528,7 +529,7 @@
- export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC
- export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
- export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
- -export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
- +export KGZIP KBZIP2 KLZIP KLZOP LZMA LZ4 XZ ZSTD
- export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
-
- export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
- diff -urdN linux-5.16.11/arch/arm/Kconfig linux-5.16.11.new/arch/arm/Kconfig
- --- linux-5.16.11/arch/arm/Kconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/arch/arm/Kconfig 2022-02-28 22:10:45.790400069 +0100
- @@ -98,6 +98,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-5.16.11/arch/arm/boot/compressed/Makefile linux-5.16.11.new/arch/arm/boot/compressed/Makefile
- --- linux-5.16.11/arch/arm/boot/compressed/Makefile 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/arch/arm/boot/compressed/Makefile 2022-02-28 22:10:45.790400069 +0100
- @@ -77,6 +77,7 @@
- CPPFLAGS_vmlinux.lds += -DMALLOC_SIZE="$(MALLOC_SIZE)"
-
- 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-5.16.11/arch/arm/boot/compressed/decompress.c linux-5.16.11.new/arch/arm/boot/compressed/decompress.c
- --- linux-5.16.11/arch/arm/boot/compressed/decompress.c 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/arch/arm/boot/compressed/decompress.c 2022-02-28 22:10:45.790400069 +0100
- @@ -38,6 +38,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-5.16.11/arch/x86/Kconfig linux-5.16.11.new/arch/x86/Kconfig
- --- linux-5.16.11/arch/x86/Kconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/arch/x86/Kconfig 2022-02-28 22:10:45.790400069 +0100
- @@ -211,6 +211,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-5.16.11/arch/x86/boot/compressed/Makefile linux-5.16.11.new/arch/x86/boot/compressed/Makefile
- --- linux-5.16.11/arch/x86/boot/compressed/Makefile 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/arch/x86/boot/compressed/Makefile 2022-02-28 22:10:45.790400069 +0100
- @@ -26,6 +26,7 @@
- KCOV_INSTRUMENT := n
-
- targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
- + vmlinux.bin.lz \
- vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst
-
- # CLANG_FLAGS must come before any cc-disable-warning or cc-option calls in
- @@ -127,6 +128,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
- @@ -140,6 +143,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-5.16.11/arch/x86/boot/compressed/misc.c linux-5.16.11.new/arch/x86/boot/compressed/misc.c
- --- linux-5.16.11/arch/x86/boot/compressed/misc.c 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/arch/x86/boot/compressed/misc.c 2022-02-28 22:10:45.790400069 +0100
- @@ -62,6 +62,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-5.16.11/fs/squashfs/Kconfig linux-5.16.11.new/fs/squashfs/Kconfig
- --- linux-5.16.11/fs/squashfs/Kconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/fs/squashfs/Kconfig 2022-02-28 22:10:45.790400069 +0100
- @@ -136,6 +136,21 @@
-
- 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"
- depends on SQUASHFS
- diff -urdN linux-5.16.11/fs/squashfs/Makefile linux-5.16.11.new/fs/squashfs/Makefile
- --- linux-5.16.11/fs/squashfs/Makefile 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/fs/squashfs/Makefile 2022-02-28 22:10:45.790400069 +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-5.16.11/fs/squashfs/decompressor.c linux-5.16.11.new/fs/squashfs/decompressor.c
- --- linux-5.16.11/fs/squashfs/decompressor.c 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/fs/squashfs/decompressor.c 2022-02-28 22:10:45.790400069 +0100
- @@ -34,6 +34,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
- @@ -65,6 +71,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-5.16.11/fs/squashfs/decompressor.h linux-5.16.11.new/fs/squashfs/decompressor.h
- --- linux-5.16.11/fs/squashfs/decompressor.h 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/fs/squashfs/decompressor.h 2022-02-28 22:10:45.790400069 +0100
- @@ -38,6 +38,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-5.16.11/fs/squashfs/lzip_wrapper.c linux-5.16.11.new/fs/squashfs/lzip_wrapper.c
- --- linux-5.16.11/fs/squashfs/lzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-5.16.11.new/fs/squashfs/lzip_wrapper.c 2022-02-28 23:14:30.780431657 +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-2022 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/bio.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)
- + return stream;
- +
- + 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 bio *bio, int offset, int length,
- + struct squashfs_page_actor *output)
- +{
- + struct bvec_iter_all iter_all = {};
- + struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
- + struct squashfs_lzip *stream = strm;
- + void *buff = stream->input, *data;
- + long out_pos;
- + int bytes = length, res;
- +
- + while (bio_next_segment(bio, &iter_all)) {
- + int avail = min(bytes, ((int)bvec->bv_len) - offset);
- +
- + data = bvec_virt(bvec);
- + memcpy(buff, data + offset, avail);
- + buff += avail;
- + bytes -= avail;
- + offset = 0;
- + }
- +
- + 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-5.16.11/fs/squashfs/squashfs_fs.h linux-5.16.11.new/fs/squashfs/squashfs_fs.h
- --- linux-5.16.11/fs/squashfs/squashfs_fs.h 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/fs/squashfs/squashfs_fs.h 2022-02-28 22:10:45.790400069 +0100
- @@ -236,6 +236,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-5.16.11/include/linux/decompress/lunzip.h linux-5.16.11.new/include/linux/decompress/lunzip.h
- --- linux-5.16.11/include/linux/decompress/lunzip.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-5.16.11.new/include/linux/decompress/lunzip.h 2022-02-28 22:10:45.790400069 +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-5.16.11/include/linux/lzip.h linux-5.16.11.new/include/linux/lzip.h
- --- linux-5.16.11/include/linux/lzip.h 1970-01-01 01:00:00.000000000 +0100
- +++ linux-5.16.11.new/include/linux/lzip.h 2022-02-28 23:01:36.770430310 +0100
- @@ -0,0 +1,53 @@
- +/* SPDX-License-Identifier: GPL-2.0 */
- +#ifndef __LZIP_H__
- +#define __LZIP_H__
- +/*
- + * LZIP decompressor
- + *
- + * Copyright (C) 2016-2022 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-5.16.11/init/Kconfig linux-5.16.11.new/init/Kconfig
- --- linux-5.16.11/init/Kconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/init/Kconfig 2022-02-28 22:44:38.850430221 +0100
- @@ -207,6 +207,9 @@
- config HAVE_KERNEL_BZIP2
- bool
-
- +config HAVE_KERNEL_LZIP
- + bool
- +
- config HAVE_KERNEL_LZMA
- bool
-
- @@ -228,7 +231,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_ZSTD || 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_ZSTD || HAVE_KERNEL_UNCOMPRESSED
- help
- The linux kernel is a kind of self-extracting executable.
- Several compression algorithms are available, which differ
- @@ -264,6 +267,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
- @@ -2247,7 +2259,7 @@
-
- Please note that the tool used to load modules needs to support the
- corresponding algorithm. module-init-tools MAY support gzip, and kmod
- - MAY support gzip, xz and zstd.
- + MAY support gzip, lzip, xz and zstd.
-
- Your build system needs to provide the appropriate compression tool
- to compress the modules.
- @@ -2266,6 +2278,12 @@
- Compress modules with GZIP. The installed modules are suffixed
- with .ko.gz.
-
- +config MODULE_COMPRESS_LZIP
- + bool "LZIP"
- + help
- + Compress modules with LZIP. The installed modules are suffixed
- + with .ko.lz.
- +
- config MODULE_COMPRESS_XZ
- bool "XZ"
- help
- diff -urdN linux-5.16.11/init/do_mounts_rd.c linux-5.16.11.new/init/do_mounts_rd.c
- --- linux-5.16.11/init/do_mounts_rd.c 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/init/do_mounts_rd.c 2022-02-28 22:10:45.790400069 +0100
- @@ -49,6 +49,7 @@
- * squashfs
- * gzip
- * bzip2
- + * lzip
- * lzma
- * xz
- * lzo
- diff -urdN linux-5.16.11/lib/Kconfig linux-5.16.11.new/lib/Kconfig
- --- linux-5.16.11/lib/Kconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/lib/Kconfig 2022-02-28 22:10:45.790400069 +0100
- @@ -311,6 +311,9 @@
- help
- Enable s390x hardware support for zlib in the kernel.
-
- +config LZIP_DECOMPRESS
- + tristate
- +
- config LZO_COMPRESS
- tristate
-
- @@ -347,6 +350,10 @@
- config DECOMPRESS_BZIP2
- tristate
-
- +config DECOMPRESS_LZIP
- + select LZIP_DECOMPRESS
- + tristate
- +
- config DECOMPRESS_LZMA
- tristate
-
- diff -urdN linux-5.16.11/lib/Makefile linux-5.16.11.new/lib/Makefile
- --- linux-5.16.11/lib/Makefile 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/lib/Makefile 2022-02-28 22:10:45.790400069 +0100
- @@ -184,6 +184,7 @@
- obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc/
- 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/
- @@ -196,6 +197,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-5.16.11/lib/decompress.c linux-5.16.11.new/lib/decompress.c
- --- linux-5.16.11/lib/decompress.c 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/lib/decompress.c 2022-02-28 22:10:45.790400069 +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>
- @@ -26,6 +27,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
- @@ -52,6 +56,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-5.16.11/lib/decompress_lunzip.c linux-5.16.11.new/lib/decompress_lunzip.c
- --- linux-5.16.11/lib/decompress_lunzip.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-5.16.11.new/lib/decompress_lunzip.c 2022-02-28 23:02:02.330425107 +0100
- @@ -0,0 +1,100 @@
- +/*
- + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
- + *
- + * Copyright (C) 2016-2022 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-5.16.11/lib/lzip_decompress.c linux-5.16.11.new/lib/lzip_decompress.c
- --- linux-5.16.11/lib/lzip_decompress.c 1970-01-01 01:00:00.000000000 +0100
- +++ linux-5.16.11.new/lib/lzip_decompress.c 2022-02-28 23:02:22.360432092 +0100
- @@ -0,0 +1,873 @@
- +/*
- + * LZIP decompressor
- + *
- + * Copyright (C) 2016-2022 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, /* >= modeled_distances */
- + 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 dictionary 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 <<= 1; symbol += 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 = 2 | Rd_decode_bit(rdec, &bm[1]);
- +
- + 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 = 2 | Rd_decode_bit(rdec, &bm[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]);
- + 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 <<= 1; model += 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]);
- +
- + symbol += Rd_decode_bit(rdec, &bm[2+symbol]) << 1;
- + symbol += Rd_decode_bit(rdec, &bm[4+symbol]) << 2;
- + symbol += Rd_decode_bit(rdec, &bm[8+symbol]) << 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 <<= 1; symbol += 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;
- + }
- + 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-5.16.11/scripts/Makefile.lib linux-5.16.11.new/scripts/Makefile.lib
- --- linux-5.16.11/scripts/Makefile.lib 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/scripts/Makefile.lib 2022-02-28 22:10:45.800401973 +0100
- @@ -397,6 +397,18 @@
- quiet_cmd_bzip2 = BZIP2 $@
- cmd_bzip2 = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
-
- +# 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 $(real-prereqs) | $(KLZIP) -9; $(size_append); } > $@
- +
- +quiet_cmd_lzip = LZIP $@
- + cmd_lzip = cat $(real-prereqs) | $(KLZIP) -9 > $@
- +
- # Lzma
- # ---------------------------------------------------------------------------
-
- diff -urdN linux-5.16.11/scripts/Makefile.modinst linux-5.16.11.new/scripts/Makefile.modinst
- --- linux-5.16.11/scripts/Makefile.modinst 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/scripts/Makefile.modinst 2022-02-28 22:29:45.920430307 +0100
- @@ -20,6 +20,7 @@
-
- suffix-y :=
- suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
- +suffix-$(CONFIG_MODULE_COMPRESS_LZIP) := .lz
- suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
- suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
-
- @@ -94,6 +95,8 @@
- #
- quiet_cmd_gzip = GZIP $@
- cmd_gzip = $(KGZIP) -n -f $<
- +quiet_cmd_lzip = LZIP $@
- + cmd_lzip = $(KLZIP) -f $<
- quiet_cmd_xz = XZ $@
- cmd_xz = $(XZ) --lzma2=dict=2MiB -f $<
- quiet_cmd_zstd = ZSTD $@
- @@ -102,6 +105,9 @@
- $(dst)/%.ko.gz: $(dst)/%.ko FORCE
- $(call cmd,gzip)
-
- +$(dst)/%.ko.lz: $(dst)/%.ko FORCE
- + $(call cmd,lzip)
- +
- $(dst)/%.ko.xz: $(dst)/%.ko FORCE
- $(call cmd,xz)
-
- diff -urdN linux-5.16.11/scripts/extract-ikconfig linux-5.16.11.new/scripts/extract-ikconfig
- --- linux-5.16.11/scripts/extract-ikconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/scripts/extract-ikconfig 2022-02-28 22:10:45.800401973 +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-5.16.11/scripts/extract-vmlinux linux-5.16.11.new/scripts/extract-vmlinux
- --- linux-5.16.11/scripts/extract-vmlinux 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/scripts/extract-vmlinux 2022-02-28 22:10:45.800401973 +0100
- @@ -52,6 +52,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-5.16.11/scripts/package/buildtar linux-5.16.11.new/scripts/package/buildtar
- --- linux-5.16.11/scripts/package/buildtar 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/scripts/package/buildtar 2022-02-28 22:10:45.800401973 +0100
- @@ -35,6 +35,10 @@
- opts="-I ${KBZIP2}"
- tarball=${tarball}.bz2
- ;;
- + tarlz-pkg)
- + opts="-I ${KLZIP}"
- + tarball=${tarball}.lz
- + ;;
- tarxz-pkg)
- opts="-I ${XZ}"
- tarball=${tarball}.xz
- diff -urdN linux-5.16.11/scripts/patch-kernel linux-5.16.11.new/scripts/patch-kernel
- --- linux-5.16.11/scripts/patch-kernel 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/scripts/patch-kernel 2022-02-28 22:10:45.800401973 +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-5.16.11/tools/testing/selftests/gen_kselftest_tar.sh linux-5.16.11.new/tools/testing/selftests/gen_kselftest_tar.sh
- --- linux-5.16.11/tools/testing/selftests/gen_kselftest_tar.sh 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/tools/testing/selftests/gen_kselftest_tar.sh 2022-02-28 23:52:00.350458667 +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-5.16.11/usr/Kconfig linux-5.16.11.new/usr/Kconfig
- --- linux-5.16.11/usr/Kconfig 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/usr/Kconfig 2022-03-01 00:01:32.160430303 +0100
- @@ -68,6 +68,14 @@
- 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
- + 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
- @@ -155,6 +163,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
- diff -urdN linux-5.16.11/usr/Makefile linux-5.16.11.new/usr/Makefile
- --- linux-5.16.11/usr/Makefile 2022-02-24 00:42:52.000000000 +0100
- +++ linux-5.16.11.new/usr/Makefile 2022-02-28 22:10:45.800401973 +0100
- @@ -11,6 +11,7 @@
- compress-y := shipped
- compress-$(CONFIG_INITRAMFS_COMPRESSION_GZIP) := gzip
- compress-$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) := bzip2
- +compress-$(CONFIG_INITRAMFS_COMPRESSION_LZIP) := lzip
- compress-$(CONFIG_INITRAMFS_COMPRESSION_LZMA) := lzma
- compress-$(CONFIG_INITRAMFS_COMPRESSION_XZ) := xzmisc
- compress-$(CONFIG_INITRAMFS_COMPRESSION_LZO) := lzo
|