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