linux-5.16.11_lzip-0.diff 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
  1. diff -urdN linux-5.16.11/Documentation/lzip.txt linux-5.16.11.new/Documentation/lzip.txt
  2. --- linux-5.16.11/Documentation/lzip.txt 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-5.16.11.new/Documentation/lzip.txt 2022-02-28 22:10:45.790400069 +0100
  4. @@ -0,0 +1,58 @@
  5. +==============================
  6. +Lzip data compression in Linux
  7. +==============================
  8. +
  9. +Introduction
  10. +============
  11. +
  12. +Lzip is a lossless data compressor with a user interface similar to the one
  13. +of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov
  14. +chain-Algorithm' (LZMA) stream format, chosen to maximize safety and
  15. +interoperability. Lzip can compress about as fast as gzip (lzip -0) or
  16. +compress most files more than bzip2 (lzip -9). Decompression speed is
  17. +intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 from
  18. +a data recovery perspective. Lzip has been designed, written, and tested
  19. +with great care to replace gzip and bzip2 as the standard general-purpose
  20. +compressed format for unix-like systems, especially for long-term archiving.
  21. +
  22. +Learn more about lzip at http://www.nongnu.org/lzip/lzip.html
  23. +
  24. +Lzip related components in the kernel
  25. +=====================================
  26. +
  27. +The lzip_decompress module in lib/lzip_decompress.c provides a versatile lzip
  28. +decompression function able to do buffer to buffer decompression or stream
  29. +decompression with fill and flush callback functions. The usage of the
  30. +function is documented in include/linux/lzip.h.
  31. +
  32. +For decompressing the kernel image, initramfs, and initrd, there is a wrapper
  33. +function in lib/decompress_lunzip.c providing the same common interface as the
  34. +other decompress_*.c files, which is defined in
  35. +include/linux/decompress/generic.h.
  36. +
  37. +For kernel makefiles, two commands are provided in scripts/Makefile.lib for
  38. +use with $(call if_changed). The kernel image must be compressed with
  39. +$(call if_changed,klzip) which will append a four-byte trailer containing the
  40. +size of the uncompressed data needed by the boot code. Other things should be
  41. +compressed with $(call if_changed,lzip).
  42. +
  43. +Testing
  44. +=======
  45. +
  46. +Lzip-compressed kernel images of multiple linux versions since 2.6.30.10 have
  47. +been built and tested, even on machines as modest as an AMD 486-DX2 at 66 MHz
  48. +with 64 MiB of RAM. In the worst case (on the slow machine above), lzip just
  49. +increased the boot time a 15% compared with gzip. On more modern machines,
  50. +lzip may boot slightly faster than gzip. It just takes 0.2 seconds for lzip to
  51. +decompress vmlinuz-4.4.16 on my machine.
  52. +
  53. +Decompression time is usually a small fraction of the total boot time. For
  54. +example, using lz4 on a desktop machine in order to save 0.05 seconds of a
  55. +total boot time of 20 seconds is probably not worth the increased image size.
  56. +
  57. +Xlunzip is a test tool for the lzip_decompress module. It is similar to
  58. +lunzip, but it uses the lzip_decompress module as a backend. The xlunzip home
  59. +page is at http://www.nongnu.org/lzip/xlunzip.html
  60. +
  61. +Author: Antonio Diaz Diaz
  62. +Updated: 2021-03-22
  63. diff -urdN linux-5.16.11/Makefile linux-5.16.11.new/Makefile
  64. --- linux-5.16.11/Makefile 2022-02-24 00:42:52.000000000 +0100
  65. +++ linux-5.16.11.new/Makefile 2022-02-28 22:22:19.180431558 +0100
  66. @@ -474,6 +474,7 @@
  67. BASH = bash
  68. KGZIP = gzip
  69. KBZIP2 = bzip2
  70. +KLZIP = lzip
  71. KLZOP = lzop
  72. LZMA = lzma
  73. LZ4 = lz4c
  74. @@ -528,7 +529,7 @@
  75. export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC
  76. export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
  77. export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
  78. -export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
  79. +export KGZIP KBZIP2 KLZIP KLZOP LZMA LZ4 XZ ZSTD
  80. export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
  81. export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
  82. diff -urdN linux-5.16.11/arch/arm/Kconfig linux-5.16.11.new/arch/arm/Kconfig
  83. --- linux-5.16.11/arch/arm/Kconfig 2022-02-24 00:42:52.000000000 +0100
  84. +++ linux-5.16.11.new/arch/arm/Kconfig 2022-02-28 22:10:45.790400069 +0100
  85. @@ -98,6 +98,7 @@
  86. select HAVE_IRQ_TIME_ACCOUNTING
  87. select HAVE_KERNEL_GZIP
  88. select HAVE_KERNEL_LZ4
  89. + select HAVE_KERNEL_LZIP
  90. select HAVE_KERNEL_LZMA
  91. select HAVE_KERNEL_LZO
  92. select HAVE_KERNEL_XZ
  93. diff -urdN linux-5.16.11/arch/arm/boot/compressed/Makefile linux-5.16.11.new/arch/arm/boot/compressed/Makefile
  94. --- linux-5.16.11/arch/arm/boot/compressed/Makefile 2022-02-24 00:42:52.000000000 +0100
  95. +++ linux-5.16.11.new/arch/arm/boot/compressed/Makefile 2022-02-28 22:10:45.790400069 +0100
  96. @@ -77,6 +77,7 @@
  97. CPPFLAGS_vmlinux.lds += -DMALLOC_SIZE="$(MALLOC_SIZE)"
  98. compress-$(CONFIG_KERNEL_GZIP) = gzip
  99. +compress-$(CONFIG_KERNEL_LZIP) = klzip
  100. compress-$(CONFIG_KERNEL_LZO) = lzo
  101. compress-$(CONFIG_KERNEL_LZMA) = lzma
  102. compress-$(CONFIG_KERNEL_XZ) = xzkern
  103. diff -urdN linux-5.16.11/arch/arm/boot/compressed/decompress.c linux-5.16.11.new/arch/arm/boot/compressed/decompress.c
  104. --- linux-5.16.11/arch/arm/boot/compressed/decompress.c 2022-02-24 00:42:52.000000000 +0100
  105. +++ linux-5.16.11.new/arch/arm/boot/compressed/decompress.c 2022-02-28 22:10:45.790400069 +0100
  106. @@ -38,6 +38,10 @@
  107. #include "../../../../lib/decompress_inflate.c"
  108. #endif
  109. +#ifdef CONFIG_KERNEL_LZIP
  110. +#include "../../../../lib/decompress_lunzip.c"
  111. +#endif
  112. +
  113. #ifdef CONFIG_KERNEL_LZO
  114. #include "../../../../lib/decompress_unlzo.c"
  115. #endif
  116. diff -urdN linux-5.16.11/arch/x86/Kconfig linux-5.16.11.new/arch/x86/Kconfig
  117. --- linux-5.16.11/arch/x86/Kconfig 2022-02-24 00:42:52.000000000 +0100
  118. +++ linux-5.16.11.new/arch/x86/Kconfig 2022-02-28 22:10:45.790400069 +0100
  119. @@ -211,6 +211,7 @@
  120. select HAVE_KERNEL_BZIP2
  121. select HAVE_KERNEL_GZIP
  122. select HAVE_KERNEL_LZ4
  123. + select HAVE_KERNEL_LZIP
  124. select HAVE_KERNEL_LZMA
  125. select HAVE_KERNEL_LZO
  126. select HAVE_KERNEL_XZ
  127. diff -urdN linux-5.16.11/arch/x86/boot/compressed/Makefile linux-5.16.11.new/arch/x86/boot/compressed/Makefile
  128. --- linux-5.16.11/arch/x86/boot/compressed/Makefile 2022-02-24 00:42:52.000000000 +0100
  129. +++ linux-5.16.11.new/arch/x86/boot/compressed/Makefile 2022-02-28 22:10:45.790400069 +0100
  130. @@ -26,6 +26,7 @@
  131. KCOV_INSTRUMENT := n
  132. targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
  133. + vmlinux.bin.lz \
  134. vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst
  135. # CLANG_FLAGS must come before any cc-disable-warning or cc-option calls in
  136. @@ -127,6 +128,8 @@
  137. $(call if_changed,gzip)
  138. $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
  139. $(call if_changed,bzip2)
  140. +$(obj)/vmlinux.bin.lz: $(vmlinux.bin.all-y) FORCE
  141. + $(call if_changed,klzip)
  142. $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
  143. $(call if_changed,lzma)
  144. $(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
  145. @@ -140,6 +143,7 @@
  146. suffix-$(CONFIG_KERNEL_GZIP) := gz
  147. suffix-$(CONFIG_KERNEL_BZIP2) := bz2
  148. +suffix-$(CONFIG_KERNEL_LZIP) := lz
  149. suffix-$(CONFIG_KERNEL_LZMA) := lzma
  150. suffix-$(CONFIG_KERNEL_XZ) := xz
  151. suffix-$(CONFIG_KERNEL_LZO) := lzo
  152. diff -urdN linux-5.16.11/arch/x86/boot/compressed/misc.c linux-5.16.11.new/arch/x86/boot/compressed/misc.c
  153. --- linux-5.16.11/arch/x86/boot/compressed/misc.c 2022-02-24 00:42:52.000000000 +0100
  154. +++ linux-5.16.11.new/arch/x86/boot/compressed/misc.c 2022-02-28 22:10:45.790400069 +0100
  155. @@ -62,6 +62,10 @@
  156. #include "../../../../lib/decompress_bunzip2.c"
  157. #endif
  158. +#ifdef CONFIG_KERNEL_LZIP
  159. +#include "../../../../lib/decompress_lunzip.c"
  160. +#endif
  161. +
  162. #ifdef CONFIG_KERNEL_LZMA
  163. #include "../../../../lib/decompress_unlzma.c"
  164. #endif
  165. diff -urdN linux-5.16.11/fs/squashfs/Kconfig linux-5.16.11.new/fs/squashfs/Kconfig
  166. --- linux-5.16.11/fs/squashfs/Kconfig 2022-02-24 00:42:52.000000000 +0100
  167. +++ linux-5.16.11.new/fs/squashfs/Kconfig 2022-02-28 22:10:45.790400069 +0100
  168. @@ -136,6 +136,21 @@
  169. If unsure, say N.
  170. +config SQUASHFS_LZIP
  171. + bool "Include support for LZIP compressed file systems"
  172. + depends on SQUASHFS
  173. + select LZIP_DECOMPRESS
  174. + help
  175. + Saying Y here includes support for reading Squashfs file systems
  176. + compressed with LZIP compression. LZIP gives better compression
  177. + than the default zlib compression, at the expense of greater CPU
  178. + and memory overhead.
  179. +
  180. + LZIP is not the standard compression used in Squashfs and so most
  181. + file systems will be readable without selecting this option.
  182. +
  183. + If unsure, say N.
  184. +
  185. config SQUASHFS_LZO
  186. bool "Include support for LZO compressed file systems"
  187. depends on SQUASHFS
  188. diff -urdN linux-5.16.11/fs/squashfs/Makefile linux-5.16.11.new/fs/squashfs/Makefile
  189. --- linux-5.16.11/fs/squashfs/Makefile 2022-02-24 00:42:52.000000000 +0100
  190. +++ linux-5.16.11.new/fs/squashfs/Makefile 2022-02-28 22:10:45.790400069 +0100
  191. @@ -13,6 +13,7 @@
  192. squashfs-$(CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU) += decompressor_multi_percpu.o
  193. squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
  194. squashfs-$(CONFIG_SQUASHFS_LZ4) += lz4_wrapper.o
  195. +squashfs-$(CONFIG_SQUASHFS_LZIP) += lzip_wrapper.o
  196. squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
  197. squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
  198. squashfs-$(CONFIG_SQUASHFS_ZLIB) += zlib_wrapper.o
  199. diff -urdN linux-5.16.11/fs/squashfs/decompressor.c linux-5.16.11.new/fs/squashfs/decompressor.c
  200. --- linux-5.16.11/fs/squashfs/decompressor.c 2022-02-24 00:42:52.000000000 +0100
  201. +++ linux-5.16.11.new/fs/squashfs/decompressor.c 2022-02-28 22:10:45.790400069 +0100
  202. @@ -34,6 +34,12 @@
  203. };
  204. #endif
  205. +#ifndef CONFIG_SQUASHFS_LZIP
  206. +static const struct squashfs_decompressor squashfs_lzip_comp_ops = {
  207. + NULL, NULL, NULL, NULL, LZIP_COMPRESSION, "lzip", 0
  208. +};
  209. +#endif
  210. +
  211. #ifndef CONFIG_SQUASHFS_LZO
  212. static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
  213. NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
  214. @@ -65,6 +71,7 @@
  215. static const struct squashfs_decompressor *decompressor[] = {
  216. &squashfs_zlib_comp_ops,
  217. &squashfs_lz4_comp_ops,
  218. + &squashfs_lzip_comp_ops,
  219. &squashfs_lzo_comp_ops,
  220. &squashfs_xz_comp_ops,
  221. &squashfs_lzma_unsupported_comp_ops,
  222. diff -urdN linux-5.16.11/fs/squashfs/decompressor.h linux-5.16.11.new/fs/squashfs/decompressor.h
  223. --- linux-5.16.11/fs/squashfs/decompressor.h 2022-02-24 00:42:52.000000000 +0100
  224. +++ linux-5.16.11.new/fs/squashfs/decompressor.h 2022-02-28 22:10:45.790400069 +0100
  225. @@ -38,6 +38,10 @@
  226. extern const struct squashfs_decompressor squashfs_lz4_comp_ops;
  227. #endif
  228. +#ifdef CONFIG_SQUASHFS_LZIP
  229. +extern const struct squashfs_decompressor squashfs_lzip_comp_ops;
  230. +#endif
  231. +
  232. #ifdef CONFIG_SQUASHFS_LZO
  233. extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
  234. #endif
  235. diff -urdN linux-5.16.11/fs/squashfs/lzip_wrapper.c linux-5.16.11.new/fs/squashfs/lzip_wrapper.c
  236. --- linux-5.16.11/fs/squashfs/lzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
  237. +++ linux-5.16.11.new/fs/squashfs/lzip_wrapper.c 2022-02-28 23:14:30.780431657 +0100
  238. @@ -0,0 +1,129 @@
  239. +/*
  240. + * Squashfs - a compressed read only filesystem for Linux
  241. + *
  242. + * Copyright (c) 2014
  243. + * Phillip Lougher <phillip@squashfs.org.uk>
  244. + * Copyright (C) 2018-2022 Antonio Diaz Diaz
  245. + *
  246. + * This program is free software; you can redistribute it and/or
  247. + * modify it under the terms of the GNU General Public License
  248. + * as published by the Free Software Foundation; either version 2,
  249. + * or (at your option) any later version.
  250. + *
  251. + * This program is distributed in the hope that it will be useful,
  252. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  253. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  254. + * GNU General Public License for more details.
  255. + *
  256. + * You should have received a copy of the GNU General Public License
  257. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  258. + *
  259. + * lzip_wrapper.c
  260. + */
  261. +
  262. +#include <linux/bio.h>
  263. +#include <linux/mutex.h>
  264. +#include <linux/slab.h>
  265. +#include <linux/vmalloc.h>
  266. +#include <linux/lzip.h>
  267. +
  268. +#include "squashfs_fs.h"
  269. +#include "squashfs_fs_sb.h"
  270. +#include "squashfs.h"
  271. +#include "decompressor.h"
  272. +#include "page_actor.h"
  273. +
  274. +struct squashfs_lzip {
  275. + void *input;
  276. + void *output;
  277. +};
  278. +
  279. +
  280. +static void *lzip_init(struct squashfs_sb_info *msblk, void *buff)
  281. +{
  282. + int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
  283. + struct squashfs_lzip *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
  284. + if (stream == NULL)
  285. + goto failed;
  286. + stream->input = vmalloc(block_size);
  287. + if (stream->input == NULL)
  288. + goto failed2;
  289. + stream->output = vmalloc(block_size);
  290. + if (stream->output != NULL)
  291. + return stream;
  292. +
  293. + vfree(stream->input);
  294. +failed2:
  295. + kfree(stream);
  296. +failed:
  297. + ERROR("Failed to initialise LZIP decompressor\n");
  298. + return ERR_PTR(-ENOMEM);
  299. +}
  300. +
  301. +
  302. +static void lzip_free(void *strm)
  303. +{
  304. + struct squashfs_lzip *stream = strm;
  305. +
  306. + if (stream) {
  307. + vfree(stream->input);
  308. + vfree(stream->output);
  309. + }
  310. + kfree(stream);
  311. +}
  312. +
  313. +
  314. +static int lzip_uncompress(struct squashfs_sb_info *msblk, void *strm,
  315. + struct bio *bio, int offset, int length,
  316. + struct squashfs_page_actor *output)
  317. +{
  318. + struct bvec_iter_all iter_all = {};
  319. + struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
  320. + struct squashfs_lzip *stream = strm;
  321. + void *buff = stream->input, *data;
  322. + long out_pos;
  323. + int bytes = length, res;
  324. +
  325. + while (bio_next_segment(bio, &iter_all)) {
  326. + int avail = min(bytes, ((int)bvec->bv_len) - offset);
  327. +
  328. + data = bvec_virt(bvec);
  329. + memcpy(buff, data + offset, avail);
  330. + buff += avail;
  331. + bytes -= avail;
  332. + offset = 0;
  333. + }
  334. +
  335. + res = lzip_decompress(stream->input, length, 0, 0, stream->output,
  336. + output->length, 0, &out_pos);
  337. + if (res < 0) {
  338. + ERROR("LZIP error code %d\n", res);
  339. + return -EIO;
  340. + }
  341. + bytes = out_pos;
  342. + data = squashfs_first_page(output);
  343. + buff = stream->output;
  344. + while (data) {
  345. + if (bytes <= PAGE_SIZE) {
  346. + memcpy(data, buff, bytes);
  347. + break;
  348. + }
  349. + memcpy(data, buff, PAGE_SIZE);
  350. + buff += PAGE_SIZE;
  351. + bytes -= PAGE_SIZE;
  352. + data = squashfs_next_page(output);
  353. + }
  354. + squashfs_finish_page(output);
  355. +
  356. + return out_pos;
  357. +}
  358. +
  359. +
  360. +const struct squashfs_decompressor squashfs_lzip_comp_ops = {
  361. + .init = lzip_init,
  362. + .free = lzip_free,
  363. + .decompress = lzip_uncompress,
  364. + .id = LZIP_COMPRESSION,
  365. + .name = "lzip",
  366. + .supported = 1
  367. +};
  368. diff -urdN linux-5.16.11/fs/squashfs/squashfs_fs.h linux-5.16.11.new/fs/squashfs/squashfs_fs.h
  369. --- linux-5.16.11/fs/squashfs/squashfs_fs.h 2022-02-24 00:42:52.000000000 +0100
  370. +++ linux-5.16.11.new/fs/squashfs/squashfs_fs.h 2022-02-28 22:10:45.790400069 +0100
  371. @@ -236,6 +236,7 @@
  372. #define XZ_COMPRESSION 4
  373. #define LZ4_COMPRESSION 5
  374. #define ZSTD_COMPRESSION 6
  375. +#define LZIP_COMPRESSION 7
  376. struct squashfs_super_block {
  377. __le32 s_magic;
  378. diff -urdN linux-5.16.11/include/linux/decompress/lunzip.h linux-5.16.11.new/include/linux/decompress/lunzip.h
  379. --- linux-5.16.11/include/linux/decompress/lunzip.h 1970-01-01 01:00:00.000000000 +0100
  380. +++ linux-5.16.11.new/include/linux/decompress/lunzip.h 2022-02-28 22:10:45.790400069 +0100
  381. @@ -0,0 +1,11 @@
  382. +/* SPDX-License-Identifier: GPL-2.0 */
  383. +#ifndef LINUX_DECOMPRESS_LUNZIP_H
  384. +#define LINUX_DECOMPRESS_LUNZIP_H
  385. +
  386. +int lunzip(unsigned char *inbuf, long in_len,
  387. + long (*fill)(void*, unsigned long),
  388. + long (*flush)(void*, unsigned long),
  389. + unsigned char *outbuf,
  390. + long *in_posp,
  391. + void (*error)(char *x));
  392. +#endif
  393. diff -urdN linux-5.16.11/include/linux/lzip.h linux-5.16.11.new/include/linux/lzip.h
  394. --- linux-5.16.11/include/linux/lzip.h 1970-01-01 01:00:00.000000000 +0100
  395. +++ linux-5.16.11.new/include/linux/lzip.h 2022-02-28 23:01:36.770430310 +0100
  396. @@ -0,0 +1,53 @@
  397. +/* SPDX-License-Identifier: GPL-2.0 */
  398. +#ifndef __LZIP_H__
  399. +#define __LZIP_H__
  400. +/*
  401. + * LZIP decompressor
  402. + *
  403. + * Copyright (C) 2016-2022 Antonio Diaz Diaz.
  404. + */
  405. +
  406. +/* Return values (< 0 = Error) */
  407. +enum {
  408. + LZIP_OOM_INBUF = -1,
  409. + LZIP_HEADER1_EOF = -2,
  410. + LZIP_HEADER2_EOF = -3,
  411. + LZIP_BAD_MAGIC1 = -4,
  412. + LZIP_BAD_MAGIC2 = -5,
  413. + LZIP_BAD_VERSION = -6,
  414. + LZIP_BAD_DICT_SIZE = -7,
  415. + LZIP_OOM_OUTBUF = -8,
  416. + LZIP_WRITE_ERROR = -9,
  417. + LZIP_BAD_DATA = -10,
  418. + LZIP_DATA_EOF = -11,
  419. + LZIP_BAD_CRC = -12
  420. +};
  421. +
  422. +int lzip_decompress(unsigned char *inbuf, long in_len,
  423. + long (*fill)(void*, unsigned long),
  424. + long (*flush)(void*, unsigned long),
  425. + unsigned char *outbuf, long out_size,
  426. + long *in_posp, long *out_posp);
  427. +
  428. +/* inbuf - input buffer. If null or in_len <= 0, fill must be non-null
  429. + * in_len - len of pre-read data in inbuf if inbuf is non-null
  430. + * fill - if non-null, function to fill inbuf when empty
  431. + * flush - if non-null, function to write out outbuf when full
  432. + * outbuf - output buffer. If null or out_size <= 0, flush must be non-null
  433. + * out_size - size of outbuf if outbuf is non-null
  434. + * in_posp - if non-null, the number of bytes consumed will be returned here
  435. + * out_posp - if non-null, the number of bytes produced will be returned here
  436. + *
  437. + * fill will be called (repeatedly) to read data. in_len bytes will be read
  438. + * per call (or 16384 bytes per call if inbuf is null or in_len <= 0).
  439. + *
  440. + * If flush is null, outbuf must be large enough to buffer all the expected
  441. + * output. Else the flush function will be called to flush the output buffer
  442. + * at the appropriate time (stream dependent).
  443. + * If out_size > 0 but is not large enough to buffer all the expected output,
  444. + * it must be at least as large as the dictionary size of the data.
  445. + *
  446. + * inbuf and outbuf may overlap (in-place decompression).
  447. + */
  448. +
  449. +#endif
  450. diff -urdN linux-5.16.11/init/Kconfig linux-5.16.11.new/init/Kconfig
  451. --- linux-5.16.11/init/Kconfig 2022-02-24 00:42:52.000000000 +0100
  452. +++ linux-5.16.11.new/init/Kconfig 2022-02-28 22:44:38.850430221 +0100
  453. @@ -207,6 +207,9 @@
  454. config HAVE_KERNEL_BZIP2
  455. bool
  456. +config HAVE_KERNEL_LZIP
  457. + bool
  458. +
  459. config HAVE_KERNEL_LZMA
  460. bool
  461. @@ -228,7 +231,7 @@
  462. choice
  463. prompt "Kernel compression mode"
  464. default KERNEL_GZIP
  465. - 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
  466. + 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
  467. help
  468. The linux kernel is a kind of self-extracting executable.
  469. Several compression algorithms are available, which differ
  470. @@ -264,6 +267,15 @@
  471. Bzip2 uses a large amount of memory. For modern kernels you
  472. will need at least 8MB RAM or more for booting.
  473. +config KERNEL_LZIP
  474. + bool "Lzip"
  475. + depends on HAVE_KERNEL_LZIP
  476. + help
  477. + Lzip's compression ratio is better than that of gzip and bzip2.
  478. + Decompression speed is between gzip and bzip2. Compression can be
  479. + as fast as gzip or slower than bzip2 depending on compression level.
  480. + Lzip can produce a kernel about a 16% smaller than gzip.
  481. +
  482. config KERNEL_LZMA
  483. bool "LZMA"
  484. depends on HAVE_KERNEL_LZMA
  485. @@ -2247,7 +2259,7 @@
  486. Please note that the tool used to load modules needs to support the
  487. corresponding algorithm. module-init-tools MAY support gzip, and kmod
  488. - MAY support gzip, xz and zstd.
  489. + MAY support gzip, lzip, xz and zstd.
  490. Your build system needs to provide the appropriate compression tool
  491. to compress the modules.
  492. @@ -2266,6 +2278,12 @@
  493. Compress modules with GZIP. The installed modules are suffixed
  494. with .ko.gz.
  495. +config MODULE_COMPRESS_LZIP
  496. + bool "LZIP"
  497. + help
  498. + Compress modules with LZIP. The installed modules are suffixed
  499. + with .ko.lz.
  500. +
  501. config MODULE_COMPRESS_XZ
  502. bool "XZ"
  503. help
  504. diff -urdN linux-5.16.11/init/do_mounts_rd.c linux-5.16.11.new/init/do_mounts_rd.c
  505. --- linux-5.16.11/init/do_mounts_rd.c 2022-02-24 00:42:52.000000000 +0100
  506. +++ linux-5.16.11.new/init/do_mounts_rd.c 2022-02-28 22:10:45.790400069 +0100
  507. @@ -49,6 +49,7 @@
  508. * squashfs
  509. * gzip
  510. * bzip2
  511. + * lzip
  512. * lzma
  513. * xz
  514. * lzo
  515. diff -urdN linux-5.16.11/lib/Kconfig linux-5.16.11.new/lib/Kconfig
  516. --- linux-5.16.11/lib/Kconfig 2022-02-24 00:42:52.000000000 +0100
  517. +++ linux-5.16.11.new/lib/Kconfig 2022-02-28 22:10:45.790400069 +0100
  518. @@ -311,6 +311,9 @@
  519. help
  520. Enable s390x hardware support for zlib in the kernel.
  521. +config LZIP_DECOMPRESS
  522. + tristate
  523. +
  524. config LZO_COMPRESS
  525. tristate
  526. @@ -347,6 +350,10 @@
  527. config DECOMPRESS_BZIP2
  528. tristate
  529. +config DECOMPRESS_LZIP
  530. + select LZIP_DECOMPRESS
  531. + tristate
  532. +
  533. config DECOMPRESS_LZMA
  534. tristate
  535. diff -urdN linux-5.16.11/lib/Makefile linux-5.16.11.new/lib/Makefile
  536. --- linux-5.16.11/lib/Makefile 2022-02-24 00:42:52.000000000 +0100
  537. +++ linux-5.16.11.new/lib/Makefile 2022-02-28 22:10:45.790400069 +0100
  538. @@ -184,6 +184,7 @@
  539. obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc/
  540. obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
  541. obj-$(CONFIG_BCH) += bch.o
  542. +obj-$(CONFIG_LZIP_DECOMPRESS) += lzip_decompress.o
  543. obj-$(CONFIG_LZO_COMPRESS) += lzo/
  544. obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
  545. obj-$(CONFIG_LZ4_COMPRESS) += lz4/
  546. @@ -196,6 +197,7 @@
  547. lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
  548. lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
  549. +lib-$(CONFIG_DECOMPRESS_LZIP) += decompress_lunzip.o
  550. lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
  551. lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
  552. lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
  553. diff -urdN linux-5.16.11/lib/decompress.c linux-5.16.11.new/lib/decompress.c
  554. --- linux-5.16.11/lib/decompress.c 2022-02-24 00:42:52.000000000 +0100
  555. +++ linux-5.16.11.new/lib/decompress.c 2022-02-28 22:10:45.790400069 +0100
  556. @@ -8,6 +8,7 @@
  557. #include <linux/decompress/generic.h>
  558. #include <linux/decompress/bunzip2.h>
  559. +#include <linux/decompress/lunzip.h>
  560. #include <linux/decompress/unlzma.h>
  561. #include <linux/decompress/unxz.h>
  562. #include <linux/decompress/inflate.h>
  563. @@ -26,6 +27,9 @@
  564. #ifndef CONFIG_DECOMPRESS_BZIP2
  565. # define bunzip2 NULL
  566. #endif
  567. +#ifndef CONFIG_DECOMPRESS_LZIP
  568. +# define lunzip NULL
  569. +#endif
  570. #ifndef CONFIG_DECOMPRESS_LZMA
  571. # define unlzma NULL
  572. #endif
  573. @@ -52,6 +56,7 @@
  574. { {0x1f, 0x8b}, "gzip", gunzip },
  575. { {0x1f, 0x9e}, "gzip", gunzip },
  576. { {0x42, 0x5a}, "bzip2", bunzip2 },
  577. + { {0x4c, 0x5a}, "lzip", lunzip },
  578. { {0x5d, 0x00}, "lzma", unlzma },
  579. { {0xfd, 0x37}, "xz", unxz },
  580. { {0x89, 0x4c}, "lzo", unlzo },
  581. diff -urdN linux-5.16.11/lib/decompress_lunzip.c linux-5.16.11.new/lib/decompress_lunzip.c
  582. --- linux-5.16.11/lib/decompress_lunzip.c 1970-01-01 01:00:00.000000000 +0100
  583. +++ linux-5.16.11.new/lib/decompress_lunzip.c 2022-02-28 23:02:02.330425107 +0100
  584. @@ -0,0 +1,100 @@
  585. +/*
  586. + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
  587. + *
  588. + * Copyright (C) 2016-2022 Antonio Diaz Diaz.
  589. + *
  590. + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  591. + */
  592. +
  593. +#ifdef STATIC
  594. +#define PREBOOT
  595. +#include "lzip_decompress.c"
  596. +#else
  597. +#include <linux/lzip.h>
  598. +#include <linux/decompress/lunzip.h>
  599. +#include <linux/decompress/mm.h>
  600. +#endif
  601. +
  602. +STATIC int INIT __lunzip(unsigned char *inbuf, long in_len,
  603. + long (*fill)(void*, unsigned long),
  604. + long (*flush)(void*, unsigned long),
  605. + unsigned char *outbuf, long out_size,
  606. + long *in_posp, long *out_posp,
  607. + void (*error)(char *x))
  608. +{
  609. + const int retval = lzip_decompress(inbuf, in_len, fill, flush,
  610. + outbuf, out_size, in_posp, out_posp);
  611. + switch (retval) {
  612. + case 0: break;
  613. + case LZIP_OOM_INBUF:
  614. + error("Out of memory while allocating input buffer.");
  615. + break;
  616. + case LZIP_HEADER1_EOF:
  617. + error("File ends unexpectedly at member header.");
  618. + break;
  619. + case LZIP_HEADER2_EOF:
  620. + error("Truncated header in multimember file.");
  621. + break;
  622. + case LZIP_BAD_MAGIC1:
  623. + error("Bad magic number (file not in lzip format).");
  624. + break;
  625. + case LZIP_BAD_MAGIC2:
  626. + error("Corrupt header in multimember file.");
  627. + break;
  628. + case LZIP_BAD_VERSION:
  629. + error("Version of lzip member format not supported.");
  630. + break;
  631. + case LZIP_BAD_DICT_SIZE:
  632. + error("Invalid dictionary size in member header.");
  633. + break;
  634. + case LZIP_OOM_OUTBUF:
  635. + error("Out of memory while allocating output buffer.");
  636. + break;
  637. + case LZIP_WRITE_ERROR:
  638. + error("Write error.");
  639. + break;
  640. + case LZIP_BAD_DATA:
  641. + error("LZIP-compressed data is corrupt.");
  642. + break;
  643. + case LZIP_DATA_EOF:
  644. + error("LZIP-compressed data ends unexpectedly.");
  645. + break;
  646. + case LZIP_BAD_CRC:
  647. + error("CRC mismatch in LZIP-compressed data.");
  648. + break;
  649. + default:
  650. + error("Bug in the LZIP decompressor.");
  651. + }
  652. + return retval;
  653. +}
  654. +
  655. +#ifndef PREBOOT
  656. +/* decompress_fn (see include/linux/decompress/generic.h) should have an
  657. + * out_size argument to prevent overflowing outbuf in case of corruption
  658. + * of the compressed data.
  659. + */
  660. +STATIC int INIT lunzip(unsigned char *inbuf, long in_len,
  661. + long (*fill)(void*, unsigned long),
  662. + long (*flush)(void*, unsigned long),
  663. + unsigned char *outbuf,
  664. + long *in_posp,
  665. + void (*error)(char *x))
  666. +{
  667. + return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX,
  668. + in_posp, 0, error);
  669. +}
  670. +#else
  671. +STATIC int INIT __decompress(unsigned char *inbuf, long in_len,
  672. + long (*fill)(void*, unsigned long),
  673. + long (*flush)(void*, unsigned long),
  674. + unsigned char *outbuf, long out_size,
  675. + long *in_posp,
  676. + void (*error)(char *x))
  677. +{
  678. +/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe
  679. + * in case of corruption of the compressed data.
  680. + */
  681. + return __lunzip(inbuf, in_len - 4, fill, flush, outbuf,
  682. + out_size ? out_size : LONG_MAX, in_posp, 0, error);
  683. +}
  684. +#endif
  685. diff -urdN linux-5.16.11/lib/lzip_decompress.c linux-5.16.11.new/lib/lzip_decompress.c
  686. --- linux-5.16.11/lib/lzip_decompress.c 1970-01-01 01:00:00.000000000 +0100
  687. +++ linux-5.16.11.new/lib/lzip_decompress.c 2022-02-28 23:02:22.360432092 +0100
  688. @@ -0,0 +1,873 @@
  689. +/*
  690. + * LZIP decompressor
  691. + *
  692. + * Copyright (C) 2016-2022 Antonio Diaz Diaz.
  693. + *
  694. + * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  695. + */
  696. +
  697. +#include <linux/module.h>
  698. +#include <linux/lzip.h>
  699. +#include <linux/decompress/mm.h>
  700. +
  701. +/*
  702. + * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
  703. + * See include/linux/decompress/mm.h for details.
  704. + */
  705. +#ifndef STATIC_RW_DATA
  706. +#define STATIC_RW_DATA static
  707. +#endif
  708. +
  709. +typedef int State;
  710. +
  711. +enum { states = 12 };
  712. +
  713. +static inline bool St_is_char(const State st) { return st < 7; }
  714. +
  715. +static inline State St_set_char(const State st)
  716. +{
  717. + STATIC_RW_DATA const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
  718. + return next[st];
  719. +}
  720. +
  721. +static inline State St_set_match(const State st)
  722. +{
  723. + return ((st < 7) ? 7 : 10);
  724. +}
  725. +
  726. +static inline State St_set_rep(const State st)
  727. +{
  728. + return ((st < 7) ? 8 : 11);
  729. +}
  730. +
  731. +static inline State St_set_short_rep(const State st)
  732. +{
  733. + return ((st < 7) ? 9 : 11);
  734. +}
  735. +
  736. +
  737. +enum {
  738. + min_dictionary_bits = 12,
  739. + min_dictionary_size = 1 << min_dictionary_bits, /* >= modeled_distances */
  740. + max_dictionary_bits = 29,
  741. + max_dictionary_size = 1 << max_dictionary_bits,
  742. + literal_context_bits = 3,
  743. + pos_state_bits = 2,
  744. + pos_states = 1 << pos_state_bits,
  745. + pos_state_mask = pos_states - 1,
  746. +
  747. + len_states = 4,
  748. + dis_slot_bits = 6,
  749. + start_dis_model = 4,
  750. + end_dis_model = 14,
  751. + modeled_distances = 1 << (end_dis_model / 2), /* 128 */
  752. + dis_align_bits = 4,
  753. + dis_align_size = 1 << dis_align_bits,
  754. +
  755. + len_low_bits = 3,
  756. + len_mid_bits = 3,
  757. + len_high_bits = 8,
  758. + len_low_symbols = 1 << len_low_bits,
  759. + len_mid_symbols = 1 << len_mid_bits,
  760. + len_high_symbols = 1 << len_high_bits,
  761. + max_len_symbols = len_low_symbols + len_mid_symbols + len_high_symbols,
  762. +
  763. + min_match_len = 2, /* must be 2 */
  764. + max_match_len = min_match_len + max_len_symbols - 1, /* 273 */
  765. + min_match_len_limit = 5
  766. +};
  767. +
  768. +static inline int get_len_state(const int len)
  769. +{
  770. + return min(len - min_match_len, len_states - 1);
  771. +}
  772. +
  773. +static inline int get_lit_state(const uint8_t prev_byte)
  774. +{
  775. + return prev_byte >> (8 - literal_context_bits);
  776. +}
  777. +
  778. +
  779. +enum { bit_model_move_bits = 5,
  780. + bit_model_total_bits = 11,
  781. + bit_model_total = 1 << bit_model_total_bits
  782. +};
  783. +
  784. +typedef int Bit_model;
  785. +
  786. +static inline void Bm_init(Bit_model * const probability)
  787. +{
  788. + *probability = bit_model_total / 2;
  789. +}
  790. +
  791. +static inline void Bm_array_init(Bit_model bm[], const int size)
  792. +{
  793. + int i;
  794. +
  795. + for (i = 0; i < size; ++i)
  796. + Bm_init(&bm[i]);
  797. +}
  798. +
  799. +struct Len_model {
  800. + Bit_model choice1;
  801. + Bit_model choice2;
  802. + Bit_model bm_low[pos_states][len_low_symbols];
  803. + Bit_model bm_mid[pos_states][len_mid_symbols];
  804. + Bit_model bm_high[len_high_symbols];
  805. +};
  806. +
  807. +static inline void Lm_init(struct Len_model * const lm)
  808. +{
  809. + Bm_init(&lm->choice1);
  810. + Bm_init(&lm->choice2);
  811. + Bm_array_init(lm->bm_low[0], pos_states * len_low_symbols);
  812. + Bm_array_init(lm->bm_mid[0], pos_states * len_mid_symbols);
  813. + Bm_array_init(lm->bm_high, len_high_symbols);
  814. +}
  815. +
  816. +
  817. +/* Table of CRCs of all 8-bit messages. */
  818. +STATIC_RW_DATA const uint32_t crc32[256] =
  819. + {
  820. + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
  821. + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
  822. + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
  823. + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
  824. + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
  825. + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
  826. + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
  827. + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
  828. + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
  829. + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
  830. + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
  831. + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
  832. + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
  833. + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
  834. + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
  835. + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
  836. + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
  837. + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
  838. + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
  839. + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
  840. + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
  841. + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
  842. + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
  843. + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
  844. + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
  845. + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
  846. + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
  847. + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
  848. + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
  849. + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
  850. + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
  851. + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
  852. + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
  853. + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
  854. + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
  855. + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
  856. + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
  857. + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
  858. + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
  859. + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
  860. + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
  861. + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
  862. + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
  863. +
  864. +
  865. +static inline void CRC32_update_buf(uint32_t * const crc,
  866. + const uint8_t * const buffer,
  867. + const long size)
  868. +{
  869. + long i;
  870. + uint32_t c = *crc;
  871. +
  872. + for (i = 0; i < size; ++i)
  873. + c = crc32[(c^buffer[i])&0xFF] ^ (c >> 8);
  874. + *crc = c;
  875. +}
  876. +
  877. +
  878. +STATIC_RW_DATA const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
  879. +
  880. +typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
  881. + /* 4 version */
  882. + /* 5 coded dictionary size */
  883. +enum { Lh_size = 6 };
  884. +
  885. +static inline bool Lh_verify_magic(const Lzip_header data)
  886. +{
  887. + int i;
  888. +
  889. + for (i = 0; i < 4; ++i)
  890. + if (data[i] != lzip_magic[i])
  891. + return false;
  892. + return true;
  893. +}
  894. +
  895. +/* detect (truncated) header */
  896. +static inline bool Lh_verify_prefix(const Lzip_header data, const int sz)
  897. +{
  898. + int i;
  899. + for (i = 0; i < sz && i < 4; ++i)
  900. + if (data[i] != lzip_magic[i])
  901. + return false;
  902. + return (sz > 0);
  903. +}
  904. +
  905. +/* detect corrupt header */
  906. +static inline bool Lh_verify_corrupt(const Lzip_header data)
  907. +{
  908. + int matches = 0;
  909. + int i;
  910. + for (i = 0; i < 4; ++i)
  911. + if (data[i] == lzip_magic[i])
  912. + ++matches;
  913. + return (matches > 1 && matches < 4);
  914. +}
  915. +
  916. +static inline bool Lh_verify_version(const Lzip_header data)
  917. +{
  918. + return (data[4] == 1);
  919. +}
  920. +
  921. +static inline unsigned Lh_get_dictionary_size(const Lzip_header data)
  922. +{
  923. + unsigned sz = (1 << (data[5] & 0x1F));
  924. +
  925. + if (sz > min_dictionary_size)
  926. + sz -= (sz / 16) * ((data[5] >> 5) & 7);
  927. + return sz;
  928. +}
  929. +
  930. +
  931. +typedef uint8_t Lzip_trailer[20];
  932. + /* 0-3 CRC32 of the uncompressed data */
  933. + /* 4-11 size of the uncompressed data */
  934. + /* 12-19 member size including header and trailer */
  935. +enum { Lt_size = 20 };
  936. +
  937. +static inline unsigned Lt_get_data_crc(const Lzip_trailer data)
  938. +{
  939. + unsigned tmp = 0;
  940. + int i;
  941. +
  942. + for (i = 3; i >= 0; --i) {
  943. + tmp <<= 8;
  944. + tmp += data[i];
  945. + }
  946. + return tmp;
  947. +}
  948. +
  949. +static inline unsigned long long Lt_get_data_size(const Lzip_trailer data)
  950. +{
  951. + unsigned long long tmp = 0;
  952. + int i;
  953. +
  954. + for (i = 11; i >= 4; --i) {
  955. + tmp <<= 8;
  956. + tmp += data[i];
  957. + }
  958. + return tmp;
  959. +}
  960. +
  961. +static inline unsigned long long Lt_get_member_size(const Lzip_trailer data)
  962. +{
  963. + unsigned long long tmp = 0;
  964. + int i;
  965. +
  966. + for (i = 19; i >= 12; --i) {
  967. + tmp <<= 8;
  968. + tmp += data[i];
  969. + }
  970. + return tmp;
  971. +}
  972. +
  973. +
  974. +struct Range_decoder {
  975. + unsigned long long partial_member_pos;
  976. + uint8_t *buffer; /* input buffer */
  977. + long buffer_size;
  978. + long pos; /* current pos in buffer */
  979. + long stream_pos; /* when reached, a new block must be read */
  980. + uint32_t code;
  981. + uint32_t range;
  982. + long (*fill)(void*, unsigned long);
  983. + bool at_stream_end;
  984. + bool buffer_given;
  985. +};
  986. +
  987. +
  988. +static bool Rd_read_block(struct Range_decoder * const rdec)
  989. +{
  990. + if (!rdec->at_stream_end) {
  991. + rdec->stream_pos = rdec->fill ?
  992. + rdec->fill(rdec->buffer, rdec->buffer_size) : 0;
  993. + rdec->at_stream_end = (rdec->stream_pos < rdec->buffer_size);
  994. + rdec->partial_member_pos += rdec->pos;
  995. + rdec->pos = 0;
  996. + }
  997. + return rdec->pos < rdec->stream_pos;
  998. +}
  999. +
  1000. +
  1001. +static inline bool Rd_init(struct Range_decoder * const rdec,
  1002. + uint8_t * const inbuf, const long in_len,
  1003. + long (*fill)(void*, unsigned long))
  1004. +{
  1005. + rdec->partial_member_pos = 0;
  1006. + rdec->buffer_given = (inbuf && in_len > 0);
  1007. + rdec->buffer_size = rdec->buffer_given ? in_len : 16384;
  1008. + rdec->buffer = rdec->buffer_given ? inbuf : malloc(rdec->buffer_size);
  1009. + if (!rdec->buffer)
  1010. + return false;
  1011. + rdec->pos = 0;
  1012. + rdec->stream_pos = rdec->buffer_given ? in_len : 0;
  1013. + rdec->code = 0;
  1014. + rdec->range = 0xFFFFFFFFU;
  1015. + rdec->fill = fill;
  1016. + rdec->at_stream_end = false;
  1017. + return true;
  1018. +}
  1019. +
  1020. +static inline void Rd_free(struct Range_decoder * const rdec)
  1021. +{
  1022. + if (!rdec->buffer_given)
  1023. + free(rdec->buffer);
  1024. +}
  1025. +
  1026. +static inline bool Rd_finished(struct Range_decoder * const rdec)
  1027. +{
  1028. + return rdec->pos >= rdec->stream_pos && !Rd_read_block(rdec);
  1029. +}
  1030. +
  1031. +static inline unsigned long long
  1032. +Rd_member_position(const struct Range_decoder * const rdec)
  1033. +{
  1034. + return rdec->partial_member_pos + rdec->pos;
  1035. +}
  1036. +
  1037. +static inline void Rd_reset_member_position(struct Range_decoder * const rdec)
  1038. +{
  1039. + rdec->partial_member_pos = 0; rdec->partial_member_pos -= rdec->pos;
  1040. +}
  1041. +
  1042. +static inline uint8_t Rd_get_byte(struct Range_decoder * const rdec)
  1043. +{
  1044. + /* 0xFF avoids decoder error if member is truncated at EOS marker */
  1045. + if (Rd_finished(rdec))
  1046. + return 0xFF;
  1047. + return rdec->buffer[rdec->pos++];
  1048. +}
  1049. +
  1050. +static inline void Rd_load(struct Range_decoder * const rdec)
  1051. +{
  1052. + int i;
  1053. +
  1054. + rdec->code = 0;
  1055. + for (i = 0; i < 5; ++i)
  1056. + rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
  1057. + rdec->range = 0xFFFFFFFFU;
  1058. +}
  1059. +
  1060. +static inline void Rd_normalize(struct Range_decoder * const rdec)
  1061. +{
  1062. + if (rdec->range <= 0x00FFFFFFU) {
  1063. + rdec->range <<= 8;
  1064. + rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
  1065. + }
  1066. +}
  1067. +
  1068. +static inline unsigned Rd_decode(struct Range_decoder * const rdec,
  1069. + const int num_bits)
  1070. +{
  1071. + unsigned symbol = 0;
  1072. + int i;
  1073. +
  1074. + for (i = num_bits; i > 0; --i) {
  1075. + bool bit;
  1076. +
  1077. + Rd_normalize(rdec);
  1078. + rdec->range >>= 1;
  1079. + /* symbol <<= 1; */
  1080. + /* if(rdec->code >= rdec->range) { rdec->code -= rdec->range; symbol |= 1; } */
  1081. + bit = (rdec->code >= rdec->range);
  1082. + symbol <<= 1; symbol += bit;
  1083. + rdec->code -= rdec->range & (0U - bit);
  1084. + }
  1085. + return symbol;
  1086. +}
  1087. +
  1088. +static inline unsigned Rd_decode_bit(struct Range_decoder * const rdec,
  1089. + Bit_model * const probability)
  1090. +{
  1091. + uint32_t bound;
  1092. +
  1093. + Rd_normalize(rdec);
  1094. + bound = (rdec->range >> bit_model_total_bits) * *probability;
  1095. + if (rdec->code < bound) {
  1096. + rdec->range = bound;
  1097. + *probability += (bit_model_total - *probability) >> bit_model_move_bits;
  1098. + return 0;
  1099. + } else {
  1100. + rdec->range -= bound;
  1101. + rdec->code -= bound;
  1102. + *probability -= *probability >> bit_model_move_bits;
  1103. + return 1;
  1104. + }
  1105. +}
  1106. +
  1107. +static inline unsigned Rd_decode_tree3(struct Range_decoder * const rdec,
  1108. + Bit_model bm[])
  1109. +{
  1110. + unsigned symbol = 2 | Rd_decode_bit(rdec, &bm[1]);
  1111. +
  1112. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1113. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1114. + return symbol & 7;
  1115. +}
  1116. +
  1117. +static inline unsigned Rd_decode_tree6(struct Range_decoder * const rdec,
  1118. + Bit_model bm[])
  1119. +{
  1120. + unsigned symbol = 2 | Rd_decode_bit(rdec, &bm[1]);
  1121. +
  1122. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1123. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1124. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1125. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1126. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1127. + return symbol & 0x3F;
  1128. +}
  1129. +
  1130. +static inline unsigned Rd_decode_tree8(struct Range_decoder * const rdec,
  1131. + Bit_model bm[])
  1132. +{
  1133. + unsigned symbol = 1;
  1134. + int i;
  1135. +
  1136. + for (i = 0; i < 8; ++i)
  1137. + symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
  1138. + return symbol & 0xFF;
  1139. +}
  1140. +
  1141. +static inline unsigned
  1142. +Rd_decode_tree_reversed(struct Range_decoder * const rdec,
  1143. + Bit_model bm[], const int num_bits)
  1144. +{
  1145. + unsigned model = 1;
  1146. + unsigned symbol = 0;
  1147. + int i;
  1148. +
  1149. + for (i = 0; i < num_bits; ++i) {
  1150. + const unsigned bit = Rd_decode_bit(rdec, &bm[model]);
  1151. +
  1152. + model <<= 1; model += bit;
  1153. + symbol |= (bit << i);
  1154. + }
  1155. + return symbol;
  1156. +}
  1157. +
  1158. +static inline unsigned
  1159. +Rd_decode_tree_reversed4(struct Range_decoder * const rdec, Bit_model bm[])
  1160. +{
  1161. + unsigned symbol = Rd_decode_bit(rdec, &bm[1]);
  1162. +
  1163. + symbol += Rd_decode_bit(rdec, &bm[2+symbol]) << 1;
  1164. + symbol += Rd_decode_bit(rdec, &bm[4+symbol]) << 2;
  1165. + symbol += Rd_decode_bit(rdec, &bm[8+symbol]) << 3;
  1166. + return symbol;
  1167. +}
  1168. +
  1169. +static inline unsigned Rd_decode_matched(struct Range_decoder * const rdec,
  1170. + Bit_model bm[], unsigned match_byte)
  1171. +{
  1172. + unsigned symbol = 1;
  1173. + unsigned mask = 0x100;
  1174. +
  1175. + while (true) {
  1176. + const unsigned match_bit = (match_byte <<= 1) & mask;
  1177. + const unsigned bit = Rd_decode_bit(rdec, &bm[symbol+match_bit+mask]);
  1178. +
  1179. + symbol <<= 1; symbol += bit;
  1180. + if (symbol > 0xFF)
  1181. + return symbol & 0xFF;
  1182. + mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
  1183. + }
  1184. +}
  1185. +
  1186. +static inline unsigned Rd_decode_len(struct Range_decoder * const rdec,
  1187. + struct Len_model * const lm,
  1188. + const int pos_state)
  1189. +{
  1190. + if (Rd_decode_bit(rdec, &lm->choice1) == 0)
  1191. + return Rd_decode_tree3(rdec, lm->bm_low[pos_state]);
  1192. + if (Rd_decode_bit(rdec, &lm->choice2) == 0)
  1193. + return len_low_symbols +
  1194. + Rd_decode_tree3(rdec, lm->bm_mid[pos_state]);
  1195. + return len_low_symbols + len_mid_symbols +
  1196. + Rd_decode_tree8(rdec, lm->bm_high);
  1197. +}
  1198. +
  1199. +
  1200. +struct LZ_decoder {
  1201. + unsigned long long partial_data_pos;
  1202. + struct Range_decoder *rdec;
  1203. + /* Don't move bm_* to LZd_decode_member; makes frame too large. */
  1204. + Bit_model bm_literal[1 << literal_context_bits][0x300];
  1205. + Bit_model bm_match[states][pos_states];
  1206. + Bit_model bm_rep[states];
  1207. + Bit_model bm_rep0[states];
  1208. + Bit_model bm_rep1[states];
  1209. + Bit_model bm_rep2[states];
  1210. + Bit_model bm_len[states][pos_states];
  1211. + Bit_model bm_dis_slot[len_states][1 << dis_slot_bits];
  1212. + Bit_model bm_dis[modeled_distances-end_dis_model+1];
  1213. + Bit_model bm_align[dis_align_size];
  1214. + struct Len_model match_len_model;
  1215. + struct Len_model rep_len_model;
  1216. +
  1217. + unsigned long buffer_size;
  1218. + unsigned dictionary_size;
  1219. + uint8_t *buffer; /* output buffer */
  1220. + unsigned long pos; /* current pos in buffer */
  1221. + unsigned long stream_pos; /* first byte not yet written to file */
  1222. + uint32_t crc;
  1223. + long (*flush)(void*, unsigned long);
  1224. + bool pos_wrapped;
  1225. + bool buffer_given;
  1226. + bool write_error;
  1227. +};
  1228. +
  1229. +static void LZd_flush_data(struct LZ_decoder * const d)
  1230. +{
  1231. + if (d->pos > d->stream_pos) {
  1232. + const long size = d->pos - d->stream_pos;
  1233. +
  1234. + CRC32_update_buf(&d->crc, d->buffer + d->stream_pos, size);
  1235. + if ((d->flush &&
  1236. + d->flush(d->buffer + d->stream_pos, size) != size) ||
  1237. + (!d->flush && d->pos_wrapped))
  1238. + d->write_error = true;
  1239. + if (d->pos >= d->buffer_size) {
  1240. + d->partial_data_pos += d->pos;
  1241. + d->pos = 0;
  1242. + d->pos_wrapped = true;
  1243. + }
  1244. + d->stream_pos = d->pos;
  1245. + }
  1246. +}
  1247. +
  1248. +static inline uint8_t LZd_peek_prev(const struct LZ_decoder * const d)
  1249. +{
  1250. + if (d->pos > 0)
  1251. + return d->buffer[d->pos-1];
  1252. + if (d->pos_wrapped)
  1253. + return d->buffer[d->buffer_size-1];
  1254. + return 0; /* prev_byte of first byte */
  1255. +}
  1256. +
  1257. +static inline uint8_t LZd_peek(const struct LZ_decoder * const d,
  1258. + const unsigned distance)
  1259. +{
  1260. + const unsigned long i = ((d->pos > distance) ? 0 : d->buffer_size) +
  1261. + d->pos - distance - 1;
  1262. + return d->buffer[i];
  1263. +}
  1264. +
  1265. +static inline void LZd_put_byte(struct LZ_decoder * const d, const uint8_t b)
  1266. +{
  1267. + d->buffer[d->pos] = b;
  1268. + if (++d->pos >= d->buffer_size)
  1269. + LZd_flush_data(d);
  1270. +}
  1271. +
  1272. +static inline void LZd_copy_block(struct LZ_decoder * const d,
  1273. + const unsigned distance, unsigned len)
  1274. +{
  1275. + unsigned long lpos = d->pos, i = lpos - distance - 1;
  1276. + bool fast, fast2;
  1277. +
  1278. + if (lpos > distance) {
  1279. + fast = (len < d->buffer_size - lpos);
  1280. + fast2 = (fast && len <= lpos - i);
  1281. + } else {
  1282. + i += d->buffer_size;
  1283. + fast = (len < d->buffer_size - i); /* (i == pos) may happen */
  1284. + fast2 = (fast && len <= i - lpos);
  1285. + }
  1286. + if (fast) { /* no wrap */
  1287. + d->pos += len;
  1288. + if (fast2) /* no wrap, no overlap */
  1289. + memcpy(d->buffer + lpos, d->buffer + i, len);
  1290. + else
  1291. + for (; len > 0; --len)
  1292. + d->buffer[lpos++] = d->buffer[i++];
  1293. + } else
  1294. + for (; len > 0; --len) {
  1295. + d->buffer[d->pos] = d->buffer[i];
  1296. + if (++d->pos >= d->buffer_size)
  1297. + LZd_flush_data(d);
  1298. + if (++i >= d->buffer_size)
  1299. + i = 0;
  1300. + }
  1301. +}
  1302. +
  1303. +static inline bool LZd_init(struct LZ_decoder * const d,
  1304. + struct Range_decoder * const rde,
  1305. + const unsigned dict_size, uint8_t * const outbuf,
  1306. + long out_size, long (*flush)(void*, unsigned long))
  1307. +{
  1308. + d->partial_data_pos = 0;
  1309. + d->rdec = rde;
  1310. + Bm_array_init(d->bm_literal[0], (1 << literal_context_bits) * 0x300);
  1311. + Bm_array_init(d->bm_match[0], states * pos_states);
  1312. + Bm_array_init(d->bm_rep, states);
  1313. + Bm_array_init(d->bm_rep0, states);
  1314. + Bm_array_init(d->bm_rep1, states);
  1315. + Bm_array_init(d->bm_rep2, states);
  1316. + Bm_array_init(d->bm_len[0], states * pos_states);
  1317. + Bm_array_init(d->bm_dis_slot[0], len_states * (1 << dis_slot_bits));
  1318. + Bm_array_init(d->bm_dis, modeled_distances - end_dis_model + 1);
  1319. + Bm_array_init(d->bm_align, dis_align_size);
  1320. + Lm_init(&d->match_len_model);
  1321. + Lm_init(&d->rep_len_model);
  1322. +
  1323. + d->buffer_given = (outbuf && out_size > 0);
  1324. + d->buffer_size = d->buffer_given ? (unsigned long)out_size : dict_size;
  1325. + d->dictionary_size = min_t(unsigned long, d->buffer_size, dict_size);
  1326. + d->buffer = d->buffer_given ? outbuf : large_malloc(d->buffer_size);
  1327. + if (!d->buffer)
  1328. + return false;
  1329. + d->pos = 0;
  1330. + d->stream_pos = 0;
  1331. + d->crc = 0xFFFFFFFFU;
  1332. + d->flush = flush;
  1333. + d->pos_wrapped = false;
  1334. + d->write_error = false;
  1335. + /* prev_byte of first byte; also for LZd_peek( 0 ) on corrupt file */
  1336. + if (!d->buffer_given) /* inbuf and outbuf may overlap */
  1337. + d->buffer[d->buffer_size-1] = 0;
  1338. + return true;
  1339. +}
  1340. +
  1341. +static inline void LZd_free(struct LZ_decoder * const d)
  1342. +{
  1343. + if (!d->buffer_given)
  1344. + large_free(d->buffer);
  1345. +}
  1346. +
  1347. +static inline unsigned LZd_crc(const struct LZ_decoder * const d)
  1348. +{
  1349. + return d->crc ^ 0xFFFFFFFFU;
  1350. +}
  1351. +
  1352. +static inline unsigned long long
  1353. +LZd_data_position(const struct LZ_decoder * const d)
  1354. +{
  1355. + return d->partial_data_pos + d->pos;
  1356. +}
  1357. +
  1358. +
  1359. +static bool LZd_verify_trailer(struct LZ_decoder * const d)
  1360. +{
  1361. + Lzip_trailer trailer;
  1362. + int i = 0;
  1363. +
  1364. + while (i < Lt_size)
  1365. + trailer[i++] = Rd_get_byte(d->rdec);
  1366. +
  1367. + return (Lt_get_data_crc(trailer) == LZd_crc(d) &&
  1368. + Lt_get_data_size(trailer) == LZd_data_position(d) &&
  1369. + Lt_get_member_size(trailer) == Rd_member_position(d->rdec));
  1370. +}
  1371. +
  1372. +
  1373. +/* Return value: 0 = OK, < 0 = error (see include/linux/lzip.h). */
  1374. +static int LZd_decode_member(struct LZ_decoder * const d)
  1375. +{
  1376. + struct Range_decoder * const rdec = d->rdec;
  1377. + unsigned rep0 = 0; /* rep[0-3] latest four distances */
  1378. + unsigned rep1 = 0; /* used for efficient coding of */
  1379. + unsigned rep2 = 0; /* repeated distances */
  1380. + unsigned rep3 = 0;
  1381. + State state = 0;
  1382. +
  1383. + Rd_load(rdec);
  1384. + while (!Rd_finished(rdec)) {
  1385. + int len;
  1386. + const int pos_state = LZd_data_position(d) & pos_state_mask;
  1387. +
  1388. + if (Rd_decode_bit(rdec, &d->bm_match[state][pos_state]) == 0) {
  1389. + /* literal byte */
  1390. + Bit_model * const bm = d->bm_literal[get_lit_state(LZd_peek_prev(d))];
  1391. +
  1392. + if (St_is_char(state)) {
  1393. + state -= (state < 4) ? state : 3;
  1394. + LZd_put_byte(d, Rd_decode_tree8(rdec, bm));
  1395. + } else {
  1396. + state -= (state < 10) ? 3 : 6;
  1397. + LZd_put_byte(d, Rd_decode_matched(rdec, bm, LZd_peek(d, rep0)));
  1398. + }
  1399. + continue;
  1400. + }
  1401. + /* match or repeated match */
  1402. + if (Rd_decode_bit(rdec, &d->bm_rep[state]) != 0) {
  1403. + if (Rd_decode_bit(rdec, &d->bm_rep0[state]) == 0) {
  1404. + if (Rd_decode_bit(rdec, &d->bm_len[state][pos_state]) == 0) {
  1405. + state = St_set_short_rep(state);
  1406. + LZd_put_byte(d, LZd_peek(d, rep0));
  1407. + continue;
  1408. + }
  1409. + } else {
  1410. + unsigned distance;
  1411. +
  1412. + if (Rd_decode_bit(rdec, &d->bm_rep1[state]) == 0)
  1413. + distance = rep1;
  1414. + else {
  1415. + if (Rd_decode_bit(rdec, &d->bm_rep2[state]) == 0)
  1416. + distance = rep2;
  1417. + else {
  1418. + distance = rep3;
  1419. + rep3 = rep2;
  1420. + }
  1421. + rep2 = rep1;
  1422. + }
  1423. + rep1 = rep0;
  1424. + rep0 = distance;
  1425. + }
  1426. + state = St_set_rep(state);
  1427. + len = min_match_len + Rd_decode_len(rdec, &d->rep_len_model, pos_state);
  1428. + } else { /* match */
  1429. + unsigned distance;
  1430. +
  1431. + len = min_match_len + Rd_decode_len(rdec, &d->match_len_model, pos_state);
  1432. + distance = Rd_decode_tree6(rdec, d->bm_dis_slot[get_len_state(len)]);
  1433. + if (distance >= start_dis_model) {
  1434. + const unsigned dis_slot = distance;
  1435. + const int direct_bits = (dis_slot >> 1) - 1;
  1436. +
  1437. + distance = (2 | (dis_slot & 1)) << direct_bits;
  1438. + if (dis_slot < end_dis_model)
  1439. + distance += Rd_decode_tree_reversed(rdec,
  1440. + d->bm_dis + (distance - dis_slot), direct_bits);
  1441. + else {
  1442. + distance +=
  1443. + Rd_decode(rdec, direct_bits - dis_align_bits) << dis_align_bits;
  1444. + distance += Rd_decode_tree_reversed4(rdec, d->bm_align);
  1445. + if (distance == 0xFFFFFFFFU) { /* marker found */
  1446. + Rd_normalize(rdec);
  1447. + LZd_flush_data(d);
  1448. + if (d->write_error)
  1449. + return LZIP_WRITE_ERROR;
  1450. + if (len == min_match_len) { /* End Of Stream marker */
  1451. + if (LZd_verify_trailer(d))
  1452. + return 0;
  1453. + else
  1454. + return LZIP_BAD_CRC;
  1455. + }
  1456. + return LZIP_BAD_DATA; /* unknown marker */
  1457. + }
  1458. + }
  1459. + }
  1460. + rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
  1461. + state = St_set_match(state);
  1462. + if (rep0 >= d->dictionary_size ||
  1463. + (rep0 >= d->pos && !d->pos_wrapped)) {
  1464. + LZd_flush_data(d);
  1465. + return LZIP_BAD_DATA;
  1466. + }
  1467. + }
  1468. + LZd_copy_block(d, rep0, len);
  1469. + }
  1470. + LZd_flush_data(d);
  1471. + return LZIP_DATA_EOF;
  1472. +}
  1473. +
  1474. +
  1475. +int lzip_decompress(unsigned char *inbuf, long in_len,
  1476. + long (*fill)(void*, unsigned long),
  1477. + long (*flush)(void*, unsigned long),
  1478. + unsigned char *outbuf, long out_size,
  1479. + long *in_posp, long *out_posp)
  1480. +{
  1481. + unsigned char *outptr = outbuf;
  1482. + struct Range_decoder rdec;
  1483. + struct LZ_decoder *decoder = 0;
  1484. + int retval = 0;
  1485. + bool first_member;
  1486. +
  1487. + if (in_posp)
  1488. + *in_posp = 0;
  1489. + if (out_posp)
  1490. + *out_posp = 0;
  1491. +
  1492. + if (!Rd_init(&rdec, inbuf, in_len, fill))
  1493. + return LZIP_OOM_INBUF;
  1494. +
  1495. + for (first_member = true;; first_member = false) {
  1496. + long data_pos;
  1497. + int size;
  1498. + unsigned dictionary_size;
  1499. + Lzip_header header;
  1500. +
  1501. + Rd_reset_member_position(&rdec);
  1502. + for (size = 0; size < Lh_size && !Rd_finished(&rdec); ++size)
  1503. + header[size] = Rd_get_byte(&rdec);
  1504. + if (Rd_finished(&rdec)) { /* End Of File */
  1505. + if (first_member)
  1506. + retval = LZIP_HEADER1_EOF;
  1507. + else if (Lh_verify_prefix(header, size))
  1508. + retval = LZIP_HEADER2_EOF;
  1509. + break;
  1510. + }
  1511. + if (!Lh_verify_magic(header)) {
  1512. + if (first_member)
  1513. + retval = LZIP_BAD_MAGIC1;
  1514. + else if (Lh_verify_corrupt(header))
  1515. + retval = LZIP_BAD_MAGIC2;
  1516. + break;
  1517. + }
  1518. + if (!Lh_verify_version(header)) {
  1519. + retval = LZIP_BAD_VERSION;
  1520. + break;
  1521. + }
  1522. + dictionary_size = Lh_get_dictionary_size(header);
  1523. + if (dictionary_size < min_dictionary_size ||
  1524. + dictionary_size > max_dictionary_size) {
  1525. + retval = LZIP_BAD_DICT_SIZE;
  1526. + break;
  1527. + }
  1528. +
  1529. + if (!decoder)
  1530. + decoder = malloc(sizeof *decoder);
  1531. + if (!decoder || !LZd_init(decoder, &rdec, dictionary_size,
  1532. + outptr, out_size, flush)) {
  1533. + retval = LZIP_OOM_OUTBUF;
  1534. + break;
  1535. + }
  1536. + retval = LZd_decode_member(decoder);
  1537. + if (in_posp)
  1538. + *in_posp += Rd_member_position(&rdec);
  1539. + data_pos = LZd_data_position(decoder);
  1540. + if (outptr)
  1541. + outptr += data_pos;
  1542. + if (out_posp)
  1543. + *out_posp += data_pos;
  1544. + if (out_size > 0)
  1545. + out_size -= data_pos;
  1546. + LZd_free(decoder);
  1547. + if (retval != 0)
  1548. + break;
  1549. + }
  1550. + if (decoder)
  1551. + free(decoder);
  1552. + Rd_free(&rdec);
  1553. + return retval;
  1554. +}
  1555. +
  1556. +#ifndef STATIC
  1557. +EXPORT_SYMBOL_GPL(lzip_decompress);
  1558. +#endif
  1559. +MODULE_DESCRIPTION("LZIP Decompressor");
  1560. +MODULE_AUTHOR("Antonio Diaz Diaz <antonio@gnu.org>");
  1561. +MODULE_LICENSE("GPL");
  1562. diff -urdN linux-5.16.11/scripts/Makefile.lib linux-5.16.11.new/scripts/Makefile.lib
  1563. --- linux-5.16.11/scripts/Makefile.lib 2022-02-24 00:42:52.000000000 +0100
  1564. +++ linux-5.16.11.new/scripts/Makefile.lib 2022-02-28 22:10:45.800401973 +0100
  1565. @@ -397,6 +397,18 @@
  1566. quiet_cmd_bzip2 = BZIP2 $@
  1567. cmd_bzip2 = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@
  1568. +# Lzip
  1569. +# ---------------------------------------------------------------------------
  1570. +# The .lz format has the uncompressed size available at the end of the
  1571. +# file, but at offset (member_size - 16). So we append a gzip-style size.
  1572. +# Use klzip to compress the kernel image and lzip to compress other things.
  1573. +
  1574. +quiet_cmd_klzip = LZIP $@
  1575. + cmd_klzip = { cat $(real-prereqs) | $(KLZIP) -9; $(size_append); } > $@
  1576. +
  1577. +quiet_cmd_lzip = LZIP $@
  1578. + cmd_lzip = cat $(real-prereqs) | $(KLZIP) -9 > $@
  1579. +
  1580. # Lzma
  1581. # ---------------------------------------------------------------------------
  1582. diff -urdN linux-5.16.11/scripts/Makefile.modinst linux-5.16.11.new/scripts/Makefile.modinst
  1583. --- linux-5.16.11/scripts/Makefile.modinst 2022-02-24 00:42:52.000000000 +0100
  1584. +++ linux-5.16.11.new/scripts/Makefile.modinst 2022-02-28 22:29:45.920430307 +0100
  1585. @@ -20,6 +20,7 @@
  1586. suffix-y :=
  1587. suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz
  1588. +suffix-$(CONFIG_MODULE_COMPRESS_LZIP) := .lz
  1589. suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
  1590. suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
  1591. @@ -94,6 +95,8 @@
  1592. #
  1593. quiet_cmd_gzip = GZIP $@
  1594. cmd_gzip = $(KGZIP) -n -f $<
  1595. +quiet_cmd_lzip = LZIP $@
  1596. + cmd_lzip = $(KLZIP) -f $<
  1597. quiet_cmd_xz = XZ $@
  1598. cmd_xz = $(XZ) --lzma2=dict=2MiB -f $<
  1599. quiet_cmd_zstd = ZSTD $@
  1600. @@ -102,6 +105,9 @@
  1601. $(dst)/%.ko.gz: $(dst)/%.ko FORCE
  1602. $(call cmd,gzip)
  1603. +$(dst)/%.ko.lz: $(dst)/%.ko FORCE
  1604. + $(call cmd,lzip)
  1605. +
  1606. $(dst)/%.ko.xz: $(dst)/%.ko FORCE
  1607. $(call cmd,xz)
  1608. diff -urdN linux-5.16.11/scripts/extract-ikconfig linux-5.16.11.new/scripts/extract-ikconfig
  1609. --- linux-5.16.11/scripts/extract-ikconfig 2022-02-24 00:42:52.000000000 +0100
  1610. +++ linux-5.16.11.new/scripts/extract-ikconfig 2022-02-28 22:10:45.800401973 +0100
  1611. @@ -59,6 +59,7 @@
  1612. try_decompress '\037\213\010' xy gunzip
  1613. try_decompress '\3757zXZ\000' abcde unxz
  1614. try_decompress 'BZh' xy bunzip2
  1615. +try_decompress 'LZIP' xyz 'lzip -d'
  1616. try_decompress '\135\0\0\0' xxx unlzma
  1617. try_decompress '\211\114\132' xy 'lzop -d'
  1618. try_decompress '\002\041\114\030' xyy 'lz4 -d -l'
  1619. diff -urdN linux-5.16.11/scripts/extract-vmlinux linux-5.16.11.new/scripts/extract-vmlinux
  1620. --- linux-5.16.11/scripts/extract-vmlinux 2022-02-24 00:42:52.000000000 +0100
  1621. +++ linux-5.16.11.new/scripts/extract-vmlinux 2022-02-28 22:10:45.800401973 +0100
  1622. @@ -52,6 +52,7 @@
  1623. try_decompress '\037\213\010' xy gunzip
  1624. try_decompress '\3757zXZ\000' abcde unxz
  1625. try_decompress 'BZh' xy bunzip2
  1626. +try_decompress 'LZIP' xyz 'lzip -d'
  1627. try_decompress '\135\0\0\0' xxx unlzma
  1628. try_decompress '\211\114\132' xy 'lzop -d'
  1629. try_decompress '\002!L\030' xxx 'lz4 -d'
  1630. diff -urdN linux-5.16.11/scripts/package/buildtar linux-5.16.11.new/scripts/package/buildtar
  1631. --- linux-5.16.11/scripts/package/buildtar 2022-02-24 00:42:52.000000000 +0100
  1632. +++ linux-5.16.11.new/scripts/package/buildtar 2022-02-28 22:10:45.800401973 +0100
  1633. @@ -35,6 +35,10 @@
  1634. opts="-I ${KBZIP2}"
  1635. tarball=${tarball}.bz2
  1636. ;;
  1637. + tarlz-pkg)
  1638. + opts="-I ${KLZIP}"
  1639. + tarball=${tarball}.lz
  1640. + ;;
  1641. tarxz-pkg)
  1642. opts="-I ${XZ}"
  1643. tarball=${tarball}.xz
  1644. diff -urdN linux-5.16.11/scripts/patch-kernel linux-5.16.11.new/scripts/patch-kernel
  1645. --- linux-5.16.11/scripts/patch-kernel 2022-02-24 00:42:52.000000000 +0100
  1646. +++ linux-5.16.11.new/scripts/patch-kernel 2022-02-28 22:10:45.800401973 +0100
  1647. @@ -117,6 +117,10 @@
  1648. ext=".bz2"
  1649. name="bzip2"
  1650. uncomp="bunzip2 -dc"
  1651. + elif [ -r ${filebase}.lz ]; then
  1652. + ext=".lz"
  1653. + name="lzip"
  1654. + uncomp="lzip -dc"
  1655. elif [ -r ${filebase}.xz ]; then
  1656. ext=".xz"
  1657. name="xz"
  1658. 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
  1659. --- linux-5.16.11/tools/testing/selftests/gen_kselftest_tar.sh 2022-02-24 00:42:52.000000000 +0100
  1660. +++ linux-5.16.11.new/tools/testing/selftests/gen_kselftest_tar.sh 2022-02-28 23:52:00.350458667 +0100
  1661. @@ -27,6 +27,10 @@
  1662. copts="cvjf"
  1663. ext=".tar.bz2"
  1664. ;;
  1665. + tarlz)
  1666. + copts="-cv --lzip -f"
  1667. + ext=".tar.lz"
  1668. + ;;
  1669. tarxz)
  1670. copts="cvJf"
  1671. ext=".tar.xz"
  1672. diff -urdN linux-5.16.11/usr/Kconfig linux-5.16.11.new/usr/Kconfig
  1673. --- linux-5.16.11/usr/Kconfig 2022-02-24 00:42:52.000000000 +0100
  1674. +++ linux-5.16.11.new/usr/Kconfig 2022-03-01 00:01:32.160430303 +0100
  1675. @@ -68,6 +68,14 @@
  1676. Support loading of a bzip2 encoded initial ramdisk or cpio buffer
  1677. If unsure, say N.
  1678. +config RD_LZIP
  1679. + bool "Support initial ramdisk/ramfs compressed using lzip"
  1680. + default y
  1681. + select DECOMPRESS_LZIP
  1682. + help
  1683. + Support loading of a lzip encoded initial ramdisk or cpio buffer.
  1684. + If unsure, say N.
  1685. +
  1686. config RD_LZMA
  1687. bool "Support initial ramdisk/ramfs compressed using LZMA"
  1688. default y
  1689. @@ -155,6 +163,18 @@
  1690. If you choose this, keep in mind that you need to have the bzip2 tool
  1691. available to be able to compress the initram.
  1692. +config INITRAMFS_COMPRESSION_LZIP
  1693. + bool "Lzip"
  1694. + depends on RD_LZIP
  1695. + help
  1696. + Lzip's compression ratio is better than that of gzip and bzip2.
  1697. + Decompression speed is between gzip and bzip2. Compression can be
  1698. + as fast as gzip or slower than bzip2 depending on compression level.
  1699. + Lzip can produce a initramfs about a 16% smaller than gzip.
  1700. +
  1701. + If you choose this, keep in mind that you need to have the lzip tool
  1702. + available to be able to compress the initram.
  1703. +
  1704. config INITRAMFS_COMPRESSION_LZMA
  1705. bool "LZMA"
  1706. depends on RD_LZMA
  1707. diff -urdN linux-5.16.11/usr/Makefile linux-5.16.11.new/usr/Makefile
  1708. --- linux-5.16.11/usr/Makefile 2022-02-24 00:42:52.000000000 +0100
  1709. +++ linux-5.16.11.new/usr/Makefile 2022-02-28 22:10:45.800401973 +0100
  1710. @@ -11,6 +11,7 @@
  1711. compress-y := shipped
  1712. compress-$(CONFIG_INITRAMFS_COMPRESSION_GZIP) := gzip
  1713. compress-$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) := bzip2
  1714. +compress-$(CONFIG_INITRAMFS_COMPRESSION_LZIP) := lzip
  1715. compress-$(CONFIG_INITRAMFS_COMPRESSION_LZMA) := lzma
  1716. compress-$(CONFIG_INITRAMFS_COMPRESSION_XZ) := xzmisc
  1717. compress-$(CONFIG_INITRAMFS_COMPRESSION_LZO) := lzo