linux-6.1.11_lzip-0.diff 54 KB

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