]>
Commit | Line | Data |
---|---|---|
cc3ac616 | 1 | diff -urNp linux-2.6.27.orig/arch/x86/boot/compressed/Makefile linux-2.6.27/arch/x86/boot/compressed/Makefile |
2 | --- linux-2.6.27.orig/arch/x86/boot/compressed/Makefile 2008-10-29 08:48:23.000000000 +0100 | |
3 | +++ linux-2.6.27/arch/x86/boot/compressed/Makefile 2008-10-30 22:30:21.000000000 +0100 | |
69622671 | 4 | @@ -4,7 +4,7 @@ |
5 | # create a compressed vmlinux image from the original vmlinux | |
6 | # | |
7 | ||
fe820330 | 8 | -targets := vmlinux vmlinux.bin vmlinux.bin.gz head_$(BITS).o misc.o piggy.o |
9 | +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o | |
69622671 | 10 | |
fe820330 | 11 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 |
12 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC | |
cc3ac616 | 13 | @@ -46,9 +46,17 @@ $(obj)/vmlinux.bin.all: $(vmlinux.bin.al |
bd724f98 | 14 | ifdef CONFIG_RELOCATABLE |
15 | $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE | |
69622671 | 16 | $(call if_changed,gzip) |
69622671 | 17 | +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin.all FORCE |
18 | + $(call if_changed,bzip2) | |
69622671 | 19 | +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin.all FORCE |
20 | + $(call if_changed,lzma) | |
bd724f98 | 21 | else |
22 | $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE | |
23 | $(call if_changed,gzip) | |
24 | +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE | |
25 | + $(call if_changed,bzip2) | |
69622671 | 26 | +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE |
27 | + $(call if_changed,lzma) | |
bd724f98 | 28 | endif |
69622671 | 29 | LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T |
30 | ||
cc3ac616 | 31 | @@ -56,9 +64,17 @@ else |
edc94f74 | 32 | $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE |
33 | $(call if_changed,gzip) | |
cc3ac616 | 34 | |
edc94f74 | 35 | +$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE |
36 | + $(call if_changed,bzip2) | |
edc94f74 | 37 | +$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE |
38 | + $(call if_changed,lzma) | |
fe820330 | 39 | LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T |
40 | endif | |
41 | ||
cc3ac616 | 42 | |
43 | -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE | |
69622671 | 44 | +suffix_$(CONFIG_KERNEL_GZIP) = gz |
45 | +suffix_$(CONFIG_KERNEL_BZIP2) = bz2 | |
46 | +suffix_$(CONFIG_KERNEL_LZMA) = lzma | |
cc3ac616 | 47 | + |
fe820330 | 48 | +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE |
69622671 | 49 | $(call if_changed,ld) |
cc3ac616 | 50 | diff -urNp linux-2.6.27.orig/arch/x86/boot/compressed/misc.c linux-2.6.27/arch/x86/boot/compressed/misc.c |
51 | --- linux-2.6.27.orig/arch/x86/boot/compressed/misc.c 2008-10-29 08:48:23.000000000 +0100 | |
52 | +++ linux-2.6.27/arch/x86/boot/compressed/misc.c 2008-10-30 22:27:54.000000000 +0100 | |
53 | @@ -116,71 +116,13 @@ | |
54 | /* | |
55 | * gzip declarations | |
56 | */ | |
57 | - | |
58 | -#define OF(args) args | |
59 | #define STATIC static | |
69622671 | 60 | |
cc3ac616 | 61 | #undef memset |
62 | #undef memcpy | |
63 | #define memzero(s, n) memset((s), 0, (n)) | |
bd724f98 | 64 | |
cc3ac616 | 65 | -typedef unsigned char uch; |
66 | -typedef unsigned short ush; | |
67 | -typedef unsigned long ulg; | |
68 | - | |
69 | -/* | |
70 | - * Window size must be at least 32k, and a power of two. | |
71 | - * We don't actually have a window just a huge output buffer, | |
72 | - * so we report a 2G window size, as that should always be | |
73 | - * larger than our output buffer: | |
74 | - */ | |
75 | -#define WSIZE 0x80000000 | |
76 | - | |
77 | -/* Input buffer: */ | |
78 | -static unsigned char *inbuf; | |
79 | - | |
80 | -/* Sliding window buffer (and final output buffer): */ | |
81 | -static unsigned char *window; | |
69622671 | 82 | |
cc3ac616 | 83 | -/* Valid bytes in inbuf: */ |
84 | -static unsigned insize; | |
85 | - | |
86 | -/* Index of next byte to be processed in inbuf: */ | |
87 | -static unsigned inptr; | |
88 | - | |
89 | -/* Bytes in output buffer: */ | |
90 | -static unsigned outcnt; | |
91 | - | |
92 | -/* gzip flag byte */ | |
93 | -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ | |
94 | -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gz file */ | |
95 | -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ | |
96 | -#define ORIG_NAM 0x08 /* bit 3 set: original file name present */ | |
97 | -#define COMMENT 0x10 /* bit 4 set: file comment present */ | |
98 | -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | |
99 | -#define RESERVED 0xC0 /* bit 6, 7: reserved */ | |
100 | - | |
101 | -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) | |
102 | - | |
103 | -/* Diagnostic functions */ | |
104 | -#ifdef DEBUG | |
105 | -# define Assert(cond, msg) do { if (!(cond)) error(msg); } while (0) | |
106 | -# define Trace(x) do { fprintf x; } while (0) | |
107 | -# define Tracev(x) do { if (verbose) fprintf x ; } while (0) | |
108 | -# define Tracevv(x) do { if (verbose > 1) fprintf x ; } while (0) | |
109 | -# define Tracec(c, x) do { if (verbose && (c)) fprintf x ; } while (0) | |
110 | -# define Tracecv(c, x) do { if (verbose > 1 && (c)) fprintf x ; } while (0) | |
111 | -#else | |
112 | -# define Assert(cond, msg) | |
113 | -# define Trace(x) | |
114 | -# define Tracev(x) | |
115 | -# define Tracevv(x) | |
116 | -# define Tracec(c, x) | |
117 | -# define Tracecv(c, x) | |
118 | -#endif | |
119 | - | |
120 | -static int fill_inbuf(void); | |
121 | -static void flush_window(void); | |
69622671 | 122 | static void error(char *m); |
bd724f98 | 123 | |
69622671 | 124 | /* |
cc3ac616 | 125 | @@ -189,11 +131,6 @@ static void error(char *m); |
126 | static struct boot_params *real_mode; /* Pointer to real-mode data */ | |
127 | static int quiet; | |
69622671 | 128 | |
cc3ac616 | 129 | -extern unsigned char input_data[]; |
130 | -extern int input_len; | |
131 | - | |
132 | -static long bytes_out; | |
133 | - | |
69622671 | 134 | static void *memset(void *s, int c, unsigned n); |
69622671 | 135 | static void *memcpy(void *dest, const void *src, unsigned n); |
136 | ||
cc3ac616 | 137 | @@ -213,7 +150,17 @@ static char *vidmem; |
138 | static int vidport; | |
139 | static int lines, cols; | |
69622671 | 140 | |
69622671 | 141 | +#ifdef CONFIG_KERNEL_GZIP |
142 | #include "../../../../lib/inflate.c" | |
143 | +#endif | |
144 | + | |
145 | +#ifdef CONFIG_KERNEL_BZIP2 | |
146 | +#include "../../../../lib/decompress_bunzip2.c" | |
147 | +#endif | |
148 | + | |
149 | +#ifdef CONFIG_KERNEL_LZMA | |
150 | +#include "../../../../lib/decompress_unlzma.c" | |
151 | +#endif | |
152 | ||
69622671 | 153 | static void scroll(void) |
154 | { | |
cc3ac616 | 155 | @@ -291,38 +238,6 @@ static void *memcpy(void *dest, const vo |
69622671 | 156 | return dest; |
157 | } | |
158 | ||
cc3ac616 | 159 | -/* =========================================================================== |
160 | - * Fill the input buffer. This is called only when the buffer is empty | |
161 | - * and at least one byte is really needed. | |
162 | - */ | |
163 | -static int fill_inbuf(void) | |
164 | -{ | |
165 | - error("ran out of input data"); | |
166 | - return 0; | |
167 | -} | |
168 | - | |
169 | -/* =========================================================================== | |
170 | - * Write the output window window[0..outcnt-1] and update crc and bytes_out. | |
171 | - * (Used for the decompressed data only.) | |
172 | - */ | |
173 | -static void flush_window(void) | |
174 | -{ | |
175 | - /* With my window equal to my output buffer | |
176 | - * I only need to compute the crc here. | |
177 | - */ | |
178 | - unsigned long c = crc; /* temporary variable */ | |
179 | - unsigned n; | |
180 | - unsigned char *in, ch; | |
181 | - | |
182 | - in = window; | |
183 | - for (n = 0; n < outcnt; n++) { | |
184 | - ch = *in++; | |
185 | - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | |
186 | - } | |
187 | - crc = c; | |
188 | - bytes_out += (unsigned long)outcnt; | |
189 | - outcnt = 0; | |
190 | -} | |
69622671 | 191 | |
192 | static void error(char *x) | |
193 | { | |
cc3ac616 | 194 | @@ -405,12 +320,8 @@ asmlinkage void decompress_kernel(void * |
195 | lines = real_mode->screen_info.orig_video_lines; | |
196 | cols = real_mode->screen_info.orig_video_cols; | |
197 | ||
198 | - window = output; /* Output buffer (Normally at 1M) */ | |
fe820330 | 199 | free_mem_ptr = heap; /* Heap */ |
bd724f98 | 200 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; |
cc3ac616 | 201 | - inbuf = input_data; /* Input buffer */ |
202 | - insize = input_len; | |
203 | - inptr = 0; | |
69622671 | 204 | |
fe820330 | 205 | #ifdef CONFIG_X86_64 |
bd724f98 | 206 | if ((unsigned long)output & (__KERNEL_ALIGN - 1)) |
cc3ac616 | 207 | @@ -428,10 +339,9 @@ asmlinkage void decompress_kernel(void * |
fe820330 | 208 | #endif |
69622671 | 209 | #endif |
210 | ||
cc3ac616 | 211 | - makecrc(); |
212 | if (!quiet) | |
213 | putstr("\nDecompressing Linux... "); | |
214 | - gunzip(); | |
215 | + decompress(input_data, input_len, NULL, NULL, output, NULL, error); | |
bd724f98 | 216 | parse_elf(output); |
cc3ac616 | 217 | if (!quiet) |
218 | putstr("done.\nBooting the kernel.\n"); | |
219 | diff -urNp linux-2.6.27.orig/drivers/block/Kconfig linux-2.6.27/drivers/block/Kconfig | |
220 | --- linux-2.6.27.orig/drivers/block/Kconfig 2008-10-29 08:48:02.000000000 +0100 | |
221 | +++ linux-2.6.27/drivers/block/Kconfig 2008-10-30 22:27:34.000000000 +0100 | |
bd724f98 | 222 | @@ -357,6 +357,30 @@ config BLK_DEV_XIP |
223 | will prevent RAM block device backing store memory from being | |
224 | allocated from highmem (only a problem for highmem systems). | |
69622671 | 225 | |
226 | +config RD_BZIP2 | |
227 | + bool "Initial ramdisk compressed using bzip2" | |
228 | + default n | |
229 | + depends on BLK_DEV_INITRD=y | |
230 | + help | |
231 | + Support loading of a bzip2 encoded initial ramdisk or cpio buffer | |
232 | + If unsure, say N. | |
233 | + | |
234 | +config RD_LZMA | |
235 | + bool "Initial ramdisk compressed using lzma" | |
236 | + default n | |
237 | + depends on BLK_DEV_INITRD=y | |
238 | + help | |
239 | + Support loading of a lzma encoded initial ramdisk or cpio buffer | |
240 | + If unsure, say N. | |
241 | + | |
242 | +config RD_GZIP | |
243 | + bool "Initial ramdisk compressed using gzip" | |
244 | + default y | |
245 | + depends on BLK_DEV_INITRD=y | |
246 | + help | |
247 | + Support loading of a gzip encoded initial ramdisk or cpio buffer. | |
248 | + If unsure, say Y. | |
249 | + | |
250 | config CDROM_PKTCDVD | |
251 | tristate "Packet writing on CD/DVD media" | |
252 | depends on !UML | |
cc3ac616 | 253 | diff -urNp linux-2.6.27.orig/include/asm-x86/boot.h linux-2.6.27/include/asm-x86/boot.h |
254 | --- linux-2.6.27.orig/include/asm-x86/boot.h 2008-10-29 08:47:54.000000000 +0100 | |
255 | +++ linux-2.6.27/include/asm-x86/boot.h 2008-10-30 22:27:38.000000000 +0100 | |
256 | @@ -17,11 +17,21 @@ | |
bd724f98 | 257 | + (CONFIG_PHYSICAL_ALIGN - 1)) \ |
258 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) | |
259 | ||
cc3ac616 | 260 | +#if (defined CONFIG_KERNEL_BZIP2) |
bd724f98 | 261 | +#define BOOT_HEAP_SIZE 0x400000 |
262 | +#else | |
263 | + | |
264 | #ifdef CONFIG_X86_64 | |
265 | #define BOOT_HEAP_SIZE 0x7000 | |
266 | -#define BOOT_STACK_SIZE 0x4000 | |
267 | #else | |
268 | #define BOOT_HEAP_SIZE 0x4000 | |
269 | +#endif | |
270 | + | |
271 | +#endif | |
272 | + | |
273 | +#ifdef CONFIG_X86_64 | |
274 | +#define BOOT_STACK_SIZE 0x4000 | |
275 | +#else | |
276 | #define BOOT_STACK_SIZE 0x1000 | |
277 | #endif | |
278 | ||
cc3ac616 | 279 | diff -urNp linux-2.6.27.orig/include/linux/decompress/bunzip2.h linux-2.6.27/include/linux/decompress/bunzip2.h |
280 | --- linux-2.6.27.orig/include/linux/decompress/bunzip2.h 1970-01-01 01:00:00.000000000 +0100 | |
281 | +++ linux-2.6.27/include/linux/decompress/bunzip2.h 2008-10-30 22:27:29.000000000 +0100 | |
282 | @@ -0,0 +1,10 @@ | |
69622671 | 283 | +#ifndef DECOMPRESS_BUNZIP2_H |
284 | +#define DECOMPRESS_BUNZIP2_H | |
285 | + | |
cc3ac616 | 286 | +int bunzip2(unsigned char *inbuf, int len, |
287 | + int(*fill)(void*, unsigned int), | |
288 | + int(*flush)(void*, unsigned int), | |
289 | + unsigned char *output, | |
290 | + int *pos, | |
291 | + void(*error)(char *x)); | |
292 | +#endif | |
293 | diff -urNp linux-2.6.27.orig/include/linux/decompress/generic.h linux-2.6.27/include/linux/decompress/generic.h | |
294 | --- linux-2.6.27.orig/include/linux/decompress/generic.h 1970-01-01 01:00:00.000000000 +0100 | |
295 | +++ linux-2.6.27/include/linux/decompress/generic.h 2008-10-30 22:27:29.000000000 +0100 | |
296 | @@ -0,0 +1,30 @@ | |
69622671 | 297 | +#ifndef DECOMPRESS_GENERIC_H |
298 | +#define DECOMPRESS_GENERIC_H | |
299 | + | |
300 | +/* Minimal chunksize to be read. | |
bd724f98 | 301 | + *Bzip2 prefers at least 4096 |
302 | + *Lzma prefers 0x10000 */ | |
69622671 | 303 | +#define COMPR_IOBUF_SIZE 4096 |
304 | + | |
cc3ac616 | 305 | +typedef int (*decompress_fn) (unsigned char *inbuf, int len, |
306 | + int(*fill)(void*, unsigned int), | |
307 | + int(*writebb)(void*, unsigned int), | |
308 | + unsigned char *output, | |
309 | + int *posp, | |
310 | + void(*error)(char *x)); | |
69622671 | 311 | + |
312 | +/* inbuf - input buffer | |
bd724f98 | 313 | + *len - len of pre-read data in inbuf |
314 | + *fill - function to fill inbuf if empty | |
315 | + *writebb - function to write out outbug | |
316 | + *posp - if non-null, input position (number of bytes read) will be | |
317 | + * returned here | |
69622671 | 318 | + * |
bd724f98 | 319 | + *If len != 0, the inbuf is initialized (with as much data), and fill |
320 | + *should not be called | |
321 | + *If len = 0, the inbuf is allocated, but empty. Its size is IOBUF_SIZE | |
322 | + *fill should be called (repeatedly...) to read data, at most IOBUF_SIZE | |
69622671 | 323 | + */ |
bd724f98 | 324 | + |
69622671 | 325 | + |
326 | +#endif | |
cc3ac616 | 327 | diff -urNp linux-2.6.27.orig/include/linux/decompress/inflate.h linux-2.6.27/include/linux/decompress/inflate.h |
328 | --- linux-2.6.27.orig/include/linux/decompress/inflate.h 1970-01-01 01:00:00.000000000 +0100 | |
329 | +++ linux-2.6.27/include/linux/decompress/inflate.h 2008-10-30 22:27:29.000000000 +0100 | |
330 | @@ -0,0 +1,13 @@ | |
331 | +#ifndef INFLATE_H | |
332 | +#define INFLATE_H | |
69622671 | 333 | + |
cc3ac616 | 334 | +/* Other housekeeping constants */ |
335 | +#define INBUFSIZ 4096 | |
336 | + | |
337 | +int gunzip(unsigned char *inbuf, int len, | |
338 | + int(*fill)(void*, unsigned int), | |
339 | + int(*flush)(void*, unsigned int), | |
340 | + unsigned char *output, | |
341 | + int *pos, | |
342 | + void(*error_fn)(char *x)); | |
343 | +#endif | |
344 | diff -urNp linux-2.6.27.orig/include/linux/decompress/mm.h linux-2.6.27/include/linux/decompress/mm.h | |
345 | --- linux-2.6.27.orig/include/linux/decompress/mm.h 1970-01-01 01:00:00.000000000 +0100 | |
346 | +++ linux-2.6.27/include/linux/decompress/mm.h 2008-10-30 22:27:54.000000000 +0100 | |
347 | @@ -0,0 +1,88 @@ | |
348 | +/* | |
349 | + * linux/compr_mm.h | |
350 | + * | |
351 | + * Memory management for pre-boot and ramdisk uncompressors | |
352 | + * | |
353 | + * Authors: Alain Knaff <alain@knaff.lu> | |
354 | + * | |
355 | + */ | |
69622671 | 356 | + |
cc3ac616 | 357 | +#ifndef DECOMPR_MM_H |
358 | +#define DECOMPR_MM_H | |
69622671 | 359 | + |
cc3ac616 | 360 | +#ifdef STATIC |
69622671 | 361 | + |
cc3ac616 | 362 | +/* Code active when included from pre-boot environment: */ |
363 | + | |
364 | +/* A trivial malloc implementation, adapted from | |
365 | + * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 | |
366 | + */ | |
367 | +static unsigned long malloc_ptr; | |
368 | +static int malloc_count; | |
369 | + | |
370 | +static void *malloc(int size) | |
371 | +{ | |
372 | + void *p; | |
373 | + | |
374 | + if (size < 0) | |
375 | + error("Malloc error"); | |
376 | + if (!malloc_ptr) | |
377 | + malloc_ptr = free_mem_ptr; | |
378 | + | |
379 | + malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ | |
380 | + | |
381 | + p = (void *)malloc_ptr; | |
382 | + malloc_ptr += size; | |
383 | + | |
384 | + if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) | |
385 | + error("Out of memory"); | |
386 | + | |
387 | + malloc_count++; | |
388 | + return p; | |
389 | +} | |
390 | + | |
391 | +static void free(void *where) | |
392 | +{ | |
393 | + malloc_count--; | |
394 | + if (!malloc_count) | |
395 | + malloc_ptr = free_mem_ptr; | |
396 | +} | |
397 | + | |
398 | +#define large_malloc(a) malloc(a) | |
399 | +#define large_free(a) free(a) | |
400 | + | |
401 | +#define set_error_fn(x) | |
402 | +#define panic error | |
403 | + | |
404 | +#define INIT | |
405 | + | |
406 | +#else /* STATIC */ | |
407 | + | |
408 | +/* Code active when compiled standalone for use when loading ramdisk: */ | |
409 | + | |
410 | +#include <linux/kernel.h> | |
411 | +#include <linux/fs.h> | |
412 | +#include <linux/string.h> | |
413 | +#include <linux/vmalloc.h> | |
414 | + | |
415 | +/* Use defines rather than static inline in order to avoid spurious | |
416 | + * warnings when not needed (indeed large_malloc / large_free are not | |
417 | + * needed by inflate */ | |
418 | + | |
419 | +#define malloc(a) kmalloc(a, GFP_KERNEL) | |
420 | +#define free(a) kfree(a) | |
421 | + | |
422 | +#define large_malloc(a) vmalloc(a) | |
423 | +#define large_free(a) vfree(a) | |
424 | + | |
425 | +static void(*error)(char *m); | |
426 | +#define set_error_fn(x) error = x; | |
427 | + | |
428 | +#define INIT __init | |
429 | +#define STATIC | |
430 | + | |
431 | +#include <linux/init.h> | |
432 | + | |
433 | +#endif /* STATIC */ | |
434 | + | |
435 | +#endif /* DECOMPR_MM_H */ | |
436 | diff -urNp linux-2.6.27.orig/include/linux/decompress/unlzma.h linux-2.6.27/include/linux/decompress/unlzma.h | |
437 | --- linux-2.6.27.orig/include/linux/decompress/unlzma.h 1970-01-01 01:00:00.000000000 +0100 | |
438 | +++ linux-2.6.27/include/linux/decompress/unlzma.h 2008-10-30 22:27:29.000000000 +0100 | |
439 | @@ -0,0 +1,12 @@ | |
440 | +#ifndef DECOMPRESS_UNLZMA_H | |
441 | +#define DECOMPRESS_UNLZMA_H | |
442 | + | |
443 | +int unlzma(unsigned char *, int, | |
444 | + int(*fill)(void*, unsigned int), | |
445 | + int(*flush)(void*, unsigned int), | |
446 | + unsigned char *output, | |
447 | + int *posp, | |
448 | + void(*error)(char *x) | |
bd724f98 | 449 | + ); |
69622671 | 450 | + |
4379298f | 451 | +#endif |
cc3ac616 | 452 | diff -urNp linux-2.6.27.orig/init/do_mounts_rd.c linux-2.6.27/init/do_mounts_rd.c |
453 | --- linux-2.6.27.orig/init/do_mounts_rd.c 2008-10-29 08:48:10.000000000 +0100 | |
454 | +++ linux-2.6.27/init/do_mounts_rd.c 2008-10-30 22:27:34.000000000 +0100 | |
455 | @@ -10,6 +10,12 @@ | |
4379298f | 456 | |
bd724f98 | 457 | #include "do_mounts.h" |
458 | ||
cc3ac616 | 459 | +#include <linux/decompress/generic.h> |
460 | + | |
461 | +#include <linux/decompress/bunzip2.h> | |
462 | +#include <linux/decompress/unlzma.h> | |
463 | +#include <linux/decompress/inflate.h> | |
464 | + | |
465 | int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ | |
466 | ||
467 | static int __init prompt_ramdisk(char *str) | |
468 | @@ -28,7 +34,7 @@ static int __init ramdisk_start_setup(ch | |
69622671 | 469 | } |
470 | __setup("ramdisk_start=", ramdisk_start_setup); | |
471 | ||
cc3ac616 | 472 | -static int __init crd_load(int in_fd, int out_fd); |
473 | +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); | |
69622671 | 474 | |
475 | /* | |
476 | * This routine tries to find a RAM disk image to load, and returns the | |
cc3ac616 | 477 | @@ -44,7 +50,7 @@ static int __init crd_load(int in_fd, in |
69622671 | 478 | * gzip |
479 | */ | |
480 | static int __init | |
481 | -identify_ramdisk_image(int fd, int start_block) | |
cc3ac616 | 482 | +identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) |
69622671 | 483 | { |
484 | const int size = 512; | |
485 | struct minix_super_block *minixsb; | |
cc3ac616 | 486 | @@ -70,6 +76,7 @@ identify_ramdisk_image(int fd, int start |
69622671 | 487 | sys_lseek(fd, start_block * BLOCK_SIZE, 0); |
488 | sys_read(fd, buf, size); | |
489 | ||
490 | +#ifdef CONFIG_RD_GZIP | |
491 | /* | |
492 | * If it matches the gzip magic numbers, return -1 | |
493 | */ | |
cc3ac616 | 494 | @@ -77,9 +84,39 @@ identify_ramdisk_image(int fd, int start |
69622671 | 495 | printk(KERN_NOTICE |
496 | "RAMDISK: Compressed image found at block %d\n", | |
497 | start_block); | |
cc3ac616 | 498 | + *decompressor = gunzip; |
69622671 | 499 | + nblocks = 0; |
500 | + goto done; | |
501 | + } | |
502 | +#endif | |
503 | + | |
504 | +#ifdef CONFIG_RD_BZIP2 | |
505 | + /* | |
cc3ac616 | 506 | + * If it matches the bzip2 magic numbers, return -1 |
69622671 | 507 | + */ |
508 | + if (buf[0] == 0x42 && (buf[1] == 0x5a)) { | |
509 | + printk(KERN_NOTICE | |
510 | + "RAMDISK: Bzipped image found at block %d\n", | |
511 | + start_block); | |
cc3ac616 | 512 | + *decompressor = bunzip2; |
513 | nblocks = 0; | |
514 | goto done; | |
515 | } | |
69622671 | 516 | +#endif |
517 | + | |
518 | +#ifdef CONFIG_RD_LZMA | |
519 | + /* | |
cc3ac616 | 520 | + * If it matches the lzma magic numbers, return -1 |
69622671 | 521 | + */ |
522 | + if (buf[0] == 0x5d && (buf[1] == 0x00)) { | |
523 | + printk(KERN_NOTICE | |
524 | + "RAMDISK: Lzma image found at block %d\n", | |
525 | + start_block); | |
cc3ac616 | 526 | + *decompressor = unlzma; |
527 | + nblocks = 0; | |
528 | + goto done; | |
529 | + } | |
69622671 | 530 | +#endif |
69622671 | 531 | |
532 | /* romfs is at block zero too */ | |
533 | if (romfsb->word0 == ROMSB_WORD0 && | |
cc3ac616 | 534 | @@ -143,6 +180,7 @@ int __init rd_load_image(char *from) |
69622671 | 535 | int nblocks, i, disk; |
536 | char *buf = NULL; | |
537 | unsigned short rotate = 0; | |
cc3ac616 | 538 | + decompress_fn decompressor = NULL; |
69622671 | 539 | #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) |
540 | char rotator[4] = { '|' , '/' , '-' , '\\' }; | |
541 | #endif | |
cc3ac616 | 542 | @@ -155,12 +193,12 @@ int __init rd_load_image(char *from) |
69622671 | 543 | if (in_fd < 0) |
544 | goto noclose_input; | |
545 | ||
546 | - nblocks = identify_ramdisk_image(in_fd, rd_image_start); | |
cc3ac616 | 547 | + nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor); |
69622671 | 548 | if (nblocks < 0) |
549 | goto done; | |
550 | ||
551 | if (nblocks == 0) { | |
69622671 | 552 | - if (crd_load(in_fd, out_fd) == 0) |
cc3ac616 | 553 | + if (crd_load(in_fd, out_fd, decompressor) == 0) |
554 | goto successful_load; | |
555 | goto done; | |
556 | } | |
557 | @@ -259,138 +297,48 @@ int __init rd_load_disk(int n) | |
558 | return rd_load_image("/dev/root"); | |
559 | } | |
69622671 | 560 | |
cc3ac616 | 561 | -/* |
562 | - * gzip declarations | |
563 | - */ | |
564 | - | |
565 | -#define OF(args) args | |
566 | - | |
567 | -#ifndef memzero | |
568 | -#define memzero(s, n) memset ((s), 0, (n)) | |
569 | -#endif | |
570 | - | |
571 | -typedef unsigned char uch; | |
572 | -typedef unsigned short ush; | |
573 | -typedef unsigned long ulg; | |
574 | - | |
575 | -#define INBUFSIZ 4096 | |
576 | -#define WSIZE 0x8000 /* window size--must be a power of two, and */ | |
577 | - /* at least 32K for zip's deflate method */ | |
578 | - | |
579 | -static uch *inbuf; | |
580 | -static uch *window; | |
581 | - | |
582 | -static unsigned insize; /* valid bytes in inbuf */ | |
583 | -static unsigned inptr; /* index of next byte to be processed in inbuf */ | |
584 | -static unsigned outcnt; /* bytes in output buffer */ | |
69622671 | 585 | static int exit_code; |
cc3ac616 | 586 | -static int unzip_error; |
587 | -static long bytes_out; | |
588 | +static int decompress_error; | |
69622671 | 589 | static int crd_infd, crd_outfd; |
590 | ||
cc3ac616 | 591 | -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) |
592 | - | |
593 | -/* Diagnostic functions (stubbed out) */ | |
594 | -#define Assert(cond,msg) | |
595 | -#define Trace(x) | |
596 | -#define Tracev(x) | |
597 | -#define Tracevv(x) | |
598 | -#define Tracec(c,x) | |
599 | -#define Tracecv(c,x) | |
600 | - | |
601 | -#define STATIC static | |
602 | -#define INIT __init | |
603 | - | |
604 | -static int __init fill_inbuf(void); | |
605 | -static void __init flush_window(void); | |
606 | -static void __init error(char *m); | |
607 | - | |
608 | -#define NO_INFLATE_MALLOC | |
609 | - | |
610 | -#include "../lib/inflate.c" | |
611 | - | |
612 | -/* =========================================================================== | |
613 | - * Fill the input buffer. This is called only when the buffer is empty | |
614 | - * and at least one byte is really needed. | |
615 | - * Returning -1 does not guarantee that gunzip() will ever return. | |
616 | - */ | |
617 | -static int __init fill_inbuf(void) | |
69622671 | 618 | +static int __init compr_fill(void *buf, unsigned int len) |
cc3ac616 | 619 | { |
620 | - if (exit_code) return -1; | |
621 | - | |
622 | - insize = sys_read(crd_infd, inbuf, INBUFSIZ); | |
623 | - if (insize == 0) { | |
624 | - error("RAMDISK: ran out of compressed data"); | |
625 | - return -1; | |
626 | - } | |
627 | - | |
628 | - inptr = 1; | |
629 | - | |
630 | - return inbuf[0]; | |
69622671 | 631 | + int r = sys_read(crd_infd, buf, len); |
bd724f98 | 632 | + if (r < 0) |
69622671 | 633 | + printk(KERN_ERR "RAMDISK: error while reading compressed data"); |
bd724f98 | 634 | + else if (r == 0) |
69622671 | 635 | + printk(KERN_ERR "RAMDISK: EOF while reading compressed data"); |
69622671 | 636 | + return r; |
69622671 | 637 | } |
69622671 | 638 | |
cc3ac616 | 639 | -/* =========================================================================== |
640 | - * Write the output window window[0..outcnt-1] and update crc and bytes_out. | |
641 | - * (Used for the decompressed data only.) | |
642 | - */ | |
643 | -static void __init flush_window(void) | |
bd724f98 | 644 | +static int __init compr_flush(void *window, unsigned int outcnt) |
cc3ac616 | 645 | { |
646 | - ulg c = crc; /* temporary variable */ | |
647 | - unsigned n, written; | |
648 | - uch *in, ch; | |
649 | - | |
650 | - written = sys_write(crd_outfd, window, outcnt); | |
651 | - if (written != outcnt && unzip_error == 0) { | |
652 | - printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", | |
653 | - written, outcnt, bytes_out); | |
654 | - unzip_error = 1; | |
655 | - } | |
656 | - in = window; | |
657 | - for (n = 0; n < outcnt; n++) { | |
658 | - ch = *in++; | |
659 | - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | |
660 | - } | |
661 | - crc = c; | |
662 | - bytes_out += (ulg)outcnt; | |
663 | - outcnt = 0; | |
69622671 | 664 | + int written = sys_write(crd_outfd, window, outcnt); |
665 | + if (written != outcnt) { | |
cc3ac616 | 666 | + if (decompress_error == 0) |
667 | + printk(KERN_ERR | |
668 | + "RAMDISK: incomplete write (%d != %d)\n", | |
669 | + written, outcnt); | |
670 | + decompress_error = 1; | |
671 | + return -1; | |
69622671 | 672 | + } |
69622671 | 673 | + return outcnt; |
cc3ac616 | 674 | } |
675 | ||
69622671 | 676 | static void __init error(char *x) |
677 | { | |
678 | printk(KERN_ERR "%s\n", x); | |
cc3ac616 | 679 | exit_code = 1; |
680 | - unzip_error = 1; | |
681 | + decompress_error = 1; | |
69622671 | 682 | } |
69622671 | 683 | |
cc3ac616 | 684 | -static int __init crd_load(int in_fd, int out_fd) |
685 | +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) | |
69622671 | 686 | { |
cc3ac616 | 687 | int result; |
688 | - | |
689 | - insize = 0; /* valid bytes in inbuf */ | |
690 | - inptr = 0; /* index of next byte to be processed in inbuf */ | |
691 | - outcnt = 0; /* bytes in output buffer */ | |
692 | - exit_code = 0; | |
693 | - bytes_out = 0; | |
694 | - crc = (ulg)0xffffffffL; /* shift register contents */ | |
695 | - | |
696 | crd_infd = in_fd; | |
697 | crd_outfd = out_fd; | |
698 | - inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); | |
699 | - if (!inbuf) { | |
700 | - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); | |
701 | - return -1; | |
702 | - } | |
703 | - window = kmalloc(WSIZE, GFP_KERNEL); | |
704 | - if (!window) { | |
705 | - printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); | |
706 | - kfree(inbuf); | |
707 | - return -1; | |
708 | - } | |
709 | - makecrc(); | |
710 | - result = gunzip(); | |
711 | - if (unzip_error) | |
712 | + result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); | |
713 | + if (decompress_error) | |
714 | result = 1; | |
715 | - kfree(inbuf); | |
716 | - kfree(window); | |
717 | return result; | |
718 | } | |
719 | diff -urNp linux-2.6.27.orig/init/initramfs.c linux-2.6.27/init/initramfs.c | |
720 | --- linux-2.6.27.orig/init/initramfs.c 2008-10-29 08:48:10.000000000 +0100 | |
721 | +++ linux-2.6.27/init/initramfs.c 2008-10-30 22:27:34.000000000 +0100 | |
722 | @@ -337,11 +337,14 @@ static int __init write_buffer(char *buf | |
69622671 | 723 | return len - count; |
724 | } | |
725 | ||
726 | -static void __init flush_buffer(char *buf, unsigned len) | |
727 | + | |
728 | +static int __init flush_buffer(void *bufv, unsigned len) | |
729 | { | |
730 | + char *buf = (char *) bufv; | |
731 | int written; | |
732 | + int origLen = len; | |
733 | if (message) | |
734 | - return; | |
735 | + return -1; | |
736 | while ((written = write_buffer(buf, len)) < len && !message) { | |
737 | char c = buf[written]; | |
738 | if (c == '0') { | |
cc3ac616 | 739 | @@ -355,73 +358,14 @@ static void __init flush_buffer(char *bu |
69622671 | 740 | } else |
741 | error("junk in compressed archive"); | |
742 | } | |
743 | + return origLen; | |
744 | } | |
745 | ||
cc3ac616 | 746 | -/* |
747 | - * gzip declarations | |
748 | - */ | |
749 | - | |
750 | -#define OF(args) args | |
751 | - | |
752 | -#ifndef memzero | |
753 | -#define memzero(s, n) memset ((s), 0, (n)) | |
754 | -#endif | |
755 | +static unsigned my_inptr; /* index of next byte to be processed in inbuf */ | |
69622671 | 756 | |
cc3ac616 | 757 | -typedef unsigned char uch; |
758 | -typedef unsigned short ush; | |
759 | -typedef unsigned long ulg; | |
760 | - | |
761 | -#define WSIZE 0x8000 /* window size--must be a power of two, and */ | |
762 | - /* at least 32K for zip's deflate method */ | |
763 | - | |
764 | -static uch *inbuf; | |
765 | -static uch *window; | |
766 | - | |
767 | -static unsigned insize; /* valid bytes in inbuf */ | |
69622671 | 768 | -static unsigned inptr; /* index of next byte to be processed in inbuf */ |
cc3ac616 | 769 | -static unsigned outcnt; /* bytes in output buffer */ |
770 | -static long bytes_out; | |
771 | - | |
772 | -#define get_byte() (inptr < insize ? inbuf[inptr++] : -1) | |
773 | - | |
774 | -/* Diagnostic functions (stubbed out) */ | |
775 | -#define Assert(cond,msg) | |
776 | -#define Trace(x) | |
777 | -#define Tracev(x) | |
778 | -#define Tracevv(x) | |
779 | -#define Tracec(c,x) | |
780 | -#define Tracecv(c,x) | |
781 | - | |
782 | -#define STATIC static | |
783 | -#define INIT __init | |
784 | - | |
785 | -static void __init flush_window(void); | |
786 | -static void __init error(char *m); | |
787 | - | |
788 | -#define NO_INFLATE_MALLOC | |
789 | - | |
790 | -#include "../lib/inflate.c" | |
791 | - | |
792 | -/* =========================================================================== | |
793 | - * Write the output window window[0..outcnt-1] and update crc and bytes_out. | |
794 | - * (Used for the decompressed data only.) | |
795 | - */ | |
796 | -static void __init flush_window(void) | |
797 | -{ | |
798 | - ulg c = crc; /* temporary variable */ | |
799 | - unsigned n; | |
800 | - uch *in, ch; | |
801 | - | |
802 | - flush_buffer(window, outcnt); | |
803 | - in = window; | |
804 | - for (n = 0; n < outcnt; n++) { | |
805 | - ch = *in++; | |
806 | - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | |
807 | - } | |
808 | - crc = c; | |
809 | - bytes_out += (ulg)outcnt; | |
810 | - outcnt = 0; | |
811 | -} | |
812 | +#include <linux/decompress/bunzip2.h> | |
813 | +#include <linux/decompress/unlzma.h> | |
814 | +#include <linux/decompress/inflate.h> | |
69622671 | 815 | |
816 | static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) | |
817 | { | |
cc3ac616 | 818 | @@ -430,9 +374,10 @@ static char * __init unpack_to_rootfs(ch |
bd724f98 | 819 | header_buf = kmalloc(110, GFP_KERNEL); |
820 | symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); | |
821 | name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); | |
cc3ac616 | 822 | - window = kmalloc(WSIZE, GFP_KERNEL); |
823 | - if (!window || !header_buf || !symlink_buf || !name_buf) | |
824 | + | |
825 | + if (!header_buf || !symlink_buf || !name_buf) | |
69622671 | 826 | panic("can't allocate buffers"); |
cc3ac616 | 827 | + |
69622671 | 828 | state = Start; |
829 | this_header = 0; | |
830 | message = NULL; | |
cc3ac616 | 831 | @@ -452,21 +397,39 @@ static char * __init unpack_to_rootfs(ch |
69622671 | 832 | continue; |
833 | } | |
834 | this_header = 0; | |
cc3ac616 | 835 | - insize = len; |
836 | - inbuf = buf; | |
837 | - inptr = 0; | |
838 | - outcnt = 0; /* bytes in output buffer */ | |
839 | - bytes_out = 0; | |
840 | - crc = (ulg)0xffffffffL; /* shift register contents */ | |
841 | - makecrc(); | |
69622671 | 842 | - gunzip(); |
cc3ac616 | 843 | + if (!gunzip(buf, len, NULL, flush_buffer, NULL, |
844 | + &my_inptr, error) && | |
845 | + message == NULL) | |
69622671 | 846 | + goto ok; |
69622671 | 847 | + |
848 | +#ifdef CONFIG_RD_BZIP2 | |
849 | + message = NULL; /* Zero out message, or else cpio will | |
850 | + think an error has already occured */ | |
cc3ac616 | 851 | + if (!bunzip2(buf, len, NULL, flush_buffer, NULL, |
852 | + &my_inptr, error) < 0 | |
853 | + && | |
854 | + message == NULL) { | |
69622671 | 855 | + goto ok; |
856 | + } | |
857 | +#endif | |
858 | + | |
859 | +#ifdef CONFIG_RD_LZMA | |
860 | + message = NULL; /* Zero out message, or else cpio will | |
861 | + think an error has already occured */ | |
cc3ac616 | 862 | + if (!unlzma(buf, len, NULL, flush_buffer, NULL, |
863 | + &my_inptr, error) < 0 | |
864 | + && | |
865 | + message == NULL) { | |
69622671 | 866 | + goto ok; |
867 | + } | |
868 | +#endif | |
bd724f98 | 869 | +ok: |
69622671 | 870 | if (state != Reset) |
871 | - error("junk in gzipped archive"); | |
cc3ac616 | 872 | - this_header = saved_offset + inptr; |
873 | - buf += inptr; | |
874 | - len -= inptr; | |
69622671 | 875 | + error("junk in compressed archive"); |
cc3ac616 | 876 | + this_header = saved_offset + my_inptr; |
877 | + buf += my_inptr; | |
878 | + len -= my_inptr; | |
69622671 | 879 | } |
cc3ac616 | 880 | - kfree(window); |
bd724f98 | 881 | kfree(name_buf); |
882 | kfree(symlink_buf); | |
883 | kfree(header_buf); | |
cc3ac616 | 884 | diff -urNp linux-2.6.27.orig/init/Kconfig linux-2.6.27/init/Kconfig |
885 | --- linux-2.6.27.orig/init/Kconfig 2008-10-29 08:48:10.000000000 +0100 | |
886 | +++ linux-2.6.27/init/Kconfig 2008-10-30 22:27:34.000000000 +0100 | |
bd724f98 | 887 | @@ -101,6 +101,56 @@ config LOCALVERSION_AUTO |
69622671 | 888 | |
bd724f98 | 889 | which is done within the script "scripts/setlocalversion".) |
890 | ||
891 | +choice | |
892 | + prompt "Kernel compression mode" | |
893 | + default KERNEL_GZIP | |
894 | + help | |
895 | + The linux kernel is a kind of self-extracting executable. | |
896 | + Several compression algorithms are available, which differ | |
897 | + in efficiency, compression and decompression speed. | |
898 | + Compression speed is only relevant when building a kernel. | |
899 | + Decompression speed is relevant at each boot. | |
900 | + | |
901 | + If you have any problems with bzip2 or lzma compressed | |
902 | + kernels, mail me (Alain Knaff) <alain@knaff.lu>. (An older | |
903 | + version of this functionality (bzip2 only), for 2.4, was | |
904 | + supplied by Christian Ludwig) | |
69622671 | 905 | + |
bd724f98 | 906 | + High compression options are mostly useful for users, who |
907 | + are low on disk space (embedded systems), but for whom ram | |
908 | + size matters less. | |
69622671 | 909 | + |
bd724f98 | 910 | + If in doubt, select 'gzip' |
911 | + | |
912 | +config KERNEL_GZIP | |
913 | + bool "Gzip" | |
914 | + help | |
915 | + The old and tried gzip compression. Its compression ratio is | |
916 | + the poorest among the 3 choices; however its speed (both | |
917 | + compression and decompression) is the fastest. | |
918 | + | |
919 | +config KERNEL_BZIP2 | |
920 | + bool "Bzip2" | |
921 | + help | |
922 | + Its compression ratio and speed is intermediate. | |
923 | + Decompression speed is slowest among the 3. | |
924 | + The kernel size is about 10 per cent smaller with bzip2, | |
925 | + in comparison to gzip. | |
926 | + Bzip2 uses a large amount of memory. For modern kernels | |
927 | + you will need at least 8MB RAM or more for booting. | |
928 | + | |
929 | +config KERNEL_LZMA | |
930 | + bool "LZMA" | |
931 | + help | |
932 | + The most recent compression algorithm. | |
933 | + Its ratio is best, decompression speed is between the other | |
934 | + 2. Compression is slowest. | |
935 | + The kernel size is about 33 per cent smaller with lzma, | |
936 | + in comparison to gzip. | |
937 | + | |
938 | +endchoice | |
939 | + | |
940 | + | |
941 | config SWAP | |
942 | bool "Support for paging of anonymous memory (swap)" | |
943 | depends on MMU && BLOCK | |
cc3ac616 | 944 | diff -urNp linux-2.6.27.orig/lib/decompress_bunzip2.c linux-2.6.27/lib/decompress_bunzip2.c |
945 | --- linux-2.6.27.orig/lib/decompress_bunzip2.c 1970-01-01 01:00:00.000000000 +0100 | |
946 | +++ linux-2.6.27/lib/decompress_bunzip2.c 2008-10-30 22:27:29.000000000 +0100 | |
947 | @@ -0,0 +1,735 @@ | |
bd724f98 | 948 | +/* vi: set sw = 4 ts = 4: */ |
69622671 | 949 | +/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net). |
950 | + | |
951 | + Based on bzip2 decompression code by Julian R Seward (jseward@acm.org), | |
952 | + which also acknowledges contributions by Mike Burrows, David Wheeler, | |
953 | + Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten, | |
954 | + Robert Sedgewick, and Jon L. Bentley. | |
955 | + | |
956 | + This code is licensed under the LGPLv2: | |
957 | + LGPL (http://www.gnu.org/copyleft/lgpl.html | |
958 | +*/ | |
959 | + | |
960 | +/* | |
961 | + Size and speed optimizations by Manuel Novoa III (mjn3@codepoet.org). | |
962 | + | |
963 | + More efficient reading of Huffman codes, a streamlined read_bunzip() | |
964 | + function, and various other tweaks. In (limited) tests, approximately | |
965 | + 20% faster than bzcat on x86 and about 10% faster on arm. | |
966 | + | |
967 | + Note that about 2/3 of the time is spent in read_unzip() reversing | |
968 | + the Burrows-Wheeler transformation. Much of that time is delay | |
969 | + resulting from cache misses. | |
970 | + | |
971 | + I would ask that anyone benefiting from this work, especially those | |
972 | + using it in commercial products, consider making a donation to my local | |
973 | + non-profit hospice organization in the name of the woman I loved, who | |
974 | + passed away Feb. 12, 2003. | |
975 | + | |
976 | + In memory of Toni W. Hagan | |
977 | + | |
978 | + Hospice of Acadiana, Inc. | |
979 | + 2600 Johnston St., Suite 200 | |
980 | + Lafayette, LA 70503-3240 | |
981 | + | |
982 | + Phone (337) 232-1234 or 1-800-738-2226 | |
983 | + Fax (337) 232-1297 | |
984 | + | |
985 | + http://www.hospiceacadiana.com/ | |
986 | + | |
987 | + Manuel | |
988 | + */ | |
989 | + | |
990 | +/* | |
991 | + Made it fit for running in Linux Kernel by Alain Knaff (alain@knaff.lu) | |
992 | +*/ | |
993 | + | |
994 | + | |
995 | +#ifndef STATIC | |
cc3ac616 | 996 | +#include <linux/decompress/bunzip2.h> |
997 | +#endif /* !STATIC */ | |
69622671 | 998 | + |
cc3ac616 | 999 | +#include <linux/decompress/mm.h> |
69622671 | 1000 | + |
cc3ac616 | 1001 | +#ifndef INT_MAX |
1002 | +#define INT_MAX 0x7fffffff | |
69622671 | 1003 | +#endif |
1004 | + | |
69622671 | 1005 | +/* Constants for Huffman coding */ |
bd724f98 | 1006 | +#define MAX_GROUPS 6 |
1007 | +#define GROUP_SIZE 50 /* 64 would have been more efficient */ | |
1008 | +#define MAX_HUFCODE_BITS 20 /* Longest Huffman code allowed */ | |
1009 | +#define MAX_SYMBOLS 258 /* 256 literals + RUNA + RUNB */ | |
1010 | +#define SYMBOL_RUNA 0 | |
1011 | +#define SYMBOL_RUNB 1 | |
69622671 | 1012 | + |
1013 | +/* Status return values */ | |
bd724f98 | 1014 | +#define RETVAL_OK 0 |
1015 | +#define RETVAL_LAST_BLOCK (-1) | |
1016 | +#define RETVAL_NOT_BZIP_DATA (-2) | |
1017 | +#define RETVAL_UNEXPECTED_INPUT_EOF (-3) | |
69622671 | 1018 | +#define RETVAL_UNEXPECTED_OUTPUT_EOF (-4) |
bd724f98 | 1019 | +#define RETVAL_DATA_ERROR (-5) |
1020 | +#define RETVAL_OUT_OF_MEMORY (-6) | |
1021 | +#define RETVAL_OBSOLETE_INPUT (-7) | |
69622671 | 1022 | + |
cc3ac616 | 1023 | +/* Other housekeeping constants */ |
1024 | +#define BZIP2_IOBUF_SIZE 4096 | |
69622671 | 1025 | + |
1026 | +/* This is what we know about each Huffman coding group */ | |
1027 | +struct group_data { | |
1028 | + /* We have an extra slot at the end of limit[] for a sentinal value. */ | |
bd724f98 | 1029 | + int limit[MAX_HUFCODE_BITS+1]; |
1030 | + int base[MAX_HUFCODE_BITS]; | |
1031 | + int permute[MAX_SYMBOLS]; | |
69622671 | 1032 | + int minLen, maxLen; |
1033 | +}; | |
1034 | + | |
1035 | +/* Structure holding all the housekeeping data, including IO buffers and | |
1036 | + memory that persists between calls to bunzip */ | |
bd724f98 | 1037 | +struct bunzip_data { |
69622671 | 1038 | + /* State for interrupting output loop */ |
bd724f98 | 1039 | + int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; |
69622671 | 1040 | + /* I/O tracking data (file handles, buffers, positions, etc.) */ |
bd724f98 | 1041 | + int (*fill)(void*, unsigned int); |
1042 | + int inbufCount, inbufPos /*, outbufPos*/; | |
69622671 | 1043 | + unsigned char *inbuf /*,*outbuf*/; |
1044 | + unsigned int inbufBitCount, inbufBits; | |
bd724f98 | 1045 | + /* The CRC values stored in the block header and calculated from the |
1046 | + data */ | |
1047 | + unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC; | |
69622671 | 1048 | + /* Intermediate buffer and its size (in bytes) */ |
1049 | + unsigned int *dbuf, dbufSize; | |
1050 | + /* These things are a bit too big to go on the stack */ | |
bd724f98 | 1051 | + unsigned char selectors[32768]; /* nSelectors = 15 bits */ |
69622671 | 1052 | + struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ |
1053 | + int io_error; /* non-zero if we have IO error */ | |
bd724f98 | 1054 | +}; |
1055 | + | |
69622671 | 1056 | + |
1057 | +/* Return the next nnn bits of input. All reads from the compressed input | |
1058 | + are done through this function. All reads are big endian */ | |
bd724f98 | 1059 | +static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted) |
69622671 | 1060 | +{ |
bd724f98 | 1061 | + unsigned int bits = 0; |
1062 | + | |
1063 | + /* If we need to get more data from the byte buffer, do so. | |
1064 | + (Loop getting one byte at a time to enforce endianness and avoid | |
1065 | + unaligned access.) */ | |
1066 | + while (bd->inbufBitCount < bits_wanted) { | |
1067 | + /* If we need to read more data from file into byte buffer, do | |
1068 | + so */ | |
1069 | + if (bd->inbufPos == bd->inbufCount) { | |
1070 | + if (bd->io_error) | |
69622671 | 1071 | + return 0; |
bd724f98 | 1072 | + bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE); |
1073 | + if (bd->inbufCount <= 0) { | |
1074 | + bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF; | |
69622671 | 1075 | + return 0; |
1076 | + } | |
bd724f98 | 1077 | + bd->inbufPos = 0; |
69622671 | 1078 | + } |
1079 | + /* Avoid 32-bit overflow (dump bit buffer to top of output) */ | |
bd724f98 | 1080 | + if (bd->inbufBitCount >= 24) { |
1081 | + bits = bd->inbufBits&((1 << bd->inbufBitCount)-1); | |
1082 | + bits_wanted -= bd->inbufBitCount; | |
1083 | + bits <<= bits_wanted; | |
1084 | + bd->inbufBitCount = 0; | |
69622671 | 1085 | + } |
1086 | + /* Grab next 8 bits of input from buffer. */ | |
bd724f98 | 1087 | + bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++]; |
1088 | + bd->inbufBitCount += 8; | |
69622671 | 1089 | + } |
1090 | + /* Calculate result */ | |
bd724f98 | 1091 | + bd->inbufBitCount -= bits_wanted; |
1092 | + bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1); | |
69622671 | 1093 | + |
1094 | + return bits; | |
1095 | +} | |
1096 | + | |
1097 | +/* Unpacks the next block and sets up for the inverse burrows-wheeler step. */ | |
1098 | + | |
bd724f98 | 1099 | +static int INIT get_next_block(struct bunzip_data *bd) |
69622671 | 1100 | +{ |
bd724f98 | 1101 | + struct group_data *hufGroup = NULL; |
1102 | + int *base = NULL; | |
1103 | + int *limit = NULL; | |
1104 | + int dbufCount, nextSym, dbufSize, groupCount, selector, | |
1105 | + i, j, k, t, runPos, symCount, symTotal, nSelectors, | |
1106 | + byteCount[256]; | |
69622671 | 1107 | + unsigned char uc, symToByte[256], mtfSymbol[256], *selectors; |
bd724f98 | 1108 | + unsigned int *dbuf, origPtr; |
69622671 | 1109 | + |
bd724f98 | 1110 | + dbuf = bd->dbuf; |
1111 | + dbufSize = bd->dbufSize; | |
1112 | + selectors = bd->selectors; | |
69622671 | 1113 | + |
1114 | + /* Read in header signature and CRC, then validate signature. | |
1115 | + (last block signature means CRC is for whole file, return now) */ | |
bd724f98 | 1116 | + i = get_bits(bd, 24); |
1117 | + j = get_bits(bd, 24); | |
1118 | + bd->headerCRC = get_bits(bd, 32); | |
1119 | + if ((i == 0x177245) && (j == 0x385090)) | |
1120 | + return RETVAL_LAST_BLOCK; | |
1121 | + if ((i != 0x314159) || (j != 0x265359)) | |
1122 | + return RETVAL_NOT_BZIP_DATA; | |
1123 | + /* We can add support for blockRandomised if anybody complains. | |
1124 | + There was some code for this in busybox 1.0.0-pre3, but nobody ever | |
1125 | + noticed that it didn't actually work. */ | |
1126 | + if (get_bits(bd, 1)) | |
1127 | + return RETVAL_OBSOLETE_INPUT; | |
1128 | + origPtr = get_bits(bd, 24); | |
1129 | + if (origPtr > dbufSize) | |
1130 | + return RETVAL_DATA_ERROR; | |
69622671 | 1131 | + /* mapping table: if some byte values are never used (encoding things |
1132 | + like ascii text), the compression code removes the gaps to have fewer | |
1133 | + symbols to deal with, and writes a sparse bitfield indicating which | |
bd724f98 | 1134 | + values were present. We make a translation table to convert the |
1135 | + symbols back to the corresponding bytes. */ | |
1136 | + t = get_bits(bd, 16); | |
1137 | + symTotal = 0; | |
1138 | + for (i = 0; i < 16; i++) { | |
1139 | + if (t&(1 << (15-i))) { | |
1140 | + k = get_bits(bd, 16); | |
1141 | + for (j = 0; j < 16; j++) | |
1142 | + if (k&(1 << (15-j))) | |
1143 | + symToByte[symTotal++] = (16*i)+j; | |
69622671 | 1144 | + } |
1145 | + } | |
1146 | + /* How many different Huffman coding groups does this block use? */ | |
bd724f98 | 1147 | + groupCount = get_bits(bd, 3); |
1148 | + if (groupCount < 2 || groupCount > MAX_GROUPS) | |
1149 | + return RETVAL_DATA_ERROR; | |
1150 | + /* nSelectors: Every GROUP_SIZE many symbols we select a new | |
1151 | + Huffman coding group. Read in the group selector list, | |
1152 | + which is stored as MTF encoded bit runs. (MTF = Move To | |
1153 | + Front, as each value is used it's moved to the start of the | |
1154 | + list.) */ | |
1155 | + nSelectors = get_bits(bd, 15); | |
1156 | + if (!nSelectors) | |
1157 | + return RETVAL_DATA_ERROR; | |
1158 | + for (i = 0; i < groupCount; i++) | |
1159 | + mtfSymbol[i] = i; | |
1160 | + for (i = 0; i < nSelectors; i++) { | |
69622671 | 1161 | + /* Get next value */ |
bd724f98 | 1162 | + for (j = 0; get_bits(bd, 1); j++) |
1163 | + if (j >= groupCount) | |
1164 | + return RETVAL_DATA_ERROR; | |
69622671 | 1165 | + /* Decode MTF to get the next selector */ |
1166 | + uc = mtfSymbol[j]; | |
cc3ac616 | 1167 | + for (; j; j--) |
1168 | + mtfSymbol[j] = mtfSymbol[j-1]; | |
bd724f98 | 1169 | + mtfSymbol[0] = selectors[i] = uc; |
69622671 | 1170 | + } |
bd724f98 | 1171 | + /* Read the Huffman coding tables for each group, which code |
1172 | + for symTotal literal symbols, plus two run symbols (RUNA, | |
1173 | + RUNB) */ | |
1174 | + symCount = symTotal+2; | |
1175 | + for (j = 0; j < groupCount; j++) { | |
1176 | + unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1]; | |
69622671 | 1177 | + int minLen, maxLen, pp; |
bd724f98 | 1178 | + /* Read Huffman code lengths for each symbol. They're |
1179 | + stored in a way similar to mtf; record a starting | |
1180 | + value for the first symbol, and an offset from the | |
1181 | + previous value for everys symbol after that. | |
1182 | + (Subtracting 1 before the loop and then adding it | |
1183 | + back at the end is an optimization that makes the | |
1184 | + test inside the loop simpler: symbol length 0 | |
1185 | + becomes negative, so an unsigned inequality catches | |
1186 | + it.) */ | |
1187 | + t = get_bits(bd, 5)-1; | |
69622671 | 1188 | + for (i = 0; i < symCount; i++) { |
bd724f98 | 1189 | + for (;;) { |
69622671 | 1190 | + if (((unsigned)t) > (MAX_HUFCODE_BITS-1)) |
1191 | + return RETVAL_DATA_ERROR; | |
bd724f98 | 1192 | + |
1193 | + /* If first bit is 0, stop. Else | |
1194 | + second bit indicates whether to | |
1195 | + increment or decrement the value. | |
1196 | + Optimization: grab 2 bits and unget | |
1197 | + the second if the first was 0. */ | |
1198 | + | |
1199 | + k = get_bits(bd, 2); | |
69622671 | 1200 | + if (k < 2) { |
1201 | + bd->inbufBitCount++; | |
1202 | + break; | |
1203 | + } | |
bd724f98 | 1204 | + /* Add one if second bit 1, else |
1205 | + * subtract 1. Avoids if/else */ | |
1206 | + t += (((k+1)&2)-1); | |
69622671 | 1207 | + } |
bd724f98 | 1208 | + /* Correct for the initial -1, to get the |
1209 | + * final symbol length */ | |
1210 | + length[i] = t+1; | |
69622671 | 1211 | + } |
1212 | + /* Find largest and smallest lengths in this group */ | |
bd724f98 | 1213 | + minLen = maxLen = length[0]; |
1214 | + | |
1215 | + for (i = 1; i < symCount; i++) { | |
1216 | + if (length[i] > maxLen) | |
1217 | + maxLen = length[i]; | |
1218 | + else if (length[i] < minLen) | |
1219 | + minLen = length[i]; | |
69622671 | 1220 | + } |
bd724f98 | 1221 | + |
1222 | + /* Calculate permute[], base[], and limit[] tables from | |
1223 | + * length[]. | |
69622671 | 1224 | + * |
bd724f98 | 1225 | + * permute[] is the lookup table for converting |
1226 | + * Huffman coded symbols into decoded symbols. base[] | |
1227 | + * is the amount to subtract from the value of a | |
1228 | + * Huffman symbol of a given length when using | |
1229 | + * permute[]. | |
69622671 | 1230 | + * |
bd724f98 | 1231 | + * limit[] indicates the largest numerical value a |
1232 | + * symbol with a given number of bits can have. This | |
1233 | + * is how the Huffman codes can vary in length: each | |
1234 | + * code with a value > limit[length] needs another | |
1235 | + * bit. | |
69622671 | 1236 | + */ |
bd724f98 | 1237 | + hufGroup = bd->groups+j; |
69622671 | 1238 | + hufGroup->minLen = minLen; |
1239 | + hufGroup->maxLen = maxLen; | |
bd724f98 | 1240 | + /* Note that minLen can't be smaller than 1, so we |
1241 | + adjust the base and limit array pointers so we're | |
1242 | + not always wasting the first entry. We do this | |
1243 | + again when using them (during symbol decoding).*/ | |
1244 | + base = hufGroup->base-1; | |
1245 | + limit = hufGroup->limit-1; | |
1246 | + /* Calculate permute[]. Concurently, initialize | |
1247 | + * temp[] and limit[]. */ | |
1248 | + pp = 0; | |
1249 | + for (i = minLen; i <= maxLen; i++) { | |
1250 | + temp[i] = limit[i] = 0; | |
1251 | + for (t = 0; t < symCount; t++) | |
1252 | + if (length[t] == i) | |
1253 | + hufGroup->permute[pp++] = t; | |
69622671 | 1254 | + } |
1255 | + /* Count symbols coded for at each bit length */ | |
cc3ac616 | 1256 | + for (i = 0; i < symCount; i++) |
1257 | + temp[length[i]]++; | |
bd724f98 | 1258 | + /* Calculate limit[] (the largest symbol-coding value |
1259 | + *at each bit length, which is (previous limit << | |
1260 | + *1)+symbols at this level), and base[] (number of | |
1261 | + *symbols to ignore at each bit length, which is limit | |
1262 | + *minus the cumulative count of symbols coded for | |
1263 | + *already). */ | |
1264 | + pp = t = 0; | |
1265 | + for (i = minLen; i < maxLen; i++) { | |
1266 | + pp += temp[i]; | |
1267 | + /* We read the largest possible symbol size | |
1268 | + and then unget bits after determining how | |
1269 | + many we need, and those extra bits could be | |
1270 | + set to anything. (They're noise from | |
1271 | + future symbols.) At each level we're | |
1272 | + really only interested in the first few | |
1273 | + bits, so here we set all the trailing | |
1274 | + to-be-ignored bits to 1 so they don't | |
1275 | + affect the value > limit[length] | |
1276 | + comparison. */ | |
1277 | + limit[i] = (pp << (maxLen - i)) - 1; | |
1278 | + pp <<= 1; | |
1279 | + base[i+1] = pp-(t += temp[i]); | |
69622671 | 1280 | + } |
bd724f98 | 1281 | + limit[maxLen+1] = INT_MAX; /* Sentinal value for |
1282 | + * reading next sym. */ | |
1283 | + limit[maxLen] = pp+temp[maxLen]-1; | |
1284 | + base[minLen] = 0; | |
69622671 | 1285 | + } |
bd724f98 | 1286 | + /* We've finished reading and digesting the block header. Now |
1287 | + read this block's Huffman coded symbols from the file and | |
1288 | + undo the Huffman coding and run length encoding, saving the | |
1289 | + result into dbuf[dbufCount++] = uc */ | |
1290 | + | |
1291 | + /* Initialize symbol occurrence counters and symbol Move To | |
1292 | + * Front table */ | |
1293 | + for (i = 0; i < 256; i++) { | |
69622671 | 1294 | + byteCount[i] = 0; |
bd724f98 | 1295 | + mtfSymbol[i] = (unsigned char)i; |
69622671 | 1296 | + } |
1297 | + /* Loop through compressed symbols. */ | |
bd724f98 | 1298 | + runPos = dbufCount = symCount = selector = 0; |
1299 | + for (;;) { | |
69622671 | 1300 | + /* Determine which Huffman coding group to use. */ |
bd724f98 | 1301 | + if (!(symCount--)) { |
1302 | + symCount = GROUP_SIZE-1; | |
1303 | + if (selector >= nSelectors) | |
1304 | + return RETVAL_DATA_ERROR; | |
1305 | + hufGroup = bd->groups+selectors[selector++]; | |
1306 | + base = hufGroup->base-1; | |
1307 | + limit = hufGroup->limit-1; | |
69622671 | 1308 | + } |
1309 | + /* Read next Huffman-coded symbol. */ | |
bd724f98 | 1310 | + /* Note: It is far cheaper to read maxLen bits and |
1311 | + back up than it is to read minLen bits and then an | |
1312 | + additional bit at a time, testing as we go. | |
1313 | + Because there is a trailing last block (with file | |
1314 | + CRC), there is no danger of the overread causing an | |
1315 | + unexpected EOF for a valid compressed file. As a | |
1316 | + further optimization, we do the read inline | |
1317 | + (falling back to a call to get_bits if the buffer | |
1318 | + runs dry). The following (up to got_huff_bits:) is | |
1319 | + equivalent to j = get_bits(bd, hufGroup->maxLen); | |
69622671 | 1320 | + */ |
bd724f98 | 1321 | + while (bd->inbufBitCount < hufGroup->maxLen) { |
1322 | + if (bd->inbufPos == bd->inbufCount) { | |
1323 | + j = get_bits(bd, hufGroup->maxLen); | |
69622671 | 1324 | + goto got_huff_bits; |
1325 | + } | |
bd724f98 | 1326 | + bd->inbufBits = |
1327 | + (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++]; | |
1328 | + bd->inbufBitCount += 8; | |
69622671 | 1329 | + }; |
bd724f98 | 1330 | + bd->inbufBitCount -= hufGroup->maxLen; |
1331 | + j = (bd->inbufBits >> bd->inbufBitCount)& | |
1332 | + ((1 << hufGroup->maxLen)-1); | |
69622671 | 1333 | +got_huff_bits: |
bd724f98 | 1334 | + /* Figure how how many bits are in next symbol and |
1335 | + * unget extras */ | |
1336 | + i = hufGroup->minLen; | |
1337 | + while (j > limit[i]) | |
1338 | + ++i; | |
69622671 | 1339 | + bd->inbufBitCount += (hufGroup->maxLen - i); |
1340 | + /* Huffman decode value to get nextSym (with bounds checking) */ | |
1341 | + if ((i > hufGroup->maxLen) | |
bd724f98 | 1342 | + || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i])) |
69622671 | 1343 | + >= MAX_SYMBOLS)) |
1344 | + return RETVAL_DATA_ERROR; | |
1345 | + nextSym = hufGroup->permute[j]; | |
bd724f98 | 1346 | + /* We have now decoded the symbol, which indicates |
1347 | + either a new literal byte, or a repeated run of the | |
1348 | + most recent literal byte. First, check if nextSym | |
1349 | + indicates a repeated run, and if so loop collecting | |
69622671 | 1350 | + how many times to repeat the last literal. */ |
1351 | + if (((unsigned)nextSym) <= SYMBOL_RUNB) { /* RUNA or RUNB */ | |
bd724f98 | 1352 | + /* If this is the start of a new run, zero out |
1353 | + * counter */ | |
1354 | + if (!runPos) { | |
69622671 | 1355 | + runPos = 1; |
1356 | + t = 0; | |
1357 | + } | |
bd724f98 | 1358 | + /* Neat trick that saves 1 symbol: instead of |
1359 | + or-ing 0 or 1 at each bit position, add 1 | |
1360 | + or 2 instead. For example, 1011 is 1 << 0 | |
1361 | + + 1 << 1 + 2 << 2. 1010 is 2 << 0 + 2 << 1 | |
1362 | + + 1 << 2. You can make any bit pattern | |
1363 | + that way using 1 less symbol than the basic | |
1364 | + or 0/1 method (except all bits 0, which | |
1365 | + would use no symbols, but a run of length 0 | |
1366 | + doesn't mean anything in this context). | |
1367 | + Thus space is saved. */ | |
1368 | + t += (runPos << nextSym); | |
1369 | + /* +runPos if RUNA; +2*runPos if RUNB */ | |
1370 | + | |
69622671 | 1371 | + runPos <<= 1; |
1372 | + continue; | |
1373 | + } | |
bd724f98 | 1374 | + /* When we hit the first non-run symbol after a run, |
1375 | + we now know how many times to repeat the last | |
1376 | + literal, so append that many copies to our buffer | |
1377 | + of decoded symbols (dbuf) now. (The last literal | |
1378 | + used is the one at the head of the mtfSymbol | |
1379 | + array.) */ | |
1380 | + if (runPos) { | |
1381 | + runPos = 0; | |
1382 | + if (dbufCount+t >= dbufSize) | |
1383 | + return RETVAL_DATA_ERROR; | |
69622671 | 1384 | + |
1385 | + uc = symToByte[mtfSymbol[0]]; | |
1386 | + byteCount[uc] += t; | |
bd724f98 | 1387 | + while (t--) |
1388 | + dbuf[dbufCount++] = uc; | |
69622671 | 1389 | + } |
1390 | + /* Is this the terminating symbol? */ | |
bd724f98 | 1391 | + if (nextSym > symTotal) |
1392 | + break; | |
1393 | + /* At this point, nextSym indicates a new literal | |
1394 | + character. Subtract one to get the position in the | |
1395 | + MTF array at which this literal is currently to be | |
1396 | + found. (Note that the result can't be -1 or 0, | |
1397 | + because 0 and 1 are RUNA and RUNB. But another | |
1398 | + instance of the first symbol in the mtf array, | |
1399 | + position 0, would have been handled as part of a | |
1400 | + run above. Therefore 1 unused mtf position minus 2 | |
1401 | + non-literal nextSym values equals -1.) */ | |
1402 | + if (dbufCount >= dbufSize) | |
1403 | + return RETVAL_DATA_ERROR; | |
69622671 | 1404 | + i = nextSym - 1; |
1405 | + uc = mtfSymbol[i]; | |
bd724f98 | 1406 | + /* Adjust the MTF array. Since we typically expect to |
1407 | + *move only a small number of symbols, and are bound | |
1408 | + *by 256 in any case, using memmove here would | |
1409 | + *typically be bigger and slower due to function call | |
1410 | + *overhead and other assorted setup costs. */ | |
69622671 | 1411 | + do { |
1412 | + mtfSymbol[i] = mtfSymbol[i-1]; | |
1413 | + } while (--i); | |
1414 | + mtfSymbol[0] = uc; | |
bd724f98 | 1415 | + uc = symToByte[uc]; |
69622671 | 1416 | + /* We have our literal byte. Save it into dbuf. */ |
1417 | + byteCount[uc]++; | |
1418 | + dbuf[dbufCount++] = (unsigned int)uc; | |
1419 | + } | |
bd724f98 | 1420 | + /* At this point, we've read all the Huffman-coded symbols |
1421 | + (and repeated runs) for this block from the input stream, | |
1422 | + and decoded them into the intermediate buffer. There are | |
1423 | + dbufCount many decoded bytes in dbuf[]. Now undo the | |
1424 | + Burrows-Wheeler transform on dbuf. See | |
1425 | + http://dogma.net/markn/articles/bwt/bwt.htm | |
69622671 | 1426 | + */ |
1427 | + /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */ | |
bd724f98 | 1428 | + j = 0; |
1429 | + for (i = 0; i < 256; i++) { | |
1430 | + k = j+byteCount[i]; | |
69622671 | 1431 | + byteCount[i] = j; |
bd724f98 | 1432 | + j = k; |
69622671 | 1433 | + } |
1434 | + /* Figure out what order dbuf would be in if we sorted it. */ | |
bd724f98 | 1435 | + for (i = 0; i < dbufCount; i++) { |
1436 | + uc = (unsigned char)(dbuf[i] & 0xff); | |
69622671 | 1437 | + dbuf[byteCount[uc]] |= (i << 8); |
1438 | + byteCount[uc]++; | |
1439 | + } | |
bd724f98 | 1440 | + /* Decode first byte by hand to initialize "previous" byte. |
1441 | + Note that it doesn't get output, and if the first three | |
1442 | + characters are identical it doesn't qualify as a run (hence | |
1443 | + writeRunCountdown = 5). */ | |
1444 | + if (dbufCount) { | |
1445 | + if (origPtr >= dbufCount) | |
1446 | + return RETVAL_DATA_ERROR; | |
1447 | + bd->writePos = dbuf[origPtr]; | |
1448 | + bd->writeCurrent = (unsigned char)(bd->writePos&0xff); | |
1449 | + bd->writePos >>= 8; | |
1450 | + bd->writeRunCountdown = 5; | |
69622671 | 1451 | + } |
bd724f98 | 1452 | + bd->writeCount = dbufCount; |
69622671 | 1453 | + |
1454 | + return RETVAL_OK; | |
1455 | +} | |
1456 | + | |
1457 | +/* Undo burrows-wheeler transform on intermediate buffer to produce output. | |
bd724f98 | 1458 | + If start_bunzip was initialized with out_fd =-1, then up to len bytes of |
69622671 | 1459 | + data are written to outbuf. Return value is number of bytes written or |
1460 | + error (all errors are negative numbers). If out_fd!=-1, outbuf and len | |
1461 | + are ignored, data is written to out_fd and return is RETVAL_OK or error. | |
1462 | +*/ | |
1463 | + | |
bd724f98 | 1464 | +static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len) |
69622671 | 1465 | +{ |
1466 | + const unsigned int *dbuf; | |
bd724f98 | 1467 | + int pos, xcurrent, previous, gotcount; |
69622671 | 1468 | + |
1469 | + /* If last read was short due to end of file, return last block now */ | |
bd724f98 | 1470 | + if (bd->writeCount < 0) |
1471 | + return bd->writeCount; | |
69622671 | 1472 | + |
1473 | + gotcount = 0; | |
bd724f98 | 1474 | + dbuf = bd->dbuf; |
1475 | + pos = bd->writePos; | |
1476 | + xcurrent = bd->writeCurrent; | |
69622671 | 1477 | + |
1478 | + /* We will always have pending decoded data to write into the output | |
1479 | + buffer unless this is the very first call (in which case we haven't | |
1480 | + Huffman-decoded a block into the intermediate buffer yet). */ | |
1481 | + | |
1482 | + if (bd->writeCopies) { | |
1483 | + /* Inside the loop, writeCopies means extra copies (beyond 1) */ | |
1484 | + --bd->writeCopies; | |
1485 | + /* Loop outputting bytes */ | |
bd724f98 | 1486 | + for (;;) { |
1487 | + /* If the output buffer is full, snapshot | |
1488 | + * state and return */ | |
1489 | + if (gotcount >= len) { | |
1490 | + bd->writePos = pos; | |
1491 | + bd->writeCurrent = xcurrent; | |
69622671 | 1492 | + bd->writeCopies++; |
1493 | + return len; | |
1494 | + } | |
1495 | + /* Write next byte into output buffer, updating CRC */ | |
1496 | + outbuf[gotcount++] = xcurrent; | |
bd724f98 | 1497 | + bd->writeCRC = (((bd->writeCRC) << 8) |
1498 | + ^bd->crc32Table[((bd->writeCRC) >> 24) | |
1499 | + ^xcurrent]); | |
1500 | + /* Loop now if we're outputting multiple | |
1501 | + * copies of this byte */ | |
69622671 | 1502 | + if (bd->writeCopies) { |
1503 | + --bd->writeCopies; | |
1504 | + continue; | |
1505 | + } | |
1506 | +decode_next_byte: | |
bd724f98 | 1507 | + if (!bd->writeCount--) |
1508 | + break; | |
1509 | + /* Follow sequence vector to undo | |
1510 | + * Burrows-Wheeler transform */ | |
1511 | + previous = xcurrent; | |
1512 | + pos = dbuf[pos]; | |
1513 | + xcurrent = pos&0xff; | |
1514 | + pos >>= 8; | |
1515 | + /* After 3 consecutive copies of the same | |
1516 | + byte, the 4th is a repeat count. We count | |
1517 | + down from 4 instead *of counting up because | |
1518 | + testing for non-zero is faster */ | |
1519 | + if (--bd->writeRunCountdown) { | |
1520 | + if (xcurrent != previous) | |
1521 | + bd->writeRunCountdown = 4; | |
69622671 | 1522 | + } else { |
bd724f98 | 1523 | + /* We have a repeated run, this byte |
1524 | + * indicates the count */ | |
1525 | + bd->writeCopies = xcurrent; | |
1526 | + xcurrent = previous; | |
1527 | + bd->writeRunCountdown = 5; | |
1528 | + /* Sometimes there are just 3 bytes | |
1529 | + * (run length 0) */ | |
1530 | + if (!bd->writeCopies) | |
1531 | + goto decode_next_byte; | |
1532 | + /* Subtract the 1 copy we'd output | |
1533 | + * anyway to get extras */ | |
69622671 | 1534 | + --bd->writeCopies; |
1535 | + } | |
1536 | + } | |
1537 | + /* Decompression of this block completed successfully */ | |
bd724f98 | 1538 | + bd->writeCRC = ~bd->writeCRC; |
1539 | + bd->totalCRC = ((bd->totalCRC << 1) | | |
1540 | + (bd->totalCRC >> 31)) ^ bd->writeCRC; | |
69622671 | 1541 | + /* If this block had a CRC error, force file level CRC error. */ |
bd724f98 | 1542 | + if (bd->writeCRC != bd->headerCRC) { |
1543 | + bd->totalCRC = bd->headerCRC+1; | |
69622671 | 1544 | + return RETVAL_LAST_BLOCK; |
1545 | + } | |
1546 | + } | |
1547 | + | |
bd724f98 | 1548 | + /* Refill the intermediate buffer by Huffman-decoding next |
1549 | + * block of input */ | |
69622671 | 1550 | + /* (previous is just a convenient unused temp variable here) */ |
bd724f98 | 1551 | + previous = get_next_block(bd); |
1552 | + if (previous) { | |
1553 | + bd->writeCount = previous; | |
1554 | + return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount; | |
69622671 | 1555 | + } |
bd724f98 | 1556 | + bd->writeCRC = 0xffffffffUL; |
1557 | + pos = bd->writePos; | |
1558 | + xcurrent = bd->writeCurrent; | |
69622671 | 1559 | + goto decode_next_byte; |
1560 | +} | |
1561 | + | |
bd724f98 | 1562 | +static int INIT nofill(void *buf, unsigned int len) |
1563 | +{ | |
69622671 | 1564 | + return -1; |
1565 | +} | |
1566 | + | |
bd724f98 | 1567 | +/* Allocate the structure, read file header. If in_fd ==-1, inbuf must contain |
69622671 | 1568 | + a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are |
1569 | + ignored, and data is read from file handle into temporary buffer. */ | |
bd724f98 | 1570 | +static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len, |
1571 | + int (*fill)(void*, unsigned int)) | |
69622671 | 1572 | +{ |
bd724f98 | 1573 | + struct bunzip_data *bd; |
1574 | + unsigned int i, j, c; | |
1575 | + const unsigned int BZh0 = | |
1576 | + (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16) | |
1577 | + +(((unsigned int)'h') << 8)+(unsigned int)'0'; | |
69622671 | 1578 | + |
1579 | + /* Figure out how much data to allocate */ | |
bd724f98 | 1580 | + i = sizeof(struct bunzip_data); |
69622671 | 1581 | + |
1582 | + /* Allocate bunzip_data. Most fields initialize to zero. */ | |
bd724f98 | 1583 | + bd = *bdp = malloc(i); |
1584 | + memset(bd, 0, sizeof(struct bunzip_data)); | |
69622671 | 1585 | + /* Setup input buffer */ |
bd724f98 | 1586 | + bd->inbuf = inbuf; |
1587 | + bd->inbufCount = len; | |
1588 | + if (fill != NULL) | |
1589 | + bd->fill = fill; | |
69622671 | 1590 | + else |
bd724f98 | 1591 | + bd->fill = nofill; |
69622671 | 1592 | + |
1593 | + /* Init the CRC32 table (big endian) */ | |
bd724f98 | 1594 | + for (i = 0; i < 256; i++) { |
1595 | + c = i << 24; | |
1596 | + for (j = 8; j; j--) | |
1597 | + c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1); | |
1598 | + bd->crc32Table[i] = c; | |
69622671 | 1599 | + } |
1600 | + | |
1601 | + /* Ensure that file starts with "BZh['1'-'9']." */ | |
bd724f98 | 1602 | + i = get_bits(bd, 32); |
1603 | + if (((unsigned int)(i-BZh0-1)) >= 9) | |
1604 | + return RETVAL_NOT_BZIP_DATA; | |
69622671 | 1605 | + |
1606 | + /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of | |
1607 | + uncompressed data. Allocate intermediate buffer for block. */ | |
bd724f98 | 1608 | + bd->dbufSize = 100000*(i-BZh0); |
69622671 | 1609 | + |
bd724f98 | 1610 | + bd->dbuf = large_malloc(bd->dbufSize * sizeof(int)); |
69622671 | 1611 | + return RETVAL_OK; |
1612 | +} | |
1613 | + | |
cc3ac616 | 1614 | +/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip2 data, |
69622671 | 1615 | + not end of file.) */ |
cc3ac616 | 1616 | +STATIC int INIT bunzip2(unsigned char *buf, int len, |
bd724f98 | 1617 | + int(*fill)(void*, unsigned int), |
bd724f98 | 1618 | + int(*flush)(void*, unsigned int), |
cc3ac616 | 1619 | + unsigned char *outbuf, |
1620 | + int *pos, | |
1621 | + void(*error_fn)(char *x)) | |
69622671 | 1622 | +{ |
bd724f98 | 1623 | + struct bunzip_data *bd; |
cc3ac616 | 1624 | + int i = -1; |
1625 | + unsigned char *inbuf; | |
1626 | + | |
1627 | + set_error_fn(error_fn); | |
1628 | + if (flush) | |
1629 | + outbuf = malloc(BZIP2_IOBUF_SIZE); | |
1630 | + else | |
1631 | + len -= 4; /* Uncompressed size hack active in pre-boot | |
1632 | + environment */ | |
1633 | + if (!outbuf) { | |
1634 | + error("Could not allocate output bufer"); | |
1635 | + return -1; | |
1636 | + } | |
1637 | + if (buf) | |
1638 | + inbuf = buf; | |
1639 | + else | |
1640 | + inbuf = malloc(BZIP2_IOBUF_SIZE); | |
1641 | + if (!inbuf) { | |
1642 | + error("Could not allocate input bufer"); | |
1643 | + goto exit_0; | |
1644 | + } | |
bd724f98 | 1645 | + i = start_bunzip(&bd, inbuf, len, fill); |
1646 | + if (!i) { | |
1647 | + for (;;) { | |
1648 | + i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE); | |
1649 | + if (i <= 0) | |
1650 | + break; | |
cc3ac616 | 1651 | + if (!flush) |
1652 | + outbuf += i; | |
1653 | + else | |
1654 | + if (i != flush(outbuf, i)) { | |
1655 | + i = RETVAL_UNEXPECTED_OUTPUT_EOF; | |
1656 | + break; | |
1657 | + } | |
69622671 | 1658 | + } |
1659 | + } | |
1660 | + /* Check CRC and release memory */ | |
bd724f98 | 1661 | + if (i == RETVAL_LAST_BLOCK) { |
1662 | + if (bd->headerCRC != bd->totalCRC) | |
69622671 | 1663 | + error("Data integrity error when decompressing."); |
bd724f98 | 1664 | + else |
1665 | + i = RETVAL_OK; | |
1666 | + } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) { | |
69622671 | 1667 | + error("Compressed file ends unexpectedly"); |
1668 | + } | |
bd724f98 | 1669 | + if (bd->dbuf) |
1670 | + large_free(bd->dbuf); | |
1671 | + if (pos) | |
69622671 | 1672 | + *pos = bd->inbufPos; |
1673 | + free(bd); | |
cc3ac616 | 1674 | + if (!buf) |
1675 | + free(inbuf); | |
1676 | +exit_0: | |
1677 | + if (flush) | |
1678 | + free(outbuf); | |
69622671 | 1679 | + return i; |
1680 | +} | |
1681 | + | |
cc3ac616 | 1682 | +#define decompress bunzip2 |
1683 | diff -urNp linux-2.6.27.orig/lib/decompress_unlzma.c linux-2.6.27/lib/decompress_unlzma.c | |
1684 | --- linux-2.6.27.orig/lib/decompress_unlzma.c 1970-01-01 01:00:00.000000000 +0100 | |
1685 | +++ linux-2.6.27/lib/decompress_unlzma.c 2008-10-30 22:27:29.000000000 +0100 | |
1686 | @@ -0,0 +1,647 @@ | |
69622671 | 1687 | +/* Lzma decompressor for Linux kernel. Shamelessly snarfed |
bd724f98 | 1688 | + *from busybox 1.1.1 |
69622671 | 1689 | + * |
bd724f98 | 1690 | + *Linux kernel adaptation |
1691 | + *Copyright (C) 2006 Alain < alain@knaff.lu > | |
69622671 | 1692 | + * |
bd724f98 | 1693 | + *Based on small lzma deflate implementation/Small range coder |
1694 | + *implementation for lzma. | |
1695 | + *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > | |
69622671 | 1696 | + * |
bd724f98 | 1697 | + *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) |
1698 | + *Copyright (C) 1999-2005 Igor Pavlov | |
69622671 | 1699 | + * |
bd724f98 | 1700 | + *Copyrights of the parts, see headers below. |
69622671 | 1701 | + * |
1702 | + * | |
bd724f98 | 1703 | + *This program is free software; you can redistribute it and/or |
1704 | + *modify it under the terms of the GNU Lesser General Public | |
1705 | + *License as published by the Free Software Foundation; either | |
1706 | + *version 2.1 of the License, or (at your option) any later version. | |
69622671 | 1707 | + * |
bd724f98 | 1708 | + *This program is distributed in the hope that it will be useful, |
1709 | + *but WITHOUT ANY WARRANTY; without even the implied warranty of | |
1710 | + *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1711 | + *Lesser General Public License for more details. | |
69622671 | 1712 | + * |
bd724f98 | 1713 | + *You should have received a copy of the GNU Lesser General Public |
1714 | + *License along with this library; if not, write to the Free Software | |
1715 | + *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
69622671 | 1716 | + */ |
1717 | + | |
1718 | +#ifndef STATIC | |
cc3ac616 | 1719 | +#include <linux/decompress/unlzma.h> |
1720 | +#endif /* STATIC */ | |
69622671 | 1721 | + |
cc3ac616 | 1722 | +#include <linux/decompress/mm.h> |
69622671 | 1723 | + |
cc3ac616 | 1724 | +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) |
69622671 | 1725 | + |
1726 | +static long long INIT read_int(unsigned char *ptr, int size) | |
1727 | +{ | |
1728 | + int i; | |
bd724f98 | 1729 | + long long ret = 0; |
69622671 | 1730 | + |
bd724f98 | 1731 | + for (i = 0; i < size; i++) |
69622671 | 1732 | + ret = (ret << 8) | ptr[size-i-1]; |
69622671 | 1733 | + return ret; |
1734 | +} | |
1735 | + | |
bd724f98 | 1736 | +#define ENDIAN_CONVERT(x) \ |
1737 | + x = (typeof(x))read_int((unsigned char *)&x, sizeof(x)) | |
69622671 | 1738 | + |
1739 | + | |
1740 | +/* Small range coder implementation for lzma. | |
bd724f98 | 1741 | + *Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > |
69622671 | 1742 | + * |
bd724f98 | 1743 | + *Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) |
1744 | + *Copyright (c) 1999-2005 Igor Pavlov | |
69622671 | 1745 | + */ |
1746 | + | |
cc3ac616 | 1747 | +#include <linux/compiler.h> |
69622671 | 1748 | + |
cc3ac616 | 1749 | +#define LZMA_IOBUF_SIZE 0x10000 |
69622671 | 1750 | + |
bd724f98 | 1751 | +struct rc { |
1752 | + int (*fill)(void*, unsigned int); | |
69622671 | 1753 | + uint8_t *ptr; |
1754 | + uint8_t *buffer; | |
1755 | + uint8_t *buffer_end; | |
1756 | + int buffer_size; | |
1757 | + uint32_t code; | |
1758 | + uint32_t range; | |
1759 | + uint32_t bound; | |
bd724f98 | 1760 | +}; |
69622671 | 1761 | + |
1762 | + | |
1763 | +#define RC_TOP_BITS 24 | |
1764 | +#define RC_MOVE_BITS 5 | |
1765 | +#define RC_MODEL_TOTAL_BITS 11 | |
1766 | + | |
1767 | + | |
1768 | +/* Called twice: once at startup and once in rc_normalize() */ | |
bd724f98 | 1769 | +static void INIT rc_read(struct rc *rc) |
69622671 | 1770 | +{ |
bd724f98 | 1771 | + rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE); |
69622671 | 1772 | + if (rc->buffer_size <= 0) |
1773 | + error("unexpected EOF"); | |
1774 | + rc->ptr = rc->buffer; | |
1775 | + rc->buffer_end = rc->buffer + rc->buffer_size; | |
1776 | +} | |
1777 | + | |
1778 | +/* Called once */ | |
cc3ac616 | 1779 | +static inline void INIT rc_init(struct rc *rc, |
bd724f98 | 1780 | + int (*fill)(void*, unsigned int), |
69622671 | 1781 | + char *buffer, int buffer_size) |
1782 | +{ | |
1783 | + rc->fill = fill; | |
1784 | + rc->buffer = (uint8_t *)buffer; | |
1785 | + rc->buffer_size = buffer_size; | |
1786 | + rc->buffer_end = rc->buffer + rc->buffer_size; | |
1787 | + rc->ptr = rc->buffer; | |
1788 | + | |
1789 | + rc->code = 0; | |
1790 | + rc->range = 0xFFFFFFFF; | |
1791 | +} | |
1792 | + | |
cc3ac616 | 1793 | +static inline void INIT rc_init_code(struct rc *rc) |
69622671 | 1794 | +{ |
1795 | + int i; | |
1796 | + | |
1797 | + for (i = 0; i < 5; i++) { | |
1798 | + if (rc->ptr >= rc->buffer_end) | |
1799 | + rc_read(rc); | |
1800 | + rc->code = (rc->code << 8) | *rc->ptr++; | |
1801 | + } | |
1802 | +} | |
1803 | + | |
1804 | + | |
1805 | +/* Called once. TODO: bb_maybe_free() */ | |
cc3ac616 | 1806 | +static inline void INIT rc_free(struct rc *rc) |
69622671 | 1807 | +{ |
1808 | + free(rc->buffer); | |
1809 | +} | |
1810 | + | |
cc3ac616 | 1811 | +/* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */ |
bd724f98 | 1812 | +static void INIT rc_do_normalize(struct rc *rc) |
69622671 | 1813 | +{ |
1814 | + if (rc->ptr >= rc->buffer_end) | |
1815 | + rc_read(rc); | |
1816 | + rc->range <<= 8; | |
1817 | + rc->code = (rc->code << 8) | *rc->ptr++; | |
1818 | +} | |
cc3ac616 | 1819 | +static inline void INIT rc_normalize(struct rc *rc) |
69622671 | 1820 | +{ |
bd724f98 | 1821 | + if (rc->range < (1 << RC_TOP_BITS)) |
69622671 | 1822 | + rc_do_normalize(rc); |
69622671 | 1823 | +} |
1824 | + | |
1825 | +/* Called 9 times */ | |
1826 | +/* Why rc_is_bit_0_helper exists? | |
bd724f98 | 1827 | + *Because we want to always expose (rc->code < rc->bound) to optimizer |
69622671 | 1828 | + */ |
cc3ac616 | 1829 | +static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p) |
69622671 | 1830 | +{ |
1831 | + rc_normalize(rc); | |
1832 | + rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); | |
1833 | + return rc->bound; | |
1834 | +} | |
cc3ac616 | 1835 | +static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p) |
69622671 | 1836 | +{ |
1837 | + uint32_t t = rc_is_bit_0_helper(rc, p); | |
1838 | + return rc->code < t; | |
1839 | +} | |
1840 | + | |
1841 | +/* Called ~10 times, but very small, thus inlined */ | |
cc3ac616 | 1842 | +static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p) |
69622671 | 1843 | +{ |
1844 | + rc->range = rc->bound; | |
1845 | + *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; | |
1846 | +} | |
cc3ac616 | 1847 | +static inline void rc_update_bit_1(struct rc *rc, uint16_t *p) |
69622671 | 1848 | +{ |
1849 | + rc->range -= rc->bound; | |
1850 | + rc->code -= rc->bound; | |
1851 | + *p -= *p >> RC_MOVE_BITS; | |
1852 | +} | |
1853 | + | |
1854 | +/* Called 4 times in unlzma loop */ | |
bd724f98 | 1855 | +static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol) |
69622671 | 1856 | +{ |
1857 | + if (rc_is_bit_0(rc, p)) { | |
1858 | + rc_update_bit_0(rc, p); | |
1859 | + *symbol *= 2; | |
1860 | + return 0; | |
1861 | + } else { | |
1862 | + rc_update_bit_1(rc, p); | |
1863 | + *symbol = *symbol * 2 + 1; | |
1864 | + return 1; | |
1865 | + } | |
1866 | +} | |
1867 | + | |
1868 | +/* Called once */ | |
cc3ac616 | 1869 | +static inline int INIT rc_direct_bit(struct rc *rc) |
69622671 | 1870 | +{ |
1871 | + rc_normalize(rc); | |
1872 | + rc->range >>= 1; | |
1873 | + if (rc->code >= rc->range) { | |
1874 | + rc->code -= rc->range; | |
1875 | + return 1; | |
1876 | + } | |
1877 | + return 0; | |
1878 | +} | |
1879 | + | |
1880 | +/* Called twice */ | |
cc3ac616 | 1881 | +static inline void INIT |
bd724f98 | 1882 | +rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol) |
69622671 | 1883 | +{ |
1884 | + int i = num_levels; | |
1885 | + | |
1886 | + *symbol = 1; | |
1887 | + while (i--) | |
1888 | + rc_get_bit(rc, p + *symbol, symbol); | |
1889 | + *symbol -= 1 << num_levels; | |
1890 | +} | |
1891 | + | |
1892 | + | |
1893 | +/* | |
1894 | + * Small lzma deflate implementation. | |
bd724f98 | 1895 | + * Copyright (C) 2006 Aurelien Jacobs < aurel@gnuage.org > |
69622671 | 1896 | + * |
1897 | + * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/) | |
1898 | + * Copyright (C) 1999-2005 Igor Pavlov | |
1899 | + */ | |
1900 | + | |
1901 | + | |
bd724f98 | 1902 | +struct lzma_header { |
69622671 | 1903 | + uint8_t pos; |
1904 | + uint32_t dict_size; | |
1905 | + uint64_t dst_size; | |
bd724f98 | 1906 | +} __attribute__ ((packed)) ; |
69622671 | 1907 | + |
1908 | + | |
1909 | +#define LZMA_BASE_SIZE 1846 | |
1910 | +#define LZMA_LIT_SIZE 768 | |
1911 | + | |
1912 | +#define LZMA_NUM_POS_BITS_MAX 4 | |
1913 | + | |
1914 | +#define LZMA_LEN_NUM_LOW_BITS 3 | |
1915 | +#define LZMA_LEN_NUM_MID_BITS 3 | |
1916 | +#define LZMA_LEN_NUM_HIGH_BITS 8 | |
1917 | + | |
1918 | +#define LZMA_LEN_CHOICE 0 | |
1919 | +#define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1) | |
1920 | +#define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1) | |
1921 | +#define LZMA_LEN_MID (LZMA_LEN_LOW \ | |
1922 | + + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))) | |
1923 | +#define LZMA_LEN_HIGH (LZMA_LEN_MID \ | |
1924 | + +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))) | |
1925 | +#define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)) | |
1926 | + | |
1927 | +#define LZMA_NUM_STATES 12 | |
1928 | +#define LZMA_NUM_LIT_STATES 7 | |
1929 | + | |
1930 | +#define LZMA_START_POS_MODEL_INDEX 4 | |
1931 | +#define LZMA_END_POS_MODEL_INDEX 14 | |
1932 | +#define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1)) | |
1933 | + | |
1934 | +#define LZMA_NUM_POS_SLOT_BITS 6 | |
1935 | +#define LZMA_NUM_LEN_TO_POS_STATES 4 | |
1936 | + | |
1937 | +#define LZMA_NUM_ALIGN_BITS 4 | |
1938 | + | |
1939 | +#define LZMA_MATCH_MIN_LEN 2 | |
1940 | + | |
1941 | +#define LZMA_IS_MATCH 0 | |
bd724f98 | 1942 | +#define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) |
69622671 | 1943 | +#define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES) |
1944 | +#define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES) | |
1945 | +#define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES) | |
1946 | +#define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES) | |
1947 | +#define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \ | |
1948 | + + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)) | |
1949 | +#define LZMA_SPEC_POS (LZMA_POS_SLOT \ | |
1950 | + +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)) | |
1951 | +#define LZMA_ALIGN (LZMA_SPEC_POS \ | |
1952 | + + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX) | |
1953 | +#define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)) | |
1954 | +#define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS) | |
1955 | +#define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS) | |
1956 | + | |
1957 | + | |
bd724f98 | 1958 | +struct writer { |
1959 | + uint8_t *buffer; | |
1960 | + uint8_t previous_byte; | |
1961 | + size_t buffer_pos; | |
bd724f98 | 1962 | + int bufsize; |
1963 | + size_t global_pos; | |
1964 | + int(*flush)(void*, unsigned int); | |
bd724f98 | 1965 | + struct lzma_header *header; |
1966 | +}; | |
1967 | + | |
1968 | +struct cstate { | |
1969 | + int state; | |
1970 | + uint32_t rep0, rep1, rep2, rep3; | |
1971 | +}; | |
1972 | + | |
cc3ac616 | 1973 | +static inline size_t INIT get_pos(struct writer *wr) |
bd724f98 | 1974 | +{ |
1975 | + return | |
cc3ac616 | 1976 | + wr->global_pos + wr->buffer_pos; |
bd724f98 | 1977 | +} |
1978 | + | |
cc3ac616 | 1979 | +static inline uint8_t INIT peek_old_byte(struct writer *wr, |
bd724f98 | 1980 | + uint32_t offs) |
1981 | +{ | |
cc3ac616 | 1982 | + if (!wr->flush) { |
1983 | + int32_t pos; | |
1984 | + while (offs > wr->header->dict_size) | |
1985 | + offs -= wr->header->dict_size; | |
1986 | + pos = wr->buffer_pos - offs; | |
1987 | + return wr->buffer[pos]; | |
1988 | + } else { | |
1989 | + uint32_t pos = wr->buffer_pos - offs; | |
1990 | + while (pos >= wr->header->dict_size) | |
1991 | + pos += wr->header->dict_size; | |
1992 | + return wr->buffer[pos]; | |
1993 | + } | |
bd724f98 | 1994 | + |
1995 | +} | |
1996 | + | |
cc3ac616 | 1997 | +static inline void INIT write_byte(struct writer *wr, uint8_t byte) |
bd724f98 | 1998 | +{ |
1999 | + wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte; | |
cc3ac616 | 2000 | + if (wr->flush && wr->buffer_pos == wr->header->dict_size) { |
bd724f98 | 2001 | + wr->buffer_pos = 0; |
2002 | + wr->global_pos += wr->header->dict_size; | |
2003 | + wr->flush((char *)wr->buffer, wr->header->dict_size); | |
2004 | + } | |
bd724f98 | 2005 | +} |
2006 | + | |
2007 | + | |
cc3ac616 | 2008 | +static inline void INIT copy_byte(struct writer *wr, uint32_t offs) |
bd724f98 | 2009 | +{ |
2010 | + write_byte(wr, peek_old_byte(wr, offs)); | |
2011 | +} | |
2012 | + | |
cc3ac616 | 2013 | +static inline void INIT copy_bytes(struct writer *wr, |
bd724f98 | 2014 | + uint32_t rep0, int len) |
69622671 | 2015 | +{ |
bd724f98 | 2016 | + do { |
2017 | + copy_byte(wr, rep0); | |
2018 | + len--; | |
2019 | + } while (len != 0 && wr->buffer_pos < wr->header->dst_size); | |
2020 | +} | |
2021 | + | |
cc3ac616 | 2022 | +static inline void INIT process_bit0(struct writer *wr, struct rc *rc, |
bd724f98 | 2023 | + struct cstate *cst, uint16_t *p, |
2024 | + int pos_state, uint16_t *prob, | |
2025 | + int lc, uint32_t literal_pos_mask) { | |
2026 | + int mi = 1; | |
2027 | + rc_update_bit_0(rc, prob); | |
2028 | + prob = (p + LZMA_LITERAL + | |
2029 | + (LZMA_LIT_SIZE | |
2030 | + * (((get_pos(wr) & literal_pos_mask) << lc) | |
2031 | + + (wr->previous_byte >> (8 - lc)))) | |
2032 | + ); | |
2033 | + | |
2034 | + if (cst->state >= LZMA_NUM_LIT_STATES) { | |
2035 | + int match_byte = peek_old_byte(wr, cst->rep0); | |
2036 | + do { | |
2037 | + int bit; | |
2038 | + uint16_t *prob_lit; | |
2039 | + | |
2040 | + match_byte <<= 1; | |
2041 | + bit = match_byte & 0x100; | |
2042 | + prob_lit = prob + 0x100 + bit + mi; | |
2043 | + if (rc_get_bit(rc, prob_lit, &mi)) { | |
2044 | + if (!bit) | |
2045 | + break; | |
2046 | + } else { | |
2047 | + if (bit) | |
2048 | + break; | |
2049 | + } | |
2050 | + } while (mi < 0x100); | |
2051 | + } | |
2052 | + while (mi < 0x100) { | |
2053 | + uint16_t *prob_lit = prob + mi; | |
2054 | + rc_get_bit(rc, prob_lit, &mi); | |
2055 | + } | |
2056 | + write_byte(wr, mi); | |
2057 | + if (cst->state < 4) | |
2058 | + cst->state = 0; | |
2059 | + else if (cst->state < 10) | |
2060 | + cst->state -= 3; | |
2061 | + else | |
2062 | + cst->state -= 6; | |
2063 | +} | |
2064 | + | |
cc3ac616 | 2065 | +static inline void INIT process_bit1(struct writer *wr, struct rc *rc, |
bd724f98 | 2066 | + struct cstate *cst, uint16_t *p, |
2067 | + int pos_state, uint16_t *prob) { | |
2068 | + int offset; | |
2069 | + uint16_t *prob_len; | |
2070 | + int num_bits; | |
2071 | + int len; | |
2072 | + | |
2073 | + rc_update_bit_1(rc, prob); | |
2074 | + prob = p + LZMA_IS_REP + cst->state; | |
2075 | + if (rc_is_bit_0(rc, prob)) { | |
2076 | + rc_update_bit_0(rc, prob); | |
2077 | + cst->rep3 = cst->rep2; | |
2078 | + cst->rep2 = cst->rep1; | |
2079 | + cst->rep1 = cst->rep0; | |
2080 | + cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3; | |
2081 | + prob = p + LZMA_LEN_CODER; | |
2082 | + } else { | |
2083 | + rc_update_bit_1(rc, prob); | |
2084 | + prob = p + LZMA_IS_REP_G0 + cst->state; | |
2085 | + if (rc_is_bit_0(rc, prob)) { | |
2086 | + rc_update_bit_0(rc, prob); | |
2087 | + prob = (p + LZMA_IS_REP_0_LONG | |
2088 | + + (cst->state << | |
2089 | + LZMA_NUM_POS_BITS_MAX) + | |
2090 | + pos_state); | |
2091 | + if (rc_is_bit_0(rc, prob)) { | |
2092 | + rc_update_bit_0(rc, prob); | |
2093 | + | |
2094 | + cst->state = cst->state < LZMA_NUM_LIT_STATES ? | |
2095 | + 9 : 11; | |
2096 | + copy_byte(wr, cst->rep0); | |
2097 | + return; | |
2098 | + } else { | |
2099 | + rc_update_bit_1(rc, prob); | |
2100 | + } | |
2101 | + } else { | |
2102 | + uint32_t distance; | |
2103 | + | |
2104 | + rc_update_bit_1(rc, prob); | |
2105 | + prob = p + LZMA_IS_REP_G1 + cst->state; | |
2106 | + if (rc_is_bit_0(rc, prob)) { | |
2107 | + rc_update_bit_0(rc, prob); | |
2108 | + distance = cst->rep1; | |
2109 | + } else { | |
2110 | + rc_update_bit_1(rc, prob); | |
2111 | + prob = p + LZMA_IS_REP_G2 + cst->state; | |
2112 | + if (rc_is_bit_0(rc, prob)) { | |
2113 | + rc_update_bit_0(rc, prob); | |
2114 | + distance = cst->rep2; | |
2115 | + } else { | |
2116 | + rc_update_bit_1(rc, prob); | |
2117 | + distance = cst->rep3; | |
2118 | + cst->rep3 = cst->rep2; | |
2119 | + } | |
2120 | + cst->rep2 = cst->rep1; | |
2121 | + } | |
2122 | + cst->rep1 = cst->rep0; | |
2123 | + cst->rep0 = distance; | |
2124 | + } | |
2125 | + cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11; | |
2126 | + prob = p + LZMA_REP_LEN_CODER; | |
2127 | + } | |
2128 | + | |
2129 | + prob_len = prob + LZMA_LEN_CHOICE; | |
2130 | + if (rc_is_bit_0(rc, prob_len)) { | |
2131 | + rc_update_bit_0(rc, prob_len); | |
2132 | + prob_len = (prob + LZMA_LEN_LOW | |
2133 | + + (pos_state << | |
2134 | + LZMA_LEN_NUM_LOW_BITS)); | |
2135 | + offset = 0; | |
2136 | + num_bits = LZMA_LEN_NUM_LOW_BITS; | |
2137 | + } else { | |
2138 | + rc_update_bit_1(rc, prob_len); | |
2139 | + prob_len = prob + LZMA_LEN_CHOICE_2; | |
2140 | + if (rc_is_bit_0(rc, prob_len)) { | |
2141 | + rc_update_bit_0(rc, prob_len); | |
2142 | + prob_len = (prob + LZMA_LEN_MID | |
2143 | + + (pos_state << | |
2144 | + LZMA_LEN_NUM_MID_BITS)); | |
2145 | + offset = 1 << LZMA_LEN_NUM_LOW_BITS; | |
2146 | + num_bits = LZMA_LEN_NUM_MID_BITS; | |
2147 | + } else { | |
2148 | + rc_update_bit_1(rc, prob_len); | |
2149 | + prob_len = prob + LZMA_LEN_HIGH; | |
2150 | + offset = ((1 << LZMA_LEN_NUM_LOW_BITS) | |
2151 | + + (1 << LZMA_LEN_NUM_MID_BITS)); | |
2152 | + num_bits = LZMA_LEN_NUM_HIGH_BITS; | |
2153 | + } | |
2154 | + } | |
2155 | + | |
2156 | + rc_bit_tree_decode(rc, prob_len, num_bits, &len); | |
2157 | + len += offset; | |
2158 | + | |
2159 | + if (cst->state < 4) { | |
2160 | + int pos_slot; | |
2161 | + | |
2162 | + cst->state += LZMA_NUM_LIT_STATES; | |
2163 | + prob = | |
2164 | + p + LZMA_POS_SLOT + | |
2165 | + ((len < | |
2166 | + LZMA_NUM_LEN_TO_POS_STATES ? len : | |
2167 | + LZMA_NUM_LEN_TO_POS_STATES - 1) | |
2168 | + << LZMA_NUM_POS_SLOT_BITS); | |
2169 | + rc_bit_tree_decode(rc, prob, | |
2170 | + LZMA_NUM_POS_SLOT_BITS, | |
2171 | + &pos_slot); | |
2172 | + if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { | |
2173 | + int i, mi; | |
2174 | + num_bits = (pos_slot >> 1) - 1; | |
2175 | + cst->rep0 = 2 | (pos_slot & 1); | |
2176 | + if (pos_slot < LZMA_END_POS_MODEL_INDEX) { | |
2177 | + cst->rep0 <<= num_bits; | |
2178 | + prob = p + LZMA_SPEC_POS + | |
2179 | + cst->rep0 - pos_slot - 1; | |
2180 | + } else { | |
2181 | + num_bits -= LZMA_NUM_ALIGN_BITS; | |
2182 | + while (num_bits--) | |
2183 | + cst->rep0 = (cst->rep0 << 1) | | |
2184 | + rc_direct_bit(rc); | |
2185 | + prob = p + LZMA_ALIGN; | |
2186 | + cst->rep0 <<= LZMA_NUM_ALIGN_BITS; | |
2187 | + num_bits = LZMA_NUM_ALIGN_BITS; | |
2188 | + } | |
2189 | + i = 1; | |
2190 | + mi = 1; | |
2191 | + while (num_bits--) { | |
2192 | + if (rc_get_bit(rc, prob + mi, &mi)) | |
2193 | + cst->rep0 |= i; | |
2194 | + i <<= 1; | |
2195 | + } | |
2196 | + } else | |
2197 | + cst->rep0 = pos_slot; | |
2198 | + if (++(cst->rep0) == 0) | |
2199 | + return; | |
2200 | + } | |
2201 | + | |
2202 | + len += LZMA_MATCH_MIN_LEN; | |
2203 | + | |
2204 | + copy_bytes(wr, cst->rep0, len); | |
2205 | +} | |
2206 | + | |
2207 | + | |
2208 | + | |
cc3ac616 | 2209 | +STATIC inline int INIT unlzma(unsigned char *buf, int in_len, |
2210 | + int(*fill)(void*, unsigned int), | |
2211 | + int(*flush)(void*, unsigned int), | |
2212 | + unsigned char *output, | |
2213 | + int *posp, | |
2214 | + void(*error_fn)(char *x) | |
2215 | + ) | |
bd724f98 | 2216 | +{ |
2217 | + struct lzma_header header; | |
69622671 | 2218 | + int lc, pb, lp; |
2219 | + uint32_t pos_state_mask; | |
2220 | + uint32_t literal_pos_mask; | |
69622671 | 2221 | + uint16_t *p; |
69622671 | 2222 | + int num_probs; |
bd724f98 | 2223 | + struct rc rc; |
69622671 | 2224 | + int i, mi; |
bd724f98 | 2225 | + struct writer wr; |
2226 | + struct cstate cst; | |
cc3ac616 | 2227 | + unsigned char *inbuf; |
2228 | + int ret = -1; | |
2229 | + | |
2230 | + set_error_fn(error_fn); | |
2231 | + if (!flush) | |
2232 | + in_len -= 4; /* Uncompressed size hack active in pre-boot | |
2233 | + environment */ | |
2234 | + if (buf) | |
2235 | + inbuf = buf; | |
2236 | + else | |
2237 | + inbuf = malloc(LZMA_IOBUF_SIZE); | |
2238 | + if (!inbuf) { | |
2239 | + error("Could not allocate input bufer"); | |
2240 | + goto exit_0; | |
2241 | + } | |
bd724f98 | 2242 | + |
2243 | + cst.state = 0; | |
2244 | + cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1; | |
2245 | + | |
2246 | + wr.header = &header; | |
bd724f98 | 2247 | + wr.flush = flush; |
2248 | + wr.global_pos = 0; | |
bd724f98 | 2249 | + wr.previous_byte = 0; |
2250 | + wr.buffer_pos = 0; | |
69622671 | 2251 | + |
2252 | + rc_init(&rc, fill, inbuf, in_len); | |
2253 | + | |
2254 | + for (i = 0; i < sizeof(header); i++) { | |
2255 | + if (rc.ptr >= rc.buffer_end) | |
2256 | + rc_read(&rc); | |
2257 | + ((unsigned char *)&header)[i] = *rc.ptr++; | |
2258 | + } | |
2259 | + | |
2260 | + if (header.pos >= (9 * 5 * 5)) | |
2261 | + error("bad header"); | |
2262 | + | |
cc3ac616 | 2263 | + mi = 0; |
2264 | + lc = header.pos; | |
2265 | + while (lc >= 9) { | |
2266 | + mi++; | |
2267 | + lc -= 9; | |
2268 | + } | |
2269 | + pb = 0; | |
2270 | + lp = mi; | |
2271 | + while (lp >= 5) { | |
2272 | + pb++; | |
2273 | + lp -= 5; | |
2274 | + } | |
69622671 | 2275 | + pos_state_mask = (1 << pb) - 1; |
2276 | + literal_pos_mask = (1 << lp) - 1; | |
2277 | + | |
2278 | + ENDIAN_CONVERT(header.dict_size); | |
2279 | + ENDIAN_CONVERT(header.dst_size); | |
2280 | + | |
2281 | + if (header.dict_size == 0) | |
2282 | + header.dict_size = 1; | |
2283 | + | |
cc3ac616 | 2284 | + if (output) |
2285 | + wr.buffer = output; | |
2286 | + else { | |
2287 | + wr.bufsize = MIN(header.dst_size, header.dict_size); | |
2288 | + wr.buffer = large_malloc(wr.bufsize); | |
2289 | + } | |
bd724f98 | 2290 | + if (wr.buffer == NULL) |
cc3ac616 | 2291 | + goto exit_1; |
69622671 | 2292 | + |
2293 | + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); | |
cc3ac616 | 2294 | + p = (uint16_t *) large_malloc(num_probs * sizeof(*p)); |
2295 | + if (p == 0) | |
2296 | + goto exit_2; | |
69622671 | 2297 | + num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp)); |
2298 | + for (i = 0; i < num_probs; i++) | |
2299 | + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; | |
2300 | + | |
2301 | + rc_init_code(&rc); | |
2302 | + | |
bd724f98 | 2303 | + while (get_pos(&wr) < header.dst_size) { |
2304 | + int pos_state = get_pos(&wr) & pos_state_mask; | |
2305 | + uint16_t *prob = p + LZMA_IS_MATCH + | |
2306 | + (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state; | |
2307 | + if (rc_is_bit_0(&rc, prob)) | |
2308 | + process_bit0(&wr, &rc, &cst, p, pos_state, prob, | |
2309 | + lc, literal_pos_mask); | |
2310 | + else { | |
2311 | + process_bit1(&wr, &rc, &cst, p, pos_state, prob); | |
2312 | + if (cst.rep0 == 0) | |
2313 | + break; | |
69622671 | 2314 | + } |
2315 | + } | |
2316 | + | |
bd724f98 | 2317 | + if (posp) |
69622671 | 2318 | + *posp = rc.ptr-rc.buffer; |
cc3ac616 | 2319 | + if (wr.flush) |
2320 | + wr.flush(wr.buffer, wr.buffer_pos); | |
2321 | + ret = 0; | |
bd724f98 | 2322 | + large_free(p); |
cc3ac616 | 2323 | +exit_2: |
2324 | + if (!output) | |
2325 | + large_free(wr.buffer); | |
2326 | +exit_1: | |
2327 | + if (!buf) | |
2328 | + free(inbuf); | |
2329 | +exit_0: | |
2330 | + return ret; | |
2331 | +} | |
2332 | + | |
2333 | +#define decompress unlzma | |
2334 | diff -urNp linux-2.6.27.orig/lib/inflate.c linux-2.6.27/lib/inflate.c | |
2335 | --- linux-2.6.27.orig/lib/inflate.c 2008-10-29 08:47:55.000000000 +0100 | |
2336 | +++ linux-2.6.27/lib/inflate.c 2008-10-30 22:27:54.000000000 +0100 | |
2337 | @@ -109,20 +109,76 @@ static char rcsid[] = "#Id: inflate.c,v | |
2338 | #endif | |
2339 | ||
2340 | #ifndef STATIC | |
2341 | +#include <linux/decompress/inflate.h> | |
2342 | +#endif /* ! STATIC */ | |
2343 | ||
2344 | -#if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) | |
2345 | -# include <sys/types.h> | |
2346 | -# include <stdlib.h> | |
2347 | -#endif | |
2348 | +#include <linux/decompress/mm.h> | |
2349 | + | |
2350 | +#include <linux/string.h> | |
2351 | ||
2352 | -#include "gzip.h" | |
2353 | -#define STATIC | |
2354 | -#endif /* !STATIC */ | |
2355 | +static int(*flush_cb)(void*, unsigned int); | |
2356 | +static int(*fill_cb)(void*, unsigned int); | |
2357 | ||
2358 | -#ifndef INIT | |
2359 | -#define INIT | |
2360 | +/* Begin stuff copied from initramfs */ | |
2361 | +/* | |
2362 | + * gzip declarations | |
2363 | + */ | |
2364 | + | |
2365 | +#define OF(args) args | |
2366 | + | |
2367 | +#ifndef memzero | |
2368 | +#define memzero(s, n) memset((s), 0, (n)) | |
2369 | #endif | |
2370 | - | |
2371 | + | |
2372 | +#define INBUFSIZ 4096 | |
2373 | + | |
2374 | +#define WSIZE 0x8000 /* window size--must be a power of two, and */ | |
2375 | + /* at least 32K for zip's deflate method */ | |
2376 | + | |
2377 | +static uint8_t *inbuf; | |
2378 | +static uint8_t *window; | |
2379 | + | |
2380 | +static unsigned insize; /* valid bytes in inbuf */ | |
2381 | +static unsigned outcnt; /* bytes in output buffer */ | |
2382 | +static long bytes_out; | |
2383 | + | |
2384 | +/* --- */ | |
2385 | + | |
2386 | +static unsigned inptr; /* index of next byte to be processed in inbuf */ | |
2387 | + | |
2388 | +/* --- */ | |
2389 | + | |
2390 | +/* =========================================================================== | |
2391 | + * Fill the input buffer. This is called only when the buffer is empty | |
2392 | + * and at least one byte is really needed. | |
2393 | + * Returning -1 does not guarantee that gunzip() will ever return. | |
2394 | + */ | |
2395 | +static int INIT fill_inbuf(void) | |
2396 | +{ | |
2397 | + insize = fill_cb(inbuf, INBUFSIZ); | |
2398 | + if (insize <= 0) { | |
2399 | + error("RAMDISK: ran out of compressed data"); | |
2400 | + return -1; | |
2401 | + } | |
2402 | + | |
2403 | + inptr = 1; | |
2404 | + | |
2405 | + return inbuf[0]; | |
2406 | +} | |
2407 | + | |
2408 | +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) | |
2409 | + | |
2410 | +/* Diagnostic functions (stubbed out) */ | |
2411 | +#define Assert(cond, msg) | |
2412 | +#define Trace(x) | |
2413 | +#define Tracev(x) | |
2414 | +#define Tracevv(x) | |
2415 | +#define Tracec(c, x) | |
2416 | +#define Tracecv(c, x) | |
2417 | + | |
2418 | +static void flush_window(void); | |
2419 | +/* End stuff copied from initramfs */ | |
2420 | + | |
2421 | #define slide window | |
2422 | ||
2423 | /* Huffman code lookup table entry--this entry is four bytes for machines | |
2424 | @@ -133,10 +189,10 @@ static char rcsid[] = "#Id: inflate.c,v | |
2425 | an unused code. If a code with e == 99 is looked up, this implies an | |
2426 | error in the data. */ | |
2427 | struct huft { | |
2428 | - uch e; /* number of extra bits or operation */ | |
2429 | - uch b; /* number of bits in this code or subcode */ | |
2430 | + uint8_t e; /* number of extra bits or operation */ | |
2431 | + uint8_t b; /* number of bits in this code or subcode */ | |
2432 | union { | |
2433 | - ush n; /* literal, length base, or distance base */ | |
2434 | + uint16_t n; /* literal, length base, or distance base */ | |
2435 | struct huft *t; /* pointer to next level of table */ | |
2436 | } v; | |
2437 | }; | |
2438 | @@ -144,7 +200,7 @@ struct huft { | |
2439 | ||
2440 | /* Function prototypes */ | |
2441 | STATIC int INIT huft_build OF((unsigned *, unsigned, unsigned, | |
2442 | - const ush *, const ush *, struct huft **, int *)); | |
2443 | + const uint16_t *, const uint16_t *, struct huft **, int *)); | |
2444 | STATIC int INIT huft_free OF((struct huft *)); | |
2445 | STATIC int INIT inflate_codes OF((struct huft *, struct huft *, int, int)); | |
2446 | STATIC int INIT inflate_stored OF((void)); | |
2447 | @@ -159,28 +215,28 @@ STATIC int INIT inflate OF((void)); | |
2448 | circular buffer. The index is updated simply by incrementing and then | |
2449 | ANDing with 0x7fff (32K-1). */ | |
2450 | /* It is left to other modules to supply the 32 K area. It is assumed | |
2451 | - to be usable as if it were declared "uch slide[32768];" or as just | |
2452 | - "uch *slide;" and then malloc'ed in the latter case. The definition | |
2453 | + to be usable as if it were declared "uint8_t slide[32768];" or as just | |
2454 | + "uint8_t *slide;" and then malloc'ed in the latter case. The definition | |
2455 | must be in unzip.h, included above. */ | |
2456 | /* unsigned wp; current position in slide */ | |
2457 | #define wp outcnt | |
2458 | #define flush_output(w) (wp=(w),flush_window()) | |
2459 | ||
2460 | /* Tables for deflate from PKZIP's appnote.txt. */ | |
2461 | -static const unsigned border[] = { /* Order of the bit length code lengths */ | |
2462 | +static const unsigned border[] = { /* Order of the bit length code lengths */ | |
2463 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | |
2464 | -static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ | |
2465 | +static const uint16_t cplens[] = { /* Copy lengths for literal codes 257..285 */ | |
2466 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | |
2467 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; | |
2468 | /* note: see note #13 above about the 258 in this list. */ | |
2469 | -static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ | |
2470 | +static const uint16_t cplext[] = { /* Extra bits for literal codes 257..285 */ | |
2471 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | |
2472 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ | |
2473 | -static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ | |
2474 | +static const uint16_t cpdist[] = { /* Copy offsets for distance codes 0..29 */ | |
2475 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | |
2476 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | |
2477 | 8193, 12289, 16385, 24577}; | |
2478 | -static const ush cpdext[] = { /* Extra bits for distance codes */ | |
2479 | +static const uint16_t cpdext[] = { /* Extra bits for distance codes */ | |
2480 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | |
2481 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | |
2482 | 12, 12, 13, 13}; | |
2483 | @@ -217,59 +273,21 @@ static const ush cpdext[] = { /* | |
2484 | the stream. | |
2485 | */ | |
2486 | ||
2487 | -STATIC ulg bb; /* bit buffer */ | |
2488 | +STATIC uint32_t bb; /* bit buffer */ | |
2489 | STATIC unsigned bk; /* bits in bit buffer */ | |
2490 | ||
2491 | -STATIC const ush mask_bits[] = { | |
2492 | +STATIC const uint16_t mask_bits[] = { | |
2493 | 0x0000, | |
2494 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | |
2495 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff | |
2496 | }; | |
2497 | ||
2498 | -#define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; }) | |
2499 | -#define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}} | |
2500 | +#define NEXTBYTE() ({ int v = get_byte(); if (v < 0) goto underrun; \ | |
2501 | + (uint8_t)v; }) | |
2502 | +#define NEEDBITS(n) {while (k < (n)) \ | |
2503 | + {b |= ((uint32_t)NEXTBYTE())<<k; k += 8; } } | |
2504 | #define DUMPBITS(n) {b>>=(n);k-=(n);} | |
2505 | ||
2506 | -#ifndef NO_INFLATE_MALLOC | |
2507 | -/* A trivial malloc implementation, adapted from | |
2508 | - * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 | |
2509 | - */ | |
2510 | - | |
2511 | -static unsigned long malloc_ptr; | |
2512 | -static int malloc_count; | |
2513 | - | |
2514 | -static void *malloc(int size) | |
2515 | -{ | |
2516 | - void *p; | |
2517 | - | |
2518 | - if (size < 0) | |
2519 | - error("Malloc error"); | |
2520 | - if (!malloc_ptr) | |
2521 | - malloc_ptr = free_mem_ptr; | |
2522 | - | |
2523 | - malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */ | |
2524 | - | |
2525 | - p = (void *)malloc_ptr; | |
2526 | - malloc_ptr += size; | |
2527 | - | |
2528 | - if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) | |
2529 | - error("Out of memory"); | |
2530 | - | |
2531 | - malloc_count++; | |
2532 | - return p; | |
2533 | -} | |
2534 | - | |
2535 | -static void free(void *where) | |
2536 | -{ | |
2537 | - malloc_count--; | |
2538 | - if (!malloc_count) | |
2539 | - malloc_ptr = free_mem_ptr; | |
2540 | -} | |
2541 | -#else | |
2542 | -#define malloc(a) kmalloc(a, GFP_KERNEL) | |
2543 | -#define free(a) kfree(a) | |
2544 | -#endif | |
2545 | - | |
2546 | /* | |
2547 | Huffman code decoding is performed using a multi-level table lookup. | |
2548 | The fastest way to decode is to simply build a lookup table whose | |
2549 | @@ -307,7 +325,7 @@ STATIC const int lbits = 9; /* | |
2550 | STATIC const int dbits = 6; /* bits in base distance lookup table */ | |
2551 | ||
2552 | ||
2553 | -/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ | |
2554 | +/* If BMAX needs to be larger than 16, then h and x[] should be uint32_t. */ | |
2555 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ | |
2556 | #define N_MAX 288 /* maximum number of codes in any set */ | |
2557 | ||
2558 | @@ -319,8 +337,8 @@ STATIC int INIT huft_build( | |
2559 | unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ | |
2560 | unsigned n, /* number of codes (assumed <= N_MAX) */ | |
2561 | unsigned s, /* number of simple-valued codes (0..s-1) */ | |
2562 | - const ush *d, /* list of base values for non-simple codes */ | |
2563 | - const ush *e, /* list of extra bits for non-simple codes */ | |
2564 | + const uint16_t *d, /* list of base values for non-simple codes */ | |
2565 | + const uint16_t *e, /* list of extra bits for non-simple codes */ | |
2566 | struct huft **t, /* result: starting table */ | |
2567 | int *m /* maximum lookup bits, returns actual */ | |
2568 | ) | |
2569 | @@ -500,8 +518,8 @@ DEBG1("5 "); | |
2570 | if (h) | |
2571 | { | |
2572 | x[h] = i; /* save pattern for backing up */ | |
2573 | - r.b = (uch)l; /* bits to dump before this table */ | |
2574 | - r.e = (uch)(16 + j); /* bits in this table */ | |
2575 | + r.b = (uint8_t)l; /* bits to dump before this table */ | |
2576 | + r.e = (uint8_t)(16 + j); /* bits in this table */ | |
2577 | r.v.t = q; /* pointer to this table */ | |
2578 | j = i >> (w - l); /* (get around Turbo C bug) */ | |
2579 | u[h-1][j] = r; /* connect to last table */ | |
2580 | @@ -511,18 +529,18 @@ DEBG1("6 "); | |
2581 | DEBG("h6c "); | |
2582 | ||
2583 | /* set up table entry in r */ | |
2584 | - r.b = (uch)(k - w); | |
2585 | + r.b = (uint8_t)(k - w); | |
2586 | if (p >= v + n) | |
2587 | r.e = 99; /* out of values--invalid code */ | |
2588 | else if (*p < s) | |
2589 | { | |
2590 | - r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ | |
2591 | - r.v.n = (ush)(*p); /* simple code is just the value */ | |
2592 | + r.e = (uint8_t)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ | |
2593 | + r.v.n = (uint16_t)(*p); /* simple code is just the value */ | |
2594 | p++; /* one compiler does not like *p++ */ | |
2595 | } | |
2596 | else | |
2597 | { | |
2598 | - r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ | |
2599 | + r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ | |
2600 | r.v.n = d[*p++ - s]; | |
2601 | } | |
2602 | DEBG("h6d "); | |
2603 | @@ -592,11 +610,12 @@ STATIC int INIT inflate_codes( | |
2604 | Return an error code or zero if it all goes ok. */ | |
2605 | { | |
2606 | register unsigned e; /* table entry flag/number of extra bits */ | |
2607 | - unsigned n, d; /* length and index for copy */ | |
2608 | + unsigned n; | |
2609 | + int d; /* source index for copy */ | |
2610 | unsigned w; /* current window position */ | |
2611 | struct huft *t; /* pointer to table entry */ | |
2612 | unsigned ml, md; /* masks for bl and bd bits */ | |
2613 | - register ulg b; /* bit buffer */ | |
2614 | + register uint32_t b; /* bit buffer */ | |
2615 | register unsigned k; /* number of bits in bit buffer */ | |
2616 | ||
2617 | ||
2618 | @@ -622,7 +641,7 @@ STATIC int INIT inflate_codes( | |
2619 | DUMPBITS(t->b) | |
2620 | if (e == 16) /* then it's a literal */ | |
2621 | { | |
2622 | - slide[w++] = (uch)t->v.n; | |
2623 | + slide[w++] = (uint8_t)t->v.n; | |
2624 | Tracevv((stderr, "%c", slide[w-1])); | |
2625 | if (w == WSIZE) | |
2626 | { | |
2627 | @@ -659,11 +678,22 @@ STATIC int INIT inflate_codes( | |
2628 | ||
2629 | /* do the copy */ | |
2630 | do { | |
2631 | - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); | |
2632 | + if (flush_cb) { | |
2633 | + /* Sliding window emulated using circular buffer: | |
2634 | + * manage wrap-around */ | |
2635 | + e = WSIZE - ((d &= WSIZE-1) > w ? d : w); | |
2636 | + if (e > n) | |
2637 | + e = n; | |
2638 | + } else { | |
2639 | + e = n; | |
2640 | + } | |
2641 | + | |
2642 | + n -= e; | |
2643 | + | |
2644 | #if !defined(NOMEMCPY) && !defined(DEBUG) | |
2645 | if (w - d >= e) /* (this test assumes unsigned comparison) */ | |
2646 | { | |
2647 | - memcpy(slide + w, slide + d, e); | |
2648 | + memcpy(slide + w, slide + d, e); | |
2649 | w += e; | |
2650 | d += e; | |
2651 | } | |
2652 | @@ -673,9 +703,8 @@ STATIC int INIT inflate_codes( | |
2653 | slide[w++] = slide[d++]; | |
2654 | Tracevv((stderr, "%c", slide[w-1])); | |
2655 | } while (--e); | |
2656 | - if (w == WSIZE) | |
2657 | - { | |
2658 | - flush_output(w); | |
2659 | + if (w == WSIZE) { | |
2660 | + flush_output(w); | |
2661 | w = 0; | |
2662 | } | |
2663 | } while (n); | |
2664 | @@ -702,7 +731,7 @@ STATIC int INIT inflate_stored(void) | |
2665 | { | |
2666 | unsigned n; /* number of bytes in block */ | |
2667 | unsigned w; /* current window position */ | |
2668 | - register ulg b; /* bit buffer */ | |
2669 | + register uint32_t b; /* bit buffer */ | |
2670 | register unsigned k; /* number of bits in bit buffer */ | |
2671 | ||
2672 | DEBG("<stor"); | |
2673 | @@ -732,7 +761,7 @@ DEBG("<stor"); | |
2674 | while (n--) | |
2675 | { | |
2676 | NEEDBITS(8) | |
2677 | - slide[w++] = (uch)b; | |
2678 | + slide[w++] = (uint8_t)b; | |
2679 | if (w == WSIZE) | |
2680 | { | |
2681 | flush_output(w); | |
2682 | @@ -838,7 +867,7 @@ STATIC int noinline INIT inflate_dynamic | |
2683 | unsigned nl; /* number of literal/length codes */ | |
2684 | unsigned nd; /* number of distance codes */ | |
2685 | unsigned *ll; /* literal/length and distance code lengths */ | |
2686 | - register ulg b; /* bit buffer */ | |
2687 | + register uint32_t b; /* bit buffer */ | |
2688 | register unsigned k; /* number of bits in bit buffer */ | |
2689 | int ret; | |
2690 | ||
2691 | @@ -1033,7 +1062,7 @@ STATIC int INIT inflate_block( | |
2692 | /* decompress an inflated block */ | |
2693 | { | |
2694 | unsigned t; /* block type */ | |
2695 | - register ulg b; /* bit buffer */ | |
2696 | + register uint32_t b; /* bit buffer */ | |
2697 | register unsigned k; /* number of bits in bit buffer */ | |
2698 | ||
2699 | DEBG("<blk"); | |
2700 | @@ -1130,8 +1159,8 @@ STATIC int INIT inflate(void) | |
2701 | * | |
2702 | **********************************************************************/ | |
2703 | ||
2704 | -static ulg crc_32_tab[256]; | |
2705 | -static ulg crc; /* initialized in makecrc() so it'll reside in bss */ | |
2706 | +static uint32_t crc_32_tab[256]; | |
2707 | +static uint32_t crc; /* initialized in makecrc() so it'll reside in bss */ | |
2708 | #define CRC_VALUE (crc ^ 0xffffffffUL) | |
2709 | ||
2710 | /* | |
2711 | @@ -1172,7 +1201,7 @@ makecrc(void) | |
2712 | } | |
2713 | ||
2714 | /* this is initialized here so this code could reside in ROM */ | |
2715 | - crc = (ulg)0xffffffffUL; /* shift register contents */ | |
2716 | + crc = (uint32_t)0xffffffffUL; /* shift register contents */ | |
2717 | } | |
2718 | ||
2719 | /* gzip flag byte */ | |
2720 | @@ -1184,18 +1213,80 @@ makecrc(void) | |
2721 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ | |
2722 | #define RESERVED 0xC0 /* bit 6,7: reserved */ | |
2723 | ||
2724 | +/* =========================================================================== | |
2725 | + * Write the output window window[0..outcnt-1] and update crc and bytes_out. | |
2726 | + * (Used for the decompressed data only.) | |
2727 | + */ | |
2728 | +static void INIT flush_window(void) | |
2729 | +{ | |
2730 | + uint32_t c = crc; /* temporary variable */ | |
2731 | + unsigned n; | |
2732 | + uint8_t *in, ch; | |
2733 | + | |
2734 | + in = window; | |
2735 | + for (n = 0; n < outcnt; n++) { | |
2736 | + ch = *in++; | |
2737 | + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | |
2738 | + } | |
2739 | + crc = c; | |
2740 | + bytes_out += (uint32_t)outcnt; | |
2741 | + if (flush_cb != NULL) | |
2742 | + flush_cb(window, outcnt); /* TODO: handle unzip_error */ | |
2743 | + else | |
2744 | + window += outcnt; | |
2745 | + outcnt = 0; | |
2746 | +} | |
2747 | + | |
2748 | +static int empty_fill(void *buf, unsigned int len) | |
2749 | +{ | |
69622671 | 2750 | + return 0; |
69622671 | 2751 | +} |
cc3ac616 | 2752 | + |
2753 | + | |
2754 | + | |
2755 | /* | |
2756 | * Do the uncompression! | |
2757 | */ | |
2758 | -static int INIT gunzip(void) | |
2759 | +STATIC int INIT gunzip(unsigned char *buf, int len, | |
2760 | + int(*fill)(void*, unsigned int), | |
2761 | + int(*flush)(void*, unsigned int), | |
2762 | + unsigned char *output, | |
2763 | + int *posp, | |
2764 | + void(*error_fn)(char *x) | |
2765 | + ) | |
2766 | { | |
2767 | - uch flags; | |
2768 | + uint8_t flags; | |
2769 | unsigned char magic[2]; /* magic header */ | |
2770 | char method; | |
2771 | - ulg orig_crc = 0; /* original crc */ | |
2772 | - ulg orig_len = 0; /* original uncompressed length */ | |
2773 | + uint32_t orig_crc = 0; /* original crc */ | |
2774 | + uint32_t orig_len = 0; /* original uncompressed length */ | |
2775 | int res; | |
2776 | ||
2777 | + set_error_fn(error_fn); | |
2778 | + if (fill == NULL) | |
2779 | + fill_cb = empty_fill; | |
2780 | + else | |
2781 | + fill_cb = fill; | |
2782 | + if (output) | |
2783 | + window = output; | |
2784 | + else { | |
2785 | + window = malloc(0x8000); | |
2786 | + if (!window) | |
2787 | + panic("can't allocate buffers"); | |
2788 | + flush_cb = flush; | |
2789 | + } | |
2790 | + | |
2791 | + insize = len; | |
2792 | + if (buf) | |
2793 | + inbuf = buf; | |
2794 | + else | |
2795 | + inbuf = malloc(INBUFSIZ); | |
2796 | + inptr = 0; | |
2797 | + outcnt = 0; /* bytes in output buffer */ | |
2798 | + bytes_out = 0; | |
2799 | + crc = (uint32_t)0xffffffffL; /* shift register contents */ | |
2800 | + makecrc(); | |
2801 | + | |
2802 | magic[0] = NEXTBYTE(); | |
2803 | magic[1] = NEXTBYTE(); | |
2804 | method = NEXTBYTE(); | |
2805 | @@ -1212,7 +1303,7 @@ static int INIT gunzip(void) | |
2806 | return -1; | |
2807 | } | |
2808 | ||
2809 | - flags = (uch)get_byte(); | |
2810 | + flags = (uint8_t)get_byte(); | |
2811 | if ((flags & ENCRYPTED) != 0) { | |
2812 | error("Input is encrypted"); | |
2813 | return -1; | |
2814 | @@ -1277,15 +1368,15 @@ static int INIT gunzip(void) | |
2815 | /* crc32 (see algorithm.doc) | |
2816 | * uncompressed input size modulo 2^32 | |
2817 | */ | |
2818 | - orig_crc = (ulg) NEXTBYTE(); | |
2819 | - orig_crc |= (ulg) NEXTBYTE() << 8; | |
2820 | - orig_crc |= (ulg) NEXTBYTE() << 16; | |
2821 | - orig_crc |= (ulg) NEXTBYTE() << 24; | |
2822 | + orig_crc = (uint32_t) NEXTBYTE(); | |
2823 | + orig_crc |= (uint32_t) NEXTBYTE() << 8; | |
2824 | + orig_crc |= (uint32_t) NEXTBYTE() << 16; | |
2825 | + orig_crc |= (uint32_t) NEXTBYTE() << 24; | |
2826 | ||
2827 | - orig_len = (ulg) NEXTBYTE(); | |
2828 | - orig_len |= (ulg) NEXTBYTE() << 8; | |
2829 | - orig_len |= (ulg) NEXTBYTE() << 16; | |
2830 | - orig_len |= (ulg) NEXTBYTE() << 24; | |
2831 | + orig_len = (uint32_t) NEXTBYTE(); | |
2832 | + orig_len |= (uint32_t) NEXTBYTE() << 8; | |
2833 | + orig_len |= (uint32_t) NEXTBYTE() << 16; | |
2834 | + orig_len |= (uint32_t) NEXTBYTE() << 24; | |
2835 | ||
2836 | /* Validate decompression */ | |
2837 | if (orig_crc != CRC_VALUE) { | |
2838 | @@ -1296,11 +1387,18 @@ static int INIT gunzip(void) | |
2839 | error("length error"); | |
2840 | return -1; | |
2841 | } | |
2842 | + if (!output) | |
2843 | + free(window); | |
2844 | + if (posp) | |
2845 | + *posp = inptr; | |
2846 | return 0; | |
2847 | ||
2848 | underrun: /* NEXTBYTE() goto's here if needed */ | |
2849 | + free(window); | |
2850 | + if (!buf) | |
2851 | + free(inbuf); | |
2852 | error("out of input data"); | |
2853 | return -1; | |
2854 | } | |
2855 | ||
2856 | - | |
2857 | +#define decompress gunzip | |
2858 | diff -urNp linux-2.6.27.orig/lib/Makefile linux-2.6.27/lib/Makefile | |
2859 | --- linux-2.6.27.orig/lib/Makefile 2008-10-29 08:47:55.000000000 +0100 | |
2860 | +++ linux-2.6.27/lib/Makefile 2008-10-30 22:27:34.000000000 +0100 | |
2861 | @@ -57,6 +57,10 @@ obj-$(CONFIG_CRC7) += crc7.o | |
bd724f98 | 2862 | obj-$(CONFIG_LIBCRC32C) += libcrc32c.o |
2863 | obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o | |
2864 | ||
cc3ac616 | 2865 | +obj-y += inflate.o |
bd724f98 | 2866 | +obj-$(CONFIG_RD_BZIP2) += decompress_bunzip2.o |
2867 | +obj-$(CONFIG_RD_LZMA) += decompress_unlzma.o | |
bd724f98 | 2868 | + |
2869 | obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ | |
2870 | obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ | |
2871 | obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ | |
cc3ac616 | 2872 | diff -urNp linux-2.6.27.orig/scripts/bin_size linux-2.6.27/scripts/bin_size |
2873 | --- linux-2.6.27.orig/scripts/bin_size 1970-01-01 01:00:00.000000000 +0100 | |
2874 | +++ linux-2.6.27/scripts/bin_size 2008-10-30 22:27:29.000000000 +0100 | |
2875 | @@ -0,0 +1,10 @@ | |
2876 | +#!/bin/sh | |
2877 | + | |
2878 | +if [ $# = 0 ] ; then | |
2879 | + echo Usage: $0 file | |
2880 | +fi | |
2881 | + | |
2882 | +size_dec=`stat -c "%s" $1` | |
2883 | +size_hex_echo_string=`printf "%08x" $size_dec | | |
2884 | + sed 's/\(..\)\(..\)\(..\)\(..\)/\\\\x\4\\\\x\3\\\\x\2\\\\x\1/g'` | |
2885 | +/bin/echo -ne $size_hex_echo_string | |
2886 | diff -urNp linux-2.6.27.orig/scripts/Makefile.lib linux-2.6.27/scripts/Makefile.lib | |
2887 | --- linux-2.6.27.orig/scripts/Makefile.lib 2008-10-29 08:48:11.000000000 +0100 | |
2888 | +++ linux-2.6.27/scripts/Makefile.lib 2008-10-30 22:27:29.000000000 +0100 | |
2889 | @@ -174,3 +174,17 @@ quiet_cmd_gzip = GZIP $@ | |
69622671 | 2890 | cmd_gzip = gzip -f -9 < $< > $@ |
2891 | ||
69622671 | 2892 | |
2893 | +# Bzip2 | |
2894 | +# --------------------------------------------------------------------------- | |
2895 | + | |
bd724f98 | 2896 | +# Bzip2 does not include size in file... so we have to fake that |
cc3ac616 | 2897 | +size_append=$(CONFIG_SHELL) $(srctree)/scripts/bin_size |
bd724f98 | 2898 | + |
69622671 | 2899 | +quiet_cmd_bzip2 = BZIP2 $@ |
cc3ac616 | 2900 | +cmd_bzip2 = (bzip2 -9 < $< ; $(size_append) $<) > $@ || (rm -f $@ ; false) |
69622671 | 2901 | + |
2902 | +# Lzma | |
2903 | +# --------------------------------------------------------------------------- | |
2904 | + | |
2905 | +quiet_cmd_lzma = LZMA $@ | |
cc3ac616 | 2906 | +cmd_lzma = (lzma -9 --format=alone -c $< ; $(size_append) $<) >$@ || (rm -f $@ ; false) |