-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathEncoding.hpp
212 lines (181 loc) · 4.08 KB
/
Encoding.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#ifndef SoftWire_Encoding_hpp
#define SoftWire_Encoding_hpp
namespace SoftWire
{
class Synthesizer;
class Instruction;
class Encoding
{
friend class Synthesizer;
public:
enum Reg
{
REG_UNKNOWN = -1,
R0 = 0, AL = 0, AX = 0, EAX = 0, RAX = 0, ST0 = 0, MM0 = 0, XMM0 = 0,
R1 = 1, CL = 1, CX = 1, ECX = 1, RCX = 1, ST1 = 1, MM1 = 1, XMM1 = 1,
R2 = 2, DL = 2, DX = 2, EDX = 2, RDX = 2, ST2 = 2, MM2 = 2, XMM2 = 2,
R3 = 3, BL = 3, BX = 3, EBX = 3, RBX = 3, ST3 = 3, MM3 = 3, XMM3 = 3,
R4 = 4, AH = 4, SP = 4, ESP = 4, RSP = 4, ST4 = 4, MM4 = 4, XMM4 = 4,
R5 = 5, CH = 5, BP = 5, EBP = 5, RBP = 5, ST5 = 5, MM5 = 5, XMM5 = 5,
R6 = 6, DH = 6, SI = 6, ESI = 6, RSI = 6, ST6 = 6, MM6 = 6, XMM6 = 6,
R7 = 7, BH = 7, DI = 7, EDI = 7, RDI = 7, ST7 = 7, MM7 = 7, XMM7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15
};
enum Mod
{
MOD_NO_DISP = 0,
MOD_BYTE_DISP = 1,
MOD_DWORD_DISP = 2,
MOD_REG = 3
};
enum Scale
{
SCALE_UNKNOWN = 0,
SCALE_1 = 0,
SCALE_2 = 1,
SCALE_4 = 2,
SCALE_8 = 3
};
Encoding(const Instruction *instruction = 0);
Encoding(const Encoding &encoding);
~Encoding();
Encoding &operator=(const Encoding &encoding);
void reset();
const char *getLabel() const;
const char *getReference() const;
const char *getLiteral() const;
int getImmediate() const;
__int64 getDisplacement() const;
void addPrefix(unsigned char p);
int length(const unsigned char *buffer) const; // Length of encoded instruction in bytes
int writeCode(unsigned char *buffer, bool write = true) const;
void setImmediate(int immediate);
void setDisplacement(__int64 displacement);
void addDisplacement(__int64 displacement);
void setJumpOffset(int offset);
void setCallOffset(int offset);
void setLabel(const char *label);
void setReference(const char *label);
bool relativeReference() const;
bool absoluteReference() const;
bool hasDisplacement() const;
bool hasImmediate() const;
bool isRipRelative() const;
void setAddress(const unsigned char *address);
const unsigned char *getAddress() const;
// Prevent or enable writing to output
Encoding *reserve();
void retain();
bool isEmitting();
int printCode(char *buffer) const;
protected:
const Instruction *instruction;
char *label;
union
{
char *reference;
char *literal;
};
bool relative;
struct
{
bool P1 : 1;
bool P2 : 1;
bool P3 : 1;
bool P4 : 1;
bool REX : 1;
bool O2 : 1;
bool O1 : 1;
bool modRM : 1;
bool SIB : 1;
bool D1 : 1;
bool D2 : 1;
bool D3 : 1;
bool D4 : 1;
bool I1 : 1;
bool I2 : 1;
bool I3 : 1;
bool I4 : 1;
} format;
unsigned char P1; // Prefixes
unsigned char P2;
unsigned char P3;
unsigned char P4;
struct
{
union
{
struct
{
unsigned char B : 1;
unsigned char X : 1;
unsigned char R : 1;
unsigned char W : 1;
unsigned char prefix : 4;
};
unsigned char b;
};
} REX;
unsigned char O1; // Opcode
unsigned char O2;
struct
{
union
{
struct
{
unsigned char r_m : 3;
unsigned char reg : 3;
unsigned char mod : 2;
};
unsigned char b;
};
} modRM;
struct
{
union
{
struct
{
unsigned char base : 3;
unsigned char index : 3;
unsigned char scale : 2;
};
unsigned char b;
};
} SIB;
union
{
__int64 displacement;
struct
{
unsigned char D1;
unsigned char D2;
unsigned char D3;
unsigned char D4;
};
};
union
{
int immediate;
struct
{
unsigned char I1;
unsigned char I2;
unsigned char I3;
unsigned char I4;
};
};
const unsigned char *address;
bool emit; // false for eliminated instructions
static int align(unsigned char *output, int alignment, bool write);
};
}
#endif // SoftWire_Encoding_hpp