summaryrefslogtreecommitdiff
path: root/src/arch/x86/operand.h
blob: 12bd3716734eb3be9c205f658ad2f0e4166ef8fd (plain)
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259

/* OpenIDA - Outil d'analyse de fichiers binaires
 * operand.h - prototypes pour la gestion des operandes de l'architecture x86
 *
 * Copyright (C) 2008 Cyrille Bagard
 *
 *  This file is part of OpenIDA.
 *
 *  OpenIDA is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpenIDA is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef _ARCH_X86_OPERAND_H
#define _ARCH_X86_OPERAND_H


#include <stdbool.h>


#include "../immediate.h"
#include "../instruction.h"
#include "registers.h"



/* ---------------------- COQUILLE VIDE POUR LES OPERANDES X86 ---------------------- */


#define G_TYPE_X86_OPERAND                  g_x86_operand_get_type()
#define G_X86_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_operand_get_type(), GX86Operand))
#define G_IS_X86_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_operand_get_type()))
#define G_X86_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_operand_get_type(), GX86OperandIface))


/* Définition d'un opérande de x86 (instance) */
typedef struct _GX86Operand GX86Operand;

/* Définition d'un opérande de x86 (classe) */
typedef struct _GX86OperandClass GX86OperandClass;


/* Indique le type défini par la GLib pour un opérande de x86. */
GType g_x86_operand_get_type(void);



/* ------------------------ OPERANDES VISANT UN REGISTRE X86 ------------------------ */


#define G_TYPE_X86_REGISTER_OPERAND                  g_x86_register_operand_get_type()
#define G_X86_REGISTER_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_register_operand_get_type(), GX86RegisterOperand))
#define G_IS_X86_REGISTER_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_register_operand_get_type()))
#define G_X86_REGISTER_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_register_operand_get_type(), GX86RegisterOperandIface))


/* Définition d'un opérande visant un registre x86 (instance) */
typedef struct _GX86RegisterOperand GX86RegisterOperand;

/* Définition d'un opérande visant un registre x86 (classe) */
typedef struct _GX86RegisterOperandClass GX86RegisterOperandClass;


/* Indique le type défini par la GLib pour un opérande de registre x86. */
GType g_x86_register_operand_get_type(void);

/* Crée un opérande visant un registre x86. */
GArchOperand *g_x86_register_operand_new_from_opcode(const bin_t *, off_t *, off_t, MemoryDataSize, bin_t);

/* Crée un opérande visant un registre x86. */
GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *, off_t *, off_t, MemoryDataSize, bool);

/* Crée un opérande visant un registre x86 donné. */
GArchOperand *g_x86_register_operand_new_from_index(bin_t, MemoryDataSize);



/* ----------------------- OPERANDES COMPLEXES DE TYPE MOD/RM ----------------------- */


#define G_TYPE_X86_MOD_RM_OPERAND                  g_x86_mod_rm_operand_get_type()
#define G_X86_MOD_RM_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_mod_rm_operand_get_type(), GX86ModRMOperand))
#define G_IS_X86_MOD_RM_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_mod_rm_operand_get_type()))
#define G_X86_MOD_RM_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_mod_rm_operand_get_type(), GX86ModRMOperandIface))


/* Définition d'un opérande x86 de type ModRM (instance) */
typedef struct _GX86ModRMOperand GX86ModRMOperand;

/* Définition d'un opérande x86 de type ModRM (classe) */
typedef struct _GX86ModRMOperandClass GX86ModRMOperandClass;


/* Indique le type défini par la GLib pour un opérande x86 de type ModRM. */
GType g_x86_mod_rm_operand_get_type(void);

/* Crée un opérande x86 de type ModRM. */
GArchOperand *g_x86_mod_rm_operand_new(const bin_t *, off_t *, off_t, MemoryDataSize);

