1229159Sadrian/* 2229159Sadrian * Branch/Call/Jump (BCJ) filter decoders 3229159Sadrian * 4229159Sadrian * Authors: Lasse Collin <lasse.collin@tukaani.org> 5229159Sadrian * Igor Pavlov <http://7-zip.org/> 6229159Sadrian * 7229159Sadrian * This file has been put into the public domain. 8229159Sadrian * You can do whatever you want with this file. 9229159Sadrian */ 10229159Sadrian 11229159Sadrian#include "xz_private.h" 12229159Sadrian 13229159Sadrian/* 14229159Sadrian * The rest of the file is inside this ifdef. It makes things a little more 15229159Sadrian * convenient when building without support for any BCJ filters. 16229159Sadrian */ 17229159Sadrian#ifdef XZ_DEC_BCJ 18229159Sadrian 19229159Sadrianstruct xz_dec_bcj { 20229159Sadrian /* Type of the BCJ filter being used */ 21229159Sadrian enum { 22229159Sadrian BCJ_X86 = 4, /* x86 or x86-64 */ 23229159Sadrian BCJ_POWERPC = 5, /* Big endian only */ 24229159Sadrian BCJ_IA64 = 6, /* Big or little endian */ 25229159Sadrian BCJ_ARM = 7, /* Little endian only */ 26229159Sadrian BCJ_ARMTHUMB = 8, /* Little endian only */ 27229159Sadrian BCJ_SPARC = 9 /* Big or little endian */ 28229159Sadrian } type; 29229159Sadrian 30229159Sadrian /* 31229159Sadrian * Return value of the next filter in the chain. We need to preserve 32229159Sadrian * this information across calls, because we must not call the next 33229159Sadrian * filter anymore once it has returned XZ_STREAM_END. 34229159Sadrian */ 35229159Sadrian enum xz_ret ret; 36229159Sadrian 37229159Sadrian /* True if we are operating in single-call mode. */ 38229159Sadrian bool single_call; 39229159Sadrian 40229159Sadrian /* 41229159Sadrian * Absolute position relative to the beginning of the uncompressed 42229159Sadrian * data (in a single .xz Block). We care only about the lowest 32 43229159Sadrian * bits so this doesn't need to be uint64_t even with big files. 44229159Sadrian */ 45229159Sadrian uint32_t pos; 46229159Sadrian 47229159Sadrian /* x86 filter state */ 48229159Sadrian uint32_t x86_prev_mask; 49229159Sadrian 50229159Sadrian /* Temporary space to hold the variables from struct xz_buf */ 51229159Sadrian uint8_t *out; 52229159Sadrian size_t out_pos; 53229159Sadrian size_t out_size; 54229159Sadrian 55229159Sadrian struct { 56229159Sadrian /* Amount of already filtered data in the beginning of buf */ 57229159Sadrian size_t filtered; 58229159Sadrian 59229159Sadrian /* Total amount of data currently stored in buf */ 60229159Sadrian size_t size; 61229159Sadrian 62229159Sadrian /* 63229159Sadrian * Buffer to hold a mix of filtered and unfiltered data. This 64229159Sadrian * needs to be big enough to hold Alignment + 2 * Look-ahead: 65229159Sadrian * 66229159Sadrian * Type Alignment Look-ahead 67229159Sadrian * x86 1 4 68229159Sadrian * PowerPC 4 0 69229159Sadrian * IA-64 16 0 70229159Sadrian * ARM 4 0 71229159Sadrian * ARM-Thumb 2 2 72229159Sadrian * SPARC 4 0 73229159Sadrian */ 74229159Sadrian uint8_t buf[16]; 75229159Sadrian } temp; 76229159Sadrian}; 77229159Sadrian 78229159Sadrian#ifdef XZ_DEC_X86 79229159Sadrian/* 80229159Sadrian * This is used to test the most significant byte of a memory address 81229159Sadrian * in an x86 instruction. 82229159Sadrian */ 83229159Sadrianstatic inline int bcj_x86_test_msbyte(uint8_t b) 84229159Sadrian{ 85229159Sadrian return b == 0x00 || b == 0xFF; 86229159Sadrian} 87229159Sadrian 88229159Sadrianstatic size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 89229159Sadrian{ 90229159Sadrian static const bool mask_to_allowed_status[8] 91229159Sadrian = { true, true, true, false, true, false, false, false }; 92229159Sadrian 93229159Sadrian static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; 94229159Sadrian 95229159Sadrian size_t i; 96229159Sadrian size_t prev_pos = (size_t)-1; 97229159Sadrian uint32_t prev_mask = s->x86_prev_mask; 98229159Sadrian uint32_t src; 99229159Sadrian uint32_t dest; 100229159Sadrian uint32_t j; 101229159Sadrian uint8_t b; 102229159Sadrian 103229159Sadrian if (size <= 4) 104229159Sadrian return 0; 105229159Sadrian 106229159Sadrian size -= 4; 107229159Sadrian for (i = 0; i < size; ++i) { 108229159Sadrian if ((buf[i] & 0xFE) != 0xE8) 109229159Sadrian continue; 110229159Sadrian 111229159Sadrian prev_pos = i - prev_pos; 112229159Sadrian if (prev_pos > 3) { 113229159Sadrian prev_mask = 0; 114229159Sadrian } else { 115229159Sadrian prev_mask = (prev_mask << (prev_pos - 1)) & 7; 116229159Sadrian if (prev_mask != 0) { 117229159Sadrian b = buf[i + 4 - mask_to_bit_num[prev_mask]]; 118229159Sadrian if (!mask_to_allowed_status[prev_mask] 119229159Sadrian || bcj_x86_test_msbyte(b)) { 120229159Sadrian prev_pos = i; 121229159Sadrian prev_mask = (prev_mask << 1) | 1; 122229159Sadrian continue; 123229159Sadrian } 124229159Sadrian } 125229159Sadrian } 126229159Sadrian 127229159Sadrian prev_pos = i; 128229159Sadrian 129229159Sadrian if (bcj_x86_test_msbyte(buf[i + 4])) { 130229159Sadrian src = get_unaligned_le32(buf + i + 1); 131229159Sadrian while (true) { 132229159Sadrian dest = src - (s->pos + (uint32_t)i + 5); 133229159Sadrian if (prev_mask == 0) 134229159Sadrian break; 135229159Sadrian 136229159Sadrian j = mask_to_bit_num[prev_mask] * 8; 137229159Sadrian b = (uint8_t)(dest >> (24 - j)); 138229159Sadrian if (!bcj_x86_test_msbyte(b)) 139229159Sadrian break; 140229159Sadrian 141229159Sadrian src = dest ^ (((uint32_t)1 << (32 - j)) - 1); 142229159Sadrian } 143229159Sadrian 144229159Sadrian dest &= 0x01FFFFFF; 145229159Sadrian dest |= (uint32_t)0 - (dest & 0x01000000); 146229159Sadrian put_unaligned_le32(dest, buf + i + 1); 147229159Sadrian i += 4; 148229159Sadrian } else { 149229159Sadrian prev_mask = (prev_mask << 1) | 1; 150229159Sadrian } 151229159Sadrian } 152229159Sadrian 153229159Sadrian prev_pos = i - prev_pos; 154229159Sadrian s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1); 155229159Sadrian return i; 156229159Sadrian} 157229159Sadrian#endif 158229159Sadrian 159229159Sadrian#ifdef XZ_DEC_POWERPC 160229159Sadrianstatic size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 161229159Sadrian{ 162229159Sadrian size_t i; 163229159Sadrian uint32_t instr; 164229159Sadrian 165229159Sadrian for (i = 0; i + 4 <= size; i += 4) { 166229159Sadrian instr = get_unaligned_be32(buf + i); 167229159Sadrian if ((instr & 0xFC000003) == 0x48000001) { 168229159Sadrian instr &= 0x03FFFFFC; 169229159Sadrian instr -= s->pos + (uint32_t)i; 170229159Sadrian instr &= 0x03FFFFFC; 171229159Sadrian instr |= 0x48000001; 172229159Sadrian put_unaligned_be32(instr, buf + i); 173229159Sadrian } 174229159Sadrian } 175229159Sadrian 176229159Sadrian return i; 177229159Sadrian} 178229159Sadrian#endif 179229159Sadrian 180229159Sadrian#ifdef XZ_DEC_IA64 181229159Sadrianstatic size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 182229159Sadrian{ 183229159Sadrian static const uint8_t branch_table[32] = { 184229159Sadrian 0, 0, 0, 0, 0, 0, 0, 0, 185229159Sadrian 0, 0, 0, 0, 0, 0, 0, 0, 186229159Sadrian 4, 4, 6, 6, 0, 0, 7, 7, 187229159Sadrian 4, 4, 0, 0, 4, 4, 0, 0 188229159Sadrian }; 189229159Sadrian 190229159Sadrian /* 191229159Sadrian * The local variables take a little bit stack space, but it's less 192229159Sadrian * than what LZMA2 decoder takes, so it doesn't make sense to reduce 193229159Sadrian * stack usage here without doing that for the LZMA2 decoder too. 194229159Sadrian */ 195229159Sadrian 196229159Sadrian /* Loop counters */ 197229159Sadrian size_t i; 198229159Sadrian size_t j; 199229159Sadrian 200229159Sadrian /* Instruction slot (0, 1, or 2) in the 128-bit instruction word */ 201229159Sadrian uint32_t slot; 202229159Sadrian 203229159Sadrian /* Bitwise offset of the instruction indicated by slot */ 204229159Sadrian uint32_t bit_pos; 205229159Sadrian 206229159Sadrian /* bit_pos split into byte and bit parts */ 207229159Sadrian uint32_t byte_pos; 208229159Sadrian uint32_t bit_res; 209229159Sadrian 210229159Sadrian /* Address part of an instruction */ 211229159Sadrian uint32_t addr; 212229159Sadrian 213229159Sadrian /* Mask used to detect which instructions to convert */ 214229159Sadrian uint32_t mask; 215229159Sadrian 216229159Sadrian /* 41-bit instruction stored somewhere in the lowest 48 bits */ 217229159Sadrian uint64_t instr; 218229159Sadrian 219229159Sadrian /* Instruction normalized with bit_res for easier manipulation */ 220229159Sadrian uint64_t norm; 221229159Sadrian 222229159Sadrian for (i = 0; i + 16 <= size; i += 16) { 223229159Sadrian mask = branch_table[buf[i] & 0x1F]; 224229159Sadrian for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) { 225229159Sadrian if (((mask >> slot) & 1) == 0) 226229159Sadrian continue; 227229159Sadrian 228229159Sadrian byte_pos = bit_pos >> 3; 229229159Sadrian bit_res = bit_pos & 7; 230229159Sadrian instr = 0; 231229159Sadrian for (j = 0; j < 6; ++j) 232229159Sadrian instr |= (uint64_t)(buf[i + j + byte_pos]) 233229159Sadrian << (8 * j); 234229159Sadrian 235229159Sadrian norm = instr >> bit_res; 236229159Sadrian 237229159Sadrian if (((norm >> 37) & 0x0F) == 0x05 238229159Sadrian && ((norm >> 9) & 0x07) == 0) { 239229159Sadrian addr = (norm >> 13) & 0x0FFFFF; 240229159Sadrian addr |= ((uint32_t)(norm >> 36) & 1) << 20; 241229159Sadrian addr <<= 4; 242229159Sadrian addr -= s->pos + (uint32_t)i; 243229159Sadrian addr >>= 4; 244229159Sadrian 245229159Sadrian norm &= ~((uint64_t)0x8FFFFF << 13); 246229159Sadrian norm |= (uint64_t)(addr & 0x0FFFFF) << 13; 247229159Sadrian norm |= (uint64_t)(addr & 0x100000) 248229159Sadrian << (36 - 20); 249229159Sadrian 250229159Sadrian instr &= (1 << bit_res) - 1; 251229159Sadrian instr |= norm << bit_res; 252229159Sadrian 253229159Sadrian for (j = 0; j < 6; j++) 254229159Sadrian buf[i + j + byte_pos] 255229159Sadrian = (uint8_t)(instr >> (8 * j)); 256229159Sadrian } 257229159Sadrian } 258229159Sadrian } 259229159Sadrian 260229159Sadrian return i; 261229159Sadrian} 262229159Sadrian#endif 263229159Sadrian 264229159Sadrian#ifdef XZ_DEC_ARM 265229159Sadrianstatic size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 266229159Sadrian{ 267229159Sadrian size_t i; 268229159Sadrian uint32_t addr; 269229159Sadrian 270229159Sadrian for (i = 0; i + 4 <= size; i += 4) { 271229159Sadrian if (buf[i + 3] == 0xEB) { 272229159Sadrian addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) 273229159Sadrian | ((uint32_t)buf[i + 2] << 16); 274229159Sadrian addr <<= 2; 275229159Sadrian addr -= s->pos + (uint32_t)i + 8; 276229159Sadrian addr >>= 2; 277229159Sadrian buf[i] = (uint8_t)addr; 278229159Sadrian buf[i + 1] = (uint8_t)(addr >> 8); 279229159Sadrian buf[i + 2] = (uint8_t)(addr >> 16); 280229159Sadrian } 281229159Sadrian } 282229159Sadrian 283229159Sadrian return i; 284229159Sadrian} 285229159Sadrian#endif 286229159Sadrian 287229159Sadrian#ifdef XZ_DEC_ARMTHUMB 288229159Sadrianstatic size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 289229159Sadrian{ 290229159Sadrian size_t i; 291229159Sadrian uint32_t addr; 292229159Sadrian 293229159Sadrian for (i = 0; i + 4 <= size; i += 2) { 294229159Sadrian if ((buf[i + 1] & 0xF8) == 0xF0 295229159Sadrian && (buf[i + 3] & 0xF8) == 0xF8) { 296229159Sadrian addr = (((uint32_t)buf[i + 1] & 0x07) << 19) 297229159Sadrian | ((uint32_t)buf[i] << 11) 298229159Sadrian | (((uint32_t)buf[i + 3] & 0x07) << 8) 299229159Sadrian | (uint32_t)buf[i + 2]; 300229159Sadrian addr <<= 1; 301229159Sadrian addr -= s->pos + (uint32_t)i + 4; 302229159Sadrian addr >>= 1; 303229159Sadrian buf[i + 1] = (uint8_t)(0xF0 | ((addr >> 19) & 0x07)); 304229159Sadrian buf[i] = (uint8_t)(addr >> 11); 305229159Sadrian buf[i + 3] = (uint8_t)(0xF8 | ((addr >> 8) & 0x07)); 306229159Sadrian buf[i + 2] = (uint8_t)addr; 307229159Sadrian i += 2; 308229159Sadrian } 309229159Sadrian } 310229159Sadrian 311229159Sadrian return i; 312229159Sadrian} 313229159Sadrian#endif 314229159Sadrian 315229159Sadrian#ifdef XZ_DEC_SPARC 316229159Sadrianstatic size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size) 317229159Sadrian{ 318229159Sadrian size_t i; 319229159Sadrian uint32_t instr; 320229159Sadrian 321229159Sadrian for (i = 0; i + 4 <= size; i += 4) { 322229159Sadrian instr = get_unaligned_be32(buf + i); 323229159Sadrian if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) { 324229159Sadrian instr <<= 2; 325229159Sadrian instr -= s->pos + (uint32_t)i; 326229159Sadrian instr >>= 2; 327229159Sadrian instr = ((uint32_t)0x40000000 - (instr & 0x400000)) 328229159Sadrian | 0x40000000 | (instr & 0x3FFFFF); 329229159Sadrian put_unaligned_be32(instr, buf + i); 330229159Sadrian } 331229159Sadrian } 332229159Sadrian 333229159Sadrian return i; 334229159Sadrian} 335229159Sadrian#endif 336229159Sadrian 337229159Sadrian/* 338229159Sadrian * Apply the selected BCJ filter. Update *pos and s->pos to match the amount 339229159Sadrian * of data that got filtered. 340229159Sadrian * 341229159Sadrian * NOTE: This is implemented as a switch statement to avoid using function 342229159Sadrian * pointers, which could be problematic in the kernel boot code, which must 343229159Sadrian * avoid pointers to static data (at least on x86). 344229159Sadrian */ 345229159Sadrianstatic void bcj_apply(struct xz_dec_bcj *s, 346229159Sadrian uint8_t *buf, size_t *pos, size_t size) 347229159Sadrian{ 348229159Sadrian size_t filtered; 349229159Sadrian 350229159Sadrian buf += *pos; 351229159Sadrian size -= *pos; 352229159Sadrian 353229159Sadrian switch (s->type) { 354229159Sadrian#ifdef XZ_DEC_X86 355229159Sadrian case BCJ_X86: 356229159Sadrian filtered = bcj_x86(s, buf, size); 357229159Sadrian break; 358229159Sadrian#endif 359229159Sadrian#ifdef XZ_DEC_POWERPC 360229159Sadrian case BCJ_POWERPC: 361229159Sadrian filtered = bcj_powerpc(s, buf, size); 362229159Sadrian break; 363229159Sadrian#endif 364229159Sadrian#ifdef XZ_DEC_IA64 365229159Sadrian case BCJ_IA64: 366229159Sadrian filtered = bcj_ia64(s, buf, size); 367229159Sadrian break; 368229159Sadrian#endif 369229159Sadrian#ifdef XZ_DEC_ARM 370229159Sadrian case BCJ_ARM: 371229159Sadrian filtered = bcj_arm(s, buf, size); 372229159Sadrian break; 373229159Sadrian#endif 374229159Sadrian#ifdef XZ_DEC_ARMTHUMB 375229159Sadrian case BCJ_ARMTHUMB: 376229159Sadrian filtered = bcj_armthumb(s, buf, size); 377229159Sadrian break; 378229159Sadrian#endif 379229159Sadrian#ifdef XZ_DEC_SPARC 380229159Sadrian case BCJ_SPARC: 381229159Sadrian filtered = bcj_sparc(s, buf, size); 382229159Sadrian break; 383229159Sadrian#endif 384229159Sadrian default: 385229159Sadrian /* Never reached but silence compiler warnings. */ 386229159Sadrian filtered = 0; 387229159Sadrian break; 388229159Sadrian } 389229159Sadrian 390229159Sadrian *pos += filtered; 391229159Sadrian s->pos += filtered; 392229159Sadrian} 393229159Sadrian 394229159Sadrian/* 395229159Sadrian * Flush pending filtered data from temp to the output buffer. 396229159Sadrian * Move the remaining mixture of possibly filtered and unfiltered 397229159Sadrian * data to the beginning of temp. 398229159Sadrian */ 399229159Sadrianstatic void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b) 400229159Sadrian{ 401229159Sadrian size_t copy_size; 402229159Sadrian 403229159Sadrian copy_size = min_t(size_t, s->temp.filtered, b->out_size - b->out_pos); 404229159Sadrian memcpy(b->out + b->out_pos, s->temp.buf, copy_size); 405229159Sadrian b->out_pos += copy_size; 406229159Sadrian 407229159Sadrian s->temp.filtered -= copy_size; 408229159Sadrian s->temp.size -= copy_size; 409229159Sadrian memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size); 410229159Sadrian} 411229159Sadrian 412229159Sadrian/* 413229159Sadrian * The BCJ filter functions are primitive in sense that they process the 414229159Sadrian * data in chunks of 1-16 bytes. To hide this issue, this function does 415229159Sadrian * some buffering. 416229159Sadrian */ 417229159SadrianXZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, 418229159Sadrian struct xz_dec_lzma2 *lzma2, 419229159Sadrian struct xz_buf *b) 420229159Sadrian{ 421229159Sadrian size_t out_start; 422229159Sadrian 423229159Sadrian /* 424229159Sadrian * Flush pending already filtered data to the output buffer. Return 425229159Sadrian * immediatelly if we couldn't flush everything, or if the next 426229159Sadrian * filter in the chain had already returned XZ_STREAM_END. 427229159Sadrian */ 428229159Sadrian if (s->temp.filtered > 0) { 429229159Sadrian bcj_flush(s, b); 430229159Sadrian if (s->temp.filtered > 0) 431229159Sadrian return XZ_OK; 432229159Sadrian 433229159Sadrian if (s->ret == XZ_STREAM_END) 434229159Sadrian return XZ_STREAM_END; 435229159Sadrian } 436229159Sadrian 437229159Sadrian /* 438229159Sadrian * If we have more output space than what is currently pending in 439229159Sadrian * temp, copy the unfiltered data from temp to the output buffer 440229159Sadrian * and try to fill the output buffer by decoding more data from the 441229159Sadrian * next filter in the chain. Apply the BCJ filter on the new data 442229159Sadrian * in the output buffer. If everything cannot be filtered, copy it 443229159Sadrian * to temp and rewind the output buffer position accordingly. 444229159Sadrian * 445229159Sadrian * This needs to be always run when temp.size == 0 to handle a special 446229159Sadrian * case where the output buffer is full and the next filter has no 447229159Sadrian * more output coming but hasn't returned XZ_STREAM_END yet. 448229159Sadrian */ 449229159Sadrian if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) { 450229159Sadrian out_start = b->out_pos; 451229159Sadrian memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size); 452229159Sadrian b->out_pos += s->temp.size; 453229159Sadrian 454229159Sadrian s->ret = xz_dec_lzma2_run(lzma2, b); 455229159Sadrian if (s->ret != XZ_STREAM_END 456229159Sadrian && (s->ret != XZ_OK || s->single_call)) 457229159Sadrian return s->ret; 458229159Sadrian 459229159Sadrian bcj_apply(s, b->out, &out_start, b->out_pos); 460229159Sadrian 461229159Sadrian /* 462229159Sadrian * As an exception, if the next filter returned XZ_STREAM_END, 463229159Sadrian * we can do that too, since the last few bytes that remain 464229159Sadrian * unfiltered are meant to remain unfiltered. 465229159Sadrian */ 466229159Sadrian if (s->ret == XZ_STREAM_END) 467229159Sadrian return XZ_STREAM_END; 468229159Sadrian 469229159Sadrian s->temp.size = b->out_pos - out_start; 470229159Sadrian b->out_pos -= s->temp.size; 471229159Sadrian memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size); 472229159Sadrian 473229159Sadrian /* 474229159Sadrian * If there wasn't enough input to the next filter to fill 475229159Sadrian * the output buffer with unfiltered data, there's no point 476229159Sadrian * to try decoding more data to temp. 477229159Sadrian */ 478229159Sadrian if (b->out_pos + s->temp.size < b->out_size) 479229159Sadrian return XZ_OK; 480229159Sadrian } 481229159Sadrian 482229159Sadrian /* 483229159Sadrian * We have unfiltered data in temp. If the output buffer isn't full 484229159Sadrian * yet, try to fill the temp buffer by decoding more data from the 485229159Sadrian * next filter. Apply the BCJ filter on temp. Then we hopefully can 486229159Sadrian * fill the actual output buffer by copying filtered data from temp. 487229159Sadrian * A mix of filtered and unfiltered data may be left in temp; it will 488229159Sadrian * be taken care on the next call to this function. 489229159Sadrian */ 490229159Sadrian if (b->out_pos < b->out_size) { 491229159Sadrian /* Make b->out{,_pos,_size} temporarily point to s->temp. */ 492229159Sadrian s->out = b->out; 493229159Sadrian s->out_pos = b->out_pos; 494229159Sadrian s->out_size = b->out_size; 495229159Sadrian b->out = s->temp.buf; 496229159Sadrian b->out_pos = s->temp.size; 497229159Sadrian b->out_size = sizeof(s->temp.buf); 498229159Sadrian 499229159Sadrian s->ret = xz_dec_lzma2_run(lzma2, b); 500229159Sadrian 501229159Sadrian s->temp.size = b->out_pos; 502229159Sadrian b->out = s->out; 503229159Sadrian b->out_pos = s->out_pos; 504229159Sadrian b->out_size = s->out_size; 505229159Sadrian 506229159Sadrian if (s->ret != XZ_OK && s->ret != XZ_STREAM_END) 507229159Sadrian return s->ret; 508229159Sadrian 509229159Sadrian bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size); 510229159Sadrian 511229159Sadrian /* 512229159Sadrian * If the next filter returned XZ_STREAM_END, we mark that 513229159Sadrian * everything is filtered, since the last unfiltered bytes 514229159Sadrian * of the stream are meant to be left as is. 515229159Sadrian */ 516229159Sadrian if (s->ret == XZ_STREAM_END) 517229159Sadrian s->temp.filtered = s->temp.size; 518229159Sadrian 519229159Sadrian bcj_flush(s, b); 520229159Sadrian if (s->temp.filtered > 0) 521229159Sadrian return XZ_OK; 522229159Sadrian } 523229159Sadrian 524229159Sadrian return s->ret; 525229159Sadrian} 526229159Sadrian 527229159SadrianXZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call) 528229159Sadrian{ 529229159Sadrian struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL); 530229159Sadrian if (s != NULL) 531229159Sadrian s->single_call = single_call; 532229159Sadrian 533229159Sadrian return s; 534229159Sadrian} 535229159Sadrian 536229159SadrianXZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id) 537229159Sadrian{ 538229159Sadrian switch (id) { 539229159Sadrian#ifdef XZ_DEC_X86 540229159Sadrian case BCJ_X86: 541229159Sadrian#endif 542229159Sadrian#ifdef XZ_DEC_POWERPC 543229159Sadrian case BCJ_POWERPC: 544229159Sadrian#endif 545229159Sadrian#ifdef XZ_DEC_IA64 546229159Sadrian case BCJ_IA64: 547229159Sadrian#endif 548229159Sadrian#ifdef XZ_DEC_ARM 549229159Sadrian case BCJ_ARM: 550229159Sadrian#endif 551229159Sadrian#ifdef XZ_DEC_ARMTHUMB 552229159Sadrian case BCJ_ARMTHUMB: 553229159Sadrian#endif 554229159Sadrian#ifdef XZ_DEC_SPARC 555229159Sadrian case BCJ_SPARC: 556229159Sadrian#endif 557229159Sadrian break; 558229159Sadrian 559229159Sadrian default: 560229159Sadrian /* Unsupported Filter ID */ 561229159Sadrian return XZ_OPTIONS_ERROR; 562229159Sadrian } 563229159Sadrian 564229159Sadrian s->type = id; 565229159Sadrian s->ret = XZ_OK; 566229159Sadrian s->pos = 0; 567229159Sadrian s->x86_prev_mask = 0; 568229159Sadrian s->temp.filtered = 0; 569229159Sadrian s->temp.size = 0; 570229159Sadrian 571229159Sadrian return XZ_OK; 572229159Sadrian} 573229159Sadrian 574229159Sadrian#endif 575