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