diff options
Diffstat (limited to 'depends/xz-embedded/src/xz_dec_bcj.c')
-rw-r--r-- | depends/xz-embedded/src/xz_dec_bcj.c | 148 |
1 files changed, 81 insertions, 67 deletions
diff --git a/depends/xz-embedded/src/xz_dec_bcj.c b/depends/xz-embedded/src/xz_dec_bcj.c index a768e6d2..9ffda3bd 100644 --- a/depends/xz-embedded/src/xz_dec_bcj.c +++ b/depends/xz-embedded/src/xz_dec_bcj.c @@ -16,15 +16,17 @@ */ #ifdef XZ_DEC_BCJ -struct xz_dec_bcj { +struct xz_dec_bcj +{ /* Type of the BCJ filter being used */ - enum { - BCJ_X86 = 4, /* x86 or x86-64 */ - BCJ_POWERPC = 5, /* Big endian only */ - BCJ_IA64 = 6, /* Big or little endian */ - BCJ_ARM = 7, /* Little endian only */ - BCJ_ARMTHUMB = 8, /* Little endian only */ - BCJ_SPARC = 9 /* Big or little endian */ + enum + { + BCJ_X86 = 4, /* x86 or x86-64 */ + BCJ_POWERPC = 5, /* Big endian only */ + BCJ_IA64 = 6, /* Big or little endian */ + BCJ_ARM = 7, /* Little endian only */ + BCJ_ARMTHUMB = 8, /* Little endian only */ + BCJ_SPARC = 9 /* Big or little endian */ } type; /* @@ -52,7 +54,8 @@ struct xz_dec_bcj { size_t out_pos; size_t out_size; - struct { + struct + { /* Amount of already filtered data in the beginning of buf */ size_t filtered; @@ -87,13 +90,13 @@ static inline int bcj_x86_test_msbyte(uint8_t b) static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size) { - static const bool mask_to_allowed_status[8] - = { true, true, true, false, true, false, false, false }; + static const bool mask_to_allowed_status[8] = {true, true, true, false, + true, false, false, false}; - static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 }; + static const uint8_t mask_to_bit_num[8] = {0, 1, 2, 2, 3, 3, 3, 3}; size_t i; - size_t prev_pos = (size_t)-1; + size_t prev_pos = (size_t) - 1; uint32_t prev_mask = s->x86_prev_mask; uint32_t src; uint32_t dest; @@ -104,19 +107,24 @@ static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size) return 0; size -= 4; - for (i = 0; i < size; ++i) { + for (i = 0; i < size; ++i) + { if ((buf[i] & 0xFE) != 0xE8) continue; prev_pos = i - prev_pos; - if (prev_pos > 3) { + if (prev_pos > 3) + { prev_mask = 0; - } else { + } + else + { prev_mask = (prev_mask << (prev_pos - 1)) & 7; - if (prev_mask != 0) { + if (prev_mask != 0) + { b = buf[i + 4 - mask_to_bit_num[prev_mask]]; - if (!mask_to_allowed_status[prev_mask] - || bcj_x86_test_msbyte(b)) { + if (!mask_to_allowed_status[prev_mask] || bcj_x86_test_msbyte(b)) + { prev_pos = i; prev_mask = (prev_mask << 1) | 1; continue; @@ -126,9 +134,11 @@ static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size) prev_pos = i; - if (bcj_x86_test_msbyte(buf[i + 4])) { + if (bcj_x86_test_msbyte(buf[i + 4])) + { src = get_unaligned_le32(buf + i + 1); - while (true) { + while (true) + { dest = src - (s->pos + (uint32_t)i + 5); if (prev_mask == 0) break; @@ -145,7 +155,9 @@ static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size) dest |= (uint32_t)0 - (dest & 0x01000000); put_unaligned_le32(dest, buf + i + 1); i += 4; - } else { + } + else + { prev_mask = (prev_mask << 1) | 1; } } @@ -162,9 +174,11 @@ static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size) size_t i; uint32_t instr; - for (i = 0; i + 4 <= size; i += 4) { + for (i = 0; i + 4 <= size; i += 4) + { instr = get_unaligned_be32(buf + i); - if ((instr & 0xFC000003) == 0x48000001) { + if ((instr & 0xFC000003) == 0x48000001) + { instr &= 0x03FFFFFC; instr -= s->pos + (uint32_t)i; instr &= 0x03FFFFFC; @@ -180,12 +194,8 @@ static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size) #ifdef XZ_DEC_IA64 static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) { - static const uint8_t branch_table[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 4, 4, 6, 6, 0, 0, 7, 7, - 4, 4, 0, 0, 4, 4, 0, 0 - }; + static const uint8_t branch_table[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 6, 6, 0, 0, 7, 7, 4, 4, 0, 0, 4, 4, 0, 0}; /* * The local variables take a little bit stack space, but it's less @@ -219,9 +229,11 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) /* Instruction normalized with bit_res for easier manipulation */ uint64_t norm; - for (i = 0; i + 16 <= size; i += 16) { + for (i = 0; i + 16 <= size; i += 16) + { mask = branch_table[buf[i] & 0x1F]; - for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) { + for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) + { if (((mask >> slot) & 1) == 0) continue; @@ -229,13 +241,12 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) bit_res = bit_pos & 7; instr = 0; for (j = 0; j < 6; ++j) - instr |= (uint64_t)(buf[i + j + byte_pos]) - << (8 * j); + instr |= (uint64_t)(buf[i + j + byte_pos]) << (8 * j); norm = instr >> bit_res; - if (((norm >> 37) & 0x0F) == 0x05 - && ((norm >> 9) & 0x07) == 0) { + if (((norm >> 37) & 0x0F) == 0x05 && ((norm >> 9) & 0x07) == 0) + { addr = (norm >> 13) & 0x0FFFFF; addr |= ((uint32_t)(norm >> 36) & 1) << 20; addr <<= 4; @@ -244,15 +255,13 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) norm &= ~((uint64_t)0x8FFFFF << 13); norm |= (uint64_t)(addr & 0x0FFFFF) << 13; - norm |= (uint64_t)(addr & 0x100000) - << (36 - 20); + norm |= (uint64_t)(addr & 0x100000) << (36 - 20); instr &= (1 << bit_res) - 1; instr |= norm << bit_res; for (j = 0; j < 6; j++) - buf[i + j + byte_pos] - = (uint8_t)(instr >> (8 * j)); + buf[i + j + byte_pos] = (uint8_t)(instr >> (8 * j)); } } } @@ -267,10 +276,12 @@ static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size) size_t i; uint32_t addr; - for (i = 0; i + 4 <= size; i += 4) { - if (buf[i + 3] == 0xEB) { - addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) - | ((uint32_t)buf[i + 2] << 16); + for (i = 0; i + 4 <= size; i += 4) + { + if (buf[i + 3] == 0xEB) + { + addr = + (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) | ((uint32_t)buf[i + 2] << 16); addr <<= 2; addr -= s->pos + (uint32_t)i + 8; addr >>= 2; @@ -290,13 +301,12 @@ static size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size) size_t i; uint32_t addr; - for (i = 0; i + 4 <= size; i += 2) { - if ((buf[i + 1] & 0xF8) == 0xF0 - && (buf[i + 3] & 0xF8) == 0xF8) { - addr = (((uint32_t)buf[i + 1] & 0x07) << 19) - | ((uint32_t)buf[i] << 11) - | (((uint32_t)buf[i + 3] & 0x07) << 8) - | (uint32_t)buf[i + 2]; + for (i = 0; i + 4 <= size; i += 2) + { + if ((buf[i + 1] & 0xF8) == 0xF0 && (buf[i + 3] & 0xF8) == 0xF8) + { + addr = (((uint32_t)buf[i + 1] & 0x07) << 19) | ((uint32_t)buf[i] << 11) | + (((uint32_t)buf[i + 3] & 0x07) << 8) | (uint32_t)buf[i + 2]; addr <<= 1; addr -= s->pos + (uint32_t)i + 4; addr >>= 1; @@ -318,14 +328,16 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size) size_t i; uint32_t instr; - for (i = 0; i + 4 <= size; i += 4) { + for (i = 0; i + 4 <= size; i += 4) + { instr = get_unaligned_be32(buf + i); - if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) { + if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) + { instr <<= 2; instr -= s->pos + (uint32_t)i; instr >>= 2; - instr = ((uint32_t)0x40000000 - (instr & 0x400000)) - | 0x40000000 | (instr & 0x3FFFFF); + instr = + ((uint32_t)0x40000000 - (instr & 0x400000)) | 0x40000000 | (instr & 0x3FFFFF); put_unaligned_be32(instr, buf + i); } } @@ -342,15 +354,15 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size) * pointers, which could be problematic in the kernel boot code, which must * avoid pointers to static data (at least on x86). */ -static void bcj_apply(struct xz_dec_bcj *s, - uint8_t *buf, size_t *pos, size_t size) +static void bcj_apply(struct xz_dec_bcj *s, uint8_t *buf, size_t *pos, size_t size) { size_t filtered; buf += *pos; size -= *pos; - switch (s->type) { + switch (s->type) + { #ifdef XZ_DEC_X86 case BCJ_X86: filtered = bcj_x86(s, buf, size); @@ -414,9 +426,8 @@ static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b) * data in chunks of 1-16 bytes. To hide this issue, this function does * some buffering. */ -XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, - struct xz_dec_lzma2 *lzma2, - struct xz_buf *b) +XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2, + struct xz_buf *b) { size_t out_start; @@ -425,7 +436,8 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, * immediatelly if we couldn't flush everything, or if the next * filter in the chain had already returned XZ_STREAM_END. */ - if (s->temp.filtered > 0) { + if (s->temp.filtered > 0) + { bcj_flush(s, b); if (s->temp.filtered > 0) return XZ_OK; @@ -446,14 +458,14 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, * case where the output buffer is full and the next filter has no * more output coming but hasn't returned XZ_STREAM_END yet. */ - if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) { + if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) + { out_start = b->out_pos; memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size); b->out_pos += s->temp.size; s->ret = xz_dec_lzma2_run(lzma2, b); - if (s->ret != XZ_STREAM_END - && (s->ret != XZ_OK || s->single_call)) + if (s->ret != XZ_STREAM_END && (s->ret != XZ_OK || s->single_call)) return s->ret; bcj_apply(s, b->out, &out_start, b->out_pos); @@ -487,7 +499,8 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, * A mix of filtered and unfiltered data may be left in temp; it will * be taken care on the next call to this function. */ - if (b->out_pos < b->out_size) { + if (b->out_pos < b->out_size) + { /* Make b->out{,_pos,_size} temporarily point to s->temp. */ s->out = b->out; s->out_pos = b->out_pos; @@ -535,7 +548,8 @@ XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call) XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id) { - switch (id) { + switch (id) + { #ifdef XZ_DEC_X86 case BCJ_X86: #endif |