83 static inline int bcj_x86_test_msbyte(
uint8_t b)
85 return b == 0x00 || b == 0xFF;
90 static const bool mask_to_allowed_status[8]
91 = {
true,
true,
true,
false,
true,
false,
false,
false };
93 static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
96 size_t prev_pos = (
size_t)-1;
97 uint32_t prev_mask = s->x86_prev_mask;
107 for (i = 0; i <
size; ++
i) {
108 if ((buf[i] & 0xFE) != 0xE8)
111 prev_pos = i - prev_pos;
115 prev_mask = (prev_mask << (prev_pos - 1)) & 7;
116 if (prev_mask != 0) {
117 b = buf[i + 4 - mask_to_bit_num[prev_mask]];
118 if (!mask_to_allowed_status[prev_mask]
119 || bcj_x86_test_msbyte(b)) {
121 prev_mask = (prev_mask << 1) | 1;
129 if (bcj_x86_test_msbyte(buf[i + 4])) {
132 dest = src - (s->pos + (
uint32_t)i + 5);
136 j = mask_to_bit_num[prev_mask] * 8;
137 b = (
uint8_t)(dest >> (24 - j));
138 if (!bcj_x86_test_msbyte(b))
141 src = dest ^ (((
uint32_t)1 << (32 - j)) - 1);
145 dest |= (
uint32_t)0 - (dest & 0x01000000);
149 prev_mask = (prev_mask << 1) | 1;
153 prev_pos = i - prev_pos;
154 s->x86_prev_mask = prev_pos > 3 ? 0 : prev_mask << (prev_pos - 1);
159 #ifdef XZ_DEC_POWERPC
160 static size_t bcj_powerpc(
struct xz_dec_bcj *s,
uint8_t *buf,
size_t size)
165 for (i = 0; i + 4 <=
size; i += 4) {
167 if ((instr & 0xFC000003) == 0x48000001) {
181 static size_t bcj_ia64(
struct xz_dec_bcj *s,
uint8_t *buf,
size_t size)
183 static const uint8_t branch_table[32] = {
184 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0,
186 4, 4, 6, 6, 0, 0, 7, 7,
187 4, 4, 0, 0, 4, 4, 0, 0
222 for (i = 0; i + 16 <=
size; i += 16) {
223 mask = branch_table[buf[
i] & 0x1F];
224 for (slot = 0, bit_pos = 5; slot < 3; ++
slot, bit_pos += 41) {
225 if (((mask >> slot) & 1) == 0)
228 byte_pos = bit_pos >> 3;
229 bit_res = bit_pos & 7;
231 for (j = 0; j < 6; ++
j)
232 instr |= (
uint64_t)(buf[i + j + byte_pos])
235 norm = instr >> bit_res;
237 if (((norm >> 37) & 0x0F) == 0x05
238 && ((norm >> 9) & 0x07) == 0) {
239 addr = (norm >> 13) & 0x0FFFFF;
240 addr |= ((
uint32_t)(norm >> 36) & 1) << 20;
245 norm &= ~((
uint64_t)0x8FFFFF << 13);
246 norm |= (
uint64_t)(addr & 0x0FFFFF) << 13;
250 instr &= (1 << bit_res) - 1;
251 instr |= norm << bit_res;
253 for (j = 0; j < 6; j++)
254 buf[i + j + byte_pos]
265 static size_t bcj_arm(
struct xz_dec_bcj *s,
uint8_t *buf,
size_t size)
270 for (i = 0; i + 4 <=
size; i += 4) {
271 if (buf[i + 3] == 0xEB) {
278 buf[i + 1] = (
uint8_t)(addr >> 8);
279 buf[i + 2] = (
uint8_t)(addr >> 16);
287 #ifdef XZ_DEC_ARMTHUMB
288 static size_t bcj_armthumb(
struct xz_dec_bcj *s,
uint8_t *buf,
size_t size)
293 for (i = 0; i + 4 <=
size; i += 2) {
294 if ((buf[i + 1] & 0xF8) == 0xF0
295 && (buf[i + 3] & 0xF8) == 0xF8) {
296 addr = (((
uint32_t)buf[i + 1] & 0x07) << 19)
298 | (((
uint32_t)buf[i + 3] & 0x07) << 8)
303 buf[i + 1] = (
uint8_t)(0xF0 | ((addr >> 19) & 0x07));
305 buf[i + 3] = (
uint8_t)(0xF8 | ((addr >> 8) & 0x07));
316 static size_t bcj_sparc(
struct xz_dec_bcj *s,
uint8_t *buf,
size_t size)
321 for (i = 0; i + 4 <=
size; i += 4) {
323 if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
327 instr = ((
uint32_t)0x40000000 - (instr & 0x400000))
328 | 0x40000000 | (instr & 0x3FFFFF);
345 static void bcj_apply(
struct xz_dec_bcj *s,
356 filtered = bcj_x86(s, buf, size);
359 #ifdef XZ_DEC_POWERPC
361 filtered = bcj_powerpc(s, buf, size);
366 filtered = bcj_ia64(s, buf, size);
371 filtered = bcj_arm(s, buf, size);
374 #ifdef XZ_DEC_ARMTHUMB
376 filtered = bcj_armthumb(s, buf, size);
381 filtered = bcj_sparc(s, buf, size);
399 static void bcj_flush(
struct xz_dec_bcj *s,
struct xz_buf *b)
407 s->temp.filtered -= copy_size;
408 s->temp.size -= copy_size;
409 memmove(s->temp.buf, s->temp.buf + copy_size, s->temp.size);
428 if (s->temp.filtered > 0) {
430 if (s->temp.filtered > 0)
456 && (s->ret !=
XZ_OK || s->single_call))
469 s->temp.size = b->
out_pos - out_start;
495 b->
out = s->temp.buf;
509 bcj_apply(s, s->temp.buf, &s->temp.filtered, s->temp.size);
517 s->temp.filtered = s->temp.size;
520 if (s->temp.filtered > 0)
527 XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(
bool single_call)
531 s->single_call = single_call;
542 #ifdef XZ_DEC_POWERPC
551 #ifdef XZ_DEC_ARMTHUMB
567 s->x86_prev_mask = 0;
568 s->temp.filtered = 0;