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

@ -20,81 +20,81 @@ typedef struct {
static op_implicit_list_t list_aaa[] = static op_implicit_list_t list_aaa[] =
/* 37 : AAA : rw AL */ /* 37 : AAA : rw AL */
/* 3F : AAS : rw AL */ /* 3F : AAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* aaa */ {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* aaa */
static op_implicit_list_t list_aad[] = static op_implicit_list_t list_aad[] =
/* D5 0A, D5 (ib) : AAD : rw AX */ /* D5 0A, D5 (ib) : AAD : rw AX */
/* D4 0A, D4 (ib) : AAM : rw AX */ /* D4 0A, D4 (ib) : AAM : rw AX */
{{ OP_R | OP_W, REG_WORD_OFFSET }, {0,0}}; /* aad */ {{ OP_R | OP_W, REG_WORD_OFFSET }, {0,0}}; /* aad */
static op_implicit_list_t list_call[] = static op_implicit_list_t list_call[] =
/* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */ /* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */
/* C2, C3, CA, CB : RET : 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_EIP_INDEX },
{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* call, ret */ { OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* call, ret */
static op_implicit_list_t list_cbw[] = static op_implicit_list_t list_cbw[] =
/* 98 : CBW : r AL, rw AX */ /* 98 : CBW : r AL, rw AX */
{{ OP_R | OP_W, REG_WORD_OFFSET }, {{ OP_R | OP_W, REG_WORD_OFFSET },
{ OP_R, REG_BYTE_OFFSET}, {0,0}}; /* cbw */ { OP_R, REG_BYTE_OFFSET}, {0,0}}; /* cbw */
static op_implicit_list_t list_cwde[] = static op_implicit_list_t list_cwde[] =
/* 98 : CWDE : r AX, rw EAX */ /* 98 : CWDE : r AX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_R, REG_WORD_OFFSET }, {0,0}}; /* cwde */ { OP_R, REG_WORD_OFFSET }, {0,0}}; /* cwde */
static op_implicit_list_t list_clts[] = static op_implicit_list_t list_clts[] =
/* 0F 06 : CLTS : rw CR0 */ /* 0F 06 : CLTS : rw CR0 */
{{ OP_R | OP_W, REG_CTRL_OFFSET}, {0,0}}; /* clts */ {{ OP_R | OP_W, REG_CTRL_OFFSET}, {0,0}}; /* clts */
static op_implicit_list_t list_cmpxchg[] = static op_implicit_list_t list_cmpxchg[] =
/* 0F B0 : CMPXCHG : rw AL */ /* 0F B0 : CMPXCHG : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* cmpxchg */ {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* cmpxchg */
static op_implicit_list_t list_cmpxchgb[] = static op_implicit_list_t list_cmpxchgb[] =
/* 0F B1 : CMPXCHG : rw EAX */ /* 0F B1 : CMPXCHG : rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* cmpxchg */ {{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* cmpxchg */
static op_implicit_list_t list_cmpxchg8b[] = static op_implicit_list_t list_cmpxchg8b[] =
/* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */ /* 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 },
{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, { OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R, REG_DWORD_OFFSET + 1 }, { OP_R, REG_DWORD_OFFSET + 1 },
{ OP_R, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cmpxchg8b */ { OP_R, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cmpxchg8b */
static op_implicit_list_t list_cpuid[] = static op_implicit_list_t list_cpuid[] =
/* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */ /* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 1 }, { OP_W, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 }, { OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cpuid */ { OP_W, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cpuid */
static op_implicit_list_t list_cwd[] = static op_implicit_list_t list_cwd[] =
/* 99 : CWD/CWQ : rw EAX, w EDX */ /* 99 : CWD/CWQ : rw EAX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* cwd */ { OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* cwd */
static op_implicit_list_t list_daa[] = static op_implicit_list_t list_daa[] =
/* 27 : DAA : rw AL */ /* 27 : DAA : rw AL */
/* 2F : DAS : rw AL */ /* 2F : DAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* daa */ {{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* daa */
static op_implicit_list_t list_idiv[] = static op_implicit_list_t list_idiv[] =
/* F6 : DIV, IDIV : r AX, w AL, w AH */ /* F6 : DIV, IDIV : r AX, w AL, w AH */
/* FIXED: first op was EAX, not Aw. TODO: verify! */ /* FIXED: first op was EAX, not Aw. TODO: verify! */
{{ OP_R, REG_WORD_OFFSET }, {{ OP_R, REG_WORD_OFFSET },
{ OP_W, REG_BYTE_OFFSET }, { OP_W, REG_BYTE_OFFSET },
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* div */ { OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* div */
static op_implicit_list_t list_div[] = static op_implicit_list_t list_div[] =
/* F7 : DIV, IDIV : rw EDX, rw EAX */ /* F7 : DIV, IDIV : rw EDX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* div */ { OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* div */
static op_implicit_list_t list_enter[] = static op_implicit_list_t list_enter[] =
/* C8 : ENTER : rw ESP w EBP */ /* C8 : ENTER : rw ESP w EBP */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 4 }, {{ OP_R | OP_W, REG_DWORD_OFFSET + 4 },
{ OP_R, REG_DWORD_OFFSET + 5 }, {0,0}}; /* enter */ { OP_R, REG_DWORD_OFFSET + 5 }, {0,0}}; /* enter */
static op_implicit_list_t list_f2xm1[] = static op_implicit_list_t list_f2xm1[] =
/* D9 F0 : F2XM1 : rw ST(0) */ /* D9 F0 : F2XM1 : rw ST(0) */
@ -109,7 +109,7 @@ static op_implicit_list_t list_f2xm1[] =
/* D9 FE : FSIN : rw ST(0) */ /* D9 FE : FSIN : rw ST(0) */
/* D9 FA : FSQRT : rw ST(0) */ /* D9 FA : FSQRT : rw ST(0) */
/* D9 F4 : FXTRACT : rw ST(0) */ /* D9 F4 : FXTRACT : rw ST(0) */
{{ OP_R | OP_W, REG_FPU_OFFSET }, {0,0}}; /* f2xm1 */ {{ OP_R | OP_W, REG_FPU_OFFSET }, {0,0}}; /* f2xm1 */
static op_implicit_list_t list_fcom[] = static op_implicit_list_t list_fcom[] =
/* D8, DC, DE D9 : FCOM : r ST(0) */ /* D8, DC, DE D9 : FCOM : r ST(0) */
@ -117,208 +117,208 @@ static op_implicit_list_t list_fcom[] =
/* DF, D8 : FIST : r ST(0) */ /* DF, D8 : FIST : r ST(0) */
/* D9 E4 : FTST : r ST(0) */ /* D9 E4 : FTST : r ST(0) */
/* D9 E5 : FXAM : r ST(0) */ /* D9 E5 : FXAM : r ST(0) */
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fcom */ {{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fcom */
static op_implicit_list_t list_fpatan[] = static op_implicit_list_t list_fpatan[] =
/* D9 F3 : FPATAN : r ST(0), rw ST(1) */ /* D9 F3 : FPATAN : r ST(0), rw ST(1) */
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fpatan */ {{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fpatan */
static op_implicit_list_t list_fprem[] = static op_implicit_list_t list_fprem[] =
/* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */ /* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */
/* D9 FD : FSCALE : rw ST(0), r ST(1) */ /* D9 FD : FSCALE : rw ST(0), r ST(1) */
{{ OP_R | OP_W, REG_FPU_OFFSET }, {{ OP_R | OP_W, REG_FPU_OFFSET },
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fprem */ { OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fprem */
static op_implicit_list_t list_faddp[] = static op_implicit_list_t list_faddp[] =
/* DE C1 : FADDP : r ST(0), rw ST(1) */ /* DE C1 : FADDP : r ST(0), rw ST(1) */
/* DE E9 : FSUBP : 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 F1 : FYL2X : r ST(0), rw ST(1) */
/* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */ /* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */
{{ OP_R, REG_FPU_OFFSET }, {{ OP_R, REG_FPU_OFFSET },
{ OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0,0}}; /* faddp */ { OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0,0}}; /* faddp */
static op_implicit_list_t list_fucompp[] = static op_implicit_list_t list_fucompp[] =
/* DA E9 : FUCOMPP : r ST(0), r ST(1) */ /* DA E9 : FUCOMPP : r ST(0), r ST(1) */
{{ OP_R, REG_FPU_OFFSET }, {{ OP_R, REG_FPU_OFFSET },
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fucompp */ { OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fucompp */
static op_implicit_list_t list_imul[] = static op_implicit_list_t list_imul[] =
/* F6 : IMUL : r AL, w AX */ /* F6 : IMUL : r AL, w AX */
/* F6 : MUL : r AL, w AX */ /* F6 : MUL : r AL, w AX */
{{ OP_R, REG_BYTE_OFFSET }, {{ OP_R, REG_BYTE_OFFSET },
{ OP_W, REG_WORD_OFFSET }, {0,0}}; /* imul */ { OP_W, REG_WORD_OFFSET }, {0,0}}; /* imul */
static op_implicit_list_t list_mul[] = static op_implicit_list_t list_mul[] =
/* F7 : IMUL : rw EAX, w EDX */ /* F7 : IMUL : rw EAX, w EDX */
/* F7 : MUL : rw EAX, w EDX */ /* F7 : MUL : rw EAX, w EDX */
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {{ OP_R | OP_W, REG_DWORD_OFFSET },
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* imul */ { OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* imul */
static op_implicit_list_t list_lahf[] = static op_implicit_list_t list_lahf[] =
/* 9F : LAHF : r EFLAGS, w AH */ /* 9F : LAHF : r EFLAGS, w AH */
{{ OP_R, REG_FLAGS_INDEX }, {{ OP_R, REG_FLAGS_INDEX },
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* lahf */ { OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* lahf */
static op_implicit_list_t list_ldmxcsr[] = static op_implicit_list_t list_ldmxcsr[] =
/* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */ /* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */
{{ OP_W, REG_MXCSG_INDEX }, {0,0}}; /* ldmxcsr */ {{ OP_W, REG_MXCSG_INDEX }, {0,0}}; /* ldmxcsr */
static op_implicit_list_t list_leave[] = static op_implicit_list_t list_leave[] =
/* C9 : LEAVE : rw ESP, w EBP */ /* C9 : LEAVE : rw ESP, w EBP */
{{ OP_R | OP_W, REG_ESP_INDEX }, {{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_DWORD_OFFSET + 5 }, {0,0}}; /* leave */ { OP_W, REG_DWORD_OFFSET + 5 }, {0,0}}; /* leave */
static op_implicit_list_t list_lgdt[] = static op_implicit_list_t list_lgdt[] =
/* 0F 01 : LGDT : w GDTR */ /* 0F 01 : LGDT : w GDTR */
{{ OP_W, REG_GDTR_INDEX }, {0,0}}; /* lgdt */ {{ OP_W, REG_GDTR_INDEX }, {0,0}}; /* lgdt */
static op_implicit_list_t list_lidt[] = static op_implicit_list_t list_lidt[] =
/* 0F 01 : LIDT : w IDTR */ /* 0F 01 : LIDT : w IDTR */
{{ OP_W, REG_IDTR_INDEX }, {0,0}}; /* lidt */ {{ OP_W, REG_IDTR_INDEX }, {0,0}}; /* lidt */
static op_implicit_list_t list_lldt[] = static op_implicit_list_t list_lldt[] =
/* 0F 00 : LLDT : w LDTR */ /* 0F 00 : LLDT : w LDTR */
{{ OP_W, REG_LDTR_INDEX }, {0,0}}; /* lldt */ {{ OP_W, REG_LDTR_INDEX }, {0,0}}; /* lldt */
static op_implicit_list_t list_lmsw[] = static op_implicit_list_t list_lmsw[] =
/* 0F 01 : LMSW : w CR0 */ /* 0F 01 : LMSW : w CR0 */
{{ OP_W, REG_CTRL_OFFSET }, {0,0}}; /* lmsw */ {{ OP_W, REG_CTRL_OFFSET }, {0,0}}; /* lmsw */
static op_implicit_list_t list_loop[] = static op_implicit_list_t list_loop[] =
/* E0, E1, E2 : LOOP : rw ECX */ /* E0, E1, E2 : LOOP : rw ECX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* loop */ {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* loop */
static op_implicit_list_t list_ltr[] = static op_implicit_list_t list_ltr[] =
/* 0F 00 : LTR : w Task Register */ /* 0F 00 : LTR : w Task Register */
{{ OP_W, REG_TR_INDEX }, {0,0}}; /* ltr */ {{ OP_W, REG_TR_INDEX }, {0,0}}; /* ltr */
static op_implicit_list_t list_pop[] = static op_implicit_list_t list_pop[] =
/* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */ /* 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 */ /* 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 */ {{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* pop, push */
static op_implicit_list_t list_popad[] = static op_implicit_list_t list_popad[] =
/* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */ /* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */
{{ OP_R | OP_W, REG_ESP_INDEX }, {{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_DWORD_OFFSET + 7 }, { OP_W, REG_DWORD_OFFSET + 7 },
{ OP_W, REG_DWORD_OFFSET + 6 }, { OP_W, REG_DWORD_OFFSET + 6 },
{ OP_W, REG_DWORD_OFFSET + 5 }, { OP_W, REG_DWORD_OFFSET + 5 },
{ OP_W, REG_DWORD_OFFSET + 3 }, { OP_W, REG_DWORD_OFFSET + 3 },
{ OP_W, REG_DWORD_OFFSET + 2 }, { OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET + 1 }, { OP_W, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* popad */ { OP_W, REG_DWORD_OFFSET }, {0,0}}; /* popad */
static op_implicit_list_t list_popfd[] = static op_implicit_list_t list_popfd[] =
/* 9D : POPFD : rw esp, w eflags */ /* 9D : POPFD : rw esp, w eflags */
{{ OP_R | OP_W, REG_ESP_INDEX }, {{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_W, REG_FLAGS_INDEX }, {0,0}}; /* popfd */ { OP_W, REG_FLAGS_INDEX }, {0,0}}; /* popfd */
static op_implicit_list_t list_pushad[] = static op_implicit_list_t list_pushad[] =
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */ /* 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 */ /* 60 : PUSHAD : rw esp, r eax ecx edx ebx esp ebp esi edi */
{{ OP_R | OP_W, REG_ESP_INDEX }, {{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_R, REG_DWORD_OFFSET }, { OP_R, REG_DWORD_OFFSET },
{ OP_R, REG_DWORD_OFFSET + 1 }, { OP_R, REG_DWORD_OFFSET + 1 },
{ OP_R, REG_DWORD_OFFSET + 2 }, { OP_R, REG_DWORD_OFFSET + 2 },
{ OP_R, REG_DWORD_OFFSET + 3 }, { OP_R, REG_DWORD_OFFSET + 3 },
{ OP_R, REG_DWORD_OFFSET + 5 }, { OP_R, REG_DWORD_OFFSET + 5 },
{ OP_R, REG_DWORD_OFFSET + 6 }, { OP_R, REG_DWORD_OFFSET + 6 },
{ OP_R, REG_DWORD_OFFSET + 7 }, {0,0}}; /* pushad */ { OP_R, REG_DWORD_OFFSET + 7 }, {0,0}}; /* pushad */
static op_implicit_list_t list_pushfd[] = static op_implicit_list_t list_pushfd[] =
/* 9C : PUSHFD : rw esp, r eflags */ /* 9C : PUSHFD : rw esp, r eflags */
{{ OP_R | OP_W, REG_ESP_INDEX }, {{ OP_R | OP_W, REG_ESP_INDEX },
{ OP_R, REG_FLAGS_INDEX }, {0,0}}; /* pushfd */ { OP_R, REG_FLAGS_INDEX }, {0,0}}; /* pushfd */
static op_implicit_list_t list_rdmsr[] = static op_implicit_list_t list_rdmsr[] =
/* 0F 32 : RDMSR : r ECX, w EDX, w EAX */ /* 0F 32 : RDMSR : r ECX, w EDX, w EAX */
{{ OP_R, REG_DWORD_OFFSET + 1 }, {{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 }, { OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdmsr */ { OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdmsr */
static op_implicit_list_t list_rdpmc[] = static op_implicit_list_t list_rdpmc[] =
/* 0F 33 : RDPMC : r ECX, w EDX, w EAX */ /* 0F 33 : RDPMC : r ECX, w EDX, w EAX */
{{ OP_R, REG_DWORD_OFFSET + 1 }, {{ OP_R, REG_DWORD_OFFSET + 1 },
{ OP_W, REG_DWORD_OFFSET + 2 }, { OP_W, REG_DWORD_OFFSET + 2 },
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdpmc */ { OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdpmc */
static op_implicit_list_t list_rdtsc[] = static op_implicit_list_t list_rdtsc[] =
/* 0F 31 : RDTSC : rw EDX, rw EAX */ /* 0F 31 : RDTSC : rw EDX, rw EAX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 }, {{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdtsc */ { OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdtsc */
static op_implicit_list_t list_rep[] = static op_implicit_list_t list_rep[] =
/* F3, F2 ... : REP : rw ECX */ /* F3, F2 ... : REP : rw ECX */
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* rep */ {{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* rep */
static op_implicit_list_t list_rsm[] = static op_implicit_list_t list_rsm[] =
/* 0F AA : RSM : r CR4, r CR0 */ /* 0F AA : RSM : r CR4, r CR0 */
{{ OP_R, REG_CTRL_OFFSET + 4 }, {{ OP_R, REG_CTRL_OFFSET + 4 },
{ OP_R, REG_CTRL_OFFSET }, {0,0}}; /* rsm */ { OP_R, REG_CTRL_OFFSET }, {0,0}}; /* rsm */
static op_implicit_list_t list_sahf[] = static op_implicit_list_t list_sahf[] =
/* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */ /* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sahf */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sahf */
static op_implicit_list_t list_sgdt[] = static op_implicit_list_t list_sgdt[] =
/* 0F : SGDT : r gdtr */ /* 0F : SGDT : r gdtr */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sgdt */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sgdt */
static op_implicit_list_t list_sidt[] = static op_implicit_list_t list_sidt[] =
/* 0F : SIDT : r idtr */ /* 0F : SIDT : r idtr */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sidt */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sidt */
static op_implicit_list_t list_sldt[] = static op_implicit_list_t list_sldt[] =
/* 0F : SLDT : r ldtr */ /* 0F : SLDT : r ldtr */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sldt */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sldt */
static op_implicit_list_t list_smsw[] = static op_implicit_list_t list_smsw[] =
/* 0F : SMSW : r CR0 */ /* 0F : SMSW : r CR0 */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* smsw */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* smsw */
static op_implicit_list_t list_stmxcsr[] = static op_implicit_list_t list_stmxcsr[] =
/* 0F AE : STMXCSR : r MXCSR */ /* 0F AE : STMXCSR : r MXCSR */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* stmxcsr */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* stmxcsr */
static op_implicit_list_t list_str[] = static op_implicit_list_t list_str[] =
/* 0F 00 : STR : r TR (task register) */ /* 0F 00 : STR : r TR (task register) */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* str */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* str */
static op_implicit_list_t list_sysenter[] = static op_implicit_list_t list_sysenter[] =
/* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags /* 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 */ * r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysenter */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysenter */
static op_implicit_list_t list_sysexit[] = static op_implicit_list_t list_sysexit[] =
/* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp /* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp
* r sysenter_cs_msr */ * r sysenter_cs_msr */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysexit */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysexit */
static op_implicit_list_t list_wrmsr[] = static op_implicit_list_t list_wrmsr[] =
/* 0F 30 : WRMST : r edx, r eax, r ecx */ /* 0F 30 : WRMST : r edx, r eax, r ecx */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* wrmsr */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* wrmsr */
static op_implicit_list_t list_xlat[] = static op_implicit_list_t list_xlat[] =
/* D7 : XLAT : rw al r ebx (ptr) */ /* D7 : XLAT : rw al r ebx (ptr) */
/* TODO: finish this! */ /* TODO: finish this! */
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* xlat */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* xlat */
/* TODO: /* TODO:
* monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R * monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R
* mwait 0f 01 c9 eax OP_R ecx OP_R * mwait 0f 01 c9 eax OP_R ecx OP_R
*/ */
static op_implicit_list_t list_monitor[] = static op_implicit_list_t list_monitor[] =
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* monitor */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* monitor */
static op_implicit_list_t list_mwait[] = static op_implicit_list_t list_mwait[] =
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* mwait */ {{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* mwait */
op_implicit_list_t *op_implicit_list[] = { op_implicit_list_t *op_implicit_list[] = {
/* This is a list of implicit operands which are read/written by /* This is a list of implicit operands which are read/written by
@ -347,7 +347,7 @@ op_implicit_list_t *op_implicit_list[] = {
list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */ list_str, list_sysenter, list_sysexit, list_wrmsr, /* 49 - 52 */
list_xlat, list_monitor, list_mwait, /* 53 - 55*/ list_xlat, list_monitor, list_mwait, /* 53 - 55*/
NULL /* end of list */ NULL /* end of list */
}; };
#define LAST_IMPL_IDX 55 #define LAST_IMPL_IDX 55

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; ia32_insn_t *sfx_insn;
size_t size; size_t size;
unsigned int prefixes = 0; 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, size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn,
&prefixes ); &prefixes );
if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) { if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) {

View File

@ -676,11 +676,11 @@ static ia32_insn_t tbl_0F[] = { /* Two-byte Opcodes */
{ 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, "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, "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_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, "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, "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_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

@ -60,7 +60,7 @@ static struct {
{ REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */ { REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */
{ REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */ { REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */
{ REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */ { REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */
}; };
/* REGISTER TABLE: size, type, and name of every register in the /* REGISTER TABLE: size, type, and name of every register in the
* CPU. Does not include MSRs since the are, after all, * CPU. Does not include MSRs since the are, after all,
@ -189,8 +189,8 @@ static struct {
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */ /* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
{ 0,reg_undef,0,{0} } { 0,reg_undef,0,"" }
}; };
static size_t sz_regtable = NUM_X86_REGS + 1; static size_t sz_regtable = NUM_X86_REGS + 1;

View File

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

View File

@ -9,8 +9,8 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#define snprintf _snprintf #define snprintf _snprintf
#define inline __inline #define inline __inline
#endif #endif
void x86_insn_t::make_invalid(unsigned char *buf) void x86_insn_t::make_invalid(unsigned char *buf)
{ {
@ -175,8 +175,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
if (next_addr != -1 ) { if (next_addr != -1 ) {
next_offset = next_addr - buf_rva; next_offset = next_addr - buf_rva;
/* if offset is in this buffer... */ /* if offset is in this buffer... */
if ( next_offset >= 0 && next_offset < int(buf_len) ) if ( next_offset >= 0 && next_offset < buf_len ) {
{
/* go ahead and disassemble */ /* go ahead and disassemble */
count += x86_disasm_forward( buf, count += x86_disasm_forward( buf,
buf_len, buf_len,

View File

@ -16,16 +16,21 @@ class CIcodeRec;
struct BB; struct BB;
struct LOCAL_ID; struct LOCAL_ID;
struct interval; struct interval;
//TODO: consider default address value -> INVALID
struct TYPEADR_TYPE struct TYPEADR_TYPE
{ {
uint32_t ip; /* Out edge icode address */ uint32_t ip; /* Out edge icode address */
BB * BBptr; /* Out edge pointer to next BB */ BB * BBptr; /* Out edge pointer to next BB */
interval *intPtr; /* Out edge ptr to next interval*/ 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> struct BB : public llvm::ilist_node<BB>
{ {
private: private:
BB(const BB&); BB(const BB&);
BB() : nodeType(0),traversed(DFS_NONE), BB() : nodeType(0),traversed(DFS_NONE),
@ -90,9 +95,8 @@ public:
int ifFollow; /* node that ends the if */ int ifFollow; /* node that ends the if */
int loopType; /* Type of loop (if any) */ int loopType; /* Type of loop (if any) */
int latchNode; /* latching node of the loop */ int latchNode; /* latching node of the loop */
int numBackEdges; /* # of back edges */ size_t numBackEdges; /* # of back edges */
int loopHead; /* most nested loop head to which int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
* thcis node belongs (dfsLast) */
int loopFollow; /* node that follows the loop */ int loopFollow; /* node that follows the loop */
int caseHead; /* most nested case to which this int caseHead; /* most nested case to which this
node belongs (dfsLast) */ node belongs (dfsLast) */
@ -100,8 +104,8 @@ public:
int index; /* Index, used in several ways */ 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(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 * CreateIntervalBB(Function *parent);
static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, 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 writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
void mergeFallThrough(CIcodeRec &Icode); void mergeFallThrough(CIcodeRec &Icode);
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last); void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
@ -120,8 +124,13 @@ public:
ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond); 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); void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
private: private:
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at); bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);

View File

@ -72,19 +72,19 @@ public:
} }
condOp op() const { return boolExpr.op;} condOp op() const { return boolExpr.op;}
public: public:
static COND_EXPR *idRegIdx(int idx, regType reg_type); static COND_EXPR * idRegIdx(int idx, regType reg_type);
static COND_EXPR *idKte(uint32_t kte, uint8_t size); static COND_EXPR * idKte(uint32_t kte, uint8_t size);
static COND_EXPR *idLoc(int off, LOCAL_ID *localId); static COND_EXPR * idLoc(int off, LOCAL_ID *localId);
static COND_EXPR *idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym); static COND_EXPR * idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static COND_EXPR *idLongIdx(int idx); static COND_EXPR * idLongIdx(int idx);
static COND_EXPR *idOther(eReg seg, eReg regi, int16_t off); static COND_EXPR * idOther(eReg seg, eReg regi, int16_t off);
static COND_EXPR *idParam(int off, const STKFRAME *argSymtab); static COND_EXPR * idParam(int off, const STKFRAME *argSymtab);
static COND_EXPR *unary(condNodeType t, COND_EXPR *sub_expr); 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 * 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 * idFunc(Function *pproc, STKFRAME *args);
static COND_EXPR *idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_); 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 * 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 insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
public: public:

View File

@ -23,6 +23,7 @@ struct SymbolCommon
}; };
struct SYM : public SymbolCommon struct SYM : public SymbolCommon
{ {
typedef uint32_t tLabel;
SYM() : label(0),flg(0) SYM() : label(0),flg(0)
{ {
@ -33,9 +34,10 @@ struct SYM : public SymbolCommon
/* STACK FRAME */ /* STACK FRAME */
struct STKSYM : public SymbolCommon struct STKSYM : public SymbolCommon
{ {
typedef int16_t tLabel;
COND_EXPR *actual; /* Expression tree of actual parameter */ COND_EXPR *actual; /* Expression tree of actual parameter */
COND_EXPR *regs; /* For register arguments only */ 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) */ uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
bool hasMacro; /* This type needs a macro */ bool hasMacro; /* This type needs a macro */
std::string macro; /* Macro name */ std::string macro; /* Macro name */
@ -60,13 +62,13 @@ class SymbolTableCommon : public std::vector<T>
public: public:
typedef typename std::vector<T>::iterator iterator; typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_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(), auto iter = std::find_if(this->begin(),this->end(),
[lab](T &s)->bool {return s.label==lab;}); [lab](T &s)->bool {return s.label==lab;});
return iter; 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(), auto iter = std::find_if(this->begin(),this->end(),
[lab](const T &s)->bool {return s.label==lab;}); [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 start - basic block starts here, might be parent->Icode.end()
* @arg fin - last of basic block's instructions * @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; BB* pnewBB;
pnewBB = new BB; 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->immedDom = NO_DOM;
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail = pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE; pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
pnewBB->instructions = make_iterator_range(start,fin); pnewBB->instructions = r;
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);
/* Mark the basic block to which the icodes belong to, but only for /* 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(parent)
{ {
if (start != parent->Icode.end()) //setInBB should automatically handle if our range is empty
parent->Icode.SetInBB(pnewBB->instructions, pnewBB); parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
parent->heldBBs.push_back(pnewBB); parent->heldBBs.push_back(pnewBB);
parent->m_cfg.push_back(pnewBB); parent->m_cfg.push_back(pnewBB);
pnewBB->Parent = parent; 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++; stats.numBBbef++;
return pnewBB; 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 endOfParent = parent->Icode.end();
iICODE fin(parent->Icode.begin()); return Create(make_iterator_range(endOfParent,endOfParent),INTERVAL_NODE,parent);
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);
} }
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call", 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. */ * h. Note that h is a case node. */
static bool successor (int s, int h, Function * pProc) static bool successor (int s, int h, Function * pProc)
{ {
BB * header; BB * header = pProc->m_dfsLast[h];
header = pProc->m_dfsLast[h];
auto iter = std::find_if(header->edges.begin(), auto iter = std::find_if(header->edges.begin(),
header->edges.end(), header->edges.end(),
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;}); [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 */ /* Structures if statements */
void Function::structIfs () void Function::structIfs ()
{ {
size_t followInEdges; /* Largest # in-edges so far */
int curr, /* Index for linear scan of nodes */ int curr, /* Index for linear scan of nodes */
/*desc,*/ /* Index for descendant */ /*desc,*/ /* Index for descendant */
followInEdges, /* Largest # in-edges so far */
follow; /* Possible follow node */ follow; /* Possible follow node */
nodeList domDesc, /* List of nodes dominated by curr */ nodeList domDesc, /* List of nodes dominated by curr */
unresolved /* List of unresolved if nodes */ unresolved /* List of unresolved if nodes */

View File

@ -3,11 +3,17 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#include "dcc.h"
#include <string.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 "graph.h"
#include "project.h" #include "project.h"
using namespace std;
using namespace boost;
extern Project g_proj; extern Project g_proj;
//static BB * rmJMP(Function * pProc, int marker, BB * pBB); //static BB * rmJMP(Function * pProc, int marker, BB * pBB);
//static void mergeFallThrough(Function * pProc, BB * pBB); //static void mergeFallThrough(Function * pProc, BB * pBB);
@ -33,12 +39,18 @@ void Function::createCFG()
BB * psBB; BB * psBB;
BB * pBB; BB * pBB;
iICODE pIcode = Icode.begin(); iICODE pIcode = Icode.begin();
iICODE iStart = Icode.begin();
stats.numBBbef = stats.numBBaft = 0; 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); iICODE nextIcode = ++iICODE(pIcode);
pBB = nullptr;
LLInst *ll = pIcode->ll(); 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 /* 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 if (nextIcode == Icode.end() and
@ -46,103 +58,79 @@ void Function::createCFG()
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and (not ll->match(iJMP)) and (not ll->match(iJMPF)) and
(not ll->match(iRET)) and (not ll->match(iRETF))) (not ll->match(iRET)) and (not ll->match(iRETF)))
{ {
//pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this); pBB=BB::Create(current_range, NOWHERE_NODE, this);
pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
} }
else
/* Only process icodes that have valid instructions */
else if (not ll->testFlags(NO_CODE) )
{
switch (ll->getOpcode()) { switch (ll->getOpcode()) {
case iJB: case iJBE: case iJAE: case iJA: case iJB: case iJBE: case iJAE: case iJA:
case iJL: case iJLE: case iJGE: case iJG: case iJL: case iJLE: case iJGE: case iJG:
case iJE: case iJNE: case iJS: case iJNS: case iJE: case iJNE: case iJS: case iJNS:
case iJO: case iJNO: case iJP: case iJNP: case iJO: case iJNO: case iJP: case iJNP:
case iJCXZ: case iJCXZ:
pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this); pBB = BB::Create(current_range, TWO_BRANCH, this);
CondJumps: CondJumps:
//start = ip + 1; pBB->addOutEdge(nextIcode->loc_ip);
iStart = ++iICODE(pIcode); /* This is checking for jumps off into nowhere */
pBB->edges[0].ip = (uint32_t)iStart->loc_ip; if ( not ll->testFlags(NO_LABEL) )
/* This is for jumps off into nowhere */ pBB->addOutEdge(ll->src().getImm2());
if ( ll->testFlags(NO_LABEL) )
{
pBB->edges.pop_back();
}
else
pBB->edges[1].ip = ll->src().getImm2();
break; break;
case iLOOP: case iLOOPE: case iLOOPNE: case iLOOP: case iLOOPE: case iLOOPNE:
//pBB = BB::Create(start, ip, LOOP_NODE, 2, this); pBB = BB::Create(current_range, LOOP_NODE, this);
pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this);
goto CondJumps; goto CondJumps;
case iJMPF: case iJMP: case iJMPF: case iJMP:
if (ll->testFlags(SWITCH)) if (ll->testFlags(SWITCH))
{ {
//pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this); pBB = BB::Create(current_range, MULTI_BRANCH, this);
pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
for (size_t i = 0; i < ll->caseTbl2.size(); i++) for (size_t i = 0; i < ll->caseTbl2.size(); i++)
pBB->edges[i].ip = ll->caseTbl2[i]; pBB->addOutEdge(ll->caseTbl2[i]);
hasCase = true; hasCase = true;
} }
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT 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(current_range, ONE_BRANCH, this);
pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this); pBB->addOutEdge(ll->src().getImm2());
pBB->edges[0].ip = ll->src().getImm2();
} }
else else
BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this); pBB = BB::Create(current_range, NOWHERE_NODE, this);
iStart = ++iICODE(pIcode);
break; break;
case iCALLF: case iCALL: case iCALLF: case iCALL:
{ {
Function * p = ll->src().proc.proc; Function * p = ll->src().proc.proc;
if (p) pBB = BB::Create(current_range, CALL_NODE, this);
i = ((p->flg) & TERMINATES) ? 0 : 1; if (p && not ((p->flg) & TERMINATES) )
else pBB->addOutEdge(nextIcode->loc_ip);
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;
}
break; break;
}
case iRET: case iRETF: case iRET: case iRETF:
//BB::Create(start, ip, RETURN_NODE, 0, this); pBB = BB::Create(current_range, RETURN_NODE, this);
BB::Create(iStart, pIcode, RETURN_NODE, 0, this);
iStart = ++iICODE(pIcode);
break; break;
default: default:
/* Check for exit to DOS */ /* Check for exit to DOS */
iICODE next1=++iICODE(pIcode);
if ( ll->testFlags(TERMINATES) ) if ( ll->testFlags(TERMINATES) )
{ {
pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this); pBB = BB::Create(current_range, TERMINATE_NODE, this);
//pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
iStart = ++iICODE(pIcode); // start = ip + 1;
} }
/* Check for a fall through */ /* 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(current_range, FALL_NODE, this);
pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this); pBB->addOutEdge(nextIcode->loc_ip);
iStart = ++iICODE(pIcode); // start = ip + 1;
pBB->addOutEdge(iStart->loc_ip);
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
} }
} }
break; 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(); auto iter=heldBBs.begin();
@ -166,7 +154,7 @@ CondJumps:
pBB->edges[edeg_idx].BBptr = psBB; pBB->edges[edeg_idx].BBptr = psBB;
psBB->inEdges.push_back((BB *)nullptr); psBB->inEdges.push_back((BB *)nullptr);
} }
} }
} }
void Function::markImpure() void Function::markImpure()
@ -368,15 +356,15 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
pChild->inEdges.clear(); pChild->inEdges.clear();
pChild->edges.clear(); pChild->edges.clear();
} }
traversed = DFS_MERGE; traversed = DFS_MERGE;
/* Process all out edges recursively */ /* Process all out edges recursively */
for (size_t i = 0; i < edges.size(); i++) for (size_t i = 0; i < edges.size(); i++)
{ {
if (edges[i].BBptr->traversed != DFS_MERGE) if (edges[i].BBptr->traversed != DFS_MERGE)
edges[i].BBptr->mergeFallThrough(Icode); edges[i].BBptr->mergeFallThrough(Icode);
} }
} }

View File

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

View File

@ -540,8 +540,8 @@ void Function::propLong()
for (size_t i = 0; i < localId.csym(); i++) for (size_t i = 0; i < localId.csym(); i++)
{ {
const ID &pLocId(localId.id_arr[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: case STK_FRAME:
@ -555,6 +555,5 @@ void Function::propLong()
break; break;
} }
} }
}
} }

View File

@ -236,29 +236,23 @@ derSeq_Entry::~derSeq_Entry()
bool Function::nextOrderGraph (derSeq &derivedGi) bool Function::nextOrderGraph (derSeq &derivedGi)
{ {
interval *Ii; /* Interval being processed */ interval *Ii; /* Interval being processed */
BB *BBnode, /* New basic block of intervals */ BB *BBnode; /* New basic block of intervals */
//*curr, /* BB being checked for out edges */ bool sameGraph; /* Boolean, isomorphic graphs */
*succ /* Successor node */
;
//queue *listIi; /* List of intervals */
int i; /* Index to outEdges array */
/*j;*/ /* Index to successors */
boolT sameGraph; /* Boolean, isomorphic graphs */
/* Process Gi's intervals */ /* Process Gi's intervals */
derSeq_Entry &prev_entry(derivedGi.back()); derSeq_Entry &prev_entry(derivedGi.back());
derivedGi.push_back(derSeq_Entry()); derivedGi.push_back(derSeq_Entry());
derSeq_Entry &new_entry(derivedGi.back()); derSeq_Entry &new_entry(derivedGi.back());
Ii = prev_entry.Ii;
sameGraph = true; sameGraph = true;
BBnode = 0; BBnode = 0;
std::vector<BB *> bbs; 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 = BB::CreateIntervalBB(this);
BBnode = bbs.back();
BBnode->correspInt = Ii; BBnode->correspInt = Ii;
bbs.push_back(BBnode);
const queue &listIi(Ii->nodes); const queue &listIi(Ii->nodes);
/* Check for more than 1 interval */ /* Check for more than 1 interval */
@ -267,23 +261,19 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
/* Find out edges */ /* 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; BB *successor_node = curr->edges[j].BBptr;
if (succ->inInterval != curr->inInterval) if (successor_node->inInterval != curr->inInterval)
BBnode->edges[i++].intPtr = succ->inInterval; BBnode->addOutEdgeInterval(successor_node->inInterval);
} }
} }
} }
/* Next interval */
Ii = Ii->next;
}
/* Convert list of pointers to intervals into a real graph. /* Convert list of pointers to intervals into a real graph.
* Determines the number of in edges to each new BB, and places it * Determines the number of in edges to each new BB, and places it
* in numInEdges and inEdgeCount for later interval processing. */ * in numInEdges and inEdgeCount for later interval processing. */
@ -303,7 +293,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
(*iter)->inEdgeCount++; (*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)) if ((wOp < 0x34) || (wOp > 0x3B))
return; return;
uint8_t buf[16]; uint8_t buf[16];
/* This is a Borland/Microsoft floating point emulation instruction. /* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
Treat as if it is an ESC opcode */
int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset); int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
memcpy(buf,prog.Image+insn.offset,actual_valid_bytes); memcpy(buf,prog.Image+insn.offset,actual_valid_bytes);

View File

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

View File

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