The ROme OpTimistic Simulator
2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
Main Page
Data Structures
Files
File List
Globals
disassemble.h
Go to the documentation of this file.
1
42
#pragma once
43
44
#if defined(__x86_64__)
45
46
#include <stdint.h>
47
#include <stdbool.h>
48
50
#define DATA_32 0x01
51
#define ADDR_32 0x02
53
#define DATA_64 0x04
55
#define ADDR_64 0x08
57
58
59
typedef
struct
insn_info_x86
{
60
unsigned
long
flags;
// Insieme di flags contenente informazioni utili generiche riguardo l'istruzione
61
unsigned
char
insn
[15];
// I byte dell'istruzione (15 è il limite massimo)
62
unsigned
char
opcode[2];
// L'opcode dell'istruzione
63
char
mnemonic[16];
// Il nome dell'istruzione
64
unsigned
long
initial;
// Posizione iniziale nel testo
65
unsigned
long
insn_size;
// Lunghezza dell'istruzione
66
unsigned
long
addr;
// Indirizzo puntato dall'istruzione, o 0x00
67
unsigned
long
span;
// Quanto in memoria verrà riscritto/letto, o 0x00
68
bool
has_index_register;
// L'indirizzamento sfrutta un indice?
69
unsigned
char
ireg;
// Quale registro contiene l'indice?
70
char
ireg_mnem[8];
// Mnemonico del registro di indice
71
bool
has_base_register;
// L'indirizzamento sfrutta una base?
72
unsigned
char
breg;
// Quale registro contiene la base?
73
char
breg_mnem[8];
// Mnemonico del registro
74
bool
has_scale;
// L'indirizzamento utilizza una scala
75
unsigned
long
scale;
// La scala
76
unsigned
long
disp_offset;
// Lo spiazzamento del displacement dall'inizio del testo, o 0x00
77
int
disp_size;
// Dimensione in byte del displacement, o 0x00
78
long
long
disp;
// Il valore dello spiazzamento
79
unsigned
long
immed_offset;
// [SE] Lo spiazzamento dei dati immediati dall'inizio del testo, o 0x00
80
int
immed_size;
// [SE] La dimensione dei dati immediati, o 0x00
81
unsigned
long
long
immed;
// [SE] Il valore dei dati immediati
82
unsigned
int
opcode_size;
// [DC] Dimensione dell'opcode per l'istruzione
83
int32_t jump_dest;
// Dove punta la jmp
84
bool
uses_rip;
85
unsigned
char
rex;
// Il byte REX, o 0x00
86
unsigned
char
modrm;
// Byte ModR/M o 0x00
87
unsigned
char
sib;
// Byte SIB o 0x00
88
unsigned
char
sse_prefix;
// Terzo byte dell'istruzione SSE/SSE2
89
unsigned
char
prefix[4];
// Prefissi all'istruzione o 0x00
90
91
bool
dest_is_reg;
// [SE] Indica se la destinazione è un registro
92
unsigned
char
reg_dest;
// [SE] Codice del registro destinazione (se esiste)
93
}
insn_info_x86
;
94
95
// [FV] Flags contenenti informazioni utili sul comportamento o la classe delle funzioni
96
#define I_MEMRD 0x1 // Legge dalla memoria
97
#define I_MEMWR 0x2 // Scrive sulla memoria
98
#define I_CTRL 0x4 // Istruzioni della famiglia "test" e "control" che controllano valori di dati o singoli bit
99
#define I_JUMP 0x8 // Istruzioni della famiglia "jump", che modificano il flusso di esecuzione del processore
100
#define I_CALL 0x10 // Istruzione del tipo "call"
101
#define I_RET 0x20 // Istruzione del tipo "call"
102
#define I_CONDITIONAL 0x40 // Istruzione che viene eseguite se e solo se e' soddisfatta una condizione
103
#define I_STRING 0x80 // Opera su stringhe (e.g. movs, stos, cmps...)
104
#define I_ALU 0x100 // Esegue operazioni di tipo logico-aritmetico
105
#define I_FPU 0x200 // Utilizza la Floating Point Unit (FPU)
106
#define I_MMX 0x400 // Istruzione che utilizza i registri MMX
107
#define I_XMM 0x800 // Istruzione che utilizza i registri XMM
108
#define I_SSE 0x1000 // Istruzione SSE
109
#define I_SSE2 0x2000 // Istruzione SSE2
110
#define I_PUSHPOP 0x4000 // Istruzione di tipo "push" o di tipo "pop"
111
#define I_STACK 0x8000 // Se l'istruzione opera nello stack
112
#define I_JUMPIND 0x10000 // Indirect Branch
113
#define I_CALLIND 0x20000 // [SE] Indirect Call
114
#define I_MEMIND 0x40000 // [SE] Indirect memory address load (LEA)
115
116
// [FV] Macro per il testing dei flags
117
#define IS_MEMRD(X) ((X)->flags & I_MEMRD)
118
#define IS_MEMWR(X) ((X)->flags & I_MEMWR)
119
#define IS_MEMIND(X) ((X)->flags & I_MEMIND)
120
#define IS_CTRL(X) ((X)->flags & I_CTRL)
121
#define IS_JUMP(X) ((X)->flags & I_JUMP)
122
#define IS_JUMPIND(X) ((X)->flags & I_JUMPIND)
123
#define IS_CALL(X) ((X)->flags & I_CALL)
124
#define IS_CALLIND(X) ((X)->flags & I_CALLIND)
125
#define IS_RET(X) ((X)->flags & I_RET)
126
#define IS_CONDITIONAL(X) ((X)->flags & I_CONDITIONAL)
127
#define IS_STRING(X) ((X)->flags & I_STRING)
128
#define IS_ALU(X) ((X)->flags & I_ALU)
129
#define IS_FPU(X) ((X)->flags & I_FPU)
130
#define IS_MMX(X) ((X)->flags & I_MMX)
131
#define IS_XMM(X) ((X)->flags & I_XMM)
132
#define IS_SSE(X) ((X)->flags & I_SSE)
133
#define IS_SSE2(X) ((X)->flags & I_SSE2)
134
#define IS_PUSHPOP(X) ((X)->flags & I_PUSHPOP)
135
#define IS_STACK(X) ((X)->flags & I_STACK)
136
137
138
// Strings to load macros from the configuration file
139
#define I_MEMRD_S "I_MEMRD"
140
#define I_MEMWR_S "I_MEMWR"
141
#define I_MEMIND_S "I_MEMIND"
142
#define I_CTRL_S "I_CTRL"
143
#define I_JUMP_S "I_JUMP"
144
#define I_JUMPIND_S "I_JUMPIND"
145
#define I_CALL_S "I_CALL"
146
#define I_CALLIND_S "I_CALLIND"
147
#define I_RET_S "I_RET"
148
#define I_CONDITIONAL_S "I_CONDITIONAL"
149
#define I_STRING_S "I_STRING"
150
#define I_ALU_S "I_ALU"
151
#define I_FPU_S "I_FPU"
152
#define I_MMX_S "I_MMX"
153
#define I_XMM_S "I_XMM"
154
#define I_SSE_S "I_SSE"
155
#define I_SSE2_S "I_SSE2"
156
#define I_PUSHPOP_S "I_PUSHPOP"
157
#define I_STACK_S "I_STACK"
158
159
// Arch-Dependent Instruction Sets
160
#define UNRECOG_INSN 0
161
#define X86_INSN 7
162
163
164
#define A32(f) ((f) & ADDR_32) // Indirizzi a 32 bit?
165
#define D32(f) ((f) & DATA_32) // Dati a 32 bit?
166
#define A64(f) ((f) & ADDR_64) // Indirizzi a 64 bit?
167
#define D64(f) ((f) & DATA_64) // Dati a 64 bit?
168
169
/* Test sui prefissi */
170
#define p_is_group1(p) (((p) == 0xf0)
/* lock */
\
171
|| ((p) == 0xf2)
/* repne/repnz */
\
172
|| ((p) == 0xf3))
/* rep/repe/repz */
173
174
#define p_is_group2(p) (((p) == 0x2e)
/* CS override/branch not taken */
\
175
|| ((p) == 0x36)
/* SS override */
\
176
|| ((p) == 0x3e)
/* DS override/branch taken */
\
177
|| ((p) == 0x26)
/* ES override */
\
178
|| ((p) == 0x64)
/* FS override */
\
179
|| ((p) == 0x65))
/* GS override */
180
181
#define p_is_group3(p) ((p) == 0x66)
/* opsize override */
182
183
#define p_is_group4(p) ((p) == 0x67)
/* addr size override */
184
185
#define is_prefix(o) (p_is_group1 (o) || p_is_group2 (o) \
186
|| p_is_group3 (o) || p_is_group4 (o))
187
188
#define is_sse_prefix(o) (((o) == 0xf2) || ((o) == 0xf3) || ((o) == 0x66))
189
190
#define is_rex_prefix(r, mode64) (((r) >= 0x40 && (r) <= 0x4f ) && (mode64))
191
192
193
/* Recuperano i bit di interesse del byte REX (i primi 4 bit sono fissi e valgono 0100b) */
194
195
#define REXW(r) (((r) & 0x08) >> 3)
196
#define REXR(r) (((r) & 0x04) >> 2)
197
#define REXX(r) (((r) & 0x02) >> 1)
198
#define REXB(r) (((r) & 0x01))
199
200
201
/* Test per le operazioni Jcc */
202
203
// opcode nell'intervallo 70-7f,e3
204
#define is_jcc_insn(o) (((o) == 0xe3) || (((o) >= 0x70) && ((o) <= 0x7f)))
205
206
// opcode nell'intervallo 80-8f (quando il primo byte è 0f)
207
#define is_esc_jcc_insn(o) (((o) >= 0x80) && ((o) <= 0x8f))
208
209
210
// Gli operandi dell'istruzione specificano se c'è o meno un byte ModR/M
211
#define has_modrm(addr) (((addr) == ADDR_C) \
212
|| ((addr) == ADDR_D) \
213
|| ((addr) == ADDR_E) \
214
|| ((addr) == ADDR_G) \
215
|| ((addr) == ADDR_M) \
216
|| ((addr) == ADDR_P) \
217
|| ((addr) == ADDR_Q) \
218
|| ((addr) == ADDR_R) \
219
|| ((addr) == ADDR_S) \
220
|| ((addr) == ADDR_T) \
221
|| ((addr) == ADDR_V) \
222
|| ((addr) == ADDR_W))
223
224
// È presente un byte SIB se il campo Mod non è 11b, il campo R/M è
225
// 100b e la modalità di indirizzamento è a 32 bit o 64 bit
226
#define has_sib(modrm, addr) ((((modrm) & 0x07) == 0x04) \
227
&& (((addr) == SIZE_32) || (addr) == SIZE_64) \
228
&& (((modrm) & 0xC0) != 0xC0))
229
230
// Se il campo Mod è 01b, allora c'è uno spiazzamento di 1 byte. Se il campo
231
// Mod è 10b, e siamo in modalità di indirizzamento a 32/64 bit, allora c'è
232
// uno spiazzamento di 4 byte. Inoltre, se la modalità di indirizzamento è
233
// a 16 bit e il campo Mod è 10b, allora c'è uno spiazzamento di 2 byte.
234
// Se la modalità di indirizzamento è a 32 o 64 bit e sia il campo Mod è 00b sia
235
// il campo R/M è 101b, o il campo Mod è 10b, allora c'è uno spiazzamento
236
// di 4 byte. Altrimenti non c'è spiazzamento.
237
#define disp_size(modrm, addr) ((((modrm) & 0xC0) == 0x40) ? 1 \
238
: ((((addr) == SIZE_16) \
239
&& ((((modrm) & 0xC7) == 0x06) \
240
|| (((modrm) & 0xC0) == 0x80))) ? 2 \
241
: (((((addr) == SIZE_32) || (addr) == SIZE_64) \
242
&& ((((modrm) & 0xC7) == 0x05) \
243
|| (((modrm) & 0xC0) == 0x80))) ? 4\
244
: 0)))
245
246
enum
addr_method {
247
ADDR_0,
/* Nessun metodo di indirizzamento */
248
ADDR_A,
/* Indirizzamento diretto, nessun byte ModR/M */
249
ADDR_C,
/* Il campo reg del byte ModR/M seleziona un registro di controllo */
250
ADDR_D,
/* Il campo reg del byte ModR/M seleziona un registro di debug */
251
ADDR_E,
/* Il byte ModR/M specifica l'operando: o un registro general purpose
252
o un offset per un indirizzo di memoria da un segment register
253
con un registro base, un registro d'indice, un fattore di scala
254
o spiazzamento */
255
ADDR_F,
/* registro EFLAGS */
256
ADDR_G,
/* Il campo reg del byte ModR/M seleziona un registro generale */
257
ADDR_I,
/* Dati immediati */
258
ADDR_J,
/* L'istruzione contiene un offset relativo, da (E)IP */
259
ADDR_M,
/* Il byte ModR/M può riferirsi solo a memoria */
260
ADDR_N,
/* [FV] Il campo R/M del byte ModR/M indica un registro MMX */
261
ADDR_O,
/* Nessun byte ModR/M. L'op è codificata come word o dword o qword in 64bit */
262
ADDR_P,
/* Il campo reg del byte ModR/M seleziona un registro packed qword MMX */
263
ADDR_Q,
/* Il byte ModR/M specifica o un registro MMX o un indirizzo in memoria (scala, ecc...) */
264
ADDR_R,
/* Il campo reg del byte ModR/M si può riferire solo a un registro generale */
265
ADDR_S,
/* Il campo reg del byte ModR/M seleziona un segment register */
266
ADDR_T,
/* Il campo reg del byte ModR/M seleziona un registro di test */
267
ADDR_U,
// Alice: Il campo R/M del byte ModR/M seleziona un registro XMM
268
ADDR_V,
/* Il campo reg del byte ModR/M seleziona un registro MMX */
269
ADDR_W,
/* Il byte ModR/M seleziona un registro XMM o un indirizzo in memoria (scala, ecc...) */
270
ADDR_X,
/* Indirizzo di memoria da DS:SI */
271
ADDR_Y,
/* Indirizzo di memoria da ES:DI */
272
273
/* Registri */
274
R_START,
275
276
R_AL,
277
R_AH,
278
R_AX,
279
R_EAX,
280
R_RAX,
281
282
R_BL,
283
R_BH,
284
R_BX,
285
R_EBX,
286
R_RBX,
287
288
R_CL,
289
R_CH,
290
R_CX,
291
R_ECX,
292
R_RCX,
293
294
R_DL,
295
R_DH,
296
R_DX,
297
R_EDX,
298
R_RDX,
299
300
R_SIL,
301
R_SI,
302
R_ESI,
303
R_RSI,
304
R_DIL,
305
R_DI,
306
R_EDI,
307
R_RDI,
308
R_BP,
309
R_EBP,
310
R_SPL,
311
R_SP,
312
R_ESP,
313
R_RSP,
314
315
/* segment registers */
316
R_CS,
317
R_DS,
318
R_SS,
319
R_ES,
320
R_FS,
321
R_GS,
322
323
/* EFLAGS */
324
R_F,
325
R_EF,
326
327
/* EIP */
328
R_IP,
329
R_EIP,
330
R_RIP,
331
332
/* floating point registers */
333
R_ST0,
334
R_ST1,
335
R_ST2,
336
R_ST3,
337
R_ST4,
338
R_ST5,
339
R_ST6,
340
R_ST7,
341
342
/* Extra registers in 64bit mode */
343
R_R8L,
344
R_R8W,
345
R_R8D,
346
R_R8,
347
348
R_R9L,
349
R_R9W,
350
R_R9D,
351
R_R9,
352
353
R_R10L,
354
R_R10W,
355
R_R10D,
356
R_R10,
357
358
R_R11L,
359
R_R11W,
360
R_R11D,
361
R_R11,
362
363
R_R12L,
364
R_R12W,
365
R_R12D,
366
R_R12,
367
368
R_R13L,
369
R_R13W,
370
R_R13D,
371
R_R13,
372
373
R_R14L,
374
R_R14W,
375
R_R14D,
376
R_R14,
377
378
R_R15L,
379
R_R15W,
380
R_R15D,
381
R_R15,
382
383
384
/* MMX registers */
385
R_MM0,
386
R_MM1,
387
R_MM2,
388
R_MM3,
389
R_MM4,
390
R_MM5,
391
R_MM6,
392
R_MM7,
393
394
/* SSE/SSE2 registers */
395
R_XMM0,
396
R_XMM1,
397
R_XMM2,
398
R_XMM3,
399
R_XMM4,
400
R_XMM5,
401
R_XMM6,
402
R_XMM7,
403
R_XMM8,
404
R_XMM9,
405
R_XMM10,
406
R_XMM11,
407
R_XMM12,
408
R_XMM13,
409
R_XMM14,
410
R_XMM15,
411
412
R_END,
413
414
/* Valore immediato interno all'istruzione (D0, D1) */
415
IMMED_1,
/* il valore 1 */
416
};
417
418
enum
operand_type {
419
OP_0,
/* nessun tipo */
420
OP_A,
/* due oper da 1 word o 2 operandi dword in mem (dipende dall'attr opsize) */
421
OP_B,
/* byte, indifferentemente dall'attrib opsize */
422
OP_C,
/* byte o word, a seconda dell'attrib opsize */
423
OP_D,
/* dword, indifferentemente dall'attributo opsize */
424
OP_DQ,
/* dqword, indifferentemebre dall'attr opsize */
425
OP_P,
/* puntatore di 32 o 48 bit a seconda dell'attributo opsize */
426
OP_PI,
/* Registro MMX qword */
427
OP_PS,
/* 128 bit packed single float [FV] o 256 bit */
428
OP_Q,
/* qword, indifferentemente dall'att opsize */
429
OP_S,
/* 6 byte pseudo-descriptor */
430
OP_SS,
/* Elemento scalare di un packed single float a 128 bit */
431
OP_SI,
/* registro dword (es: eax) */
432
OP_V,
/* word o dword, a seconda dell'attributo opsize */
433
OP_W,
/* word, indifferentemente dall'attributo opsize */
434
OP_PD,
/* registri dqword o xmm [FV] 128 bit o 256 bit packed double-precision float */
435
OP_SD,
/* registri qword o xmm */
436
OP_E,
/* usato quando i registri sono codificati direttamente */
437
OP_Y,
/* [FV] doubleword o quadword (in modalita' 64 bit), a seconda dell'attributo operand-size */
438
OP_FS,
/* [FV] 14 o 24 byte in memoria, a seconda di operand-size (usato da istruzioni load/store FPU state) */
439
OP_FSR,
/* [FV] 94 o 108 byte in memoria, a seconda di operand-size (usato da istruzioni FRSTOR/FSAVE FPU
440
* state piu' 80 bit registri FPU) */
441
OP_M80,
/* 80 bit in memoria */
442
OP_M512byte
/* 512 byte in memoria */
443
};
444
445
enum
op_size {
446
SIZE_8,
//Alice
447
SIZE_16,
448
SIZE_32,
449
SIZE_64
450
};
451
452
/* dimensione operando / indirizzo */
453
enum
reg_size {
454
REG_SIZE_8, REG_SIZE_16, REG_SIZE_32, REG_SIZE_64, REG_SIZE_128
455
};
456
457
458
// Per tenere traccia dello stato dell'interpretazione
459
struct
disassembly_state
{
460
enum
op_size opd_size;
// Dimensione dell'operando corrente
461
enum
op_size addr_size;
// Dimensione dell'indirizzo corrente
462
unsigned
char
*text;
// Sezione testo corrente (su cui si opera)
463
unsigned
long
pos;
// Posizione corrente nel testo
464
unsigned
char
rex;
// Il byte REX, o 0x00
465
bool
mode64;
// Stiamo eseguendo a 32 o a 64 bit?
466
unsigned
char
opcode[2];
// Opcode corrente
467
unsigned
char
modrm;
// Byte ModR/M o 0x00
468
bool
read_modrm;
// Indica se il byte ModR/M è stato letto
469
unsigned
char
sib;
// Byte SIB o 0x00
470
unsigned
long
disp_offset;
// L'inizio del displacement o 0
471
int
disp_size;
// Dimensione in byte del displacement
472
unsigned
long
immed_offset;
// L'inizio dei dati immediati o 0
473
int
immed_size;
// La dimensione dei dati immediati
474
enum
addr_method addr[3];
// Codice per il metodo di indirizzamento
475
enum
operand_type op[3];
// Codice per il tipo di operando
476
unsigned
char
prefix[4];
// Prefissi all'istruzione o 0x00
477
unsigned
char
sse_prefix;
// Terzo byte dell'istruzione SSE/SSE2
478
unsigned
long
orig_pos;
// Posizione iniziale nel testo
479
bool
read_dest;
// Indica se è stata analizzata la destinazione
480
481
// [FV] Flag indicante se l'istruzione usi un indirizzamento RIP_Relative o meno
482
bool
uses_rip;
483
484
insn_info_x86
*instrument;
// Struttura dati per gestire l'instrumentazione
485
};
486
487
488
struct
_insn
{
489
char
*instruction;
// Nome dell'istruzione (es: "mov")
490
enum
addr_method addr_method[3];
// Metodo di indirizzamento (Appendice A di IA-32 SDM)
491
enum
operand_type operand_type[3];
// Tipo corrispondete (sempre dall'appendice A)
492
void (*esc_function)(
struct
disassembly_state
*);
// Gestore dei byte addizionali dell'opcode
493
unsigned
long
flags;
// Flag contenente info utili sull'istruzione (così come definiti in "instruction.h")
494
};
495
496
typedef
struct
_insn
insn, *
insn_table
;
497
498
499
extern
void
x86_disassemble_instruction(
unsigned
char
*text,
unsigned
long
*pos,
insn_info_x86
*instrument,
char
flags);
500
501
#endif
/* defined(__x86_64__) */
502
disassembly_state
Definition:
disassemble.h:459
insn_info_x86
Definition:
disassemble.h:59
_insn
Definition:
disassemble.h:488
src
arch
x86
disassemble.h
Generated by
1.8.11