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)
20 struct lzma_simple_s
{
27 x86_code(lzma_simple
*simple
, 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 uint32_t prev_mask
= simple
->prev_mask
;
37 uint32_t prev_pos
= simple
->prev_pos
;
42 if (now_pos
- prev_pos
> 5)
43 prev_pos
= now_pos
- 5;
45 const size_t limit
= size
- 5;
46 size_t buffer_pos
= 0;
48 while (buffer_pos
<= limit
) {
49 uint8_t b
= buffer
[buffer_pos
];
50 if (b
!= 0xE8 && b
!= 0xE9) {
55 const uint32_t offset
= now_pos
+ (uint32_t)(buffer_pos
)
57 prev_pos
= now_pos
+ (uint32_t)(buffer_pos
);
62 for (uint32_t i
= 0; i
< offset
; ++i
) {
68 b
= buffer
[buffer_pos
+ 4];
71 && MASK_TO_ALLOWED_STATUS
[(prev_mask
>> 1) & 0x7]
72 && (prev_mask
>> 1) < 0x10) {
74 uint32_t src
= ((uint32_t)(b
) << 24)
75 | ((uint32_t)(buffer
[buffer_pos
+ 3]) << 16)
76 | ((uint32_t)(buffer
[buffer_pos
+ 2]) << 8)
77 | (buffer
[buffer_pos
+ 1]);
82 dest
= src
+ (now_pos
+ (uint32_t)(
85 dest
= src
- (now_pos
+ (uint32_t)(
91 const uint32_t i
= MASK_TO_BIT_NUMBER
[
94 b
= (uint8_t)(dest
>> (24 - i
* 8));
99 src
= dest
^ ((1 << (32 - i
* 8)) - 1);
102 buffer
[buffer_pos
+ 4]
103 = (uint8_t)(~(((dest
>> 24) & 1) - 1));
104 buffer
[buffer_pos
+ 3] = (uint8_t)(dest
>> 16);
105 buffer
[buffer_pos
+ 2] = (uint8_t)(dest
>> 8);
106 buffer
[buffer_pos
+ 1] = (uint8_t)(dest
);
118 simple
->prev_mask
= prev_mask
;
119 simple
->prev_pos
= prev_pos
;
126 x86_coder_init(lzma_next_coder
*next
, const lzma_allocator
*allocator
,
127 const lzma_filter_info
*filters
, bool is_encoder
)
129 const lzma_ret ret
= lzma_simple_coder_init(next
, allocator
, filters
,
130 &x86_code
, sizeof(lzma_simple
), 5, 1, is_encoder
);
132 if (ret
== LZMA_OK
) {
133 next
->coder
->simple
->prev_mask
= 0;
134 next
->coder
->simple
->prev_pos
= (uint32_t)(-5);
142 lzma_simple_x86_encoder_init(lzma_next_coder
*next
,
143 const lzma_allocator
*allocator
,
144 const lzma_filter_info
*filters
)
146 return x86_coder_init(next
, allocator
, filters
, true);
151 lzma_simple_x86_decoder_init(lzma_next_coder
*next
,
152 const lzma_allocator
*allocator
,
153 const lzma_filter_info
*filters
)
155 return x86_coder_init(next
, allocator
, filters
, false);