More simplifications on BB creation

This commit is contained in:
Artur K 2012-07-14 23:04:09 +02:00
parent ba110a64cb
commit 5087a051b5
19 changed files with 989 additions and 1027 deletions

View File

@ -5,7 +5,7 @@
#include "ia32_reg.h"
#include "x86_operand_list.h"
/* Conventions: Register operands which are aliases of another register
/* Conventions: Register operands which are aliases of another register
* operand (e.g. AX in one operand and AL in another) assume that the
* operands are different registers and that alias tracking will resolve
* data flow. This means that something like
@ -13,412 +13,412 @@
* would have 'write only' access for AX and 'read only' access for AL,
* even though both AL and AX are read and written */
typedef struct {
uint32_t type;
uint32_t operand;
uint32_t type;
uint32_t operand;
} op_implicit_list_t;
static op_implicit_list_t list_aaa[] =
/* 37 : AAA : rw AL */
/* 3F : AAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* aaa */
static op_implicit_list_t list_aaa[] =
/* 37 : AAA : rw AL */
/* 3F : AAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* aaa */
static op_implicit_list_t list_aad[] =
/* D5 0A, D5 (ib) : AAD : rw AX */
/* D4 0A, D4 (ib) : AAM : rw AX */
{{ OP_R | OP_W, REG_WORD_OFFSET }, {0,0}}; /* aad */
static op_implicit_list_t list_aad[] =
/* D5 0A, D5 (ib) : AAD : rw AX */
/* D4 0A, D4 (ib) : AAM : rw AX */
{{ OP_R | OP_W, REG_WORD_OFFSET }, {0,0}}; /* aad */
static op_implicit_list_t list_call[] =
/* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */
/* C2, C3, CA, CB : RET : rw ESP, rw EIP */
{{ OP_R | OP_W, REG_EIP_INDEX },
{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* call, ret */
static op_implicit_list_t list_call[] =
/* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */
/* C2, C3, CA, CB : RET : rw ESP, rw EIP */
{{ OP_R | OP_W, REG_EIP_INDEX },
{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* call, ret */
static op_implicit_list_t list_cbw[] =
/* 98 : CBW : r AL, rw AX */
{{ OP_R | OP_W, REG_WORD_OFFSET },
{ OP_R, REG_BYTE_OFFSET}, {0,0}}; /* cbw */
static op_implicit_list_t list_cbw[] =
/* 98 : CBW : r AL, rw AX */
{{ OP_R | OP_W, REG_WORD_OFFSET },
{ OP_R, REG_BYTE_OFFSET}, {0,0}}; /* cbw */
static op_implicit_list_t list_cwde[] =
/* 98 : CWDE : r AX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_R, REG_WORD_OFFSET }, {0,0}}; /* cwde */
static op_implicit_list_t list_cwde[] =
/* 98 : CWDE : r AX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_R, REG_WORD_OFFSET }, {0,0}}; /* cwde */
static op_implicit_list_t list_clts[] =
/* 0F 06 : CLTS : rw CR0 */
{{ OP_R | OP_W, REG_CTRL_OFFSET}, {0,0}}; /* clts */
static op_implicit_list_t list_clts[] =
/* 0F 06 : CLTS : rw CR0 */
{{ OP_R | OP_W, REG_CTRL_OFFSET}, {0,0}}; /* clts */
static op_implicit_list_t list_cmpxchg[] =
/* 0F B0 : CMPXCHG : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* cmpxchg */
static op_implicit_list_t list_cmpxchg[] =
/* 0F B0 : CMPXCHG : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* cmpxchg */
static op_implicit_list_t list_cmpxchgb[] =
/* 0F B1 : CMPXCHG : rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* cmpxchg */
static op_implicit_list_t list_cmpxchgb[] =
/* 0F B1 : CMPXCHG : rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* cmpxchg */
static op_implicit_list_t list_cmpxchg8b[] =
/* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_R, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cmpxchg8b */
static op_implicit_list_t list_cmpxchg8b[] =
/* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_R, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cmpxchg8b */
static op_implicit_list_t list_cpuid[] =
/* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cpuid */
static op_implicit_list_t list_cpuid[] =
/* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cpuid */
static op_implicit_list_t list_cwd[] =
/* 99 : CWD/CWQ : rw EAX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* cwd */
static op_implicit_list_t list_cwd[] =
/* 99 : CWD/CWQ : rw EAX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* cwd */
static op_implicit_list_t list_daa[] =
/* 27 : DAA : rw AL */
/* 2F : DAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* daa */
static op_implicit_list_t list_daa[] =
/* 27 : DAA : rw AL */
/* 2F : DAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* daa */
static op_implicit_list_t list_idiv[] =
/* F6 : DIV, IDIV : r AX, w AL, w AH */
/* FIXED: first op was EAX, not Aw. TODO: verify! */
{{ OP_R, REG_WORD_OFFSET },
{ OP_W, REG_BYTE_OFFSET },
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* div */
static op_implicit_list_t list_idiv[] =
/* F6 : DIV, IDIV : r AX, w AL, w AH */
/* FIXED: first op was EAX, not Aw. TODO: verify! */
{{ OP_R, REG_WORD_OFFSET },
{ OP_W, REG_BYTE_OFFSET },
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* div */
static op_implicit_list_t list_div[] =
/* F7 : DIV, IDIV : rw EDX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* div */
static op_implicit_list_t list_div[] =
/* F7 : DIV, IDIV : rw EDX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* div */
static op_implicit_list_t list_enter[] =
/* C8 : ENTER : rw ESP w EBP */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 4 },
{ OP_R, REG_DWORD_OFFSET + 5 }, {0,0}}; /* enter */
static op_implicit_list_t list_enter[] =
/* C8 : ENTER : rw ESP w EBP */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 4 },
{ OP_R, REG_DWORD_OFFSET + 5 }, {0,0}}; /* enter */
static op_implicit_list_t list_f2xm1[] =
/* D9 F0 : F2XM1 : rw ST(0) */
/* D9 E1 : FABS : rw ST(0) */
/* D9 E0 : FCHS : rw ST(0) */
/* D9 FF : FCOS : rw ST(0)*/
/* D8, DA : FDIV : rw ST(0) */
/* D8, DA : FDIVR : rw ST(0) */
/* D9 F2 : FPTAN : rw ST(0) */
/* D9 FC : FRNDINT : rw ST(0) */
/* D9 FB : FSINCOS : rw ST(0) */
/* D9 FE : FSIN : rw ST(0) */
/* D9 FA : FSQRT : rw ST(0) */
/* D9 F4 : FXTRACT : rw ST(0) */
{{ OP_R | OP_W, REG_FPU_OFFSET }, {0,0}}; /* f2xm1 */
static op_implicit_list_t list_f2xm1[] =
/* D9 F0 : F2XM1 : rw ST(0) */
/* D9 E1 : FABS : rw ST(0) */
/* D9 E0 : FCHS : rw ST(0) */
/* D9 FF : FCOS : rw ST(0)*/
/* D8, DA : FDIV : rw ST(0) */
/* D8, DA : FDIVR : rw ST(0) */
/* D9 F2 : FPTAN : rw ST(0) */
/* D9 FC : FRNDINT : rw ST(0) */
/* D9 FB : FSINCOS : rw ST(0) */
/* D9 FE : FSIN : rw ST(0) */
/* D9 FA : FSQRT : rw ST(0) */
/* D9 F4 : FXTRACT : rw ST(0) */
{{ OP_R | OP_W, REG_FPU_OFFSET }, {0,0}}; /* f2xm1 */
static op_implicit_list_t list_fcom[] =
/* D8, DC, DE D9 : FCOM : r ST(0) */
/* DE, DA : FICOM : r ST(0) */
/* DF, D8 : FIST : r ST(0) */
/* D9 E4 : FTST : r ST(0) */
/* D9 E5 : FXAM : r ST(0) */
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fcom */
static op_implicit_list_t list_fcom[] =
/* D8, DC, DE D9 : FCOM : r ST(0) */
/* DE, DA : FICOM : r ST(0) */
/* DF, D8 : FIST : r ST(0) */
/* D9 E4 : FTST : r ST(0) */
/* D9 E5 : FXAM : r ST(0) */
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fcom */
static op_implicit_list_t list_fpatan[] =
/* D9 F3 : FPATAN : r ST(0), rw ST(1) */
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fpatan */
static op_implicit_list_t list_fpatan[] =
/* D9 F3 : FPATAN : r ST(0), rw ST(1) */
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fpatan */
static op_implicit_list_t list_fprem[] =
/* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */
/* D9 FD : FSCALE : rw ST(0), r ST(1) */
{{ OP_R | OP_W, REG_FPU_OFFSET },
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fprem */
static op_implicit_list_t list_fprem[] =
/* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */
/* D9 FD : FSCALE : rw ST(0), r ST(1) */
{{ OP_R | OP_W, REG_FPU_OFFSET },
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fprem */
static op_implicit_list_t list_faddp[] =
/* DE C1 : FADDP : r ST(0), rw ST(1) */
/* DE E9 : FSUBP : r ST(0), rw ST(1) */
/* D9 F1 : FYL2X : r ST(0), rw ST(1) */
/* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */
{{ OP_R, REG_FPU_OFFSET },
{ OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0,0}}; /* faddp */
static op_implicit_list_t list_faddp[] =
/* DE C1 : FADDP : r ST(0), rw ST(1) */
/* DE E9 : FSUBP : r ST(0), rw ST(1) */
/* D9 F1 : FYL2X : r ST(0), rw ST(1) */
/* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */
{{ OP_R, REG_FPU_OFFSET },
{ OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0,0}}; /* faddp */
static op_implicit_list_t list_fucompp[] =
/* DA E9 : FUCOMPP : r ST(0), r ST(1) */
{{ OP_R, REG_FPU_OFFSET },
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fucompp */
static op_implicit_list_t list_fucompp[] =
/* DA E9 : FUCOMPP : r ST(0), r ST(1) */
{{ OP_R, REG_FPU_OFFSET },
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fucompp */
static op_implicit_list_t list_imul[] =
/* F6 : IMUL : r AL, w AX */
/* F6 : MUL : r AL, w AX */
{{ OP_R, REG_BYTE_OFFSET },
{ OP_W, REG_WORD_OFFSET }, {0,0}}; /* imul */
static op_implicit_list_t list_imul[] =
/* F6 : IMUL : r AL, w AX */
/* F6 : MUL : r AL, w AX */
{{ OP_R, REG_BYTE_OFFSET },
{ OP_W, REG_WORD_OFFSET }, {0,0}}; /* imul */
static op_implicit_list_t list_mul[] =
/* F7 : IMUL : rw EAX, w EDX */
/* F7 : MUL : rw EAX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* imul */
static op_implicit_list_t list_mul[] =
/* F7 : IMUL : rw EAX, w EDX */
/* F7 : MUL : rw EAX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* imul */
static op_implicit_list_t list_lahf[] =
/* 9F : LAHF : r EFLAGS, w AH */
{{ OP_R, REG_FLAGS_INDEX },
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* lahf */
static op_implicit_list_t list_lahf[] =
/* 9F : LAHF : r EFLAGS, w AH */
{{ OP_R, REG_FLAGS_INDEX },
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* lahf */
static op_implicit_list_t list_ldmxcsr[] =
/* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */
{{ OP_W, REG_MXCSG_INDEX }, {0,0}}; /* ldmxcsr */
static op_implicit_list_t list_ldmxcsr[] =
/* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */
{{ OP_W, REG_MXCSG_INDEX }, {0,0}}; /* ldmxcsr */
static op_implicit_list_t list_leave[] =
/* C9 : LEAVE : rw ESP, w EBP */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_DWORD_OFFSET + 5 }, {0,0}}; /* leave */
static op_implicit_list_t list_leave[] =
/* C9 : LEAVE : rw ESP, w EBP */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_DWORD_OFFSET + 5 }, {0,0}}; /* leave */
static op_implicit_list_t list_lgdt[] =
/* 0F 01 : LGDT : w GDTR */
{{ OP_W, REG_GDTR_INDEX }, {0,0}}; /* lgdt */
static op_implicit_list_t list_lgdt[] =
/* 0F 01 : LGDT : w GDTR */
{{ OP_W, REG_GDTR_INDEX }, {0,0}}; /* lgdt */
static op_implicit_list_t list_lidt[] =
/* 0F 01 : LIDT : w IDTR */
{{ OP_W, REG_IDTR_INDEX }, {0,0}}; /* lidt */
static op_implicit_list_t list_lidt[] =
/* 0F 01 : LIDT : w IDTR */
{{ OP_W, REG_IDTR_INDEX }, {0,0}}; /* lidt */
static op_implicit_list_t list_lldt[] =
/* 0F 00 : LLDT : w LDTR */
{{ OP_W, REG_LDTR_INDEX }, {0,0}}; /* lldt */
static op_implicit_list_t list_lldt[] =
/* 0F 00 : LLDT : w LDTR */
{{ OP_W, REG_LDTR_INDEX }, {0,0}}; /* lldt */
static op_implicit_list_t list_lmsw[] =
/* 0F 01 : LMSW : w CR0 */
{{ OP_W, REG_CTRL_OFFSET }, {0,0}}; /* lmsw */
static op_implicit_list_t list_lmsw[] =
/* 0F 01 : LMSW : w CR0 */
{{ OP_W, REG_CTRL_OFFSET }, {0,0}}; /* lmsw */
static op_implicit_list_t list_loop[] =
/* E0, E1, E2 : LOOP : rw ECX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* loop */
static op_implicit_list_t list_loop[] =
/* E0, E1, E2 : LOOP : rw ECX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* loop */
static op_implicit_list_t list_ltr[] =
/* 0F 00 : LTR : w Task Register */
{{ OP_W, REG_TR_INDEX }, {0,0}}; /* ltr */
static op_implicit_list_t list_ltr[] =
/* 0F 00 : LTR : w Task Register */
{{ OP_W, REG_TR_INDEX }, {0,0}}; /* ltr */
static op_implicit_list_t list_pop[] =
/* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
{{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* pop, push */
static op_implicit_list_t list_pop[] =
/* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
{{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* pop, push */
static op_implicit_list_t list_popad[] =
/* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_DWORD_OFFSET + 7 },
{ OP_W, REG_DWORD_OFFSET + 6 },
{ OP_W, REG_DWORD_OFFSET + 5 },
{ OP_W, REG_DWORD_OFFSET + 3 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* popad */
static op_implicit_list_t list_popad[] =
/* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_DWORD_OFFSET + 7 },
{ OP_W, REG_DWORD_OFFSET + 6 },
{ OP_W, REG_DWORD_OFFSET + 5 },
{ OP_W, REG_DWORD_OFFSET + 3 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* popad */
static op_implicit_list_t list_popfd[] =
/* 9D : POPFD : rw esp, w eflags */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_FLAGS_INDEX }, {0,0}}; /* popfd */
static op_implicit_list_t list_popfd[] =
/* 9D : POPFD : rw esp, w eflags */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_FLAGS_INDEX }, {0,0}}; /* popfd */
static op_implicit_list_t list_pushad[] =
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
/* 60 : PUSHAD : rw esp, r eax ecx edx ebx esp ebp esi edi */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_R, REG_DWORD_OFFSET },
{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_R, REG_DWORD_OFFSET + 2 },
{ OP_R, REG_DWORD_OFFSET + 3 },
{ OP_R, REG_DWORD_OFFSET + 5 },
{ OP_R, REG_DWORD_OFFSET + 6 },
{ OP_R, REG_DWORD_OFFSET + 7 }, {0,0}}; /* pushad */
static op_implicit_list_t list_pushad[] =
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
/* 60 : PUSHAD : rw esp, r eax ecx edx ebx esp ebp esi edi */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_R, REG_DWORD_OFFSET },
{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_R, REG_DWORD_OFFSET + 2 },
{ OP_R, REG_DWORD_OFFSET + 3 },
{ OP_R, REG_DWORD_OFFSET + 5 },
{ OP_R, REG_DWORD_OFFSET + 6 },
{ OP_R, REG_DWORD_OFFSET + 7 }, {0,0}}; /* pushad */
static op_implicit_list_t list_pushfd[] =
/* 9C : PUSHFD : rw esp, r eflags */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_R, REG_FLAGS_INDEX }, {0,0}}; /* pushfd */
static op_implicit_list_t list_pushfd[] =
/* 9C : PUSHFD : rw esp, r eflags */
{{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_R, REG_FLAGS_INDEX }, {0,0}}; /* pushfd */
static op_implicit_list_t list_rdmsr[] =
/* 0F 32 : RDMSR : r ECX, w EDX, w EAX */
{{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdmsr */
static op_implicit_list_t list_rdmsr[] =
/* 0F 32 : RDMSR : r ECX, w EDX, w EAX */
{{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdmsr */
static op_implicit_list_t list_rdpmc[] =
/* 0F 33 : RDPMC : r ECX, w EDX, w EAX */
{{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdpmc */
static op_implicit_list_t list_rdpmc[] =
/* 0F 33 : RDPMC : r ECX, w EDX, w EAX */
{{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdpmc */
static op_implicit_list_t list_rdtsc[] =
/* 0F 31 : RDTSC : rw EDX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdtsc */
static op_implicit_list_t list_rdtsc[] =
/* 0F 31 : RDTSC : rw EDX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdtsc */
static op_implicit_list_t list_rep[] =
/* F3, F2 ... : REP : rw ECX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* rep */
static op_implicit_list_t list_rep[] =
/* F3, F2 ... : REP : rw ECX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* rep */
static op_implicit_list_t list_rsm[] =
/* 0F AA : RSM : r CR4, r CR0 */
{{ OP_R, REG_CTRL_OFFSET + 4 },
{ OP_R, REG_CTRL_OFFSET }, {0,0}}; /* rsm */
static op_implicit_list_t list_rsm[] =
/* 0F AA : RSM : r CR4, r CR0 */
{{ OP_R, REG_CTRL_OFFSET + 4 },
{ OP_R, REG_CTRL_OFFSET }, {0,0}}; /* rsm */
static op_implicit_list_t list_sahf[] =
/* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sahf */
static op_implicit_list_t list_sahf[] =
/* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sahf */
static op_implicit_list_t list_sgdt[] =
/* 0F : SGDT : r gdtr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sgdt */
static op_implicit_list_t list_sgdt[] =
/* 0F : SGDT : r gdtr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sgdt */
static op_implicit_list_t list_sidt[] =
/* 0F : SIDT : r idtr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sidt */
static op_implicit_list_t list_sidt[] =
/* 0F : SIDT : r idtr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sidt */
static op_implicit_list_t list_sldt[] =
/* 0F : SLDT : r ldtr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sldt */
static op_implicit_list_t list_sldt[] =
/* 0F : SLDT : r ldtr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sldt */
static op_implicit_list_t list_smsw[] =
/* 0F : SMSW : r CR0 */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* smsw */
static op_implicit_list_t list_smsw[] =
/* 0F : SMSW : r CR0 */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* smsw */
static op_implicit_list_t list_stmxcsr[] =
/* 0F AE : STMXCSR : r MXCSR */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* stmxcsr */
static op_implicit_list_t list_stmxcsr[] =
/* 0F AE : STMXCSR : r MXCSR */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* stmxcsr */
static op_implicit_list_t list_str[] =
/* 0F 00 : STR : r TR (task register) */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* str */
static op_implicit_list_t list_str[] =
/* 0F 00 : STR : r TR (task register) */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* str */
static op_implicit_list_t list_sysenter[] =
/* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags
* r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysenter */
static op_implicit_list_t list_sysenter[] =
/* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags
* r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysenter */
static op_implicit_list_t list_sysexit[] =
/* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp
* r sysenter_cs_msr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysexit */
static op_implicit_list_t list_sysexit[] =
/* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp
* r sysenter_cs_msr */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysexit */
static op_implicit_list_t list_wrmsr[] =
/* 0F 30 : WRMST : r edx, r eax, r ecx */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* wrmsr */
static op_implicit_list_t list_wrmsr[] =
/* 0F 30 : WRMST : r edx, r eax, r ecx */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* wrmsr */
static op_implicit_list_t list_xlat[] =
/* D7 : XLAT : rw al r ebx (ptr) */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* xlat */
static op_implicit_list_t list_xlat[] =
/* D7 : XLAT : rw al r ebx (ptr) */
/* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* xlat */
/* TODO:
* monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R
* mwait 0f 01 c9 eax OP_R ecx OP_R
*/
static op_implicit_list_t list_monitor[] =
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* monitor */
static op_implicit_list_t list_mwait[] =
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* mwait */
static op_implicit_list_t list_monitor[] =
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* monitor */
static op_implicit_list_t list_mwait[] =
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* mwait */
op_implicit_list_t *op_implicit_list[] = {
/* This is a list of implicit operands which are read/written by
* various x86 instructions. Note that modifications to the stack
* register are mentioned here, but that additional information on
* the effect an instruction has on the stack is contained in the
* x86_insn_t 'stack_mod' and 'stack_mod_val' fields. Use of the
* eflags register, i.e. setting, clearing, and testing flags, is
* not recorded here but rather in the flags_set and flags_tested
* fields of the x86_insn_t.*/
NULL,
list_aaa, list_aad, list_call, list_cbw, /* 1 - 4 */
list_cwde, list_clts, list_cmpxchg, list_cmpxchgb, /* 5 - 8 */
list_cmpxchg8b, list_cpuid, list_cwd, list_daa, /* 9 - 12 */
list_idiv, list_div, list_enter, list_f2xm1, /* 13 - 16 */
list_fcom, list_fpatan, list_fprem, list_faddp, /* 17 - 20 */
list_fucompp, list_imul, list_mul, list_lahf, /* 21 - 24 */
list_ldmxcsr, list_leave, list_lgdt, list_lidt, /* 25 - 28 */
list_lldt, list_lmsw, list_loop, list_ltr, /* 29 - 32 */
list_pop, list_popad, list_popfd, list_pushad, /* 33 - 36 */
list_pushfd, list_rdmsr, list_rdpmc, list_rdtsc, /* 37 - 40 */
/* NOTE: 'REP' is a hack since it is a prefix: if its position
* in the table changes, then change IDX_IMPLICIT_REP in the .h */
list_rep, list_rsm, list_sahf, list_sgdt, /* 41 - 44 */
list_sidt, list_sldt, list_smsw, list_stmxcsr, /* 45 - 48 */
list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */
list_xlat, list_monitor, list_mwait, /* 53 - 55*/
NULL /* end of list */
};
/* This is a list of implicit operands which are read/written by
* various x86 instructions. Note that modifications to the stack
* register are mentioned here, but that additional information on
* the effect an instruction has on the stack is contained in the
* x86_insn_t 'stack_mod' and 'stack_mod_val' fields. Use of the
* eflags register, i.e. setting, clearing, and testing flags, is
* not recorded here but rather in the flags_set and flags_tested
* fields of the x86_insn_t.*/
NULL,
list_aaa, list_aad, list_call, list_cbw, /* 1 - 4 */
list_cwde, list_clts, list_cmpxchg, list_cmpxchgb, /* 5 - 8 */
list_cmpxchg8b, list_cpuid, list_cwd, list_daa, /* 9 - 12 */
list_idiv, list_div, list_enter, list_f2xm1, /* 13 - 16 */
list_fcom, list_fpatan, list_fprem, list_faddp, /* 17 - 20 */
list_fucompp, list_imul, list_mul, list_lahf, /* 21 - 24 */
list_ldmxcsr, list_leave, list_lgdt, list_lidt, /* 25 - 28 */
list_lldt, list_lmsw, list_loop, list_ltr, /* 29 - 32 */
list_pop, list_popad, list_popfd, list_pushad, /* 33 - 36 */
list_pushfd, list_rdmsr, list_rdpmc, list_rdtsc, /* 37 - 40 */
/* NOTE: 'REP' is a hack since it is a prefix: if its position
* in the table changes, then change IDX_IMPLICIT_REP in the .h */
list_rep, list_rsm, list_sahf, list_sgdt, /* 41 - 44 */
list_sidt, list_sldt, list_smsw, list_stmxcsr, /* 45 - 48 */
list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */
list_xlat, list_monitor, list_mwait, /* 53 - 55*/
NULL /* end of list */
};
#define LAST_IMPL_IDX 55
static void handle_impl_reg( x86_op_t *op, uint32_t val ) {
x86_reg_t *reg = &op->data.reg;
op->type = op_register;
ia32_handle_register( reg, (unsigned int) val );
switch (reg->size) {
case 1:
op->datatype = op_byte; break;
case 2:
op->datatype = op_word; break;
case 4:
op->datatype = op_dword; break;
case 8:
op->datatype = op_qword; break;
case 10:
op->datatype = op_extreal; break;
case 16:
op->datatype = op_dqword; break;
}
return;
x86_reg_t *reg = &op->data.reg;
op->type = op_register;
ia32_handle_register( reg, (unsigned int) val );
switch (reg->size) {
case 1:
op->datatype = op_byte; break;
case 2:
op->datatype = op_word; break;
case 4:
op->datatype = op_dword; break;
case 8:
op->datatype = op_qword; break;
case 10:
op->datatype = op_extreal; break;
case 16:
op->datatype = op_dqword; break;
}
return;
}
/* 'impl_idx' is the value from the opcode table: between 1 and LAST_IMPL_IDX */
/* returns number of operands added */
unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
op_implicit_list_t *list;
x86_oplist_t * existing=0;
x86_op_t *op;
unsigned int num = 0;
op_implicit_list_t *list;
x86_oplist_t * existing=0;
x86_op_t *op;
unsigned int num = 0;
if (! impl_idx || impl_idx > LAST_IMPL_IDX ) {
return 0;
}
if (! impl_idx || impl_idx > LAST_IMPL_IDX ) {
return 0;
}
for ( list = op_implicit_list[impl_idx]; list->type; list++, num++ ) {
enum x86_op_access access = (enum x86_op_access) OP_PERM(list->type);
x86_op_flags flags;
for ( list = op_implicit_list[impl_idx]; list->type; list++, num++ ) {
enum x86_op_access access = (enum x86_op_access) OP_PERM(list->type);
x86_op_flags flags;
flags.whole = (OP_FLAGS(list->type) >> 12);
op = NULL;
/* In some cases (MUL), EAX is an implicit operand hardcoded in
op = NULL;
/* In some cases (MUL), EAX is an implicit operand hardcoded in
* the instruction without being explicitly listed in assembly.
* For this situation, find the hardcoded operand and add the
* implied flag rather than adding a new implicit operand. */
existing=0;
if (ia32_true_register_id(list->operand) == REG_DWORD_OFFSET) {
for ( existing = m_decoded->operands; existing; existing = existing->next ) {
if (existing->op.type == op_register &&
existing->op.data.reg.id == list->operand) {
op = &existing->op;
break;
}
}
}
if (!op) {
op = m_decoded->x86_operand_new();
/* all implicit operands are registers */
handle_impl_reg( op, list->operand );
/* decrement the 'explicit count' incremented by default in
* x86_operand_new */
m_decoded->explicit_count = m_decoded->explicit_count -1;
}
if (!op) {
return num; /* gah! return early */
}
op->access = x86_op_access((int)op->access | (int)access);
op->flags.whole |= flags.whole;
op->flags.op_implied=true;
}
return num;
existing=0;
if (ia32_true_register_id(list->operand) == REG_DWORD_OFFSET) {
for ( existing = m_decoded->operands; existing; existing = existing->next ) {
if (existing->op.type == op_register &&
existing->op.data.reg.id == list->operand) {
op = &existing->op;
break;
}
}
}
if (!op) {
op = m_decoded->x86_operand_new();
/* all implicit operands are registers */
handle_impl_reg( op, list->operand );
/* decrement the 'explicit count' incremented by default in
* x86_operand_new */
m_decoded->explicit_count = m_decoded->explicit_count -1;
}
if (!op) {
return num; /* gah! return early */
}
op->access = x86_op_access((int)op->access | (int)access);
op->flags.whole |= flags.whole;
op->flags.op_implied=true;
}
return num;
}

View File

@ -543,8 +543,7 @@ size_t Ia32_Decoder::handle_insn_suffix( unsigned char *buf, size_t buf_len,
ia32_insn_t *sfx_insn;
size_t size;
unsigned int prefixes = 0;
// table_desc = &ia32_tables[raw_insn->table];
//table_desc = &ia32_tables[raw_insn->table];
size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn,
&prefixes );
if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) {

View File

@ -9,8 +9,8 @@ extern ia32_table_desc_t *ia32_tables;
extern ia32_settings_t ia32_settings;
extern size_t ia32_table_lookup( unsigned char *buf, size_t buf_len,
unsigned int table, ia32_insn_t **raw_insn,
unsigned int *prefixes );
unsigned int table, ia32_insn_t **raw_insn,
unsigned int *prefixes );
/* -------------------------------- ModR/M, SIB */
@ -47,10 +47,10 @@ extern size_t ia32_table_lookup( unsigned char *buf, size_t buf_len,
#define SIB_SCALE_NOBASE 0x00
/* Convenience struct for modR/M bitfield */
struct modRM_byte {
struct modRM_byte {
unsigned int mod : 2;
unsigned int reg : 3;
unsigned int rm : 3;
unsigned int rm : 3;
};
/* Convenience struct for SIB bitfield */
@ -65,249 +65,249 @@ static void byte_decode(unsigned char b, struct modRM_byte *modrm) {
#else
static inline void byte_decode(unsigned char b, struct modRM_byte *modrm) {
#endif
/* generic bitfield-packing routine */
/* generic bitfield-packing routine */
modrm->mod = b >> 6; /* top 2 bits */
modrm->reg = (b & 56) >> 3; /* middle 3 bits */
modrm->rm = b & 7; /* bottom 3 bits */
modrm->mod = b >> 6; /* top 2 bits */
modrm->reg = (b & 56) >> 3; /* middle 3 bits */
modrm->rm = b & 7; /* bottom 3 bits */
}
static int ia32_invariant_modrm( unsigned char *in, unsigned char *out,
unsigned int mode_16, x86_invariant_op_t *op) {
struct modRM_byte modrm;
struct SIB_byte sib;
unsigned char *c, *cin;
unsigned short *s;
unsigned int *i;
int size = 0; /* modrm byte is already counted */
unsigned int mode_16, x86_invariant_op_t *op) {
struct modRM_byte modrm;
struct SIB_byte sib;
unsigned char *c, *cin;
unsigned short *s;
unsigned int *i;
int size = 0; /* modrm byte is already counted */
byte_decode(*in, &modrm); /* get bitfields */
byte_decode(*in, &modrm); /* get bitfields */
out[0] = in[0]; /* save modrm byte */
cin = &in[1];
c = &out[1];
s = (unsigned short *)&out[1];
i = (unsigned int *)&out[1];
out[0] = in[0]; /* save modrm byte */
cin = &in[1];
c = &out[1];
s = (unsigned short *)&out[1];
i = (unsigned int *)&out[1];
op->type = op_expression;
op->flags.op_pointer = true; //|= op_pointer;
if ( ! mode_16 && modrm.rm == MODRM_RM_SIB &&
modrm.mod != MODRM_MOD_NOEA ) {
size ++;
byte_decode(*cin, (struct modRM_byte *)(void*)&sib);
op->type = op_expression;
op->flags.op_pointer = true; //|= op_pointer;
if ( ! mode_16 && modrm.rm == MODRM_RM_SIB &&
modrm.mod != MODRM_MOD_NOEA ) {
size ++;
byte_decode(*cin, (struct modRM_byte *)(void*)&sib);
out[1] = in[1]; /* save sib byte */
cin = &in[2];
c = &out[2];
s = (unsigned short *)&out[2];
i = (unsigned int *)&out[2];
out[1] = in[1]; /* save sib byte */
cin = &in[2];
c = &out[2];
s = (unsigned short *)&out[2];
i = (unsigned int *)&out[2];
if ( sib.base == SIB_BASE_EBP && ! modrm.mod ) {
/* disp 32 is variant! */
memset( i, X86_WILDCARD_BYTE, 4 );
size += 4;
}
}
if ( sib.base == SIB_BASE_EBP && ! modrm.mod ) {
/* disp 32 is variant! */
memset( i, X86_WILDCARD_BYTE, 4 );
size += 4;
}
}
if (! modrm.mod && modrm.rm == 101) {
if ( mode_16 ) { /* straight RVA in disp */
memset( s, X86_WILDCARD_BYTE, 2 );
size += 2;
} else {
memset( i, X86_WILDCARD_BYTE, 2 );
size += 4;
}
} else if (modrm.mod && modrm.mod < 3) {
if (modrm.mod == MODRM_MOD_DISP8) { /* offset in disp */
*c = *cin;
size += 1;
} else if ( mode_16 ) {
*s = (* ((unsigned short *) cin));
size += 2;
} else {
*i = (*((unsigned int *) cin));
size += 4;
}
} else if ( modrm.mod == 3 ) {
op->type = op_register;
op->flags.op_pointer = false;// &= ~op_pointer;
}
if (! modrm.mod && modrm.rm == 101) {
if ( mode_16 ) { /* straight RVA in disp */
memset( s, X86_WILDCARD_BYTE, 2 );
size += 2;
} else {
memset( i, X86_WILDCARD_BYTE, 2 );
size += 4;
}
} else if (modrm.mod && modrm.mod < 3) {
if (modrm.mod == MODRM_MOD_DISP8) { /* offset in disp */
*c = *cin;
size += 1;
} else if ( mode_16 ) {
*s = (* ((unsigned short *) cin));
size += 2;
} else {
*i = (*((unsigned int *) cin));
size += 4;
}
} else if ( modrm.mod == 3 ) {
op->type = op_register;
op->flags.op_pointer = false;// &= ~op_pointer;
}
return (size);
return (size);
}
static int ia32_decode_invariant( unsigned char *buf, size_t /*buf_len*/,
ia32_insn_t *t, unsigned char *out,
unsigned int prefixes, x86_invariant_t *inv) {
ia32_insn_t *t, unsigned char *out,
unsigned int prefixes, x86_invariant_t *inv) {
unsigned int addr_size, op_size, mode_16;
unsigned int op_flags[3] = { t->dest_flag, t->src_flag, t->aux_flag };
int x, type, bytes = 0, size = 0, modrm = 0;
unsigned int addr_size, op_size, mode_16;
unsigned int op_flags[3] = { t->dest_flag, t->src_flag, t->aux_flag };
int x, type, bytes = 0, size = 0, modrm = 0;
/* set addressing mode */
if (ia32_settings.options & opt_16_bit) {
op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2;
addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2;
mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 0 : 1;
} else {
op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4;
addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4;
mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 1 : 0;
}
/* set addressing mode */
if (ia32_settings.options & opt_16_bit) {
op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2;
addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2;
mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 0 : 1;
} else {
op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4;
addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4;
mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 1 : 0;
}
for (x = 0; x < 3; x++) {
inv->operands[x].access = (enum x86_op_access) OP_PERM(op_flags[x]);
inv->operands[x].flags.whole = (OP_FLAGS(op_flags[x]) >> 12);
for (x = 0; x < 3; x++) {
inv->operands[x].access = (enum x86_op_access) OP_PERM(op_flags[x]);
inv->operands[x].flags.whole = (OP_FLAGS(op_flags[x]) >> 12);
//(enum x86_op_flags) (OP_FLAGS(op_flags[x]) >> 12);
switch (op_flags[x] & OPTYPE_MASK) {
case OPTYPE_c:
size = (op_size == 4) ? 2 : 1;
break;
case OPTYPE_a: case OPTYPE_v:
size = (op_size == 4) ? 4 : 2;
break;
case OPTYPE_p:
size = (op_size == 4) ? 6 : 4;
break;
case OPTYPE_b:
size = 1;
break;
case OPTYPE_w:
size = 2;
break;
case OPTYPE_d: case OPTYPE_fs: case OPTYPE_fd:
case OPTYPE_fe: case OPTYPE_fb: case OPTYPE_fv:
case OPTYPE_si: case OPTYPE_fx:
size = 4;
break;
case OPTYPE_s:
size = 6;
break;
case OPTYPE_q: case OPTYPE_pi:
size = 8;
break;
case OPTYPE_dq: case OPTYPE_ps: case OPTYPE_ss:
case OPTYPE_pd: case OPTYPE_sd:
size = 16;
break;
case OPTYPE_m:
size = (addr_size == 4) ? 4 : 2;
break;
default:
break;
}
switch (op_flags[x] & OPTYPE_MASK) {
case OPTYPE_c:
size = (op_size == 4) ? 2 : 1;
break;
case OPTYPE_a: case OPTYPE_v:
size = (op_size == 4) ? 4 : 2;
break;
case OPTYPE_p:
size = (op_size == 4) ? 6 : 4;
break;
case OPTYPE_b:
size = 1;
break;
case OPTYPE_w:
size = 2;
break;
case OPTYPE_d: case OPTYPE_fs: case OPTYPE_fd:
case OPTYPE_fe: case OPTYPE_fb: case OPTYPE_fv:
case OPTYPE_si: case OPTYPE_fx:
size = 4;
break;
case OPTYPE_s:
size = 6;
break;
case OPTYPE_q: case OPTYPE_pi:
size = 8;
break;
case OPTYPE_dq: case OPTYPE_ps: case OPTYPE_ss:
case OPTYPE_pd: case OPTYPE_sd:
size = 16;
break;
case OPTYPE_m:
size = (addr_size == 4) ? 4 : 2;
break;
default:
break;
}
type = op_flags[x] & ADDRMETH_MASK;
switch (type) {
case ADDRMETH_E: case ADDRMETH_M: case ADDRMETH_Q:
case ADDRMETH_R: case ADDRMETH_W:
modrm = 1;
bytes += ia32_invariant_modrm( buf, out,
mode_16, &inv->operands[x]);
break;
case ADDRMETH_C: case ADDRMETH_D: case ADDRMETH_G:
case ADDRMETH_P: case ADDRMETH_S: case ADDRMETH_T:
case ADDRMETH_V:
inv->operands[x].type = op_register;
modrm = 1;
break;
case ADDRMETH_A: case ADDRMETH_O:
/* pad with xF4's */
memset( &out[bytes + modrm], X86_WILDCARD_BYTE,
size );
bytes += size;
inv->operands[x].type = op_offset;
if ( type == ADDRMETH_O ) {
inv->operands[x].flags.op_signed = true;
type = op_flags[x] & ADDRMETH_MASK;
switch (type) {
case ADDRMETH_E: case ADDRMETH_M: case ADDRMETH_Q:
case ADDRMETH_R: case ADDRMETH_W:
modrm = 1;
bytes += ia32_invariant_modrm( buf, out,
mode_16, &inv->operands[x]);
break;
case ADDRMETH_C: case ADDRMETH_D: case ADDRMETH_G:
case ADDRMETH_P: case ADDRMETH_S: case ADDRMETH_T:
case ADDRMETH_V:
inv->operands[x].type = op_register;
modrm = 1;
break;
case ADDRMETH_A: case ADDRMETH_O:
/* pad with xF4's */
memset( &out[bytes + modrm], X86_WILDCARD_BYTE,
size );
bytes += size;
inv->operands[x].type = op_offset;
if ( type == ADDRMETH_O ) {
inv->operands[x].flags.op_signed = true;
inv->operands[x].flags.op_pointer = true;
}
break;
case ADDRMETH_I: case ADDRMETH_J:
/* grab imm value */
if ((op_flags[x] & OPTYPE_MASK) == OPTYPE_v) {
/* assume this is an address */
memset( &out[bytes + modrm], X86_WILDCARD_BYTE, size );
} else {
memcpy( &out[bytes + modrm], &buf[bytes + modrm], size );
}
bytes += size;
if ( type == ADDRMETH_J ) {
if ( size == 1 ) {
inv->operands[x].type = op_relative_near;
} else {
inv->operands[x].type = op_relative_far;
}
inv->operands[x].flags.op_signed=true;
} else {
inv->operands[x].type = op_immediate;
}
break;
case ADDRMETH_F:
inv->operands[x].type = op_register;
break;
case ADDRMETH_X:
inv->operands[x].flags.op_signed=true;
inv->operands[x].flags.op_pointer=true;
}
break;
case ADDRMETH_I: case ADDRMETH_J:
/* grab imm value */
if ((op_flags[x] & OPTYPE_MASK) == OPTYPE_v) {
/* assume this is an address */
memset( &out[bytes + modrm], X86_WILDCARD_BYTE, size );
} else {
memcpy( &out[bytes + modrm], &buf[bytes + modrm], size );
}
bytes += size;
if ( type == ADDRMETH_J ) {
if ( size == 1 ) {
inv->operands[x].type = op_relative_near;
} else {
inv->operands[x].type = op_relative_far;
}
inv->operands[x].flags.op_signed=true;
} else {
inv->operands[x].type = op_immediate;
}
break;
case ADDRMETH_F:
inv->operands[x].type = op_register;
break;
case ADDRMETH_X:
inv->operands[x].flags.op_signed=true;
inv->operands[x].flags.op_pointer=true;
inv->operands[x].flags.op_seg=(x86_op_flags::op_ds_seg)>>8;
inv->operands[x].flags.op_string=true;
break;
case ADDRMETH_Y:
break;
case ADDRMETH_Y:
inv->operands[x].flags.op_signed=true;
inv->operands[x].flags.op_pointer=true;
inv->operands[x].flags.op_seg=x86_op_flags::op_es_seg>>8;
inv->operands[x].flags.op_string=true;
break;
case ADDRMETH_RR:
inv->operands[x].type = op_register;
break;
case ADDRMETH_II:
inv->operands[x].type = op_immediate;
break;
default:
inv->operands[x].type = op_unused;
break;
}
}
break;
case ADDRMETH_RR:
inv->operands[x].type = op_register;
break;
case ADDRMETH_II:
inv->operands[x].type = op_immediate;
break;
default:
inv->operands[x].type = op_unused;
break;
}
}
return (bytes + modrm);
return (bytes + modrm);
}
size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len,
x86_invariant_t *inv ) {
ia32_insn_t *raw_insn = NULL;
unsigned int prefixes=0;
unsigned int type;
size_t size;
size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len,
x86_invariant_t *inv ) {
ia32_insn_t *raw_insn = NULL;
unsigned int prefixes=0;
unsigned int type;
size_t size;
/* Perform recursive table lookup starting with main table (0) */
size = ia32_table_lookup( buf, buf_len, 0, &raw_insn, &prefixes );
if ( size == INVALID_INSN || size > buf_len ) {
/* TODO: set errno */
return 0;
}
/* Perform recursive table lookup starting with main table (0) */
size = ia32_table_lookup( buf, buf_len, 0, &raw_insn, &prefixes );
if ( size == INVALID_INSN || size > buf_len ) {
/* TODO: set errno */
return 0;
}
/* copy opcode bytes to buffer */
memcpy( inv->bytes, buf, size );
/* copy opcode bytes to buffer */
memcpy( inv->bytes, buf, size );
/* set mnemonic type and group */
type = raw_insn->mnem_flag & ~INS_FLAG_MASK;
/* set mnemonic type and group */
type = raw_insn->mnem_flag & ~INS_FLAG_MASK;
inv->group = (x86_insn_t::x86_insn_group) ((INS_GROUP(type)) >> 12);
inv->type = (enum x86_insn_type) INS_TYPE(type);
/* handle operands */
size += ia32_decode_invariant( buf + size, buf_len - size, raw_insn,
&buf[size - 1], prefixes, inv );
/* handle operands */
size += ia32_decode_invariant( buf + size, buf_len - size, raw_insn,
&buf[size - 1], prefixes, inv );
inv->size = size;
inv->size = size;
return size; /* return size of instruction in bytes */
return size; /* return size of instruction in bytes */
}
size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ) {
x86_invariant_t inv;
memset(&inv,0,sizeof(x86_invariant_t));
return( ia32_disasm_invariant( buf, buf_len, &inv ) );
x86_invariant_t inv;
memset(&inv,0,sizeof(x86_invariant_t));
return( ia32_disasm_invariant( buf, buf_len, &inv ) );
}

View File

@ -480,7 +480,7 @@ static ia32_insn_t tbl_0F[] = { /* Two-byte Opcodes */
{ 0, INS_SYSTEM, 0, ARG_NONE, ARG_NONE, ARG_NONE, cpu_PENTIUM2 | isa_GP, "sysexit", "", 0, 0, 0, 0 , 51 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshufb", "", 0, 0, 0, 0, 0 },
{ 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ADDRMETH_I | OPTYPE_b | OP_R, cpu_PENTIUM4 | isa_GP, "pshufb", "", 0, 0, 0, 0, 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
@ -655,7 +655,7 @@ static ia32_insn_t tbl_0F[] = { /* Two-byte Opcodes */
{ 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pavgw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmulhuw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmulhw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_MOV, INS_NOTE_NOSUFFIX, ADDRMETH_W | OPTYPE_q | OP_W, ADDRMETH_V | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "movntq", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubsb", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubsw", "", 0, 0, 0, 0 , 0 },
@ -665,22 +665,22 @@ static ia32_insn_t tbl_0F[] = { /* Two-byte Opcodes */
{ 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddsw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_ARITH, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "pmaxsw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_XOR, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pxor", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 },
{ 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pslld", "", 0, 0, 0, 0 , 0 },
{ 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psllq", "", 0, 0, 0, 0 , 0 },
{ 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmuludq", "", 0, 0, 0, 0, 0 },
{ 0, INS_MUL, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "pmuludq", "", 0, 0, 0, 0, 0 },
{ 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "pmaddwd", "", 0, 0, 0, 0 , 0 },
{ 0, INS_OTHER, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "psadbw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_MOV, 0, ADDRMETH_P | OPTYPE_pi | OP_W, ADDRMETH_Q | OPTYPE_pi | OP_R, ARG_NONE, cpu_PENTIUM2 | isa_GP, "maskmovq", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubb", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "psubd", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubq", "", 0, 0, 0, 0 , 0 },
{ 0, INS_SUB, 0, ADDRMETH_P | OPTYPE_q | OP_R | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM4 | isa_GP, "psubq", "", 0, 0, 0, 0, 0 },
{ 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddb", "", 0, 0, 0, 0 , 0 },
{ 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddw", "", 0, 0, 0, 0 , 0 },
{ 0, INS_ADD, 0, ADDRMETH_P | OPTYPE_q | OP_W, ADDRMETH_Q | OPTYPE_q | OP_R, ARG_NONE, cpu_PENTIUM | isa_MMX, "paddd", "", 0, 0, 0, 0 , 0 },
{ 0, INS_INVALID,0, ARG_NONE , ARG_NONE , ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0}
{ 0, INS_INVALID, 0, ARG_NONE, ARG_NONE, ARG_NONE, 0, "", "", 0, 0, 0, 0 , 0 }
};

View File

@ -31,204 +31,204 @@
* of the MMX registers, so this aliasing is not 100% accurate.
* */
static struct {
unsigned char alias; /* id of register this is an alias for */
unsigned char shift; /* # of bits register must be shifted */
unsigned char alias; /* id of register this is an alias for */
unsigned char shift; /* # of bits register must be shifted */
} ia32_reg_aliases[] = {
{ 0,0 },
{ REG_DWORD_OFFSET, 0 }, /* al : 1 */
{ REG_DWORD_OFFSET, 8 }, /* ah : 2 */
{ REG_DWORD_OFFSET, 0 }, /* ax : 3 */
{ REG_DWORD_OFFSET + 1, 0 }, /* cl : 4 */
{ REG_DWORD_OFFSET + 1, 8 }, /* ch : 5 */
{ REG_DWORD_OFFSET + 1, 0 }, /* cx : 6 */
{ REG_DWORD_OFFSET + 2, 0 }, /* dl : 7 */
{ REG_DWORD_OFFSET + 2, 8 }, /* dh : 8 */
{ REG_DWORD_OFFSET + 2, 0 }, /* dx : 9 */
{ REG_DWORD_OFFSET + 3, 0 }, /* bl : 10 */
{ REG_DWORD_OFFSET + 3, 8 }, /* bh : 11 */
{ REG_DWORD_OFFSET + 3, 0 }, /* bx : 12 */
{ REG_DWORD_OFFSET + 4, 0 }, /* sp : 13 */
{ REG_DWORD_OFFSET + 5, 0 }, /* bp : 14 */
{ REG_DWORD_OFFSET + 6, 0 }, /* si : 15 */
{ REG_DWORD_OFFSET + 7, 0 }, /* di : 16 */
{ REG_EIP_INDEX, 0 }, /* ip : 17 */
{ REG_FPU_OFFSET, 0 }, /* mm0 : 18 */
{ REG_FPU_OFFSET + 1, 0 }, /* mm1 : 19 */
{ REG_FPU_OFFSET + 2, 0 }, /* mm2 : 20 */
{ REG_FPU_OFFSET + 3, 0 }, /* mm3 : 21 */
{ REG_FPU_OFFSET + 4, 0 }, /* mm4 : 22 */
{ REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */
{ REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */
{ REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */
};
{ 0,0 },
{ REG_DWORD_OFFSET, 0 }, /* al : 1 */
{ REG_DWORD_OFFSET, 8 }, /* ah : 2 */
{ REG_DWORD_OFFSET, 0 }, /* ax : 3 */
{ REG_DWORD_OFFSET + 1, 0 }, /* cl : 4 */
{ REG_DWORD_OFFSET + 1, 8 }, /* ch : 5 */
{ REG_DWORD_OFFSET + 1, 0 }, /* cx : 6 */
{ REG_DWORD_OFFSET + 2, 0 }, /* dl : 7 */
{ REG_DWORD_OFFSET + 2, 8 }, /* dh : 8 */
{ REG_DWORD_OFFSET + 2, 0 }, /* dx : 9 */
{ REG_DWORD_OFFSET + 3, 0 }, /* bl : 10 */
{ REG_DWORD_OFFSET + 3, 8 }, /* bh : 11 */
{ REG_DWORD_OFFSET + 3, 0 }, /* bx : 12 */
{ REG_DWORD_OFFSET + 4, 0 }, /* sp : 13 */
{ REG_DWORD_OFFSET + 5, 0 }, /* bp : 14 */
{ REG_DWORD_OFFSET + 6, 0 }, /* si : 15 */
{ REG_DWORD_OFFSET + 7, 0 }, /* di : 16 */
{ REG_EIP_INDEX, 0 }, /* ip : 17 */
{ REG_FPU_OFFSET, 0 }, /* mm0 : 18 */
{ REG_FPU_OFFSET + 1, 0 }, /* mm1 : 19 */
{ REG_FPU_OFFSET + 2, 0 }, /* mm2 : 20 */
{ REG_FPU_OFFSET + 3, 0 }, /* mm3 : 21 */
{ REG_FPU_OFFSET + 4, 0 }, /* mm4 : 22 */
{ REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */
{ REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */
{ REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */
};
/* REGISTER TABLE: size, type, and name of every register in the
* CPU. Does not include MSRs since the are, after all,
* model specific. */
static struct {
unsigned int size;
enum x86_reg_type type;
unsigned int alias;
char mnemonic[8];
unsigned int size;
enum x86_reg_type type;
unsigned int alias;
char mnemonic[8];
} ia32_reg_table[NUM_X86_REGS + 2] = {
{ 0, reg_undef, 0, "" },
/* REG_DWORD_OFFSET */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_ret), 0, "eax" },
{ 0, reg_undef, 0, "" },
/* REG_DWORD_OFFSET */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_ret), 0, "eax" },
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_count), 0, "ecx" },
{ REG_DWORD_SIZE, reg_gen, 0, "edx" },
{ REG_DWORD_SIZE, reg_gen, 0, "ebx" },
/* REG_ESP_INDEX */
{ REG_DWORD_SIZE, reg_gen, 0, "edx" },
{ REG_DWORD_SIZE, reg_gen, 0, "ebx" },
/* REG_ESP_INDEX */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_sp), 0, "esp" },
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_fp), 0, "ebp" },
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_src), 0, "esi" },
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_dest), 0, "edi" },
/* REG_WORD_OFFSET */
/* REG_WORD_OFFSET */
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_ret), 3, "ax" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_count), 6, "cx" },
{ REG_WORD_SIZE, reg_gen, 9, "dx" },
{ REG_WORD_SIZE, reg_gen, 12, "bx" },
{ REG_WORD_SIZE, reg_gen, 9, "dx" },
{ REG_WORD_SIZE, reg_gen, 12, "bx" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_sp), 13, "sp" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_fp), 14, "bp" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_src), 15, "si" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_dest), 16, "di" },
/* REG_BYTE_OFFSET */
{ REG_BYTE_SIZE, reg_gen, 1, "al" },
{ REG_BYTE_SIZE, reg_gen, 4, "cl" },
{ REG_BYTE_SIZE, reg_gen, 7, "dl" },
{ REG_BYTE_SIZE, reg_gen, 10, "bl" },
{ REG_BYTE_SIZE, reg_gen, 2, "ah" },
{ REG_BYTE_SIZE, reg_gen, 5, "ch" },
{ REG_BYTE_SIZE, reg_gen, 8, "dh" },
{ REG_BYTE_SIZE, reg_gen, 11, "bh" },
/* REG_MMX_OFFSET */
{ REG_MMX_SIZE, reg_simd, 18, "mm0" },
{ REG_MMX_SIZE, reg_simd, 19, "mm1" },
{ REG_MMX_SIZE, reg_simd, 20, "mm2" },
{ REG_MMX_SIZE, reg_simd, 21, "mm3" },
{ REG_MMX_SIZE, reg_simd, 22, "mm4" },
{ REG_MMX_SIZE, reg_simd, 23, "mm5" },
{ REG_MMX_SIZE, reg_simd, 24, "mm6" },
{ REG_MMX_SIZE, reg_simd, 25, "mm7" },
/* REG_SIMD_OFFSET */
{ REG_SIMD_SIZE, reg_simd, 0, "xmm0" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm1" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm2" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm3" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm4" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm5" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm6" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm7" },
/* REG_DEBUG_OFFSET */
{ REG_DEBUG_SIZE, reg_sys, 0, "dr0" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr1" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr2" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr3" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr4" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr5" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr6" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr7" },
/* REG_CTRL_OFFSET */
{ REG_CTRL_SIZE, reg_sys, 0, "cr0" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr1" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr2" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr3" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr4" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr5" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr6" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr7" },
/* REG_TEST_OFFSET */
{ REG_TEST_SIZE, reg_sys, 0, "tr0" },
{ REG_TEST_SIZE, reg_sys, 0, "tr1" },
{ REG_TEST_SIZE, reg_sys, 0, "tr2" },
{ REG_TEST_SIZE, reg_sys, 0, "tr3" },
{ REG_TEST_SIZE, reg_sys, 0, "tr4" },
{ REG_TEST_SIZE, reg_sys, 0, "tr5" },
{ REG_TEST_SIZE, reg_sys, 0, "tr6" },
{ REG_TEST_SIZE, reg_sys, 0, "tr7" },
/* REG_SEG_OFFSET */
{ REG_SEG_SIZE, reg_seg, 0, "es" },
{ REG_SEG_SIZE, reg_seg, 0, "cs" },
{ REG_SEG_SIZE, reg_seg, 0, "ss" },
{ REG_SEG_SIZE, reg_seg, 0, "ds" },
{ REG_SEG_SIZE, reg_seg, 0, "fs" },
{ REG_SEG_SIZE, reg_seg, 0, "gs" },
/* REG_LDTR_INDEX */
{ REG_DWORD_SIZE, reg_sys, 0, "ldtr" },
/* REG_GDTR_INDEX */
{ REG_DWORD_SIZE, reg_sys, 0, "gdtr" },
/* REG_FPU_OFFSET */
{ REG_FPU_SIZE, reg_fpu, 0, "st(0)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(1)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(2)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(3)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(4)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(5)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(6)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(7)" },
/* REG_FLAGS_INDEX : 81 */
{ REG_FLAGS_SIZE, reg_cond, 0, "eflags" },
/* REG_FPCTRL_INDEX : 82*/
/* REG_BYTE_OFFSET */
{ REG_BYTE_SIZE, reg_gen, 1, "al" },
{ REG_BYTE_SIZE, reg_gen, 4, "cl" },
{ REG_BYTE_SIZE, reg_gen, 7, "dl" },
{ REG_BYTE_SIZE, reg_gen, 10, "bl" },
{ REG_BYTE_SIZE, reg_gen, 2, "ah" },
{ REG_BYTE_SIZE, reg_gen, 5, "ch" },
{ REG_BYTE_SIZE, reg_gen, 8, "dh" },
{ REG_BYTE_SIZE, reg_gen, 11, "bh" },
/* REG_MMX_OFFSET */
{ REG_MMX_SIZE, reg_simd, 18, "mm0" },
{ REG_MMX_SIZE, reg_simd, 19, "mm1" },
{ REG_MMX_SIZE, reg_simd, 20, "mm2" },
{ REG_MMX_SIZE, reg_simd, 21, "mm3" },
{ REG_MMX_SIZE, reg_simd, 22, "mm4" },
{ REG_MMX_SIZE, reg_simd, 23, "mm5" },
{ REG_MMX_SIZE, reg_simd, 24, "mm6" },
{ REG_MMX_SIZE, reg_simd, 25, "mm7" },
/* REG_SIMD_OFFSET */
{ REG_SIMD_SIZE, reg_simd, 0, "xmm0" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm1" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm2" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm3" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm4" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm5" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm6" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm7" },
/* REG_DEBUG_OFFSET */
{ REG_DEBUG_SIZE, reg_sys, 0, "dr0" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr1" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr2" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr3" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr4" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr5" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr6" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr7" },
/* REG_CTRL_OFFSET */
{ REG_CTRL_SIZE, reg_sys, 0, "cr0" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr1" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr2" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr3" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr4" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr5" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr6" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr7" },
/* REG_TEST_OFFSET */
{ REG_TEST_SIZE, reg_sys, 0, "tr0" },
{ REG_TEST_SIZE, reg_sys, 0, "tr1" },
{ REG_TEST_SIZE, reg_sys, 0, "tr2" },
{ REG_TEST_SIZE, reg_sys, 0, "tr3" },
{ REG_TEST_SIZE, reg_sys, 0, "tr4" },
{ REG_TEST_SIZE, reg_sys, 0, "tr5" },
{ REG_TEST_SIZE, reg_sys, 0, "tr6" },
{ REG_TEST_SIZE, reg_sys, 0, "tr7" },
/* REG_SEG_OFFSET */
{ REG_SEG_SIZE, reg_seg, 0, "es" },
{ REG_SEG_SIZE, reg_seg, 0, "cs" },
{ REG_SEG_SIZE, reg_seg, 0, "ss" },
{ REG_SEG_SIZE, reg_seg, 0, "ds" },
{ REG_SEG_SIZE, reg_seg, 0, "fs" },
{ REG_SEG_SIZE, reg_seg, 0, "gs" },
/* REG_LDTR_INDEX */
{ REG_DWORD_SIZE, reg_sys, 0, "ldtr" },
/* REG_GDTR_INDEX */
{ REG_DWORD_SIZE, reg_sys, 0, "gdtr" },
/* REG_FPU_OFFSET */
{ REG_FPU_SIZE, reg_fpu, 0, "st(0)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(1)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(2)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(3)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(4)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(5)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(6)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(7)" },
/* REG_FLAGS_INDEX : 81 */
{ REG_FLAGS_SIZE, reg_cond, 0, "eflags" },
/* REG_FPCTRL_INDEX : 82*/
{ REG_FPCTRL_SIZE, (x86_reg_type)(reg_fpu | reg_sys), 0, "fpctrl" },
/* REG_FPSTATUS_INDEX : 83*/
/* REG_FPSTATUS_INDEX : 83*/
{ REG_FPSTATUS_SIZE, (x86_reg_type)(reg_fpu | reg_sys), 0, "fpstat" },
/* REG_FPTAG_INDEX : 84 */
/* REG_FPTAG_INDEX : 84 */
{ REG_FPTAG_SIZE, (x86_reg_type)(reg_fpu | reg_sys), 0, "fptag" },
/* REG_EIP_INDEX : 85 */
{ REG_EIP_SIZE, reg_pc, 0, "eip" },
/* REG_IP_INDEX : 86 */
{ REG_IP_SIZE, reg_pc, 17, "ip" },
/* REG_IDTR_INDEX : 87 */
{ REG_DWORD_SIZE, reg_sys, 0, "idtr" },
/* REG_MXCSG_INDEX : SSE Control Reg : 88 */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_sys | reg_simd), 0, "mxcsr" },
/* REG_TR_INDEX : Task Register : 89 */
{ 16 + 64, reg_sys, 0, "tr" },
/* REG_CSMSR_INDEX : SYSENTER_CS_MSR : 90 */
{ REG_DWORD_SIZE, reg_sys, 0, "cs_msr" },
/* REG_ESPMSR_INDEX : SYSENTER_ESP_MSR : 91 */
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
{ 0,reg_undef,0,{0} }
};
/* REG_EIP_INDEX : 85 */
{ REG_EIP_SIZE, reg_pc, 0, "eip" },
/* REG_IP_INDEX : 86 */
{ REG_IP_SIZE, reg_pc, 17, "ip" },
/* REG_IDTR_INDEX : 87 */
{ REG_DWORD_SIZE, reg_sys, 0, "idtr" },
/* REG_MXCSG_INDEX : SSE Control Reg : 88 */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_sys | reg_simd), 0, "mxcsr" },
/* REG_TR_INDEX : Task Register : 89 */
{ 16 + 64, reg_sys, 0, "tr" },
/* REG_CSMSR_INDEX : SYSENTER_CS_MSR : 90 */
{ REG_DWORD_SIZE, reg_sys, 0, "cs_msr" },
/* REG_ESPMSR_INDEX : SYSENTER_ESP_MSR : 91 */
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
{ 0,reg_undef,0,"" }
};
static size_t sz_regtable = NUM_X86_REGS + 1;
void ia32_handle_register( x86_reg_t *reg, size_t id ) {
unsigned int alias;
if (! id || id > sz_regtable ) {
return;
}
memset( reg, 0, sizeof(x86_reg_t) );
strncpy( reg->name, ia32_reg_table[id].mnemonic, MAX_REGNAME );
reg->type = ia32_reg_table[id].type;
reg->size = ia32_reg_table[id].size;
alias = ia32_reg_table[id].alias;
if ( alias ) {
reg->alias = ia32_reg_aliases[alias].alias;
reg->shift = ia32_reg_aliases[alias].shift;
}
reg->id = id;
unsigned int alias;
if (! id || id > sz_regtable ) {
return;
}
memset( reg, 0, sizeof(x86_reg_t) );
strncpy( reg->name, ia32_reg_table[id].mnemonic, MAX_REGNAME );
reg->type = ia32_reg_table[id].type;
reg->size = ia32_reg_table[id].size;
alias = ia32_reg_table[id].alias;
if ( alias ) {
reg->alias = ia32_reg_aliases[alias].alias;
reg->shift = ia32_reg_aliases[alias].shift;
}
reg->id = id;
return;
}
size_t ia32_true_register_id( size_t id ) {
size_t reg;
size_t reg;
if (! id || id > sz_regtable ) {
return 0;
}
if (! id || id > sz_regtable ) {
return 0;
}
reg = id;
if (ia32_reg_table[reg].alias) {
reg = ia32_reg_aliases[ia32_reg_table[reg].alias].alias;
}
return reg;
reg = id;
if (ia32_reg_table[reg].alias) {
reg = ia32_reg_aliases[ia32_reg_table[reg].alias].alias;
}
return reg;
}

View File

@ -814,10 +814,9 @@ public:
* void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
* where 'alias_reg' is a reg operand and 'output_reg' is filled with the
* register that the operand is an alias for */
/*
#define x86_get_aliased_reg( alias_reg, output_reg ) \
x86_reg_from_id( alias_reg->alias, output_reg )
*/
//#define x86_get_aliased_reg( alias_reg, output_reg )
// x86_reg_from_id( alias_reg->alias, output_reg )
/* ================================== Invariant Instruction Representation */
/* Invariant instructions are used for generating binary signatures;

View File

@ -9,8 +9,8 @@
#ifdef _MSC_VER
#define snprintf _snprintf
#define inline __inline
#define snprintf _snprintf
#define inline __inline
#endif
void x86_insn_t::make_invalid(unsigned char *buf)
{
@ -22,8 +22,8 @@ void x86_insn_t::make_invalid(unsigned char *buf)
memcpy( bytes, buf, 1 );
}
unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len,
uint32_t buf_rva, unsigned int offset,
x86_insn_t *insn ){
uint32_t buf_rva, unsigned int offset,
x86_insn_t *insn ){
int len, size;
unsigned char bytes[MAX_INSTRUCTION_SIZE];
@ -53,7 +53,7 @@ unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len,
* helps prevent buffer overruns at the end of a file */
memset( bytes, 0, MAX_INSTRUCTION_SIZE );
memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE) ? len :
MAX_INSTRUCTION_SIZE );
MAX_INSTRUCTION_SIZE );
/* actually do the disassembly */
/* TODO: allow switching when more disassemblers are added */
@ -81,140 +81,139 @@ unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len,
}
unsigned int X86_Disasm::x86_disasm_range( unsigned char *buf, uint32_t buf_rva,
unsigned int offset, unsigned int len,
DISASM_CALLBACK func, void *arg ) {
x86_insn_t insn;
unsigned int buf_len, size, count = 0, bytes = 0;
unsigned int offset, unsigned int len,
DISASM_CALLBACK func, void *arg ) {
x86_insn_t insn;
unsigned int buf_len, size, count = 0, bytes = 0;
/* buf_len is implied by the arguments */
buf_len = len + offset;
/* buf_len is implied by the arguments */
buf_len = len + offset;
while ( bytes < len ) {
size = x86_disasm( buf, buf_len, buf_rva, offset + bytes,
&insn );
if ( size ) {
/* invoke callback if it exists */
if ( func ) {
(*func)( &insn, arg );
}
bytes += size;
count ++;
} else {
/* error */
bytes++; /* try next byte */
}
insn.x86_oplist_free();
while ( bytes < len ) {
size = x86_disasm( buf, buf_len, buf_rva, offset + bytes,
&insn );
if ( size ) {
/* invoke callback if it exists */
if ( func ) {
(*func)( &insn, arg );
}
bytes += size;
count ++;
} else {
/* error */
bytes++; /* try next byte */
}
return( count );
insn.x86_oplist_free();
}
return( count );
}
static inline int follow_insn_dest( x86_insn_t *insn ) {
if ( insn->type == insn_jmp || insn->type == insn_jcc ||
insn->type == insn_call || insn->type == insn_callcc ) {
return(1);
}
return(0);
if ( insn->type == insn_jmp || insn->type == insn_jcc ||
insn->type == insn_call || insn->type == insn_callcc ) {
return(1);
}
return(0);
}
static inline int insn_doesnt_return( x86_insn_t *insn ) {
return( (insn->type == insn_jmp || insn->type == insn_return) ? 1: 0 );
return( (insn->type == insn_jmp || insn->type == insn_return) ? 1: 0 );
}
static int32_t internal_resolver( x86_op_t *op, x86_insn_t *insn ){
int32_t next_addr = -1;
if ( x86_optype_is_address(op->type) ) {
next_addr = op->data.sdword;
} else if ( op->type == op_relative_near ) {
next_addr = insn->addr + insn->size + op->data.relative_near;
} else if ( op->type == op_relative_far ) {
next_addr = insn->addr + insn->size + op->data.relative_far;
}
return( next_addr );
int32_t next_addr = -1;
if ( x86_optype_is_address(op->type) ) {
next_addr = op->data.sdword;
} else if ( op->type == op_relative_near ) {
next_addr = insn->addr + insn->size + op->data.relative_near;
} else if ( op->type == op_relative_far ) {
next_addr = insn->addr + insn->size + op->data.relative_far;
}
return( next_addr );
}
unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int buf_len,
uint32_t buf_rva, unsigned int offset,
DISASM_CALLBACK func, void *arg,
DISASM_RESOLVER resolver, void *r_arg ){
x86_insn_t insn;
x86_op_t *op;
int32_t next_addr;
int32_t next_offset;
unsigned int size, count = 0, bytes = 0, cont = 1;
uint32_t buf_rva, unsigned int offset,
DISASM_CALLBACK func, void *arg,
DISASM_RESOLVER resolver, void *r_arg ){
x86_insn_t insn;
x86_op_t *op;
int32_t next_addr;
int32_t next_offset;
unsigned int size, count = 0, bytes = 0, cont = 1;
while ( cont && bytes < buf_len ) {
size = x86_disasm( buf, buf_len, buf_rva, offset + bytes,
while ( cont && bytes < buf_len ) {
size = x86_disasm( buf, buf_len, buf_rva, offset + bytes,
&insn );
if ( size ) {
/* invoke callback if it exists */
if ( func ) {
(*func)( &insn, arg );
}
bytes += size;
count ++;
} else {
/* error */
bytes++; /* try next byte */
}
if ( follow_insn_dest(&insn) ) {
op = insn.x86_operand_1st();//x86_get_dest_operand
next_addr = -1;
/* if caller supplied a resolver, use it to determine
* the address to disassemble */
if ( resolver ) {
next_addr = resolver(op, &insn, r_arg);
} else {
next_addr = internal_resolver(op, &insn);
}
if (next_addr != -1 ) {
next_offset = next_addr - buf_rva;
/* if offset is in this buffer... */
if ( next_offset >= 0 && next_offset < int(buf_len) )
{
/* go ahead and disassemble */
count += x86_disasm_forward( buf,
buf_len,
buf_rva,
next_offset,
func, arg,
resolver, r_arg );
} else {
/* report unresolved address */
x86_report_error( report_disasm_bounds,
(void*)(long)next_addr );
}
}
} /* end follow_insn */
if ( insn_doesnt_return(&insn) ) {
/* stop disassembling */
cont = 0;
}
insn.x86_oplist_free( );
if ( size ) {
/* invoke callback if it exists */
if ( func ) {
(*func)( &insn, arg );
}
bytes += size;
count ++;
} else {
/* error */
bytes++; /* try next byte */
}
return( count );
if ( follow_insn_dest(&insn) ) {
op = insn.x86_operand_1st();//x86_get_dest_operand
next_addr = -1;
/* if caller supplied a resolver, use it to determine
* the address to disassemble */
if ( resolver ) {
next_addr = resolver(op, &insn, r_arg);
} else {
next_addr = internal_resolver(op, &insn);
}
if (next_addr != -1 ) {
next_offset = next_addr - buf_rva;
/* if offset is in this buffer... */
if ( next_offset >= 0 && next_offset < buf_len ) {
/* go ahead and disassemble */
count += x86_disasm_forward( buf,
buf_len,
buf_rva,
next_offset,
func, arg,
resolver, r_arg );
} else {
/* report unresolved address */
x86_report_error( report_disasm_bounds,
(void*)(long)next_addr );
}
}
} /* end follow_insn */
if ( insn_doesnt_return(&insn) ) {
/* stop disassembling */
cont = 0;
}
insn.x86_oplist_free( );
}
return( count );
}
/* invariant instruction representation */
size_t x86_invariant_disasm( unsigned char *buf, int buf_len,
x86_invariant_t *inv ){
if (! buf || ! buf_len || ! inv ) {
return(0);
}
x86_invariant_t *inv ){
if (! buf || ! buf_len || ! inv ) {
return(0);
}
return ia32_disasm_invariant(buf, buf_len, inv);
return ia32_disasm_invariant(buf, buf_len, inv);
}
size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ) {
if (! buf || ! buf_len ) {
return(0);
}
if (! buf || ! buf_len ) {
return(0);
}
return ia32_disasm_size(buf, buf_len);
return ia32_disasm_size(buf, buf_len);
}

View File

@ -16,16 +16,21 @@ class CIcodeRec;
struct BB;
struct LOCAL_ID;
struct interval;
//TODO: consider default address value -> INVALID
struct TYPEADR_TYPE
{
uint32_t ip; /* Out edge icode address */
BB * BBptr; /* Out edge pointer to next BB */
interval *intPtr; /* Out edge ptr to next interval*/
TYPEADR_TYPE(uint32_t addr=0) : ip(addr),BBptr(nullptr),intPtr(nullptr)
{}
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
{}
};
struct BB : public llvm::ilist_node<BB>
{
private:
BB(const BB&);
BB() : nodeType(0),traversed(DFS_NONE),
@ -76,7 +81,7 @@ public:
* derived graph Gi-1 */
/* For live register analysis
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */
std::bitset<32> liveUse; /* LiveUse(b) */
std::bitset<32> def; /* Def(b) */
std::bitset<32> liveIn; /* LiveIn(b) */
@ -90,9 +95,8 @@ public:
int ifFollow; /* node that ends the if */
int loopType; /* Type of loop (if any) */
int latchNode; /* latching node of the loop */
int numBackEdges; /* # of back edges */
int loopHead; /* most nested loop head to which
* thcis node belongs (dfsLast) */
size_t numBackEdges; /* # of back edges */
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
int loopFollow; /* node that follows the loop */
int caseHead; /* most nested case to which this
node belongs (dfsLast) */
@ -100,8 +104,8 @@ public:
int index; /* Index, used in several ways */
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent);
static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent);
static BB * CreateIntervalBB(Function *parent);
static BB * Create(const rCODE &r, uint8_t _nodeType, Function *parent);
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
void mergeFallThrough(CIcodeRec &Icode);
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
@ -118,10 +122,15 @@ public:
bool valid() {return 0==(flg & INVALID_BB); }
bool wasTraversedAtLevel(int l) const {return traversed==l;}
ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond);
void addOutEdge(uint32_t ip) // TODO: fix this
void addOutEdge(uint32_t ip) // TODO: fix this
{
edges[0].ip = ip;
edges.push_back(TYPEADR_TYPE(ip));
}
void addOutEdgeInterval(interval *i) // TODO: fix this
{
edges.push_back(TYPEADR_TYPE(i));
}
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
private:
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);

