The ROme OpTimistic Simulator
2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
Main Page
Data Structures
Files
File List
Globals
x86.h
Go to the documentation of this file.
1
31
#pragma once
32
33
#include <stdbool.h>
34
35
#include "instruction.h"
36
37
#define A32(f) ((f) & ADDR_32) // Indirizzi a 32 bit?
38
#define D32(f) ((f) & DATA_32) // Dati a 32 bit?
39
#define A64(f) ((f) & ADDR_64) // Indirizzi a 64 bit?
40
#define D64(f) ((f) & DATA_64) // Dati a 64 bit?
41
42
/* Test sui prefissi */
43
#define p_is_group1(p) (((p) == 0xf0)
/* lock */
\
44
|| ((p) == 0xf2)
/* repne/repnz */
\
45
|| ((p) == 0xf3))
/* rep/repe/repz */
46
47
#define p_is_group2(p) (((p) == 0x2e)
/* CS override/branch not taken */
\
48
|| ((p) == 0x36)
/* SS override */
\
49
|| ((p) == 0x3e)
/* DS override/branch taken */
\
50
|| ((p) == 0x26)
/* ES override */
\
51
|| ((p) == 0x64)
/* FS override */
\
52
|| ((p) == 0x65))
/* GS override */
53
54
#define p_is_group3(p) ((p) == 0x66)
/* opsize override */
55
56
#define p_is_group4(p) ((p) == 0x67)
/* addr size override */
57
58
#define is_prefix(o) (p_is_group1 (o) || p_is_group2 (o) \
59
|| p_is_group3 (o) || p_is_group4 (o))
60
61
#define is_sse_prefix(o) (((o) == 0xf2) || ((o) == 0xf3) || ((o) == 0x66))
62
63
#define is_rex_prefix(r, mode64) (((r) >= 0x40 && (r) <= 0x4f ) && (mode64))
64
65
/* Recuperano i bit di interesse del byte REX (i primi 4 bit sono fissi e valgono 0100b) */
66
67
#define REXW(r) (((r) & 0x08) >> 3)
68
#define REXR(r) (((r) & 0x04) >> 2)
69
#define REXX(r) (((r) & 0x02) >> 1)
70
#define REXB(r) (((r) & 0x01))
71
72
/* Test per le operazioni Jcc */
73
74
// opcode nell'intervallo 70-7f,e3
75
#define is_jcc_insn(o) (((o) == 0xe3) || (((o) >= 0x70) && ((o) <= 0x7f)))
76
77
// opcode nell'intervallo 80-8f (quando il primo byte è 0f)
78
#define is_esc_jcc_insn(o) (((o) >= 0x80) && ((o) <= 0x8f))
79
80
// Gli operandi dell'istruzione specificano se c'è o meno un byte ModR/M
81
#define has_modrm(addr) (((addr) == ADDR_C) \
82
|| ((addr) == ADDR_D) \
83
|| ((addr) == ADDR_E) \
84
|| ((addr) == ADDR_G) \
85
|| ((addr) == ADDR_M) \
86
|| ((addr) == ADDR_P) \
87
|| ((addr) == ADDR_Q) \
88
|| ((addr) == ADDR_R) \
89
|| ((addr) == ADDR_S) \
90
|| ((addr) == ADDR_T) \
91
|| ((addr) == ADDR_V) \
92
|| ((addr) == ADDR_W))
93
94
// È presente un byte SIB se il campo Mod non è 11b, il campo R/M è
95
// 100b e la modalità di indirizzamento è a 32 bit o 64 bit
96
#define has_sib(modrm, addr) ((((modrm) & 0x07) == 0x04) \
97
&& (((addr) == SIZE_32) || (addr) == SIZE_64) \
98
&& (((modrm) & 0xC0) != 0xC0))
99
100
// Se il campo Mod è 01b, allora c'è uno spiazzamento di 1 byte. Se il campo
101
// Mod è 10b, e siamo in modalità di indirizzamento a 32/64 bit, allora c'è
102
// uno spiazzamento di 4 byte. Inoltre, se la modalità di indirizzamento è
103
// a 16 bit e il campo Mod è 10b, allora c'è uno spiazzamento di 2 byte.
104
// Se la modalità di indirizzamento è a 32 o 64 bit e sia il campo Mod è 00b sia
105
// il campo R/M è 101b, o il campo Mod è 10b, allora c'è uno spiazzamento
106
// di 4 byte. Altrimenti non c'è spiazzamento.
107
#define disp_size(modrm, addr) ((((modrm) & 0xC0) == 0x40) ? 1 \
108
: ((((addr) == SIZE_16) \
109
&& ((((modrm) & 0xC7) == 0x06) \
110
|| (((modrm) & 0xC0) == 0x80))) ? 2 \
111
: (((((addr) == SIZE_32) || (addr) == SIZE_64) \
112
&& ((((modrm) & 0xC7) == 0x05) \
113
|| (((modrm) & 0xC0) == 0x80))) ? 4\
114
: 0)))
115
116
enum
addr_method {
117
ADDR_0,
/* Nessun metodo di indirizzamento */
118
ADDR_A,
/* Indirizzamento diretto, nessun byte ModR/M */
119
ADDR_C,
/* Il campo reg del byte ModR/M seleziona un registro di controllo */
120
ADDR_D,
/* Il campo reg del byte ModR/M seleziona un registro di debug */
121
ADDR_E,
/* Il byte ModR/M specifica l'operando: o un registro general purpose
122
o un offset per un indirizzo di memoria da un segment register
123
con un registro base, un registro d'indice, un fattore di scala
124
o spiazzamento */
125
ADDR_F,
/* registro EFLAGS */
126
ADDR_G,
/* Il campo reg del byte ModR/M seleziona un registro generale */
127
ADDR_I,
/* Dati immediati */
128
ADDR_J,
/* L'istruzione contiene un offset relativo, da (E)IP */
129
ADDR_M,
/* Il byte ModR/M può riferirsi solo a memoria */
130
ADDR_N,
/* [FV] Il campo R/M del byte ModR/M indica un registro MMX */
131
ADDR_O,
/* Nessun byte ModR/M. L'op è codificata come word o dword o qword in 64bit */
132
ADDR_P,
/* Il campo reg del byte ModR/M seleziona un registro packed qword MMX */
133
ADDR_Q,
/* Il byte ModR/M specifica o un registro MMX o un indirizzo in memoria (scala, ecc...) */
134
ADDR_R,
/* Il campo reg del byte ModR/M si può riferire solo a un registro generale */
135
ADDR_S,
/* Il campo reg del byte ModR/M seleziona un segment register */
136
ADDR_T,
/* Il campo reg del byte ModR/M seleziona un registro di test */
137
ADDR_U,
// Alice: Il campo R/M del byte ModR/M seleziona un registro XMM
138
ADDR_V,
/* Il campo reg del byte ModR/M seleziona un registro MMX */
139
ADDR_W,
/* Il byte ModR/M seleziona un registro XMM o un indirizzo in memoria (scala, ecc...) */
140
ADDR_X,
/* Indirizzo di memoria da DS:SI */
141
ADDR_Y,
/* Indirizzo di memoria da ES:DI */
142
143
/* Registri */
144
R_START,
145
146
R_AL,
147
R_AH,
148
R_AX,
149
R_EAX,
150
R_RAX,
151
152
R_BL,
153
R_BH,
154
R_BX,
155
R_EBX,
156
R_RBX,
157
158
R_CL,
159
R_CH,
160
R_CX,
161
R_ECX,
162
R_RCX,
163
164
R_DL,
165
R_DH,
166
R_DX,
167
R_EDX,
168
R_RDX,
169
170
R_SIL,
171
R_SI,
172
R_ESI,
173
R_RSI,
174
R_DIL,
175
R_DI,
176
R_EDI,
177
R_RDI,
178
R_BP,
179
R_EBP,
180
R_SPL,
181
R_SP,
182
R_ESP,
183
R_RSP,
184
185
/* segment registers */
186
R_CS,
187
R_DS,
188
R_SS,
189
R_ES,
190
R_FS,
191
R_GS,
192
193
/* EFLAGS */
194
R_F,
195
R_EF,
196
197
/* EIP */
198
R_IP,
199
R_EIP,
200
R_RIP,
201
202
/* floating point registers */
203
R_ST0,
204
R_ST1,
205
R_ST2,
206
R_ST3,
207
R_ST4,
208
R_ST5,
209
R_ST6,
210
R_ST7,
211
212
/* Extra registers in 64bit mode */
213
R_R8L,
214
R_R8W,
215
R_R8D,
216
R_R8,
217
218
R_R9L,
219
R_R9W,
220
R_R9D,
221
R_R9,
222
223
R_R10L,
224
R_R10W,
225
R_R10D,
226
R_R10,
227
228
R_R11L,
229
R_R11W,
230
R_R11D,
231
R_R11,
232
233
R_R12L,
234
R_R12W,
235
R_R12D,
236
R_R12,
237
238
R_R13L,
239
R_R13W,
240
R_R13D,
241
R_R13,
242
243
R_R14L,
244
R_R14W,
245
R_R14D,
246
R_R14,
247
248
R_R15L,
249
R_R15W,
250
R_R15D,
251
R_R15,
252
253
/* MMX registers */
254
R_MM0,
255
R_MM1,
256
R_MM2,
257
R_MM3,
258
R_MM4,
259
R_MM5,
260
R_MM6,
261
R_MM7,
262
263
/* SSE/SSE2 registers */
264
R_XMM0,
265
R_XMM1,
266
R_XMM2,
267
R_XMM3,
268
R_XMM4,
269
R_XMM5,
270
R_XMM6,
271
R_XMM7,
272
R_XMM8,
273
R_XMM9,
274
R_XMM10,
275
R_XMM11,
276
R_XMM12,
277
R_XMM13,
278
R_XMM14,
279
R_XMM15,
280
281
R_END,
282
283
/* Valore immediato interno all'istruzione (D0, D1) */
284
IMMED_1,
/* il valore 1 */
285
};
286
287
enum
operand_type {
288
OP_0,
/* nessun tipo */
289
OP_A,
/* due oper da 1 word o 2 operandi dword in mem (dipende dall'attr opsize) */
290
OP_B,
/* byte, indifferentemente dall'attrib opsize */
291
OP_C,
/* byte o word, a seconda dell'attrib opsize */
292
OP_D,
/* dword, indifferentemente dall'attributo opsize */
293
OP_DQ,
/* dqword, indifferentemebre dall'attr opsize */
294
OP_P,
/* puntatore di 32 o 48 bit a seconda dell'attributo opsize */
295
OP_PI,
/* Registro MMX qword */
296
OP_PS,
/* 128 bit packed single float [FV] o 256 bit */
297
OP_Q,
/* qword, indifferentemente dall'att opsize */
298
OP_S,
/* 6 byte pseudo-descriptor */
299
OP_SS,
/* Elemento scalare di un packed single float a 128 bit */
300
OP_SI,
/* registro dword (es: eax) */
301
OP_V,
/* word o dword, a seconda dell'attributo opsize */
302
OP_W,
/* word, indifferentemente dall'attributo opsize */
303
OP_PD,
/* registri dqword o xmm [FV] 128 bit o 256 bit packed double-precision float */
304
OP_SD,
/* registri qword o xmm */
305
OP_E,
/* usato quando i registri sono codificati direttamente */
306
OP_Y,
/* [FV] doubleword o quadword (in modalita' 64 bit), a seconda dell'attributo operand-size */
307
OP_FS,
/* [FV] 14 o 24 byte in memoria, a seconda di operand-size (usato da istruzioni load/store FPU state) */
308
OP_FSR,
/* [FV] 94 o 108 byte in memoria, a seconda di operand-size (usato da istruzioni FRSTOR/FSAVE FPU
309
* state piu' 80 bit registri FPU) */
310
OP_M80,
/* 80 bit in memoria */
311
OP_M512byte
/* 512 byte in memoria */
312
};
313
314
enum
op_size {
315
SIZE_8,
//Alice
316
SIZE_16,
317
SIZE_32,
318
SIZE_64
319
};
320
321
/* dimensione operando / indirizzo */
322
enum
reg_size {
323
REG_SIZE_8, REG_SIZE_16, REG_SIZE_32, REG_SIZE_64, REG_SIZE_128
324
};
325
326
// Per tenere traccia dello stato dell'interpretazione
327
struct
disassembly_state
{
328
enum
op_size opd_size;
// Dimensione dell'operando corrente
329
enum
op_size addr_size;
// Dimensione dell'indirizzo corrente
330
unsigned
char
*text;
// Sezione testo corrente (su cui si opera)
331
unsigned
long
pos;
// Posizione corrente nel testo
332
unsigned
char
rex;
// Il byte REX, o 0x00
333
bool
mode64;
// Stiamo eseguendo a 32 o a 64 bit?
334
unsigned
char
opcode[2];
// Opcode corrente
335
unsigned
char
modrm;
// Byte ModR/M o 0x00
336
bool
read_modrm;
// Indica se il byte ModR/M è stato letto
337
unsigned
char
sib;
// Byte SIB o 0x00
338
unsigned
long
disp_offset;
// L'inizio del displacement o 0
339
int
disp_size;
// Dimensione in byte del displacement
340
unsigned
long
immed_offset;
// L'inizio dei dati immediati o 0
341
int
immed_size;
// La dimensione dei dati immediati
342
enum
addr_method addr[3];
// Codice per il metodo di indirizzamento
343
enum
operand_type op[3];
// Codice per il tipo di operando
344
unsigned
char
prefix[4];
// Prefissi all'istruzione o 0x00
345
unsigned
char
sse_prefix;
// Terzo byte dell'istruzione SSE/SSE2
346
unsigned
long
orig_pos;
// Posizione iniziale nel testo
347
bool
read_dest;
// Indica se è stata analizzata la destinazione
348
349
// [FV] Flag indicante se l'istruzione usa un indirizzamento RIP_Relative o meno
350
bool
uses_rip;
351
352
insn_info_x86
*instrument;
// Struttura dati per gestire l'instrumentazione
353
};
354
355
struct
_insn
{
356
char
*instruction;
// Nome dell'istruzione (es: "mov")
357
enum
addr_method addr_method[3];
// Metodo di indirizzamento (Appendice A di IA-32 SDM)
358
enum
operand_type operand_type[3];
// Tipo corrispondete (sempre dall'appendice A)
359
void (*esc_function)(
struct
disassembly_state
*);
// Gestore dei byte addizionali dell'opcode
360
unsigned
long
flags;
// Flag contenente info utili sull'istruzione (così come definiti in "instruction.h")
361
};
362
363
typedef
struct
_insn
insn
, *
insn_table
;
364
365
extern
void
x86_disassemble_instruction(
unsigned
char
*text,
unsigned
long
*pos,
insn_info_x86
* instrument,
char
flags);
disassembly_state
Definition:
disassemble.h:459
insn_info_x86
Definition:
disassemble.h:59
_insn
Definition:
disassemble.h:488
src
arch
x86.h
Generated by
1.8.11