/* Fournit l'indice et l'échelle d'un opérande x86 ModRM. */
void g_x86_mod_rm_operand_get_scale_and_index(const GX86ModRMOperand *operand, uint8_t *, const GX86Register **);

/* Fournit le registre de base d'un opérande x86 ModRM. */
const GX86Register *g_x86_mod_rm_operand_get_base(const GX86ModRMOperand *);

/* Fournit le décallage supplémentaire d'un opérande x86 ModRM. */
const GImmOperand *g_x86_mod_rm_operand_get_displacement(const GX86ModRMOperand *);



/* ------------------------- OPERANDES D'ADRESSES RELATIVES ------------------------- */


#define G_TYPE_X86_RELATIVE_OPERAND                  g_x86_relative_operand_get_type()
#define G_X86_RELATIVE_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_relative_operand_get_type(), GX86RelativeOperand))
#define G_IS_X86_RELATIVE_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_relative_operand_get_type()))
#define G_X86_RELATIVE_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_relative_operand_get_type(), GX86RelativeOperandIface))


/* Définition d'un opérande x86 d'adresse relative (instance) */
typedef struct _GX86RelativeOperand GX86RelativeOperand;

/* Définition d'un opérande x86 d'adresse relative (classe) */
typedef struct _GX86RelativeOperandClass GX86RelativeOperandClass;


/* Indique le type défini par la GLib pour un opérande x86 d'adresse relative. */
GType g_x86_relative_operand_get_type(void);

/* Crée un opérande X86 d'adresse relative. */
GArchOperand *g_x86_relative_operand_new(const bin_t *, off_t *, off_t, MemoryDataSize, vmpa_t);

/* Fournit l'adresse représentée par une opérande X86. */
const GImmOperand *g_x86_relative_operand_get_value(const GX86RelativeOperand *);



/* ------------------------ OPERANDES D'EMPLACEMENTS MEMOIRE ------------------------ */


#define G_TYPE_X86_MOFFS_OPERAND                  g_x86_moffs_operand_get_type()
#define G_X86_MOFFS_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_moffs_operand_get_type(), GX86MoffsOperand))
#define G_IS_X86_MOFFS_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_moffs_operand_get_type()))
#define G_X86_MOFFS_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_moffs_operand_get_type(), GX86MoffsOperandIface))


/* Définition d'un opérande visant un emplacement mémoire x86 (instance) */
typedef struct _GX86MOffsOperand GX86MOffsOperand;

/* Définition d'un opérande visant un emplacement mémoire x86 (classe) */
typedef struct _GX86MOffsOperandClass GX86MOffsOperandClass;


/* Indique le type défini par la GLib pour un opérande d'emplacement mémoire x86. */
GType g_x86_moffs_operand_get_type(void);

/* Crée un opérande d'emplacement mémoire x86. */
GArchOperand *g_x86_moffs_operand_new(const bin_t *, off_t *, off_t, MemoryDataSize);



/* ---------------------- OPERANDES DE MANIPULATION DE DONNEES ---------------------- */


#define G_TYPE_X86_DATA_OPERAND                  g_x86_data_operand_get_type()
#define G_X86_DATA_OPERAND(obj)                  (G_TYPE_CHECK_INSTANCE_CAST((obj), g_x86_data_operand_get_type(), GX86DataOperand))
#define G_IS_X86_DATA_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_x86_data_operand_get_type()))
#define G_X86_DATA_OPERAND_GET_IFACE(inst)       (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_data_operand_get_type(), GX86DataOperandIface))


/* Définition d'un opérande x86 de manipulation de données (instance) */
typedef struct _GX86DataOperand GX86DataOperand;

/* Définition d'un opérande x86 de manipulation de données (classe) */
typedef struct _GX86DataOperandClass GX86DataOperandClass;


/* Indique le type défini par la GLib pour un opérande x86 de manipulation de données. */
GType g_x86_data_operand_get_type(void);