View File

@ -45,10 +45,10 @@ protected:
} boolExpr;
public:
condNodeType m_type; /* Conditional Expression Node Type */
condNodeType m_type; /* Conditional Expression Node Type */
union _exprNode { /* Different cond expr nodes */
COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/
IDENTTYPE ident; /* for IDENTIFIER */
COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/
IDENTTYPE ident; /* for IDENTIFIER */
} expr;
COND_EXPR *lhs()
{
@ -72,19 +72,19 @@ public:
}
condOp op() const { return boolExpr.op;}
public:
static COND_EXPR *idRegIdx(int idx, regType reg_type);
static COND_EXPR *idKte(uint32_t kte, uint8_t size);
static COND_EXPR *idLoc(int off, LOCAL_ID *localId);
static COND_EXPR *idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static COND_EXPR *idLongIdx(int idx);
static COND_EXPR *idOther(eReg seg, eReg regi, int16_t off);
static COND_EXPR *idParam(int off, const STKFRAME *argSymtab);
static COND_EXPR *unary(condNodeType t, COND_EXPR *sub_expr);
static COND_EXPR *idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static COND_EXPR *idFunc(Function *pproc, STKFRAME *args);
static COND_EXPR *idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static COND_EXPR * idRegIdx(int idx, regType reg_type);
static COND_EXPR * idKte(uint32_t kte, uint8_t size);
static COND_EXPR * idLoc(int off, LOCAL_ID *localId);
static COND_EXPR * idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static COND_EXPR * idLongIdx(int idx);
static COND_EXPR * idOther(eReg seg, eReg regi, int16_t off);
static COND_EXPR * idParam(int off, const STKFRAME *argSymtab);
static COND_EXPR * unary(condNodeType t, COND_EXPR *sub_expr);
static COND_EXPR * idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static COND_EXPR * idFunc(Function *pproc, STKFRAME *args);
static COND_EXPR * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
static COND_EXPR *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
static COND_EXPR * boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
public:

