summaryrefslogtreecommitdiff
path: root/src/arch/x86/processor.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-08-03 15:35:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-08-03 15:35:43 (GMT)
commit1249cf6e2c0ed87e1c593e488beedbbfe153ff00 (patch)
tree0a92b85df9dabe76b34810071e0c1def906311da /src/arch/x86/processor.c
parentf0b80c6ab55ede4f8ab8ede757f1f8951512affa (diff)
Read registers from the ModR/M encoding.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@13 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/x86/processor.c')
-rw-r--r--src/arch/x86/processor.c223
1 files changed, 112 insertions, 111 deletions
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 487e4a0..0014652 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -43,19 +43,44 @@ typedef struct _x86_opcode
{
uint8_t prefix; /* préfixe eventuel */
uint8_t opcode; /* Opcode seul */
+ uint8_t op_ext; /* Extension de l'opcode */
+
+ bool opt_prefix; /* Préfixe optionnel ? */
+ bool has_op_ext; /* Ext. à prendre en compte ? */
+
const char *name; /* Désignation humaine */
read_instr read; /* Décodage de l'instruction */
} x86_opcode;
-#define register_opcode(target, pre, bin, n, func) \
-do {\
-target.prefix = pre; \
-target.opcode = bin; \
-target.name = n; \
-target.read = func; \
-} while (0)
+#define EXT_OPCODE_MASK 0x38
+
+
+#define register_opcode(target, _prefix, _opcode, _name, _read) \
+ do { \
+ target.prefix = _prefix; \
+ target.opcode = _opcode; \
+ target.opt_prefix = true; \
+ target.has_op_ext = false; \
+ target.name = _name; \
+ target.read = _read; \
+ } while (0)
+
+#define register_opcode_with_ext(target, _prefix, _opcode, _ext, _name, _read) \
+ do { \
+ target.prefix = _prefix; \
+ target.opcode = _opcode; \
+ target.op_ext = _ext << 3; \
+ target.opt_prefix = true; \
+ target.has_op_ext = true; \
+ target.name = _name; \
+ target.read = _read; \
+ } while (0)
+
+
+
+
/* Définition générique d'une architecture */
@@ -169,59 +194,67 @@ AsmOperandSize switch_x86_operand_size(const asm_x86_processor *proc)
void x86_register_instructions(asm_x86_processor *proc)
{
- /* TODO : voir pour une inversion avec le mode 16 bits ! */
-
- register_opcode(proc->opcodes[X86_OP_INC_EAX], 0x00, 0x40, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_ECX], 0x00, 0x41, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_EDX], 0x00, 0x42, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_EBX], 0x00, 0x43, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_ESP], 0x00, 0x44, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_EBP], 0x00, 0x45, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_ESI], 0x00, 0x46, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_EDI], 0x00, 0x47, "inc", read_instr_inc_1632);
-
- register_opcode(proc->opcodes[X86_OP_DEC_EAX], 0x00, 0x48, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_ECX], 0x00, 0x49, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_EDX], 0x00, 0x4a, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_EBX], 0x00, 0x4b, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_ESP], 0x00, 0x4c, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_EBP], 0x00, 0x4d, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_ESI], 0x00, 0x4e, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_EDI], 0x00, 0x4f, "dec", read_instr_dec_1632);
-
- register_opcode(proc->opcodes[X86_OP_PUSH_EAX], 0x00, 0x50, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_ECX], 0x00, 0x51, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EDX], 0x00, 0x52, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EBX], 0x00, 0x53, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_ESP], 0x00, 0x54, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EBP], 0x00, 0x55, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_ESI], 0x00, 0x56, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EDI], 0x00, 0x57, "push", read_instr_push_reg1632);
-
- register_opcode(proc->opcodes[X86_OP_POP_EAX], 0x00, 0x58, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_ECX], 0x00, 0x59, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_EDX], 0x00, 0x5a, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_EBX], 0x00, 0x5b, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_ESP], 0x00, 0x5c, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_EBP], 0x00, 0x5d, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_ESI], 0x00, 0x5e, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_EDI], 0x00, 0x5f, "pop", read_instr_pop_reg1632);
-
- register_opcode(proc->opcodes[X86_OP_PUSH_IMM32], 0x00, 0x68, "push", read_instr_push_imm1632);
-
+ register_opcode(proc->opcodes[X86_OP_XOR_REG1632], 0x00/*0x66*/, 0x31, "xor", read_instr_xor_with_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_INC_E_AX], 0x66, 0x40, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_CX], 0x66, 0x41, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_DX], 0x66, 0x42, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_BX], 0x66, 0x43, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_SP], 0x66, 0x44, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_BP], 0x66, 0x45, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_SI], 0x66, 0x46, "inc", read_instr_inc_1632);
+ register_opcode(proc->opcodes[X86_OP_INC_E_DI], 0x66, 0x47, "inc", read_instr_inc_1632);
+
+ register_opcode(proc->opcodes[X86_OP_DEC_E_AX], 0x66, 0x48, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_CX], 0x66, 0x49, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_DX], 0x66, 0x4a, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_BX], 0x66, 0x4b, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_SP], 0x66, 0x4c, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_BP], 0x66, 0x4d, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_SI], 0x66, 0x4e, "dec", read_instr_dec_1632);
+ register_opcode(proc->opcodes[X86_OP_DEC_E_DI], 0x66, 0x4f, "dec", read_instr_dec_1632);
+
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_AX], 0x66, 0x50, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_CX], 0x66, 0x51, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_DX], 0x66, 0x52, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_BX], 0x66, 0x53, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_SP], 0x66, 0x54, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_BP], 0x66, 0x55, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_SI], 0x66, 0x56, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_E_DI], 0x66, 0x57, "push", read_instr_push_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_POP_E_AX], 0x66, 0x58, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_CX], 0x66, 0x59, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_DX], 0x66, 0x5a, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_BX], 0x66, 0x5b, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_SP], 0x66, 0x5c, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_BP], 0x66, 0x5d, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_SI], 0x66, 0x5e, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_E_DI], 0x66, 0x5f, "pop", read_instr_pop_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_PUSH_IMM1632], 0x66, 0x68, "push", read_instr_push_imm1632);
+
+
+ register_opcode(proc->opcodes[X86_OP_MOV_REG1632], 0x66, 0x89, "mov", read_instr_mov_with_reg1632);
+
+ register_opcode_with_ext(proc->opcodes[X86_OP_ADD8_REG1632], 0x66, 0x83, 0, "add", read_instr_add8_with_reg1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_OR8_REG1632], 0x66, 0x83, 1, "or", read_instr_or8_with_reg1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_ADC8_REG1632], 0x66, 0x83, 2, "adc", read_instr_adc8_with_reg1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_SBB8_REG1632], 0x66, 0x83, 3, "sbb", read_instr_sbb8_with_reg1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_AND8_REG1632], 0x66, 0x83, 4, "and", read_instr_and8_with_reg1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_SUB8_REG1632], 0x66, 0x83, 5, "sub", read_instr_sub8_with_reg1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_XOR8_REG1632], 0x66, 0x83, 6, "xor", read_instr_xor8_with_reg1632);
register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop);
-
- register_opcode(proc->opcodes[X86_OP_MOV_AX], 0x00, 0xb8, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_CX], 0x00, 0xb9, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xba, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_BX], 0x00, 0xbb, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_SP], 0x00, 0xbc, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_BP], 0x00, 0xbd, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_SI], 0x00, 0xbe, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_DI], 0x00, 0xbf, "mov", read_instr_mov_to_1632);
-
+ register_opcode(proc->opcodes[X86_OP_MOV_E_AX], 0x66, 0xb8, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_CX], 0x66, 0xb9, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_DX], 0x66, 0xba, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_BX], 0x66, 0xbb, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_SP], 0x66, 0xbc, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_BP], 0x66, 0xbd, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_SI], 0x66, 0xbe, "mov", read_instr_mov_to_1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", read_instr_mov_to_1632);
register_opcode(proc->opcodes[X86_OP_RET], 0x00, 0xc3, "ret", read_instr_ret);
register_opcode(proc->opcodes[X86_OP_LEAVE], 0x00, 0xc9, "leave", read_instr_leave);
@@ -234,54 +267,6 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", read_instr_hlt);
- register_opcode(proc->opcodes[X86_OP_INC_AX], 0x66, 0x40, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_CX], 0x66, 0x41, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_DX], 0x66, 0x42, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_BX], 0x66, 0x43, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_SP], 0x66, 0x44, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_BP], 0x66, 0x45, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_SI], 0x66, 0x46, "inc", read_instr_inc_1632);
- register_opcode(proc->opcodes[X86_OP_INC_DI], 0x66, 0x47, "inc", read_instr_inc_1632);
-
- register_opcode(proc->opcodes[X86_OP_DEC_AX], 0x66, 0x48, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_CX], 0x66, 0x49, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_DX], 0x66, 0x4a, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_BX], 0x66, 0x4b, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_SP], 0x66, 0x4c, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_BP], 0x66, 0x4d, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_SI], 0x66, 0x4e, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_DEC_DI], 0x66, 0x4f, "dec", read_instr_dec_1632);
-
- register_opcode(proc->opcodes[X86_OP_PUSH_AX], 0x66, 0x50, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_CX], 0x66, 0x51, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_DX], 0x66, 0x52, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_BX], 0x66, 0x53, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_SP], 0x66, 0x54, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_BP], 0x66, 0x55, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_SI], 0x66, 0x56, "push", read_instr_push_reg1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_DI], 0x66, 0x57, "push", read_instr_push_reg1632);
-
- register_opcode(proc->opcodes[X86_OP_POP_AX], 0x66, 0x58, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_CX], 0x66, 0x59, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_DX], 0x66, 0x5a, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_BX], 0x66, 0x5b, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_SP], 0x66, 0x5c, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_BP], 0x66, 0x5d, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_SI], 0x66, 0x5e, "pop", read_instr_pop_reg1632);
- register_opcode(proc->opcodes[X86_OP_POP_DI], 0x66, 0x5f, "pop", read_instr_pop_reg1632);
-
- register_opcode(proc->opcodes[X86_OP_PUSH_IMM16], 0x66, 0x68, "push", read_instr_push_imm1632);
-
- register_opcode(proc->opcodes[X86_OP_MOV_EAX], 0x66, 0xb8, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_ECX], 0x66, 0xb9, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_EDX], 0x66, 0xba, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_EBX], 0x66, 0xbb, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_ESP], 0x66, 0xbc, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_EBP], 0x66, 0xbd, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_ESI], 0x66, 0xbe, "mov", read_instr_mov_to_1632);
- register_opcode(proc->opcodes[X86_OP_MOV_EDI], 0x66, 0xbf, "mov", read_instr_mov_to_1632);
-
-
}
@@ -307,20 +292,36 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
{
asm_x86_instr *result; /* Résultat à faire remonter */
X86Opcodes i; /* Boucle de parcours */
+ off_t tmp; /* Tête de lecture */
result = NULL;
for (i = 0; i < X86_OP_COUNT; i++)
{
- if ((proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode)
- || (proc->opcodes[i].prefix == 0 && data[*pos] == proc->opcodes[i].opcode))
+ if (proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode)
+ {
+ tmp = *pos + 2;
+ goto find_instr;
+ }
+
+ if (proc->opcodes[i].opt_prefix && data[*pos] == proc->opcodes[i].opcode)
{
- result = proc->opcodes[i].read(data, pos, len, offset, proc);
- if (result != NULL) result->type = i;
- else printf("err while decoding :: [0x%02hhx] 0x%02hhx\n", proc->opcodes[i].prefix, proc->opcodes[i].opcode);
- break;
+ tmp = *pos + 1;
+ goto find_instr;
}
+ continue;
+
+ find_instr:
+
+ if (proc->opcodes[i].has_op_ext && (data[tmp] & EXT_OPCODE_MASK) != proc->opcodes[i].op_ext)
+ continue;
+
+ result = proc->opcodes[i].read(data, pos, len, offset, proc);
+ if (result != NULL) result->type = i;
+ else printf("err while decoding :: [0x%02hhx] 0x%02hhx\n", proc->opcodes[i].prefix, proc->opcodes[i].opcode);
+ break;
+
}
return ASM_INSTRUCTION(result);