/* Crée un opérande x86 de manipulation de données. */
GArchOperand *g_x86_data_operand_new(MemoryDataSize, bool);



/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */


/* Construction d'identifiants typés */

#define X86_OTP_IMM_TYPE    0x8000
#define X86_OTP_REG_TYPE    0x4000
#define X86_OTP_RM_TYPE     0x2000
#define X86_OTP_DATA_TYPE   0x1000

#define X86_OTP_IMM(b)  X86_OTP_IMM_TYPE  | (1 << b)
#define X86_OTP_REG(b)  X86_OTP_REG_TYPE  | (1 << b)
#define X86_OTP_RM(b)   X86_OTP_RM_TYPE   | (1 << b)
#define X86_OTP_DATA(b) X86_OTP_DATA_TYPE | (1 << b)

/* Types d'opérandes supportés */
typedef enum _X86OperandType
{
    X86_OTP_NONE        = 0,                /* Aucun opérande de prévu     */

    X86_OTP_IMM8        = X86_OTP_IMM(1),   /* Valeur immédiate sur 8 bits */
    X86_OTP_IMM16       = X86_OTP_IMM(2),   /* Valeur immédiate sur 16b    */
    X86_OTP_IMM1632     = X86_OTP_IMM(3),   /* Valeur immédiate sur 16/32b */
    X86_OTP_MOFFS8      = X86_OTP_IMM(4),   /* Décallage immédiat 8 bits   */
    X86_OTP_MOFFS1632   = X86_OTP_IMM(5),   /* Décallage immédiat 16/32b   */
    X86_OTP_REL8        = X86_OTP_IMM(6),   /* Adresse relative 8 bits     */
    X86_OTP_REL1632     = X86_OTP_IMM(7),   /* Adresse relative 16/32 bits */

    X86_OTP_R8          = X86_OTP_REG(1),   /* Registre 8 bits             */
    X86_OTP_R1632       = X86_OTP_REG(2),   /* Registre 16 ou 32 bits      */
    X86_OTP_OP_R8       = X86_OTP_REG(3),   /* Registre 8 bits             */
    X86_OTP_OP_R1632    = X86_OTP_REG(4),   /* Registre 16 ou 32 bits      */

    X86_OTP_RM8         = X86_OTP_RM(1),    /* Registre 8 bits ou mémoire  */
    X86_OTP_RM16        = X86_OTP_RM(2),    /* Registre 16 bits ou mémoire */
    X86_OTP_RM1632      = X86_OTP_RM(3),    /* Registre 16/32b ou mémoire  */

    X86_OTP_DST_8       = X86_OTP_DATA(1),  /* Emplacement sur 8 bits      */
    X86_OTP_DST_1632    = X86_OTP_DATA(2),  /* Emplacement sur 16/32 bits  */
    X86_OTP_SRC_8       = X86_OTP_DATA(3),  /* Emplacement sur 8 bits      */
    X86_OTP_SRC_1632    = X86_OTP_DATA(4),  /* Emplacement sur 16/32 bits  */

    X86_OTP_ONE         = 0x0ffc,           /* Valeur immédiate "1"        */
    X86_OTP_CL          = 0x0ffd,           /* Registre cl                 */
    X86_OTP_AL          = 0x0ffe,           /* Registre al                 */
    X86_OTP_E_AX        = 0x0fff            /* Registre eax ou ax          */

} X86OperandType;


/* Nombre maximal d'opérande */
#define MAX_OPERANDS 3


#define x86_read_one_operand(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 1, __VA_ARGS__)
#define x86_read_two_operands(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 2, __VA_ARGS__)
#define x86_read_three_operands(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 3, __VA_ARGS__)

/* Procède à la lecture de n opérandes donnés. */
bool _x86_read_operands(GArchInstruction *, const bin_t *, off_t *, off_t, unsigned int, ...);



#endif  /* _ARCH_X86_OPERAND_H */