View File

@ -23,6 +23,7 @@ struct SymbolCommon
};
struct SYM : public SymbolCommon
{
typedef uint32_t tLabel;
SYM() : label(0),flg(0)
{
@ -33,9 +34,10 @@ struct SYM : public SymbolCommon
/* STACK FRAME */
struct STKSYM : public SymbolCommon
{
typedef int16_t tLabel;
COND_EXPR *actual; /* Expression tree of actual parameter */
COND_EXPR *regs; /* For register arguments only */
int16_t label; /* Immediate off from BP (+:args, -:params) */
tLabel label; /* Immediate off from BP (+:args, -:params) */
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
bool hasMacro; /* This type needs a macro */
std::string macro; /* Macro name */
@ -60,13 +62,13 @@ class SymbolTableCommon : public std::vector<T>
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
iterator findByLabel(uint32_t lab)
iterator findByLabel(typename T::tLabel lab)
{
auto iter = std::find_if(this->begin(),this->end(),
[lab](T &s)->bool {return s.label==lab;});
return iter;
}
const_iterator findByLabel(uint32_t lab) const
const_iterator findByLabel(typename T::tLabel lab) const
{
auto iter = std::find_if(this->begin(),this->end(),
[lab](const T &s)->bool {return s.label==lab;});

View File

@ -19,7 +19,7 @@ BB *BB::Create(void */*ctx*/, const string &/*s*/, Function *parent, BB */*inser
* @arg start - basic block starts here, might be parent->Icode.end()
* @arg fin - last of basic block's instructions
*/
BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent)
BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent)
{
BB* pnewBB;
pnewBB = new BB;
@ -27,47 +27,28 @@ BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Fun
pnewBB->immedDom = NO_DOM;
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
pnewBB->instructions = make_iterator_range(start,fin);
if(start==parent->Icode.end())
{
pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end());
}
else
{
pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive
}
if (numOutEdges)
pnewBB->edges.resize(numOutEdges);
pnewBB->instructions = r;
/* Mark the basic block to which the icodes belong to, but only for
* real code basic blocks (ie. not interval bbs) */
* real code basic blocks (ie. not interval bbs) */
if(parent)
{
if (start != parent->Icode.end())
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
//setInBB should automatically handle if our range is empty
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
parent->heldBBs.push_back(pnewBB);
parent->m_cfg.push_back(pnewBB);
pnewBB->Parent = parent;
}
if ( start != parent->Icode.end() ) /* Only for code BB's */
if ( r.begin() != parent->Icode.end() ) /* Only for code BB's */
stats.numBBbef++;
return pnewBB;
}
BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent)
BB *BB::CreateIntervalBB(Function *parent)
{
iICODE st(parent->Icode.begin());
iICODE fin(parent->Icode.begin());
if(start==-1)
{
st = parent->Icode.end();
fin = parent->Icode.end();
}
else
{
advance(st,start);
advance(fin,ip);
}
return Create(st,fin,_nodeType,numOutEdges,parent);
iICODE endOfParent = parent->Icode.end();
return Create(make_iterator_range(endOfParent,endOfParent),INTERVAL_NODE,parent);
}
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",

View File

@ -336,9 +336,7 @@ void Function::structLoops(derSeq *derivedG)
* h. Note that h is a case node. */
static bool successor (int s, int h, Function * pProc)
{
BB * header;
header = pProc->m_dfsLast[h];
BB * header = pProc->m_dfsLast[h];
auto iter = std::find_if(header->edges.begin(),
header->edges.end(),
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
@ -431,9 +429,9 @@ static void flagNodes (nodeList &l, int f, Function * pProc)
/* Structures if statements */
void Function::structIfs ()
{
size_t followInEdges; /* Largest # in-edges so far */
int curr, /* Index for linear scan of nodes */
/*desc,*/ /* Index for descendant */
followInEdges, /* Largest # in-edges so far */
follow; /* Possible follow node */
nodeList domDesc, /* List of nodes dominated by curr */
unresolved /* List of unresolved if nodes */

View File

@ -3,11 +3,17 @@
* (C) Cristina Cifuentes
****************************************************************************/
#include "dcc.h"
#include <string.h>
#include <malloc.h> /* For free() */
#include <boost/range/rbegin.hpp>
#include <boost/range/rend.hpp>
#include <boost/range/adaptors.hpp>
#include "dcc.h"
#include "graph.h"
#include "project.h"
using namespace std;
using namespace boost;
extern Project g_proj;
//static BB * rmJMP(Function * pProc, int marker, BB * pBB);
//static void mergeFallThrough(Function * pProc, BB * pBB);
@ -33,116 +39,98 @@ void Function::createCFG()
BB * psBB;
BB * pBB;
iICODE pIcode = Icode.begin();
iICODE iStart = Icode.begin();
stats.numBBbef = stats.numBBaft = 0;
for (; pIcode!=Icode.end(); ++pIcode)
rICODE current_range=make_iterator_range(pIcode,++iICODE(pIcode));
for (; pIcode!=Icode.end(); ++pIcode,current_range.advance_end(1))
{
iICODE nextIcode = ++iICODE(pIcode);
pBB = nullptr;
LLInst *ll = pIcode->ll();
/* Only process icodes that have valid instructions */
if(ll->testFlags(NO_CODE))
continue;
/* Stick a NOWHERE_NODE on the end if we terminate
* with anything other than a ret, jump or terminate */
* with anything other than a ret, jump or terminate */
if (nextIcode == Icode.end() and
(not ll->testFlags(TERMINATES)) and
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and
(not ll->match(iRET)) and (not ll->match(iRETF)))
{
//pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
pBB=BB::Create(current_range, NOWHERE_NODE, this);
}
/* Only process icodes that have valid instructions */
else if (not ll->testFlags(NO_CODE) )
{
else
switch (ll->getOpcode()) {
case iJB: case iJBE: case iJAE: case iJA:
case iJL: case iJLE: case iJGE: case iJG:
case iJE: case iJNE: case iJS: case iJNS:
case iJO: case iJNO: case iJP: case iJNP:
case iJCXZ:
pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this);
pBB = BB::Create(current_range, TWO_BRANCH, this);
CondJumps:
//start = ip + 1;
iStart = ++iICODE(pIcode);
pBB->edges[0].ip = (uint32_t)iStart->loc_ip;
/* This is for jumps off into nowhere */
if ( ll->testFlags(NO_LABEL) )
{
pBB->edges.pop_back();
}
else
pBB->edges[1].ip = ll->src().getImm2();
pBB->addOutEdge(nextIcode->loc_ip);
/* This is checking for jumps off into nowhere */
if ( not ll->testFlags(NO_LABEL) )
pBB->addOutEdge(ll->src().getImm2());
break;
case iLOOP: case iLOOPE: case iLOOPNE:
//pBB = BB::Create(start, ip, LOOP_NODE, 2, this);
pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this);
pBB = BB::Create(current_range, LOOP_NODE, this);
goto CondJumps;
case iJMPF: case iJMP:
if (ll->testFlags(SWITCH))
{
//pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
pBB = BB::Create(current_range, MULTI_BRANCH, this);
for (size_t i = 0; i < ll->caseTbl2.size(); i++)
pBB->edges[i].ip = ll->caseTbl2[i];
pBB->addOutEdge(ll->caseTbl2[i]);
hasCase = true;
}
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
{
//pBB = BB::Create(start, ip, ONE_BRANCH, 1, this);
pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this);
pBB->edges[0].ip = ll->src().getImm2();
pBB = BB::Create(current_range, ONE_BRANCH, this);
pBB->addOutEdge(ll->src().getImm2());
}
else
BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
iStart = ++iICODE(pIcode);
pBB = BB::Create(current_range, NOWHERE_NODE, this);
break;
case iCALLF: case iCALL:
{
Function * p = ll->src().proc.proc;
if (p)
i = ((p->flg) & TERMINATES) ? 0 : 1;
else
i = 1;
pBB = BB::Create(iStart, pIcode, CALL_NODE, i, this);
iStart = ++iICODE(pIcode);//start = ip + 1;
if (i)
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
}
pBB = BB::Create(current_range, CALL_NODE, this);
if (p && not ((p->flg) & TERMINATES) )
pBB->addOutEdge(nextIcode->loc_ip);
break;
}
case iRET: case iRETF:
//BB::Create(start, ip, RETURN_NODE, 0, this);
BB::Create(iStart, pIcode, RETURN_NODE, 0, this);
iStart = ++iICODE(pIcode);
pBB = BB::Create(current_range, RETURN_NODE, this);
break;
default:
/* Check for exit to DOS */
iICODE next1=++iICODE(pIcode);
if ( ll->testFlags(TERMINATES) )
{
pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this);
//pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
iStart = ++iICODE(pIcode); // start = ip + 1;
pBB = BB::Create(current_range, TERMINATE_NODE, this);
}
/* Check for a fall through */
else if (next1 != Icode.end())
else if (nextIcode != Icode.end())
{
if (next1->ll()->testFlags(TARGET | CASE))
if (nextIcode->ll()->testFlags(TARGET | CASE))
{
//pBB = BB::Create(start, ip, FALL_NODE, 1, this);
pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this);
iStart = ++iICODE(pIcode); // start = ip + 1;
pBB->addOutEdge(iStart->loc_ip);
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
pBB = BB::Create(current_range, FALL_NODE, this);
pBB->addOutEdge(nextIcode->loc_ip);
}
}
break;
}
if(pBB!=nullptr) // created a new Basic block
{
// restart the range
// end iterator will be updated by expression in for statement
current_range=make_iterator_range(nextIcode,nextIcode);
}
}
auto iter=heldBBs.begin();
@ -160,14 +148,14 @@ CondJumps:
}
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
[ip](BB *psBB)->bool {return psBB->begin()->loc_ip==ip;});
if(iter2==heldBBs.end())
fatalError(NO_BB, ip, name.c_str());
psBB = *iter2;
pBB->edges[edeg_idx].BBptr = psBB;
psBB->inEdges.push_back((BB *)nullptr);
}
if(iter2==heldBBs.end())
fatalError(NO_BB, ip, name.c_str());
psBB = *iter2;
pBB->edges[edeg_idx].BBptr = psBB;
psBB->inEdges.push_back((BB *)nullptr);
}
}
}
void Function::markImpure()
{
@ -350,33 +338,33 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
auto iter=std::find_if(this->end(),pChild->begin(),[](ICODE &c)
{return not c.ll()->testFlags(NO_CODE);});
if (iter != pChild->begin())
break;
back().ll()->setFlags(NO_CODE);
back().invalidate();
nodeType = FALL_NODE;
//instructions.advance_end(-1); //TODO: causes creation of empty BB
}
/* If there's no other edges into child can merge */
if (pChild->inEdges.size() != 1)
if (iter != pChild->begin())
break;
nodeType = pChild->nodeType;
instructions = boost::make_iterator_range(begin(),pChild->end());
pChild->front().ll()->clrFlags(TARGET);
edges.swap(pChild->edges);
pChild->inEdges.clear();
pChild->edges.clear();
back().ll()->setFlags(NO_CODE);
back().invalidate();
nodeType = FALL_NODE;
//instructions.advance_end(-1); //TODO: causes creation of empty BB
}
traversed = DFS_MERGE;
/* If there's no other edges into child can merge */
if (pChild->inEdges.size() != 1)
break;
/* Process all out edges recursively */
for (size_t i = 0; i < edges.size(); i++)
{
if (edges[i].BBptr->traversed != DFS_MERGE)
edges[i].BBptr->mergeFallThrough(Icode);
}
nodeType = pChild->nodeType;
instructions = boost::make_iterator_range(begin(),pChild->end());
pChild->front().ll()->clrFlags(TARGET);
edges.swap(pChild->edges);
pChild->inEdges.clear();
pChild->edges.clear();
}
traversed = DFS_MERGE;
/* Process all out edges recursively */
for (size_t i = 0; i < edges.size(); i++)
{
if (edges[i].BBptr->traversed != DFS_MERGE)
edges[i].BBptr->mergeFallThrough(Icode);
}
}

