From daa0084325d4e748f334a223e1cd3800120e6055 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 7 Oct 2009 00:22:10 +0000 Subject: Created a function to load n x86 operands and supported extra x86 opcodes. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@128 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 36 +++++ src/arch/artificial.c | 2 +- src/arch/instruction.c | 48 ------ src/arch/instruction.h | 6 - src/arch/jvm/operand.c | 2 +- src/arch/x86/instruction.c | 392 +++++++++++++++++++++++---------------------- src/arch/x86/instruction.h | 13 +- src/arch/x86/op_and.c | 110 +++++++++++++ src/arch/x86/op_cmp.c | 36 +++++ src/arch/x86/op_int.c | 2 +- src/arch/x86/op_jump.c | 72 +++++++++ src/arch/x86/op_mul.c | 36 +++++ src/arch/x86/opcodes.h | 21 +++ src/arch/x86/operand.c | 381 ++++++++++++++----------------------------- src/arch/x86/operand.h | 13 +- src/arch/x86/processor.c | 35 ++++ 16 files changed, 694 insertions(+), 511 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d4ecd5..a22419d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,39 @@ +09-10-07 Cyrille Bagard + + * src/arch/artificial.c: + Replace a call to g_arch_instruction_attach_one_operand() by a call + to g_arch_instruction_attach_extra_operand(). + + * src/arch/instruction.c: + * src/arch/instruction.h: + Remove the g_arch_instruction_attach_(one|two)_operand[s]() functions. + One can use g_arch_instruction_attach_extra_operand() instead. + + * src/arch/jvm/operand.c: + Replace a call to g_arch_instruction_attach_one_operand() by a call + to g_arch_instruction_attach_extra_operand(). + + * src/arch/x86/instruction.c: + * src/arch/x86/instruction.h: + * src/arch/x86/op_and.c: + * src/arch/x86/op_cmp.c: + * src/arch/x86/opcodes.h: + Support extra x86 opcodes. + + * src/arch/x86/operand.c: + * src/arch/x86/operand.h: + Create a function to load n operands. Remove the older ones allowing to + load one or two operands. Add comments to fix later endianness. + + * src/arch/x86/op_int.c: + Replace a call to g_arch_instruction_attach_one_operand() by a call + to g_arch_instruction_attach_extra_operand(). + + * src/arch/x86/op_jump.c: + * src/arch/x86/op_mul.c: + * src/arch/x86/processor.c: + Support extra x86 opcodes. + 09-10-06 Cyrille Bagard * src/arch/immediate.c: diff --git a/src/arch/artificial.c b/src/arch/artificial.c index a1fa56e..16e95bc 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -139,7 +139,7 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos, g_arch_processor_get_endianness(proc)); if (operand == NULL) goto gdinfd_error; - g_arch_instruction_attach_one_operand(result, operand); + g_arch_instruction_attach_extra_operand(result, operand); return result; diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 8bc317b..16e5c81 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -196,54 +196,6 @@ void g_arch_instruction_get_location(GArchInstruction *instr, off_t *offset, off * Paramètres : instr = instance à mettre à jour. * * opererand = instruction à venir associer. * * * -* Description : Attache un seul opérande à un instruction. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_attach_one_operand(GArchInstruction *instr, GArchOperand *operand) -{ - instr->operands = (GArchOperand **)calloc(1, sizeof(GArchOperand *)); - instr->operands_count = 1; - - instr->operands[0] = operand; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance à mettre à jour. * -* operand1 = première instruction à venir associer. * -* operand2 = seconde instruction à venir associer. * -* * -* Description : Attache deux opérandes à un instruction. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_arch_instruction_attach_two_operands(GArchInstruction *instr, GArchOperand *operand1, GArchOperand *operand2) -{ - instr->operands = (GArchOperand **)calloc(2, sizeof(GArchOperand *)); - instr->operands_count = 2; - - instr->operands[0] = operand1; - instr->operands[1] = operand2; - -} - - -/****************************************************************************** -* * -* Paramètres : instr = instance à mettre à jour. * -* opererand = instruction à venir associer. * -* * * Description : Attache un opérande supplémentaire à une instruction. * * * * Retour : - * diff --git a/src/arch/instruction.h b/src/arch/instruction.h index accaed6..0c51b93 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -70,12 +70,6 @@ void g_arch_instruction_set_location(GArchInstruction *, off_t, off_t, vmpa_t); /* Fournit la localisation d'une instruction. */ void g_arch_instruction_get_location(GArchInstruction *, off_t *, off_t *, vmpa_t *); -/* Attache un seul opérande à une instruction. */ -void g_arch_instruction_attach_one_operand(GArchInstruction *, GArchOperand *); - -/* Attache deux opérandes à une instruction. */ -void g_arch_instruction_attach_two_operands(GArchInstruction *, GArchOperand *, GArchOperand *); - /* Attache un opérande supplémentaire à une instruction. */ void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *); diff --git a/src/arch/jvm/operand.c b/src/arch/jvm/operand.c index 429516a..a485a2b 100644 --- a/src/arch/jvm/operand.c +++ b/src/arch/jvm/operand.c @@ -324,7 +324,7 @@ bool jvm_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos if (op == NULL) return false; - g_arch_instruction_attach_one_operand(instr, op); + g_arch_instruction_attach_extra_operand(instr, op); return true; diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c index c8d31a0..72143ee 100644 --- a/src/arch/x86/instruction.c +++ b/src/arch/x86/instruction.c @@ -80,262 +80,274 @@ typedef struct _x86_instruction static x86_instruction _instructions[XOP_COUNT] = { - [XOP_ADD_RM8_R8] = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE }, - [XOP_ADD_RM1632_R1632] = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ADD_R8_RM8] = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE }, - [XOP_ADD_R1632_RM1632] = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ADD_AL_IMM8] = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE }, - [XOP_ADD_E_AX_IMM1632] = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADD_RM8_R8] = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE }, + [XOP_ADD_RM1632_R1632] = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADD_R8_RM8] = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE }, + [XOP_ADD_R1632_RM1632] = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADD_AL_IMM8] = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE }, + [XOP_ADD_E_AX_IMM1632] = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, + [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, - [XOP_OR_RM8_R8] = { false, 0x08, IDX_TO_EXT(-1), "or", XPX_NONE }, - [XOP_OR_RM1632_R1632] = { false, 0x09, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, - [XOP_OR_R1632_RM1632] = { false, 0x0b, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_OR_AL_IMM8] = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE }, + [XOP_OR_RM8_R8] = { false, 0x08, IDX_TO_EXT(-1), "or", XPX_NONE }, + [XOP_OR_RM1632_R1632] = { false, 0x09, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, + [XOP_OR_R1632_RM1632] = { false, 0x0b, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_OR_AL_IMM8] = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE }, - [XOP_JE_REL1632] = { false, 0x84, IDX_TO_EXT(-1), "je", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JNE_REL1632] = { false, 0x85, IDX_TO_EXT(-1), "jne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JE_REL1632] = { false, 0x84, IDX_TO_EXT(-1), "je", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JNE_REL1632] = { false, 0x85, IDX_TO_EXT(-1), "jne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JBE_REL1632] = { false, 0x86, IDX_TO_EXT(-1), "jbe", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JA_REL1632] = { false, 0x87, IDX_TO_EXT(-1), "ja", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JA_REL1632] = { false, 0x87, IDX_TO_EXT(-1), "ja", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - - [XOP_JGE_REL1632] = { false, 0x8d, IDX_TO_EXT(-1), "jge", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JLE_REL1632] = { false, 0x8e, IDX_TO_EXT(-1), "jle", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - - - [XOP_SETE_RM8] = { false, 0x94, IDX_TO_EXT(-1), "sete", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SETNE_RM8] = { false, 0x95, IDX_TO_EXT(-1), "setne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - - - [XOP_MOVZX_R1632_RM8] = { false, 0xb6, IDX_TO_EXT(-1), "movzx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOVSX_R1632_RM8] = { false, 0xbe, IDX_TO_EXT(-1), "movsx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JGE_REL1632] = { false, 0x8d, IDX_TO_EXT(-1), "jge", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JLE_REL1632] = { false, 0x8e, IDX_TO_EXT(-1), "jle", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JG_REL1632] = { false, 0x8f, IDX_TO_EXT(-1), "jg", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ADC_RM8_R8] = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE }, - - [XOP_AND_RM8_R8] = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE }, - - [XOP_SUB_RM1632_R1632] = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - - [XOP_SUB_R8_RM8] = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE }, - [XOP_SUB_AL_IMM8] = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE }, - - [XOP_SUB_E_AX_IMM1632] = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - + [XOP_SETE_RM8] = { false, 0x94, IDX_TO_EXT(-1), "sete", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SETNE_RM8] = { false, 0x95, IDX_TO_EXT(-1), "setne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XOR_RM8_R8] = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE}, - [XOP_XOR_RM1632_R1632] = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XOR_R8_RM8] = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE}, - [XOP_XOR_R1632_RM1632] = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XOR_AL_IMM8] = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE }, - [XOP_XOR_E_AX_IMM1632] = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOVZX_R1632_RM8] = { false, 0xb6, IDX_TO_EXT(-1), "movzx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOVSX_R1632_RM8] = { false, 0xbe, IDX_TO_EXT(-1), "movsx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADC_RM8_R8] = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE }, + [XOP_AND_RM8_R8] = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE }, + [XOP_AND_RM1632_R1632] = { false, 0x21, IDX_TO_EXT(-1), "and", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_CMP_RM1632_R1632] = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_AX] = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_CX] = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_DX] = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_BX] = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_SP] = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_BP] = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_SI] = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INC_E_DI] = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_AX] = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_CX] = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_DX] = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_BX] = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_SP] = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_BP] = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_SI] = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_E_DI] = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_AX] = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_CX] = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_DX] = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_BX] = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_SP] = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_BP] = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_SI] = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_E_DI] = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_AX] = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_CX] = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_DX] = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_BX] = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_SP] = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_BP] = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_SI] = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_POP_E_DI] = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_AND_AL_IMM8] = { false, 0x24, IDX_TO_EXT(-1), "and", XPX_NONE }, + [XOP_AND_E_AX_IMM1632] = { false, 0x25, IDX_TO_EXT(-1), "and", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_IMM1632] = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_RM1632_R1632] = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_R8_RM8] = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE }, + [XOP_SUB_AL_IMM8] = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE }, - [XOP_IMUL_RM1632_IMM8] = { false, 0x6b, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_E_AX_IMM1632] = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JO_REL8] = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE }, - [XOP_JNO_REL8] = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE }, - [XOP_JB_REL8] = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE }, - [XOP_JNB_REL8] = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE }, - [XOP_JE_REL8] = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE }, - [XOP_JNE_REL8] = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE }, - [XOP_JNA_REL8] = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE }, - [XOP_JA_REL8] = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE }, - [XOP_JS_REL8] = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE }, - [XOP_JNS_REL8] = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE }, - [XOP_JP_REL8] = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE }, - [XOP_JNP_REL8] = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE }, - [XOP_JL_REL8] = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE }, - [XOP_JNL_REL8] = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE }, - [XOP_JNG_REL8] = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE }, - [XOP_JG_REL8] = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE }, - [XOP_ADD_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE }, - [XOP_OR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE }, - [XOP_ADC_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE }, - [XOP_SBB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE }, - [XOP_AND_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE }, - [XOP_SUB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE }, - [XOP_XOR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE }, - [XOP_CMP_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE }, - [XOP_ADD_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_OR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ADC_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SBB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_AND_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SUB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XOR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_CMP_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_RM8_R8] = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE}, + [XOP_XOR_RM1632_R1632] = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_R8_RM8] = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE}, + [XOP_XOR_R1632_RM1632] = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_AL_IMM8] = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE }, + [XOP_XOR_E_AX_IMM1632] = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ADD_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_OR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ADC_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SBB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_AND_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SUB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XOR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_CMP_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_TEST_RM8_R8] = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE }, - [XOP_TEST_RM1632_R1632] = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_RM8_R8] = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_RM1632_R1632] = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CMP_RM1632_R1632] = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CMP_R1632_RM1632] = { false, 0x3b, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_R1632_RM1632] = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_AX] = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_CX] = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_DX] = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_BX] = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_SP] = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_BP] = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_SI] = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_DI] = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_AX] = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_CX] = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_DX] = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_BX] = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_SP] = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_BP] = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_SI] = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_DI] = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_AX] = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_CX] = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_DX] = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_BX] = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_SP] = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_BP] = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_SI] = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_DI] = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_AX] = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_CX] = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_DX] = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_BX] = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_SP] = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_BP] = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_SI] = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_DI] = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_LEA_R1632_M] = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_IMM1632] = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_IMUL_R1632_RM1632_IMM1632] = { false, 0x69, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_NOP] = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE }, - [XOP_XCHG_R1632_E_AX] = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_CX] = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_DX] = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_BX] = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_SP] = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_BP] = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_SI] = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_XCHG_R1632_E_DI] = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_IMUL_RM1632_IMM8] = { false, 0x6b, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_AL_MOFFS8] = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_E_AX_MOFFS1632] = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_MOFFS8_AL] = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_MOFFS1632_E_AX] = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JO_REL8] = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE }, + [XOP_JNO_REL8] = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE }, + [XOP_JB_REL8] = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE }, + [XOP_JNB_REL8] = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE }, + [XOP_JE_REL8] = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE }, + [XOP_JNE_REL8] = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE }, + [XOP_JNA_REL8] = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE }, + [XOP_JA_REL8] = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE }, + [XOP_JS_REL8] = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE }, + [XOP_JNS_REL8] = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE }, + [XOP_JP_REL8] = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE }, + [XOP_JNP_REL8] = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE }, + [XOP_JL_REL8] = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE }, + [XOP_JNL_REL8] = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE }, + [XOP_JNG_REL8] = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE }, + [XOP_JG_REL8] = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE }, + [XOP_ADD_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE }, + [XOP_OR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE }, + [XOP_ADC_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE }, + [XOP_SBB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE }, + [XOP_AND_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE }, + [XOP_SUB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE }, + [XOP_XOR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE }, + [XOP_CMP_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE }, + [XOP_ADD_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_OR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADC_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SBB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_AND_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CMP_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_TEST_AL_IMM8] = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE }, - [XOP_TEST_E_AX_IMM1632] = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADD_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_OR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADC_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SBB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_AND_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CMP_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SCAS_AL_M8] = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE }, + [XOP_TEST_RM8_R8] = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE }, + [XOP_TEST_RM1632_R1632] = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_AL_IMM8] = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_CL_IMM8] = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_DL_IMM8] = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_BL_IMM8] = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_AH_IMM8] = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_CH_IMM8] = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_DH_IMM8] = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_BH_IMM8] = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE }, - [XOP_MOV_E_AX_IMM1632] = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_CX_IMM1632] = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_DX_IMM1632] = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_BX_IMM1632] = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_SP_IMM1632] = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_BP_IMM1632] = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_SI_IMM1632] = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_E_DI_IMM1632] = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_RM8_R8] = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_RM1632_R1632] = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_R1632_RM1632] = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ROL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_ROR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_RCL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_RCR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SHL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SHR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SAL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_SAR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_LEA_R1632_M] = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_RET] = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE }, + [XOP_NOP] = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE }, + [XOP_XCHG_R1632_E_AX] = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_CX] = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_DX] = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_BX] = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_SP] = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_BP] = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_SI] = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_DI] = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_MOV_RM8_IMM8] = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE }, - [XOP_MOV_RM1632_IMM1632] = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_AL_MOFFS8] = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_E_AX_MOFFS1632] = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_MOFFS8_AL] = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_MOFFS1632_E_AX] = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_LEAVE] = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE }, + [XOP_TEST_AL_IMM8] = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE }, + [XOP_TEST_E_AX_IMM1632] = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_INT_3] = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE }, - [XOP_INT] = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE }, + [XOP_SCAS_AL_M8] = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE }, - [XOP_SHL_RM1632_CL] = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_AL_IMM8] = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_CL_IMM8] = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_DL_IMM8] = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_BL_IMM8] = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_AH_IMM8] = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_CH_IMM8] = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_DH_IMM8] = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_BH_IMM8] = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_E_AX_IMM1632] = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_CX_IMM1632] = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_DX_IMM1632] = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_BX_IMM1632] = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_SP_IMM1632] = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_BP_IMM1632] = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_SI_IMM1632] = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_DI_IMM1632] = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_CALL_REL1632] = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JMP_REL1632] = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JMP_REL8] = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE }, - [XOP_HLT] = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE }, + [XOP_ROL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ROR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_RCL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_RCR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SHL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SHR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SAL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SAR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_TEST_RM8_IMM8] = { false, 0xf6, IDX_TO_EXT(0), "test", XPX_NONE }, - [XOP_TEST_RM8_IMM8_BIS] = { false, 0xf6, IDX_TO_EXT(1), "test", XPX_NONE }, - [XOP_NOT_RM8] = { false, 0xf6, IDX_TO_EXT(2), "not", XPX_NONE }, - [XOP_TEST_RM1632_IMM1632] = { false, 0xf7, IDX_TO_EXT(0), "test", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_TEST_RM1632_IMM1632_BIS] = { false, 0xf7, IDX_TO_EXT(1), "test", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_NOT_RM1632] = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_RET] = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE }, - [XOP_IMUL_RM1632] = { false, 0xf7, IDX_TO_EXT(5), "imul", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_RM8_IMM8] = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE }, + [XOP_MOV_RM1632_IMM1632] = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_CLD] = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE }, - [XOP_INC_RM8] = { false, 0xfe, IDX_TO_EXT(0), "inc", XPX_NONE }, - [XOP_DEC_RM8] = { false, 0xfe, IDX_TO_EXT(1), "dec", XPX_NONE }, - [XOP_INC_RM1632] = { false, 0xff, IDX_TO_EXT(0), "inc", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_DEC_RM1632] = { false, 0xff, IDX_TO_EXT(1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_CALL_RM1632] = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_JMP_RM1632] = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, - [XOP_PUSH_RM1632] = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE } + [XOP_LEAVE] = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE }, + + + [XOP_INT_3] = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE }, + [XOP_INT] = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE }, + + + [XOP_SHL_RM1632_CL] = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_CALL_REL1632] = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JMP_REL1632] = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, + + [XOP_JMP_REL8] = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE }, + + [XOP_HLT] = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE }, + + [XOP_TEST_RM8_IMM8] = { false, 0xf6, IDX_TO_EXT(0), "test", XPX_NONE }, + [XOP_TEST_RM8_IMM8_BIS] = { false, 0xf6, IDX_TO_EXT(1), "test", XPX_NONE }, + [XOP_NOT_RM8] = { false, 0xf6, IDX_TO_EXT(2), "not", XPX_NONE }, + + [XOP_TEST_RM1632_IMM1632] = { false, 0xf7, IDX_TO_EXT(0), "test", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_TEST_RM1632_IMM1632_BIS] = { false, 0xf7, IDX_TO_EXT(1), "test", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_NOT_RM1632] = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE }, + + [XOP_IMUL_RM1632] = { false, 0xf7, IDX_TO_EXT(5), "imul", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_CLD] = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE }, + + + [XOP_INC_RM8] = { false, 0xfe, IDX_TO_EXT(0), "inc", XPX_NONE }, + [XOP_DEC_RM8] = { false, 0xfe, IDX_TO_EXT(1), "dec", XPX_NONE }, + [XOP_INC_RM1632] = { false, 0xff, IDX_TO_EXT(0), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_RM1632] = { false, 0xff, IDX_TO_EXT(1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CALL_RM1632] = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JMP_RM1632] = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_RM1632] = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE } }; diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index ad50834..de5f124 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -50,11 +50,12 @@ typedef enum _X86Opcodes XOP_JE_REL1632, /* je ([0x66] 0x0f 0x84) */ XOP_JNE_REL1632, /* jne ([0x66] 0x0f 0x85) */ - + XOP_JBE_REL1632, /* jbe ([0x66] 0x0f 0x86) */ XOP_JA_REL1632, /* jne ([0x66] 0x0f 0x87) */ XOP_JGE_REL1632, /* jge ([0x66] 0x0f 0x8d) */ XOP_JLE_REL1632, /* jle ([0x66] 0x0f 0x8e) */ + XOP_JG_REL1632, /* jle ([0x66] 0x0f 0x8f) */ XOP_SETE_RM8, /* sete ([0x66] 0x0f 0x94) */ XOP_SETNE_RM8, /* setne ([0x66] 0x0f 0x95) */ @@ -65,6 +66,10 @@ typedef enum _X86Opcodes XOP_ADC_RM8_R8, /* adc (0x10) */ XOP_AND_RM8_R8, /* and (0x20) */ + XOP_AND_RM1632_R1632, /* and ([0x66] 0x21) */ + + XOP_AND_AL_IMM8, /* and (0x24) */ + XOP_AND_E_AX_IMM1632, /* and ([0x66] 0x25) */ XOP_SUB_RM1632_R1632, /* sub ([0x66] 0x29) */ @@ -81,8 +86,11 @@ typedef enum _X86Opcodes XOP_XOR_AL_IMM8, /* xor (0x34) */ XOP_XOR_E_AX_IMM1632, /* xor ([0x66] 0x35) */ - XOP_CMP_RM1632_R1632, /* cmp ([0x66] 0x39) */ + + XOP_CMP_R1632_RM1632, /* cmp ([0x66] 0x3b) */ + + XOP_INC_E_AX, /* inc ([0x66] 0x40) */ XOP_INC_E_CX, /* inc ([0x66] 0x41) */ XOP_INC_E_DX, /* inc ([0x66] 0x42) */ @@ -118,6 +126,7 @@ typedef enum _X86Opcodes XOP_PUSH_IMM1632, /* push ([0x66] 0x68) */ + XOP_IMUL_R1632_RM1632_IMM1632, /* imul ([0x66] 0x69) */ XOP_IMUL_RM1632_IMM8, /* imul ([0x66] 0x6b) */ diff --git a/src/arch/x86/op_and.c b/src/arch/x86/op_and.c index c923441..d59c8f0 100644 --- a/src/arch/x86/op_and.c +++ b/src/arch/x86/op_and.c @@ -38,6 +38,75 @@ * addr = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'and al, ...' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_and_al_imm8(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_x86_instruction_new(XOP_AND_AL_IMM8); + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_IMM8)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'and [e]ax, ...' (16/32 bits).* +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_and_e_ax_imm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = g_x86_instruction_new(XOP_AND_E_AX_IMM1632); + + oprsize = g_x86_processor_get_operand_size(proc, prefix); + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_E_AX, X86_OTP_IMM1632, oprsize)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * * Description : Décode une instruction de type 'and' (8 bits). * * * * Retour : Instruction mise en place ou NULL. * @@ -65,6 +134,11 @@ GArchInstruction *x86_read_instr_and_rm8_imm8(const bin_t *data, off_t *pos, off /****************************************************************************** * * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * * * * Description : Décode une instruction de type 'and' (8 bits). * * * @@ -161,3 +235,39 @@ GArchInstruction *x86_read_instr_and_rm1632_imm1632(const bin_t *data, off_t *po return result; } + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'and' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_and_rm1632_r1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = g_x86_instruction_new(XOP_AND_RM1632_R1632); + + oprsize = g_x86_processor_get_operand_size(proc, prefix); + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c index 709054b..5dfa20d 100644 --- a/src/arch/x86/op_cmp.c +++ b/src/arch/x86/op_cmp.c @@ -38,6 +38,42 @@ * addr = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'cmp' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_cmp_r1632_rm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = g_x86_instruction_new(XOP_CMP_R1632_RM1632); + + oprsize = g_x86_processor_get_operand_size(proc, prefix); + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * * Description : Décode une instruction de type 'cmp' (8 bits). * * * * Retour : Instruction mise en place ou NULL. * diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c index cbeda87..eef2c1c 100644 --- a/src/arch/x86/op_int.c +++ b/src/arch/x86/op_int.c @@ -55,7 +55,7 @@ GArchInstruction *x86_read_instr_int_3(const bin_t *data, off_t *pos, off_t len, result = g_x86_instruction_new(XOP_INT_3); three = g_imm_operand_new_from_value(AOS_8_BITS, 3); - g_arch_instruction_attach_one_operand(result, three); + g_arch_instruction_attach_extra_operand(result, three); return result; diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c index 1f7db24..be8d305 100644 --- a/src/arch/x86/op_jump.c +++ b/src/arch/x86/op_jump.c @@ -140,6 +140,42 @@ GArchInstruction *x86_read_instr_jb_rel8(const bin_t *data, off_t *pos, off_t le * addr = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'je' (saut 16/32b si inf.). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_jbe_rel1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = g_x86_instruction_new(XOP_JBE_REL1632); + + oprsize = g_x86_processor_get_operand_size(proc, prefix); + + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, addr)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * * Description : Décode une instruction de type 'je' (saut 8b si égal). * * * * Retour : Instruction mise en place ou NULL. * @@ -242,6 +278,42 @@ GArchInstruction *x86_read_instr_jg_rel8(const bin_t *data, off_t *pos, off_t le * addr = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'jg' (saut 16/32b si sup.). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_jg_rel1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = g_x86_instruction_new(XOP_JG_REL1632); + + oprsize = g_x86_processor_get_operand_size(proc, prefix); + + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, addr)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * * Description : Décode une instruction de type 'jge' (saut 16/32b si sup.). * * * * Retour : Instruction mise en place ou NULL. * diff --git a/src/arch/x86/op_mul.c b/src/arch/x86/op_mul.c index f1ed641..2f29929 100644 --- a/src/arch/x86/op_mul.c +++ b/src/arch/x86/op_mul.c @@ -46,6 +46,42 @@ * * ******************************************************************************/ +GArchInstruction *x86_read_instr_imul_r1632_rm1632_imm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + + result = g_x86_instruction_new(XOP_IMUL_R1632_RM1632_IMM1632); + + oprsize = g_x86_processor_get_operand_size(proc, prefix); + + if (!x86_read_three_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'imul' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + GArchInstruction *x86_read_instr_imul_rm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) { GArchInstruction *result; /* Instruction à retourner */ diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 5317415..e45b107 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -69,6 +69,12 @@ GArchInstruction *x86_read_instr_add_rm1632_imm1632(const bin_t *, off_t *, off_ /* Décode une instruction de type 'add' (16 ou 32 bits). */ GArchInstruction *x86_read_instr_add_rm1632_r1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'and al, ...' (8 bits). */ +GArchInstruction *x86_read_instr_and_al_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + +/* Décode une instruction de type 'and [e]ax, ...' (16/32 bits). */ +GArchInstruction *x86_read_instr_and_e_ax_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + /* Décode une instruction de type 'and' (8 bits). */ GArchInstruction *x86_read_instr_and_rm8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -81,6 +87,9 @@ GArchInstruction *x86_read_instr_and_rm1632_imm8(const bin_t *, off_t *, off_t, /* Décode une instruction de type 'and' (16 ou 32 bits). */ GArchInstruction *x86_read_instr_and_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'and' (16 ou 32 bits). */ +GArchInstruction *x86_read_instr_and_rm1632_r1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + /* Décode une instruction de type 'call'. */ GArchInstruction *x86_read_instr_call_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -90,6 +99,9 @@ GArchInstruction *x86_read_instr_call_rm1632(const bin_t *, off_t *, off_t, vmpa /* Décode une instruction de type 'cld'. */ GArchInstruction *x86_read_instr_cld(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'cmp' (16 ou 32 bits). */ +GArchInstruction *x86_read_instr_cmp_r1632_rm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + /* Décode une instruction de type 'cmp' (8 bits). */ GArchInstruction *x86_read_instr_cmp_rm8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -115,6 +127,9 @@ GArchInstruction *x86_read_instr_dec_rm1632(const bin_t *, off_t *, off_t, vmpa_ GArchInstruction *x86_read_instr_hlt(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); /* Décode une instruction de type 'imul' (16 ou 32 bits). */ +GArchInstruction *x86_read_instr_imul_r1632_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + +/* Décode une instruction de type 'imul' (16 ou 32 bits). */ GArchInstruction *x86_read_instr_imul_rm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); /* Décode une instruction de type 'imul' (16 ou 32 bits). */ @@ -144,6 +159,9 @@ GArchInstruction *x86_read_instr_ja_rel1632(const bin_t *, off_t *, off_t, vmpa_ /* Décode une instruction de type 'jb' (saut 8b si inférieur). */ GArchInstruction *x86_read_instr_jb_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'je' (saut 16/32b si inf.). */ +GArchInstruction *x86_read_instr_jbe_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + /* Décode une instruction de type 'je' (saut 8b si égal). */ GArchInstruction *x86_read_instr_je_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -153,6 +171,9 @@ GArchInstruction *x86_read_instr_je_rel1632(const bin_t *, off_t *, off_t, vmpa_ /* Décode une instruction de type 'jg' (saut 8b si supérieur). */ GArchInstruction *x86_read_instr_jg_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'jg' (saut 16/32b si sup.). */ +GArchInstruction *x86_read_instr_jg_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + /* Décode une instruction de type 'jge' (saut 16/32b si sup.). */ GArchInstruction *x86_read_instr_jge_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index eb6f5f3..d0e923f 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -512,7 +512,7 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len, if (g_x86_register_is_base_pointer(reg) && mod == 0x00) { /* FIXME *///free_x86_register(reg); - return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE); + return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/); } result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL); @@ -552,19 +552,19 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len, /* FIXME *///free_x86_register(result->base); result->base = NULL; - result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE); + result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */); if (result->displacement == NULL) goto gxmron_error; } break; case 0x40: - result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE); + result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */); if (result->displacement == NULL) goto gxmron_error; break; case 0x80: - result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE); + result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */); if (result->displacement == NULL) goto gxmron_error; break; @@ -805,15 +805,15 @@ GArchOperand *g_x86_relative_operand_new(const bin_t *data, off_t *pos, off_t le switch (size) { case AOS_8_BITS_UNSIGNED: - read_s8(&val8, data, pos, len, SRE_LITTLE); + read_s8(&val8, data, pos, len, SRE_LITTLE /* FIXME */); address = base + (*pos - init_pos) + val8; break; case AOS_16_BITS_UNSIGNED: - read_s16(&val16, data, pos, len, SRE_LITTLE); + read_s16(&val16, data, pos, len, SRE_LITTLE /* FIXME */); address = base + (*pos - init_pos) + val16; break; case AOS_32_BITS_UNSIGNED: - read_s32(&val32, data, pos, len, SRE_LITTLE); + read_s32(&val32, data, pos, len, SRE_LITTLE /* FIXME */); address = base + (*pos - init_pos) + val32; break; default: @@ -945,7 +945,7 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len, result = NULL; - offset = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE); + offset = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */); if (offset != NULL) { @@ -997,10 +997,10 @@ static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operan * data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * len = taille totale des données à analyser. * -* type = type de l'opérande. * +* count = quantité d'opérandes à lire. * * ... = éventuelle(s) information(s) complémentaire(s). * * * -* Description : Procède à la lecture d'un opérande donné. * +* Description : Procède à la lecture de trois opérandes donnés. * * * * Retour : Bilan de l'opération : true en cas de succès, false sinon. * * * @@ -1008,135 +1008,39 @@ static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operan * * ******************************************************************************/ -bool x86_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, X86OperandType type, ...) +bool _x86_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, unsigned int count, ...) { + bool result; /* Bilan à retourner */ va_list ap; /* Liste des compléments */ + X86OperandType types[MAX_OPERANDS]; /* Type des opérandes */ + unsigned int i; /* Boucle de parcours */ + bool op1_first; /* Position de l'opérande #1 */ + bool op2_first; /* Position de l'opérande #2 */ AsmOperandSize oprsize; /* Taille des opérandes */ + off_t op_pos[MAX_OPERANDS]; /* Position après lecture */ vmpa_t offset; /* Adresse courante */ bin_t base; /* Indice du premier registre */ GArchOperand *op; /* Opérande unique décodé */ - va_start(ap, type); - - /* Lecture du premier opérande */ - - switch (type) - { - case X86_OTP_IMM8: - op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, len, SRE_LITTLE); - break; - - case X86_OTP_IMM1632: - oprsize = va_arg(ap, AsmOperandSize); - op = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, pos, len, SRE_LITTLE); - break; - - case X86_OTP_REL8: - offset = va_arg(ap, vmpa_t); - op = g_x86_relative_operand_new(data, pos, len, AOS_8_BITS, offset + 1); - break; - - case X86_OTP_REL1632: - oprsize = va_arg(ap, AsmOperandSize); - offset = va_arg(ap, vmpa_t); - op = g_x86_relative_operand_new(data, pos, len, oprsize, offset + 1); - break; - - case X86_OTP_R8: - op = g_x86_register_operand_new_from_mod_rm(data, pos, len, AOS_8_BITS, true); - break; - - case X86_OTP_R1632: - oprsize = va_arg(ap, AsmOperandSize); - op = g_x86_register_operand_new_from_mod_rm(data, pos, len, oprsize, true); - break; - - case X86_OTP_OP_R8: - base = (bin_t)va_arg(ap, int); - op = g_x86_register_operand_new_from_opcode(data, pos, len, AOS_8_BITS, base); - break; - - case X86_OTP_OP_R1632: - oprsize = va_arg(ap, AsmOperandSize); - base = (bin_t)va_arg(ap, int); - op = g_x86_register_operand_new_from_opcode(data, pos, len, oprsize, base); - break; - - case X86_OTP_RM8: - op = g_x86_mod_rm_operand_new(data, pos, len, AOS_8_BITS); - break; - - case X86_OTP_RM1632: - oprsize = va_arg(ap, AsmOperandSize); - op = g_x86_mod_rm_operand_new(data, pos, len, oprsize); - break; - - case X86_OTP_CL: - op = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); - break; - - case X86_OTP_AL: - op = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); - break; - - case X86_OTP_E_AX: - oprsize = va_arg(ap, AsmOperandSize); - op = g_x86_register_operand_new_from_index(0x00, oprsize); - break; - - } - - va_end(ap); - - if (op == NULL) return false; - - g_arch_instruction_attach_one_operand(instr, op); - - return true; - -} + if (count > MAX_OPERANDS) return false; + result = true; -/****************************************************************************** -* * -* Paramètres : instr = instruction dont la définition est à compléter. [OUT]* -* data = flux de données à analyser. * -* pos = position courante dans ce flux. [OUT] * -* len = taille totale des données à analyser. * -* type1 = type du premier opérande. * -* type2 = type du second opérande. * -* ... = éventuelle(s) information(s) complémentaire(s). * -* * -* Description : Procède à la lecture de deux opérandes donnés. * -* * -* Retour : Bilan de l'opération : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ + va_start(ap, count); -bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, X86OperandType type1, X86OperandType type2, ...) -{ - va_list ap; /* Liste des compléments */ - AsmOperandSize oprsize; /* Taille des opérandes */ - bool op1_first; /* Position de l'opérande #1 */ - bool op2_first; /* Position de l'opérande #2 */ - off_t op1_pos; /* Position après lecture #1 */ - bin_t base; /* Indice du premier registre */ - GArchOperand *op1; /* Premier opérande décodé */ - off_t op2_pos; /* Position après lecture #2 */ - GArchOperand *op2; /* Second opérande décodé */ + /* Types à charger */ - va_start(ap, type2); + for (i = 0; i < count; i++) + types[i] = va_arg(ap, AsmOperandSize); - oprsize = AOS_UNDEFINED; + /* Initialisations */ - if (type1 & X86_OTP_RM_TYPE) + if (types[0] & X86_OTP_RM_TYPE) { op1_first = true; op2_first = false; } - else if (type2 & X86_OTP_RM_TYPE) + else if (types[1] & X86_OTP_RM_TYPE) { op1_first = false; op2_first = true; @@ -1147,154 +1051,115 @@ bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *po op2_first = false; } - /* Lecture du premier opérande */ - - op1_pos = *pos; - - switch (type1) - { - case X86_OTP_IMM8: - op1 = g_imm_operand_new_from_data(MDS_8_BITS, data, &op1_pos, len, SRE_LITTLE); - break; - - case X86_OTP_IMM1632: - if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); - op1 = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op1_pos, len, SRE_LITTLE); - break; - - case X86_OTP_MOFFS8: - op1 = g_x86_moffs_operand_new(data, &op1_pos, len, AOS_8_BITS); - break; - - case X86_OTP_MOFFS1632: - oprsize = va_arg(ap, AsmOperandSize); - op1 = g_x86_moffs_operand_new(data, &op1_pos, len, oprsize); - break; - - case X86_OTP_R8: - op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, AOS_8_BITS, op1_first); - break; - - case X86_OTP_R1632: - oprsize = va_arg(ap, AsmOperandSize); - op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, oprsize, op1_first); - break; - - case X86_OTP_OP_R8: - base = (bin_t)va_arg(ap, int); - op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, AOS_8_BITS, base); - break; - - case X86_OTP_OP_R1632: - oprsize = va_arg(ap, AsmOperandSize); - base = (bin_t)va_arg(ap, int); - op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, oprsize, base); - break; - - case X86_OTP_RM8: - op1 = g_x86_mod_rm_operand_new(data, &op1_pos, len, AOS_8_BITS); - break; - - case X86_OTP_RM1632: - oprsize = va_arg(ap, AsmOperandSize); - op1 = g_x86_mod_rm_operand_new(data, &op1_pos, len, oprsize); - break; - - case X86_OTP_CL: - op1 = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); - break; - - case X86_OTP_AL: - op1 = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); - break; - - case X86_OTP_E_AX: - oprsize = va_arg(ap, AsmOperandSize); - op1 = g_x86_register_operand_new_from_index(0x00, oprsize); - break; - - } - - if (op1 == NULL) - { - va_end(ap); - return false; - } - - /* Lecture du second opérande */ + oprsize = AOS_UNDEFINED; - if ((type1 & X86_OTP_REG_TYPE || type1 & X86_OTP_RM_TYPE) && (type2 & X86_OTP_IMM_TYPE)) - op2_pos = op1_pos; - else op2_pos = *pos; + /* Lecture des opérandes */ - switch (type2) + for (i = 0; i < count && result; i++) { - case X86_OTP_IMM8: - op2 = g_imm_operand_new_from_data(MDS_8_BITS, data, &op2_pos, len, SRE_LITTLE); - break; - - case X86_OTP_IMM1632: - if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); - op2 = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op2_pos, len, SRE_LITTLE); - break; - - case X86_OTP_MOFFS8: - op2 = g_x86_moffs_operand_new(data, &op2_pos, len, AOS_8_BITS); - break; - - case X86_OTP_MOFFS1632: - if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); - op2 = g_x86_moffs_operand_new(data, &op2_pos, len, oprsize); - break; - - case X86_OTP_R8: - op2 = g_x86_register_operand_new_from_mod_rm(data, &op2_pos, len, AOS_8_BITS, op2_first); - break; - - case X86_OTP_R1632: - if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); - op2 = g_x86_register_operand_new_from_mod_rm(data, &op2_pos, len, oprsize, op2_first); - break; + /* Tête de lecture */ + switch (i) + { + case 0: + op_pos[0] = *pos; + break; - case X86_OTP_RM8: - op2 = g_x86_mod_rm_operand_new(data, &op2_pos, len, AOS_8_BITS); - break; + case 1: + if ((types[0] & X86_OTP_REG_TYPE || types[0] & X86_OTP_RM_TYPE) && (types[1] & X86_OTP_IMM_TYPE)) + op_pos[1] = op_pos[0]; + else op_pos[1] = *pos; + *pos = op_pos[0]; + break; - case X86_OTP_RM1632: - if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); - op2 = g_x86_mod_rm_operand_new(data, &op2_pos, len, oprsize); - break; + case 2 ... MAX_OPERANDS: + *pos = MAX(*pos, op_pos[i - 1]); + op_pos[i] = *pos; - case X86_OTP_CL: - op2 = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); - break; + } - case X86_OTP_AL: - op2 = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); - break; + /* Lecture */ + switch (types[i]) + { + case X86_OTP_IMM8: + op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); + break; + + case X86_OTP_IMM1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); + break; + + case X86_OTP_MOFFS8: + op = g_x86_moffs_operand_new(data, &op_pos[i], len, AOS_8_BITS); + break; + + case X86_OTP_MOFFS1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op = g_x86_moffs_operand_new(data, &op_pos[i], len, oprsize); + break; + + case X86_OTP_REL8: + offset = va_arg(ap, vmpa_t); + op = g_x86_relative_operand_new(data, &op_pos[i], len, AOS_8_BITS, offset + 1); + break; + + case X86_OTP_REL1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + offset = va_arg(ap, vmpa_t); + op = g_x86_relative_operand_new(data, &op_pos[i], len, oprsize, offset + 1); + break; + + case X86_OTP_R8: + op = g_x86_register_operand_new_from_mod_rm(data, &op_pos[i], len, AOS_8_BITS, i == 0 ? op1_first : op2_first); + break; + + case X86_OTP_R1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op = g_x86_register_operand_new_from_mod_rm(data, &op_pos[i], len, oprsize, i == 0 ? op1_first : op2_first); + break; + + case X86_OTP_OP_R8: + base = (bin_t)va_arg(ap, int); + op = g_x86_register_operand_new_from_opcode(data, &op_pos[i], len, AOS_8_BITS, base); + break; + + case X86_OTP_OP_R1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + base = (bin_t)va_arg(ap, int); + op = g_x86_register_operand_new_from_opcode(data, &op_pos[i], len, oprsize, base); + break; + + case X86_OTP_RM8: + op = g_x86_mod_rm_operand_new(data, &op_pos[i], len, AOS_8_BITS); + break; + + case X86_OTP_RM1632: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op = g_x86_mod_rm_operand_new(data, &op_pos[i], len, oprsize); + break; + + case X86_OTP_CL: + op = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); + break; + + case X86_OTP_AL: + op = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); + break; + + case X86_OTP_E_AX: + if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); + op = g_x86_register_operand_new_from_index(0x00, oprsize); + break; - case X86_OTP_E_AX: - if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); - op2 = g_x86_register_operand_new_from_index(0x00, oprsize); - break; + } - } + if (op == NULL) result = false; + else g_arch_instruction_attach_extra_operand(instr, op); - if (op2 == NULL) - { - free(op1); - va_end(ap); - return false; } - va_end(ap); - - /* Assemblage final */ - - *pos = MAX(op1_pos, op2_pos); - - g_arch_instruction_attach_two_operands(instr, op1, op2); + *pos = MAX(*pos, op_pos[i - 1]); - return true; + return result; } diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index cb04ca8..fc40b38 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -207,11 +207,16 @@ typedef enum _X86OperandType } X86OperandType; -/* Procède à la lecture d'un opérande donné. */ -bool x86_read_one_operand(GArchInstruction *, const bin_t *data, off_t *pos, off_t, X86OperandType, ...); +/* Nombre maximal d'opérande */ +#define MAX_OPERANDS 3 -/* Procède à la lecture de deux opérandes donnés. */ -bool x86_read_two_operands(GArchInstruction *, const bin_t *data, off_t *pos, off_t, X86OperandType, X86OperandType, ...); + +#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, ...); diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 15179e2..3dc5fc2 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -225,6 +225,19 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor result = x86_read_instr_or_rm1632_r1632(data, pos, len, addr, prefix, proc); break; + + + case XOP_AND_AL_IMM8: + result = x86_read_instr_and_al_imm8(data, pos, len, addr, prefix, proc); + break; + + case XOP_AND_E_AX_IMM1632: + result = x86_read_instr_and_e_ax_imm1632(data, pos, len, addr, prefix, proc); + break; + + + + case XOP_OR_R8_RM8: result = x86_read_instr_or_r8_rm8(data, pos, len, addr, prefix, proc); break; @@ -246,6 +259,9 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor result = x86_read_instr_jne_rel1632(data, pos, len, addr, prefix, proc); break; + case XOP_JBE_REL1632: + result = x86_read_instr_jbe_rel1632(data, pos, len, addr, prefix, proc); + break; case XOP_JA_REL1632: result = x86_read_instr_ja_rel1632(data, pos, len, addr, prefix, proc); @@ -270,6 +286,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor result = x86_read_instr_jle_rel1632(data, pos, len, addr, prefix, proc); break; + case XOP_JG_REL1632: + result = x86_read_instr_jg_rel1632(data, pos, len, addr, prefix, proc); + break; + case XOP_MOVZX_R1632_RM8: result = x86_read_instr_movzx_r1632_rm8(data, pos, len, addr, prefix, proc); @@ -291,6 +311,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor result = x86_read_instr_and_rm8_r8(data, pos, len, addr, prefix, proc); break; + case XOP_AND_RM1632_R1632: + result = x86_read_instr_and_rm1632_r1632(data, pos, len, addr, prefix, proc); + break; + case XOP_SUB_RM1632_R1632: result = x86_read_instr_sub_rm1632_r1632(data, pos, len, addr, prefix, proc); @@ -342,6 +366,13 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor result = x86_read_instr_cmp_rm1632_r1632(data, pos, len, addr, prefix, proc); break; + + case XOP_CMP_R1632_RM1632: + result = x86_read_instr_cmp_r1632_rm1632(data, pos, len, addr, prefix, proc); + break; + + + case XOP_INC_E_AX: case XOP_INC_E_CX: case XOP_INC_E_DX: @@ -391,6 +422,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor result = x86_read_instr_push_imm1632(data, pos, len, addr, prefix, proc); break; + case XOP_IMUL_R1632_RM1632_IMM1632: + result = x86_read_instr_imul_r1632_rm1632_imm1632(data, pos, len, addr, prefix, proc); + break; + case XOP_IMUL_RM1632_IMM8: result = x86_read_instr_imul_rm1632_imm8(data, pos, len, addr, prefix, proc); -- cgit v0.11.2-87-g4458