xref: /OK3568_Linux_fs/kernel/lib/decompress_unlzma.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* Lzma decompressor for Linux kernel. Shamelessly snarfed
2*4882a593Smuzhiyun  *from busybox 1.1.1
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *Linux kernel adaptation
5*4882a593Smuzhiyun  *Copyright (C) 2006  Alain < alain@knaff.lu >
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *Based on small lzma deflate implementation/Small range coder
8*4882a593Smuzhiyun  *implementation for lzma.
9*4882a593Smuzhiyun  *Copyright (C) 2006  Aurelien Jacobs < aurel@gnuage.org >
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  *Based on LzmaDecode.c from the LZMA SDK 4.22 (https://www.7-zip.org/)
12*4882a593Smuzhiyun  *Copyright (C) 1999-2005  Igor Pavlov
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *Copyrights of the parts, see headers below.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  *
17*4882a593Smuzhiyun  *This program is free software; you can redistribute it and/or
18*4882a593Smuzhiyun  *modify it under the terms of the GNU Lesser General Public
19*4882a593Smuzhiyun  *License as published by the Free Software Foundation; either
20*4882a593Smuzhiyun  *version 2.1 of the License, or (at your option) any later version.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  *This program is distributed in the hope that it will be useful,
23*4882a593Smuzhiyun  *but WITHOUT ANY WARRANTY; without even the implied warranty of
24*4882a593Smuzhiyun  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25*4882a593Smuzhiyun  *Lesser General Public License for more details.
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  *You should have received a copy of the GNU Lesser General Public
28*4882a593Smuzhiyun  *License along with this library; if not, write to the Free Software
29*4882a593Smuzhiyun  *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #ifdef STATIC
33*4882a593Smuzhiyun #define PREBOOT
34*4882a593Smuzhiyun #else
35*4882a593Smuzhiyun #include <linux/decompress/unlzma.h>
36*4882a593Smuzhiyun #endif /* STATIC */
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #include <linux/decompress/mm.h>
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define	MIN(a, b) (((a) < (b)) ? (a) : (b))
41*4882a593Smuzhiyun 
read_int(unsigned char * ptr,int size)42*4882a593Smuzhiyun static long long INIT read_int(unsigned char *ptr, int size)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun 	int i;
45*4882a593Smuzhiyun 	long long ret = 0;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	for (i = 0; i < size; i++)
48*4882a593Smuzhiyun 		ret = (ret << 8) | ptr[size-i-1];
49*4882a593Smuzhiyun 	return ret;
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define ENDIAN_CONVERT(x) \
53*4882a593Smuzhiyun   x = (typeof(x))read_int((unsigned char *)&x, sizeof(x))
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* Small range coder implementation for lzma.
57*4882a593Smuzhiyun  *Copyright (C) 2006  Aurelien Jacobs < aurel@gnuage.org >
58*4882a593Smuzhiyun  *
59*4882a593Smuzhiyun  *Based on LzmaDecode.c from the LZMA SDK 4.22 (https://www.7-zip.org/)
60*4882a593Smuzhiyun  *Copyright (c) 1999-2005  Igor Pavlov
61*4882a593Smuzhiyun  */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #include <linux/compiler.h>
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #define LZMA_IOBUF_SIZE	0x10000
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun struct rc {
68*4882a593Smuzhiyun 	long (*fill)(void*, unsigned long);
69*4882a593Smuzhiyun 	uint8_t *ptr;
70*4882a593Smuzhiyun 	uint8_t *buffer;
71*4882a593Smuzhiyun 	uint8_t *buffer_end;
72*4882a593Smuzhiyun 	long buffer_size;
73*4882a593Smuzhiyun 	uint32_t code;
74*4882a593Smuzhiyun 	uint32_t range;
75*4882a593Smuzhiyun 	uint32_t bound;
76*4882a593Smuzhiyun 	void (*error)(char *);
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #define RC_TOP_BITS 24
81*4882a593Smuzhiyun #define RC_MOVE_BITS 5
82*4882a593Smuzhiyun #define RC_MODEL_TOTAL_BITS 11
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 
nofill(void * buffer,unsigned long len)85*4882a593Smuzhiyun static long INIT nofill(void *buffer, unsigned long len)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	return -1;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /* Called twice: once at startup and once in rc_normalize() */
rc_read(struct rc * rc)91*4882a593Smuzhiyun static void INIT rc_read(struct rc *rc)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun 	rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
94*4882a593Smuzhiyun 	if (rc->buffer_size <= 0)
95*4882a593Smuzhiyun 		rc->error("unexpected EOF");
96*4882a593Smuzhiyun 	rc->ptr = rc->buffer;
97*4882a593Smuzhiyun 	rc->buffer_end = rc->buffer + rc->buffer_size;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /* Called once */
rc_init(struct rc * rc,long (* fill)(void *,unsigned long),char * buffer,long buffer_size)101*4882a593Smuzhiyun static inline void INIT rc_init(struct rc *rc,
102*4882a593Smuzhiyun 				       long (*fill)(void*, unsigned long),
103*4882a593Smuzhiyun 				       char *buffer, long buffer_size)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	if (fill)
106*4882a593Smuzhiyun 		rc->fill = fill;
107*4882a593Smuzhiyun 	else
108*4882a593Smuzhiyun 		rc->fill = nofill;
109*4882a593Smuzhiyun 	rc->buffer = (uint8_t *)buffer;
110*4882a593Smuzhiyun 	rc->buffer_size = buffer_size;
111*4882a593Smuzhiyun 	rc->buffer_end = rc->buffer + rc->buffer_size;
112*4882a593Smuzhiyun 	rc->ptr = rc->buffer;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	rc->code = 0;
115*4882a593Smuzhiyun 	rc->range = 0xFFFFFFFF;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
rc_init_code(struct rc * rc)118*4882a593Smuzhiyun static inline void INIT rc_init_code(struct rc *rc)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	int i;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	for (i = 0; i < 5; i++) {
123*4882a593Smuzhiyun 		if (rc->ptr >= rc->buffer_end)
124*4882a593Smuzhiyun 			rc_read(rc);
125*4882a593Smuzhiyun 		rc->code = (rc->code << 8) | *rc->ptr++;
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun /* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
rc_do_normalize(struct rc * rc)131*4882a593Smuzhiyun static void INIT rc_do_normalize(struct rc *rc)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	if (rc->ptr >= rc->buffer_end)
134*4882a593Smuzhiyun 		rc_read(rc);
135*4882a593Smuzhiyun 	rc->range <<= 8;
136*4882a593Smuzhiyun 	rc->code = (rc->code << 8) | *rc->ptr++;
137*4882a593Smuzhiyun }
rc_normalize(struct rc * rc)138*4882a593Smuzhiyun static inline void INIT rc_normalize(struct rc *rc)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	if (rc->range < (1 << RC_TOP_BITS))
141*4882a593Smuzhiyun 		rc_do_normalize(rc);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /* Called 9 times */
145*4882a593Smuzhiyun /* Why rc_is_bit_0_helper exists?
146*4882a593Smuzhiyun  *Because we want to always expose (rc->code < rc->bound) to optimizer
147*4882a593Smuzhiyun  */
rc_is_bit_0_helper(struct rc * rc,uint16_t * p)148*4882a593Smuzhiyun static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	rc_normalize(rc);
151*4882a593Smuzhiyun 	rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
152*4882a593Smuzhiyun 	return rc->bound;
153*4882a593Smuzhiyun }
rc_is_bit_0(struct rc * rc,uint16_t * p)154*4882a593Smuzhiyun static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	uint32_t t = rc_is_bit_0_helper(rc, p);
157*4882a593Smuzhiyun 	return rc->code < t;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /* Called ~10 times, but very small, thus inlined */
rc_update_bit_0(struct rc * rc,uint16_t * p)161*4882a593Smuzhiyun static inline void INIT rc_update_bit_0(struct rc *rc, uint16_t *p)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	rc->range = rc->bound;
164*4882a593Smuzhiyun 	*p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
165*4882a593Smuzhiyun }
rc_update_bit_1(struct rc * rc,uint16_t * p)166*4882a593Smuzhiyun static inline void INIT rc_update_bit_1(struct rc *rc, uint16_t *p)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	rc->range -= rc->bound;
169*4882a593Smuzhiyun 	rc->code -= rc->bound;
170*4882a593Smuzhiyun 	*p -= *p >> RC_MOVE_BITS;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun /* Called 4 times in unlzma loop */
rc_get_bit(struct rc * rc,uint16_t * p,int * symbol)174*4882a593Smuzhiyun static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun 	if (rc_is_bit_0(rc, p)) {
177*4882a593Smuzhiyun 		rc_update_bit_0(rc, p);
178*4882a593Smuzhiyun 		*symbol *= 2;
179*4882a593Smuzhiyun 		return 0;
180*4882a593Smuzhiyun 	} else {
181*4882a593Smuzhiyun 		rc_update_bit_1(rc, p);
182*4882a593Smuzhiyun 		*symbol = *symbol * 2 + 1;
183*4882a593Smuzhiyun 		return 1;
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun /* Called once */
rc_direct_bit(struct rc * rc)188*4882a593Smuzhiyun static inline int INIT rc_direct_bit(struct rc *rc)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	rc_normalize(rc);
191*4882a593Smuzhiyun 	rc->range >>= 1;
192*4882a593Smuzhiyun 	if (rc->code >= rc->range) {
193*4882a593Smuzhiyun 		rc->code -= rc->range;
194*4882a593Smuzhiyun 		return 1;
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 	return 0;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun /* Called twice */
200*4882a593Smuzhiyun static inline void INIT
rc_bit_tree_decode(struct rc * rc,uint16_t * p,int num_levels,int * symbol)201*4882a593Smuzhiyun rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	int i = num_levels;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	*symbol = 1;
206*4882a593Smuzhiyun 	while (i--)
207*4882a593Smuzhiyun 		rc_get_bit(rc, p + *symbol, symbol);
208*4882a593Smuzhiyun 	*symbol -= 1 << num_levels;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun /*
213*4882a593Smuzhiyun  * Small lzma deflate implementation.
214*4882a593Smuzhiyun  * Copyright (C) 2006  Aurelien Jacobs < aurel@gnuage.org >
215*4882a593Smuzhiyun  *
216*4882a593Smuzhiyun  * Based on LzmaDecode.c from the LZMA SDK 4.22 (https://www.7-zip.org/)
217*4882a593Smuzhiyun  * Copyright (C) 1999-2005  Igor Pavlov
218*4882a593Smuzhiyun  */
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun struct lzma_header {
222*4882a593Smuzhiyun 	uint8_t pos;
223*4882a593Smuzhiyun 	uint32_t dict_size;
224*4882a593Smuzhiyun 	uint64_t dst_size;
225*4882a593Smuzhiyun } __attribute__ ((packed)) ;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun #define LZMA_BASE_SIZE 1846
229*4882a593Smuzhiyun #define LZMA_LIT_SIZE 768
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun #define LZMA_NUM_POS_BITS_MAX 4
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun #define LZMA_LEN_NUM_LOW_BITS 3
234*4882a593Smuzhiyun #define LZMA_LEN_NUM_MID_BITS 3
235*4882a593Smuzhiyun #define LZMA_LEN_NUM_HIGH_BITS 8
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun #define LZMA_LEN_CHOICE 0
238*4882a593Smuzhiyun #define LZMA_LEN_CHOICE_2 (LZMA_LEN_CHOICE + 1)
239*4882a593Smuzhiyun #define LZMA_LEN_LOW (LZMA_LEN_CHOICE_2 + 1)
240*4882a593Smuzhiyun #define LZMA_LEN_MID (LZMA_LEN_LOW \
241*4882a593Smuzhiyun 		      + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS)))
242*4882a593Smuzhiyun #define LZMA_LEN_HIGH (LZMA_LEN_MID \
243*4882a593Smuzhiyun 		       +(1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS)))
244*4882a593Smuzhiyun #define LZMA_NUM_LEN_PROBS (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS))
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun #define LZMA_NUM_STATES 12
247*4882a593Smuzhiyun #define LZMA_NUM_LIT_STATES 7
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun #define LZMA_START_POS_MODEL_INDEX 4
250*4882a593Smuzhiyun #define LZMA_END_POS_MODEL_INDEX 14
251*4882a593Smuzhiyun #define LZMA_NUM_FULL_DISTANCES (1 << (LZMA_END_POS_MODEL_INDEX >> 1))
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun #define LZMA_NUM_POS_SLOT_BITS 6
254*4882a593Smuzhiyun #define LZMA_NUM_LEN_TO_POS_STATES 4
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun #define LZMA_NUM_ALIGN_BITS 4
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun #define LZMA_MATCH_MIN_LEN 2
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun #define LZMA_IS_MATCH 0
261*4882a593Smuzhiyun #define LZMA_IS_REP (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
262*4882a593Smuzhiyun #define LZMA_IS_REP_G0 (LZMA_IS_REP + LZMA_NUM_STATES)
263*4882a593Smuzhiyun #define LZMA_IS_REP_G1 (LZMA_IS_REP_G0 + LZMA_NUM_STATES)
264*4882a593Smuzhiyun #define LZMA_IS_REP_G2 (LZMA_IS_REP_G1 + LZMA_NUM_STATES)
265*4882a593Smuzhiyun #define LZMA_IS_REP_0_LONG (LZMA_IS_REP_G2 + LZMA_NUM_STATES)
266*4882a593Smuzhiyun #define LZMA_POS_SLOT (LZMA_IS_REP_0_LONG \
267*4882a593Smuzhiyun 		       + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX))
268*4882a593Smuzhiyun #define LZMA_SPEC_POS (LZMA_POS_SLOT \
269*4882a593Smuzhiyun 		       +(LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS))
270*4882a593Smuzhiyun #define LZMA_ALIGN (LZMA_SPEC_POS \
271*4882a593Smuzhiyun 		    + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX)
272*4882a593Smuzhiyun #define LZMA_LEN_CODER (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS))
273*4882a593Smuzhiyun #define LZMA_REP_LEN_CODER (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS)
274*4882a593Smuzhiyun #define LZMA_LITERAL (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS)
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun struct writer {
278*4882a593Smuzhiyun 	uint8_t *buffer;
279*4882a593Smuzhiyun 	uint8_t previous_byte;
280*4882a593Smuzhiyun 	size_t buffer_pos;
281*4882a593Smuzhiyun 	int bufsize;
282*4882a593Smuzhiyun 	size_t global_pos;
283*4882a593Smuzhiyun 	long (*flush)(void*, unsigned long);
284*4882a593Smuzhiyun 	struct lzma_header *header;
285*4882a593Smuzhiyun };
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun struct cstate {
288*4882a593Smuzhiyun 	int state;
289*4882a593Smuzhiyun 	uint32_t rep0, rep1, rep2, rep3;
290*4882a593Smuzhiyun };
291*4882a593Smuzhiyun 
get_pos(struct writer * wr)292*4882a593Smuzhiyun static inline size_t INIT get_pos(struct writer *wr)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun 	return
295*4882a593Smuzhiyun 		wr->global_pos + wr->buffer_pos;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun 
peek_old_byte(struct writer * wr,uint32_t offs)298*4882a593Smuzhiyun static inline uint8_t INIT peek_old_byte(struct writer *wr,
299*4882a593Smuzhiyun 						uint32_t offs)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun 	if (!wr->flush) {
302*4882a593Smuzhiyun 		int32_t pos;
303*4882a593Smuzhiyun 		while (offs > wr->header->dict_size)
304*4882a593Smuzhiyun 			offs -= wr->header->dict_size;
305*4882a593Smuzhiyun 		pos = wr->buffer_pos - offs;
306*4882a593Smuzhiyun 		return wr->buffer[pos];
307*4882a593Smuzhiyun 	} else {
308*4882a593Smuzhiyun 		uint32_t pos = wr->buffer_pos - offs;
309*4882a593Smuzhiyun 		while (pos >= wr->header->dict_size)
310*4882a593Smuzhiyun 			pos += wr->header->dict_size;
311*4882a593Smuzhiyun 		return wr->buffer[pos];
312*4882a593Smuzhiyun 	}
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
write_byte(struct writer * wr,uint8_t byte)316*4882a593Smuzhiyun static inline int INIT write_byte(struct writer *wr, uint8_t byte)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
319*4882a593Smuzhiyun 	if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
320*4882a593Smuzhiyun 		wr->buffer_pos = 0;
321*4882a593Smuzhiyun 		wr->global_pos += wr->header->dict_size;
322*4882a593Smuzhiyun 		if (wr->flush((char *)wr->buffer, wr->header->dict_size)
323*4882a593Smuzhiyun 				!= wr->header->dict_size)
324*4882a593Smuzhiyun 			return -1;
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 	return 0;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 
copy_byte(struct writer * wr,uint32_t offs)330*4882a593Smuzhiyun static inline int INIT copy_byte(struct writer *wr, uint32_t offs)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	return write_byte(wr, peek_old_byte(wr, offs));
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
copy_bytes(struct writer * wr,uint32_t rep0,int len)335*4882a593Smuzhiyun static inline int INIT copy_bytes(struct writer *wr,
336*4882a593Smuzhiyun 					 uint32_t rep0, int len)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun 	do {
339*4882a593Smuzhiyun 		if (copy_byte(wr, rep0))
340*4882a593Smuzhiyun 			return -1;
341*4882a593Smuzhiyun 		len--;
342*4882a593Smuzhiyun 	} while (len != 0 && wr->buffer_pos < wr->header->dst_size);
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	return len;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
process_bit0(struct writer * wr,struct rc * rc,struct cstate * cst,uint16_t * p,int pos_state,uint16_t * prob,int lc,uint32_t literal_pos_mask)347*4882a593Smuzhiyun static inline int INIT process_bit0(struct writer *wr, struct rc *rc,
348*4882a593Smuzhiyun 				     struct cstate *cst, uint16_t *p,
349*4882a593Smuzhiyun 				     int pos_state, uint16_t *prob,
350*4882a593Smuzhiyun 				     int lc, uint32_t literal_pos_mask) {
351*4882a593Smuzhiyun 	int mi = 1;
352*4882a593Smuzhiyun 	rc_update_bit_0(rc, prob);
353*4882a593Smuzhiyun 	prob = (p + LZMA_LITERAL +
354*4882a593Smuzhiyun 		(LZMA_LIT_SIZE
355*4882a593Smuzhiyun 		 * (((get_pos(wr) & literal_pos_mask) << lc)
356*4882a593Smuzhiyun 		    + (wr->previous_byte >> (8 - lc))))
357*4882a593Smuzhiyun 		);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	if (cst->state >= LZMA_NUM_LIT_STATES) {
360*4882a593Smuzhiyun 		int match_byte = peek_old_byte(wr, cst->rep0);
361*4882a593Smuzhiyun 		do {
362*4882a593Smuzhiyun 			int bit;
363*4882a593Smuzhiyun 			uint16_t *prob_lit;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 			match_byte <<= 1;
366*4882a593Smuzhiyun 			bit = match_byte & 0x100;
367*4882a593Smuzhiyun 			prob_lit = prob + 0x100 + bit + mi;
368*4882a593Smuzhiyun 			if (rc_get_bit(rc, prob_lit, &mi)) {
369*4882a593Smuzhiyun 				if (!bit)
370*4882a593Smuzhiyun 					break;
371*4882a593Smuzhiyun 			} else {
372*4882a593Smuzhiyun 				if (bit)
373*4882a593Smuzhiyun 					break;
374*4882a593Smuzhiyun 			}
375*4882a593Smuzhiyun 		} while (mi < 0x100);
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun 	while (mi < 0x100) {
378*4882a593Smuzhiyun 		uint16_t *prob_lit = prob + mi;
379*4882a593Smuzhiyun 		rc_get_bit(rc, prob_lit, &mi);
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 	if (cst->state < 4)
382*4882a593Smuzhiyun 		cst->state = 0;
383*4882a593Smuzhiyun 	else if (cst->state < 10)
384*4882a593Smuzhiyun 		cst->state -= 3;
385*4882a593Smuzhiyun 	else
386*4882a593Smuzhiyun 		cst->state -= 6;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	return write_byte(wr, mi);
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
process_bit1(struct writer * wr,struct rc * rc,struct cstate * cst,uint16_t * p,int pos_state,uint16_t * prob)391*4882a593Smuzhiyun static inline int INIT process_bit1(struct writer *wr, struct rc *rc,
392*4882a593Smuzhiyun 					    struct cstate *cst, uint16_t *p,
393*4882a593Smuzhiyun 					    int pos_state, uint16_t *prob) {
394*4882a593Smuzhiyun   int offset;
395*4882a593Smuzhiyun 	uint16_t *prob_len;
396*4882a593Smuzhiyun 	int num_bits;
397*4882a593Smuzhiyun 	int len;
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	rc_update_bit_1(rc, prob);
400*4882a593Smuzhiyun 	prob = p + LZMA_IS_REP + cst->state;
401*4882a593Smuzhiyun 	if (rc_is_bit_0(rc, prob)) {
402*4882a593Smuzhiyun 		rc_update_bit_0(rc, prob);
403*4882a593Smuzhiyun 		cst->rep3 = cst->rep2;
404*4882a593Smuzhiyun 		cst->rep2 = cst->rep1;
405*4882a593Smuzhiyun 		cst->rep1 = cst->rep0;
406*4882a593Smuzhiyun 		cst->state = cst->state < LZMA_NUM_LIT_STATES ? 0 : 3;
407*4882a593Smuzhiyun 		prob = p + LZMA_LEN_CODER;
408*4882a593Smuzhiyun 	} else {
409*4882a593Smuzhiyun 		rc_update_bit_1(rc, prob);
410*4882a593Smuzhiyun 		prob = p + LZMA_IS_REP_G0 + cst->state;
411*4882a593Smuzhiyun 		if (rc_is_bit_0(rc, prob)) {
412*4882a593Smuzhiyun 			rc_update_bit_0(rc, prob);
413*4882a593Smuzhiyun 			prob = (p + LZMA_IS_REP_0_LONG
414*4882a593Smuzhiyun 				+ (cst->state <<
415*4882a593Smuzhiyun 				   LZMA_NUM_POS_BITS_MAX) +
416*4882a593Smuzhiyun 				pos_state);
417*4882a593Smuzhiyun 			if (rc_is_bit_0(rc, prob)) {
418*4882a593Smuzhiyun 				rc_update_bit_0(rc, prob);
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 				cst->state = cst->state < LZMA_NUM_LIT_STATES ?
421*4882a593Smuzhiyun 					9 : 11;
422*4882a593Smuzhiyun 				return copy_byte(wr, cst->rep0);
423*4882a593Smuzhiyun 			} else {
424*4882a593Smuzhiyun 				rc_update_bit_1(rc, prob);
425*4882a593Smuzhiyun 			}
426*4882a593Smuzhiyun 		} else {
427*4882a593Smuzhiyun 			uint32_t distance;
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 			rc_update_bit_1(rc, prob);
430*4882a593Smuzhiyun 			prob = p + LZMA_IS_REP_G1 + cst->state;
431*4882a593Smuzhiyun 			if (rc_is_bit_0(rc, prob)) {
432*4882a593Smuzhiyun 				rc_update_bit_0(rc, prob);
433*4882a593Smuzhiyun 				distance = cst->rep1;
434*4882a593Smuzhiyun 			} else {
435*4882a593Smuzhiyun 				rc_update_bit_1(rc, prob);
436*4882a593Smuzhiyun 				prob = p + LZMA_IS_REP_G2 + cst->state;
437*4882a593Smuzhiyun 				if (rc_is_bit_0(rc, prob)) {
438*4882a593Smuzhiyun 					rc_update_bit_0(rc, prob);
439*4882a593Smuzhiyun 					distance = cst->rep2;
440*4882a593Smuzhiyun 				} else {
441*4882a593Smuzhiyun 					rc_update_bit_1(rc, prob);
442*4882a593Smuzhiyun 					distance = cst->rep3;
443*4882a593Smuzhiyun 					cst->rep3 = cst->rep2;
444*4882a593Smuzhiyun 				}
445*4882a593Smuzhiyun 				cst->rep2 = cst->rep1;
446*4882a593Smuzhiyun 			}
447*4882a593Smuzhiyun 			cst->rep1 = cst->rep0;
448*4882a593Smuzhiyun 			cst->rep0 = distance;
449*4882a593Smuzhiyun 		}
450*4882a593Smuzhiyun 		cst->state = cst->state < LZMA_NUM_LIT_STATES ? 8 : 11;
451*4882a593Smuzhiyun 		prob = p + LZMA_REP_LEN_CODER;
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun 	prob_len = prob + LZMA_LEN_CHOICE;
455*4882a593Smuzhiyun 	if (rc_is_bit_0(rc, prob_len)) {
456*4882a593Smuzhiyun 		rc_update_bit_0(rc, prob_len);
457*4882a593Smuzhiyun 		prob_len = (prob + LZMA_LEN_LOW
458*4882a593Smuzhiyun 			    + (pos_state <<
459*4882a593Smuzhiyun 			       LZMA_LEN_NUM_LOW_BITS));
460*4882a593Smuzhiyun 		offset = 0;
461*4882a593Smuzhiyun 		num_bits = LZMA_LEN_NUM_LOW_BITS;
462*4882a593Smuzhiyun 	} else {
463*4882a593Smuzhiyun 		rc_update_bit_1(rc, prob_len);
464*4882a593Smuzhiyun 		prob_len = prob + LZMA_LEN_CHOICE_2;
465*4882a593Smuzhiyun 		if (rc_is_bit_0(rc, prob_len)) {
466*4882a593Smuzhiyun 			rc_update_bit_0(rc, prob_len);
467*4882a593Smuzhiyun 			prob_len = (prob + LZMA_LEN_MID
468*4882a593Smuzhiyun 				    + (pos_state <<
469*4882a593Smuzhiyun 				       LZMA_LEN_NUM_MID_BITS));
470*4882a593Smuzhiyun 			offset = 1 << LZMA_LEN_NUM_LOW_BITS;
471*4882a593Smuzhiyun 			num_bits = LZMA_LEN_NUM_MID_BITS;
472*4882a593Smuzhiyun 		} else {
473*4882a593Smuzhiyun 			rc_update_bit_1(rc, prob_len);
474*4882a593Smuzhiyun 			prob_len = prob + LZMA_LEN_HIGH;
475*4882a593Smuzhiyun 			offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
476*4882a593Smuzhiyun 				  + (1 << LZMA_LEN_NUM_MID_BITS));
477*4882a593Smuzhiyun 			num_bits = LZMA_LEN_NUM_HIGH_BITS;
478*4882a593Smuzhiyun 		}
479*4882a593Smuzhiyun 	}
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	rc_bit_tree_decode(rc, prob_len, num_bits, &len);
482*4882a593Smuzhiyun 	len += offset;
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	if (cst->state < 4) {
485*4882a593Smuzhiyun 		int pos_slot;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 		cst->state += LZMA_NUM_LIT_STATES;
488*4882a593Smuzhiyun 		prob =
489*4882a593Smuzhiyun 			p + LZMA_POS_SLOT +
490*4882a593Smuzhiyun 			((len <
491*4882a593Smuzhiyun 			  LZMA_NUM_LEN_TO_POS_STATES ? len :
492*4882a593Smuzhiyun 			  LZMA_NUM_LEN_TO_POS_STATES - 1)
493*4882a593Smuzhiyun 			 << LZMA_NUM_POS_SLOT_BITS);
494*4882a593Smuzhiyun 		rc_bit_tree_decode(rc, prob,
495*4882a593Smuzhiyun 				   LZMA_NUM_POS_SLOT_BITS,
496*4882a593Smuzhiyun 				   &pos_slot);
497*4882a593Smuzhiyun 		if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
498*4882a593Smuzhiyun 			int i, mi;
499*4882a593Smuzhiyun 			num_bits = (pos_slot >> 1) - 1;
500*4882a593Smuzhiyun 			cst->rep0 = 2 | (pos_slot & 1);
501*4882a593Smuzhiyun 			if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
502*4882a593Smuzhiyun 				cst->rep0 <<= num_bits;
503*4882a593Smuzhiyun 				prob = p + LZMA_SPEC_POS +
504*4882a593Smuzhiyun 					cst->rep0 - pos_slot - 1;
505*4882a593Smuzhiyun 			} else {
506*4882a593Smuzhiyun 				num_bits -= LZMA_NUM_ALIGN_BITS;
507*4882a593Smuzhiyun 				while (num_bits--)
508*4882a593Smuzhiyun 					cst->rep0 = (cst->rep0 << 1) |
509*4882a593Smuzhiyun 						rc_direct_bit(rc);
510*4882a593Smuzhiyun 				prob = p + LZMA_ALIGN;
511*4882a593Smuzhiyun 				cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
512*4882a593Smuzhiyun 				num_bits = LZMA_NUM_ALIGN_BITS;
513*4882a593Smuzhiyun 			}
514*4882a593Smuzhiyun 			i = 1;
515*4882a593Smuzhiyun 			mi = 1;
516*4882a593Smuzhiyun 			while (num_bits--) {
517*4882a593Smuzhiyun 				if (rc_get_bit(rc, prob + mi, &mi))
518*4882a593Smuzhiyun 					cst->rep0 |= i;
519*4882a593Smuzhiyun 				i <<= 1;
520*4882a593Smuzhiyun 			}
521*4882a593Smuzhiyun 		} else
522*4882a593Smuzhiyun 			cst->rep0 = pos_slot;
523*4882a593Smuzhiyun 		if (++(cst->rep0) == 0)
524*4882a593Smuzhiyun 			return 0;
525*4882a593Smuzhiyun 		if (cst->rep0 > wr->header->dict_size
526*4882a593Smuzhiyun 				|| cst->rep0 > get_pos(wr))
527*4882a593Smuzhiyun 			return -1;
528*4882a593Smuzhiyun 	}
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	len += LZMA_MATCH_MIN_LEN;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	return copy_bytes(wr, cst->rep0, len);
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 
unlzma(unsigned char * buf,long in_len,long (* fill)(void *,unsigned long),long (* flush)(void *,unsigned long),unsigned char * output,long * posp,void (* error)(char * x))537*4882a593Smuzhiyun STATIC inline int INIT unlzma(unsigned char *buf, long in_len,
538*4882a593Smuzhiyun 			      long (*fill)(void*, unsigned long),
539*4882a593Smuzhiyun 			      long (*flush)(void*, unsigned long),
540*4882a593Smuzhiyun 			      unsigned char *output,
541*4882a593Smuzhiyun 			      long *posp,
542*4882a593Smuzhiyun 			      void(*error)(char *x)
543*4882a593Smuzhiyun 	)
544*4882a593Smuzhiyun {
545*4882a593Smuzhiyun 	struct lzma_header header;
546*4882a593Smuzhiyun 	int lc, pb, lp;
547*4882a593Smuzhiyun 	uint32_t pos_state_mask;
548*4882a593Smuzhiyun 	uint32_t literal_pos_mask;
549*4882a593Smuzhiyun 	uint16_t *p;
550*4882a593Smuzhiyun 	int num_probs;
551*4882a593Smuzhiyun 	struct rc rc;
552*4882a593Smuzhiyun 	int i, mi;
553*4882a593Smuzhiyun 	struct writer wr;
554*4882a593Smuzhiyun 	struct cstate cst;
555*4882a593Smuzhiyun 	unsigned char *inbuf;
556*4882a593Smuzhiyun 	int ret = -1;
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	rc.error = error;
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun 	if (buf)
561*4882a593Smuzhiyun 		inbuf = buf;
562*4882a593Smuzhiyun 	else
563*4882a593Smuzhiyun 		inbuf = malloc(LZMA_IOBUF_SIZE);
564*4882a593Smuzhiyun 	if (!inbuf) {
565*4882a593Smuzhiyun 		error("Could not allocate input buffer");
566*4882a593Smuzhiyun 		goto exit_0;
567*4882a593Smuzhiyun 	}
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	cst.state = 0;
570*4882a593Smuzhiyun 	cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	wr.header = &header;
573*4882a593Smuzhiyun 	wr.flush = flush;
574*4882a593Smuzhiyun 	wr.global_pos = 0;
575*4882a593Smuzhiyun 	wr.previous_byte = 0;
576*4882a593Smuzhiyun 	wr.buffer_pos = 0;
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	rc_init(&rc, fill, inbuf, in_len);
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	for (i = 0; i < sizeof(header); i++) {
581*4882a593Smuzhiyun 		if (rc.ptr >= rc.buffer_end)
582*4882a593Smuzhiyun 			rc_read(&rc);
583*4882a593Smuzhiyun 		((unsigned char *)&header)[i] = *rc.ptr++;
584*4882a593Smuzhiyun 	}
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	if (header.pos >= (9 * 5 * 5)) {
587*4882a593Smuzhiyun 		error("bad header");
588*4882a593Smuzhiyun 		goto exit_1;
589*4882a593Smuzhiyun 	}
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	mi = 0;
592*4882a593Smuzhiyun 	lc = header.pos;
593*4882a593Smuzhiyun 	while (lc >= 9) {
594*4882a593Smuzhiyun 		mi++;
595*4882a593Smuzhiyun 		lc -= 9;
596*4882a593Smuzhiyun 	}
597*4882a593Smuzhiyun 	pb = 0;
598*4882a593Smuzhiyun 	lp = mi;
599*4882a593Smuzhiyun 	while (lp >= 5) {
600*4882a593Smuzhiyun 		pb++;
601*4882a593Smuzhiyun 		lp -= 5;
602*4882a593Smuzhiyun 	}
603*4882a593Smuzhiyun 	pos_state_mask = (1 << pb) - 1;
604*4882a593Smuzhiyun 	literal_pos_mask = (1 << lp) - 1;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	ENDIAN_CONVERT(header.dict_size);
607*4882a593Smuzhiyun 	ENDIAN_CONVERT(header.dst_size);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	if (header.dict_size == 0)
610*4882a593Smuzhiyun 		header.dict_size = 1;
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	if (output)
613*4882a593Smuzhiyun 		wr.buffer = output;
614*4882a593Smuzhiyun 	else {
615*4882a593Smuzhiyun 		wr.bufsize = MIN(header.dst_size, header.dict_size);
616*4882a593Smuzhiyun 		wr.buffer = large_malloc(wr.bufsize);
617*4882a593Smuzhiyun 	}
618*4882a593Smuzhiyun 	if (wr.buffer == NULL)
619*4882a593Smuzhiyun 		goto exit_1;
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
622*4882a593Smuzhiyun 	p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
623*4882a593Smuzhiyun 	if (p == NULL)
624*4882a593Smuzhiyun 		goto exit_2;
625*4882a593Smuzhiyun 	num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
626*4882a593Smuzhiyun 	for (i = 0; i < num_probs; i++)
627*4882a593Smuzhiyun 		p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	rc_init_code(&rc);
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	while (get_pos(&wr) < header.dst_size) {
632*4882a593Smuzhiyun 		int pos_state =	get_pos(&wr) & pos_state_mask;
633*4882a593Smuzhiyun 		uint16_t *prob = p + LZMA_IS_MATCH +
634*4882a593Smuzhiyun 			(cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
635*4882a593Smuzhiyun 		if (rc_is_bit_0(&rc, prob)) {
636*4882a593Smuzhiyun 			if (process_bit0(&wr, &rc, &cst, p, pos_state, prob,
637*4882a593Smuzhiyun 					lc, literal_pos_mask)) {
638*4882a593Smuzhiyun 				error("LZMA data is corrupt");
639*4882a593Smuzhiyun 				goto exit_3;
640*4882a593Smuzhiyun 			}
641*4882a593Smuzhiyun 		} else {
642*4882a593Smuzhiyun 			if (process_bit1(&wr, &rc, &cst, p, pos_state, prob)) {
643*4882a593Smuzhiyun 				error("LZMA data is corrupt");
644*4882a593Smuzhiyun 				goto exit_3;
645*4882a593Smuzhiyun 			}
646*4882a593Smuzhiyun 			if (cst.rep0 == 0)
647*4882a593Smuzhiyun 				break;
648*4882a593Smuzhiyun 		}
649*4882a593Smuzhiyun 		if (rc.buffer_size <= 0)
650*4882a593Smuzhiyun 			goto exit_3;
651*4882a593Smuzhiyun 	}
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	if (posp)
654*4882a593Smuzhiyun 		*posp = rc.ptr-rc.buffer;
655*4882a593Smuzhiyun 	if (!wr.flush || wr.flush(wr.buffer, wr.buffer_pos) == wr.buffer_pos)
656*4882a593Smuzhiyun 		ret = 0;
657*4882a593Smuzhiyun exit_3:
658*4882a593Smuzhiyun 	large_free(p);
659*4882a593Smuzhiyun exit_2:
660*4882a593Smuzhiyun 	if (!output)
661*4882a593Smuzhiyun 		large_free(wr.buffer);
662*4882a593Smuzhiyun exit_1:
663*4882a593Smuzhiyun 	if (!buf)
664*4882a593Smuzhiyun 		free(inbuf);
665*4882a593Smuzhiyun exit_0:
666*4882a593Smuzhiyun 	return ret;
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun #ifdef PREBOOT
__decompress(unsigned char * buf,long in_len,long (* fill)(void *,unsigned long),long (* flush)(void *,unsigned long),unsigned char * output,long out_len,long * posp,void (* error)(char * x))670*4882a593Smuzhiyun STATIC int INIT __decompress(unsigned char *buf, long in_len,
671*4882a593Smuzhiyun 			      long (*fill)(void*, unsigned long),
672*4882a593Smuzhiyun 			      long (*flush)(void*, unsigned long),
673*4882a593Smuzhiyun 			      unsigned char *output, long out_len,
674*4882a593Smuzhiyun 			      long *posp,
675*4882a593Smuzhiyun 			      void (*error)(char *x))
676*4882a593Smuzhiyun {
677*4882a593Smuzhiyun 	return unlzma(buf, in_len - 4, fill, flush, output, posp, error);
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun #endif
680