View File

@ -12,7 +12,7 @@ OPTION option; /* Command line options */
Project *Project::s_instance = 0;
Project::Project() : callGraph(nullptr)
{
memset(&prog,0,sizeof(prog));
}
void Project::initialize()
{
@ -49,8 +49,7 @@ ilFunction Project::findByEntry(uint32_t entry)
{
/* Search procedure list for one with appropriate entry point */
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
[entry](const Function &f) ->
bool { return f.procEntry==entry; });
[entry](const Function &f) { return f.procEntry==entry; });
return iter;
}

View File

@ -540,20 +540,19 @@ void Function::propLong()
for (size_t i = 0; i < localId.csym(); i++)
{
const ID &pLocId(localId.id_arr[i]);
if ((pLocId.type==TYPE_LONG_SIGN) || (pLocId.type==TYPE_LONG_UNSIGN))
if ((pLocId.type!=TYPE_LONG_SIGN) and (pLocId.type!=TYPE_LONG_UNSIGN))
continue;
switch (pLocId.loc)
{
switch (pLocId.loc)
{
case STK_FRAME:
propLongStk (i, pLocId);
break;
case REG_FRAME:
propLongReg (i, pLocId);
break;
case GLB_FRAME:
propLongGlb (i, pLocId);
break;
}
case STK_FRAME:
propLongStk (i, pLocId);
break;
case REG_FRAME:
propLongReg (i, pLocId);
break;
case GLB_FRAME:
propLongGlb (i, pLocId);
break;
}
}
}

