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