1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Filter for x86 binaries (BCJ filter)
6 // Authors: Igor Pavlov
9 // This file has been put into the public domain.
10 // You can do whatever you want with this file.
12 ///////////////////////////////////////////////////////////////////////////////
14 #include "simple_private.h"
17 #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
27 x86_code(void *simple_ptr
, uint32_t now_pos
, bool is_encoder
,
28 uint8_t *buffer
, size_t size
)
30 static const bool MASK_TO_ALLOWED_STATUS
[8]
31 = { true, true, true, false, true, false, false, false };
33 static const uint32_t MASK_TO_BIT_NUMBER
[8]
34 = { 0, 1, 2, 2, 3, 3, 3, 3 };
36 lzma_simple_x86
*simple
= simple_ptr
;
37 uint32_t prev_mask
= simple
->prev_mask
;
38 uint32_t prev_pos
= simple
->prev_pos
;
43 if (now_pos
- prev_pos
> 5)
44 prev_pos
= now_pos
- 5;
46 const size_t limit
= size
- 5;
47 size_t buffer_pos
= 0;
49 while (buffer_pos
<= limit
) {
50 uint8_t b
= buffer
[buffer_pos
];
51 if (b
!= 0xE8 && b
!= 0xE9) {
56 const uint32_t offset
= now_pos
+ (uint32_t)(buffer_pos
)
58 prev_pos
= now_pos
+ (uint32_t)(buffer_pos
);
63 for (uint32_t i
= 0; i
< offset
; ++i
) {
69 b
= buffer
[buffer_pos
+ 4];
72 && MASK_TO_ALLOWED_STATUS
[(prev_mask
>> 1) & 0x7]
73 && (prev_mask
>> 1) < 0x10) {
75 uint32_t src
= ((uint32_t)(b
) << 24)
76 | ((uint32_t)(buffer
[buffer_pos
+ 3]) << 16)
77 | ((uint32_t)(buffer
[buffer_pos
+ 2]) << 8)
78 | (buffer
[buffer_pos
+ 1]);
83 dest
= src
+ (now_pos
+ (uint32_t)(
86 dest
= src
- (now_pos
+ (uint32_t)(
92 const uint32_t i
= MASK_TO_BIT_NUMBER
[
95 b
= (uint8_t)(dest
>> (24 - i
* 8));
100 src
= dest
^ ((1 << (32 - i
* 8)) - 1);
103 buffer
[buffer_pos
+ 4]
104 = (uint8_t)(~(((dest
>> 24) & 1) - 1));
105 buffer
[buffer_pos
+ 3] = (uint8_t)(dest
>> 16);
106 buffer
[buffer_pos
+ 2] = (uint8_t)(dest
>> 8);
107 buffer
[buffer_pos
+ 1] = (uint8_t)(dest
);
119 simple
->prev_mask
= prev_mask
;
120 simple
->prev_pos
= prev_pos
;
127 x86_coder_init(lzma_next_coder
*next
, const lzma_allocator
*allocator
,
128 const lzma_filter_info
*filters
, bool is_encoder
)
130 const lzma_ret ret
= lzma_simple_coder_init(next
, allocator
, filters
,
131 &x86_code
, sizeof(lzma_simple_x86
), 5, 1, is_encoder
);
133 if (ret
== LZMA_OK
) {
134 lzma_simple_coder
*coder
= next
->coder
;
135 lzma_simple_x86
*simple
= coder
->simple
;
136 simple
->prev_mask
= 0;
137 simple
->prev_pos
= (uint32_t)(-5);
145 lzma_simple_x86_encoder_init(lzma_next_coder
*next
,
146 const lzma_allocator
*allocator
,
147 const lzma_filter_info
*filters
)
149 return x86_coder_init(next
, allocator
, filters
, true);
154 lzma_simple_x86_decoder_init(lzma_next_coder
*next
,
155 const lzma_allocator
*allocator
,
156 const lzma_filter_info
*filters
)
158 return x86_coder_init(next
, allocator
, filters
, false);