View File

@ -236,29 +236,23 @@ derSeq_Entry::~derSeq_Entry()
bool Function::nextOrderGraph (derSeq &derivedGi)
{
interval *Ii; /* Interval being processed */
BB *BBnode, /* New basic block of intervals */
//*curr, /* BB being checked for out edges */
*succ /* Successor node */
;
//queue *listIi; /* List of intervals */
int i; /* Index to outEdges array */
/*j;*/ /* Index to successors */
boolT sameGraph; /* Boolean, isomorphic graphs */
BB *BBnode; /* New basic block of intervals */
bool sameGraph; /* Boolean, isomorphic graphs */
/* Process Gi's intervals */
derSeq_Entry &prev_entry(derivedGi.back());
derivedGi.push_back(derSeq_Entry());
derSeq_Entry &new_entry(derivedGi.back());
Ii = prev_entry.Ii;
sameGraph = true;
BBnode = 0;
std::vector<BB *> bbs;
while (Ii)
for(Ii = prev_entry.Ii; Ii != nullptr; Ii = Ii->next)
{
i = 0;
bbs.push_back(BB::Create(-1, -1, INTERVAL_NODE, Ii->numOutEdges, this));
BBnode = bbs.back();
BBnode = BB::CreateIntervalBB(this);
BBnode->correspInt = Ii;
bbs.push_back(BBnode);
const queue &listIi(Ii->nodes);
/* Check for more than 1 interval */
@ -267,21 +261,17 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
/* Find out edges */
if (BBnode->edges.size() > 0)
if (Ii->numOutEdges <= 0)
continue;
for(BB *curr : listIi)
{
for(BB *curr : listIi)
for (size_t j = 0; j < curr->edges.size(); j++)
{
for (size_t j = 0; j < curr->edges.size(); j++)
{
succ = curr->edges[j].BBptr;
if (succ->inInterval != curr->inInterval)
BBnode->edges[i++].intPtr = succ->inInterval;
}
BB *successor_node = curr->edges[j].BBptr;
if (successor_node->inInterval != curr->inInterval)
BBnode->addOutEdgeInterval(successor_node->inInterval);
}
}
/* Next interval */
Ii = Ii->next;
}
/* Convert list of pointers to intervals into a real graph.
@ -303,7 +293,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
(*iter)->inEdgeCount++;
}
}
return (boolT)(! sameGraph);
return not sameGraph;
}

View File

@ -357,8 +357,7 @@ static void fixFloatEmulation(x86_insn_t &insn)
if ((wOp < 0x34) || (wOp > 0x3B))
return;
uint8_t buf[16];
/* This is a Borland/Microsoft floating point emulation instruction.
Treat as if it is an ESC opcode */
/* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
memcpy(buf,prog.Image+insn.offset,actual_valid_bytes);

View File

@ -1,6 +1,6 @@
#include "dcc.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "dcc.h"
TEST(CowriteTest, HandlesZeroInput) {
EXPECT_EQ(1, 1);

View File

@ -13,8 +13,8 @@ TEST(Project, NewProjectIsInitalized) {
TEST(Project, CreatedProjectHasValidNames) {
Project p;
std::vector<std::string> strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro ject3"};
std::vector<std::string> expected = {"Project1","Project2","Pro ject3"};
std::vector<std::string> strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro\\ ject3"};
std::vector<std::string> expected = {"Project1","Project2","Pro\\ ject3"};
for(size_t i=0; i<strs.size(); i++)
{
p.create(strs[i]);