/* 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 .
*/
#ifndef _ARCH_X86_OPERAND_H
#define _ARCH_X86_OPERAND_H
#include
#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_IMM1632 = X86_OTP_IMM(2), /* Valeur immédiate sur 16/32b */
X86_OTP_MOFFS8 = X86_OTP_IMM(3), /* Décallage immédiat 8 bits */
X86_OTP_MOFFS1632 = X86_OTP_IMM(4), /* Décallage immédiat 16/32b */
X86_OTP_REL8 = X86_OTP_IMM(5), /* Adresse relative 8 bits */
X86_OTP_REL1632 = X86_OTP_IMM(6), /* 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_RM1632 = X86_OTP_RM(2), /* 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_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 */