OLD | NEW |
1 /* Bra86.c -- Converter for x86 code (BCJ) | 1 /* Bra86.c -- Converter for x86 code (BCJ) |
2 2008-10-04 : Igor Pavlov : Public domain */ | 2 2013-11-12 : Igor Pavlov : Public domain */ |
| 3 |
| 4 #include "Precomp.h" |
3 | 5 |
4 #include "Bra.h" | 6 #include "Bra.h" |
5 | 7 |
6 #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) | 8 #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) |
7 | |
8 const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; | |
9 const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; | |
10 | 9 |
11 SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
) | 10 SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
) |
12 { | 11 { |
13 SizeT bufferPos = 0, prevPosT; | 12 SizeT pos = 0; |
14 UInt32 prevMask = *state & 0x7; | 13 UInt32 mask = *state & 7; |
15 if (size < 5) | 14 if (size < 5) |
16 return 0; | 15 return 0; |
| 16 size -= 4; |
17 ip += 5; | 17 ip += 5; |
18 prevPosT = (SizeT)0 - 1; | |
19 | 18 |
20 for (;;) | 19 for (;;) |
21 { | 20 { |
22 Byte *p = data + bufferPos; | 21 Byte *p = data + pos; |
23 Byte *limit = data + size - 4; | 22 const Byte *limit = data + size; |
24 for (; p < limit; p++) | 23 for (; p < limit; p++) |
25 if ((*p & 0xFE) == 0xE8) | 24 if ((*p & 0xFE) == 0xE8) |
26 break; | 25 break; |
27 bufferPos = (SizeT)(p - data); | 26 |
28 if (p >= limit) | |
29 break; | |
30 prevPosT = bufferPos - prevPosT; | |
31 if (prevPosT > 3) | |
32 prevMask = 0; | |
33 else | |
34 { | 27 { |
35 prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; | 28 SizeT d = (SizeT)(p - data - pos); |
36 if (prevMask != 0) | 29 pos = (SizeT)(p - data); |
| 30 if (p >= limit) |
37 { | 31 { |
38 Byte b = p[4 - kMaskToBitNumber[prevMask]]; | 32 *state = (d > 2 ? 0 : mask >> (unsigned)d); |
39 if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) | 33 return pos; |
| 34 } |
| 35 if (d > 2) |
| 36 mask = 0; |
| 37 else |
| 38 { |
| 39 mask >>= (unsigned)d; |
| 40 if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) +
1]))) |
40 { | 41 { |
41 prevPosT = bufferPos; | 42 mask = (mask >> 1) | 4; |
42 prevMask = ((prevMask << 1) & 0x7) | 1; | 43 pos++; |
43 bufferPos++; | |
44 continue; | 44 continue; |
45 } | 45 } |
46 } | 46 } |
47 } | 47 } |
48 prevPosT = bufferPos; | |
49 | 48 |
50 if (Test86MSByte(p[4])) | 49 if (Test86MSByte(p[4])) |
51 { | 50 { |
52 UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] <
< 8) | ((UInt32)p[1]); | 51 UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] <<
8) | ((UInt32)p[1]); |
53 UInt32 dest; | 52 UInt32 cur = ip + (UInt32)pos; |
54 for (;;) | 53 pos += 5; |
| 54 if (encoding) |
| 55 v += cur; |
| 56 else |
| 57 v -= cur; |
| 58 if (mask != 0) |
55 { | 59 { |
56 Byte b; | 60 unsigned sh = (mask & 6) << 2; |
57 int index; | 61 if (Test86MSByte((Byte)(v >> sh))) |
58 if (encoding) | 62 { |
59 dest = (ip + (UInt32)bufferPos) + src; | 63 v ^= (((UInt32)0x100 << sh) - 1); |
60 else | 64 if (encoding) |
61 dest = src - (ip + (UInt32)bufferPos); | 65 v += cur; |
62 if (prevMask == 0) | 66 else |
63 break; | 67 v -= cur; |
64 index = kMaskToBitNumber[prevMask] * 8; | 68 } |
65 b = (Byte)(dest >> (24 - index)); | 69 mask = 0; |
66 if (!Test86MSByte(b)) | |
67 break; | |
68 src = dest ^ ((1 << (32 - index)) - 1); | |
69 } | 70 } |
70 p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); | 71 p[1] = (Byte)v; |
71 p[3] = (Byte)(dest >> 16); | 72 p[2] = (Byte)(v >> 8); |
72 p[2] = (Byte)(dest >> 8); | 73 p[3] = (Byte)(v >> 16); |
73 p[1] = (Byte)dest; | 74 p[4] = (Byte)(0 - ((v >> 24) & 1)); |
74 bufferPos += 5; | |
75 } | 75 } |
76 else | 76 else |
77 { | 77 { |
78 prevMask = ((prevMask << 1) & 0x7) | 1; | 78 mask = (mask >> 1) | 4; |
79 bufferPos++; | 79 pos++; |
80 } | 80 } |
81 } | 81 } |
82 prevPosT = bufferPos - prevPosT; | |
83 *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); | |
84 return bufferPos; | |
85 } | 82 } |
OLD | NEW |