1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Filter for x86 binaries (BCJ filter)
6 // Copyright (C) 1999-2006 Igor Pavlov
7 // Copyright (C) 2007 Lasse Collin
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
19 ///////////////////////////////////////////////////////////////////////////////
21 #include "simple_private.h"
24 #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
27 struct lzma_simple_s {
34 x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder,
35 uint8_t *buffer, size_t size)
37 static const bool MASK_TO_ALLOWED_STATUS[8]
38 = { true, true, true, false, true, false, false, false };
40 static const uint32_t MASK_TO_BIT_NUMBER[8]
41 = { 0, 1, 2, 2, 3, 3, 3, 3 };
43 uint32_t prev_mask = simple->prev_mask;
44 uint32_t prev_pos = simple->prev_pos;
49 if (now_pos - prev_pos > 5)
50 prev_pos = now_pos - 5;
52 const size_t limit = size - 5;
53 size_t buffer_pos = 0;
55 while (buffer_pos <= limit) {
56 uint8_t b = buffer[buffer_pos];
57 if (b != 0xE8 && b != 0xE9) {
62 const uint32_t offset = now_pos + (uint32_t)(buffer_pos)
64 prev_pos = now_pos + (uint32_t)(buffer_pos);
69 for (uint32_t i = 0; i < offset; ++i) {
75 b = buffer[buffer_pos + 4];
78 && MASK_TO_ALLOWED_STATUS[(prev_mask >> 1) & 0x7]
79 && (prev_mask >> 1) < 0x10) {
81 uint32_t src = ((uint32_t)(b) << 24)
82 | ((uint32_t)(buffer[buffer_pos + 3]) << 16)
83 | ((uint32_t)(buffer[buffer_pos + 2]) << 8)
84 | (buffer[buffer_pos + 1]);
89 dest = src + (now_pos + (uint32_t)(
92 dest = src - (now_pos + (uint32_t)(
98 const uint32_t i = MASK_TO_BIT_NUMBER[
101 b = (uint8_t)(dest >> (24 - i * 8));
103 if (!Test86MSByte(b))
106 src = dest ^ ((1 << (32 - i * 8)) - 1);
109 buffer[buffer_pos + 4]
110 = (uint8_t)(~(((dest >> 24) & 1) - 1));
111 buffer[buffer_pos + 3] = (uint8_t)(dest >> 16);
112 buffer[buffer_pos + 2] = (uint8_t)(dest >> 8);
113 buffer[buffer_pos + 1] = (uint8_t)(dest);
125 simple->prev_mask = prev_mask;
126 simple->prev_pos = prev_pos;
133 x86_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
134 const lzma_filter_info *filters, bool is_encoder)
136 const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters,
137 &x86_code, sizeof(lzma_simple), 5, is_encoder);
139 if (ret == LZMA_OK) {
140 next->coder->simple->prev_mask = 0;
141 next->coder->simple->prev_pos = (uint32_t)(-5);
149 lzma_simple_x86_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
150 const lzma_filter_info *filters)
152 return x86_coder_init(next, allocator, filters, true);
157 lzma_simple_x86_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
158 const lzma_filter_info *filters)
160 return x86_coder_init(next, allocator, filters, false);