From 5087a051b5257308b17d61e2e7e16165562f1c68 Mon Sep 17 00:00:00 2001 From: Artur K Date: Sat, 14 Jul 2012 23:04:09 +0200 Subject: [PATCH] More simplifications on BB creation --- 3rd_party/libdisasm/ia32_implicit.cpp | 666 ++++++++++----------- 3rd_party/libdisasm/ia32_insn.cpp | 3 +- 3rd_party/libdisasm/ia32_invariant.cpp | 416 ++++++------- 3rd_party/libdisasm/ia32_opcode_tables.cpp | 12 +- 3rd_party/libdisasm/ia32_reg.cpp | 334 +++++------ 3rd_party/libdisasm/libdis.h | 7 +- 3rd_party/libdisasm/x86_disasm.cpp | 225 ++++--- include/BasicBlock.h | 27 +- include/ast.h | 30 +- include/symtab.h | 8 +- src/BasicBlock.cpp | 41 +- src/control.cpp | 6 +- src/graph.cpp | 162 +++-- src/project.cpp | 5 +- src/proplong.cpp | 25 +- src/reducible.cpp | 40 +- src/scanner.cpp | 3 +- src/tests/comwrite.cpp | 2 +- src/tests/project.cpp | 4 +- 19 files changed, 989 insertions(+), 1027 deletions(-) diff --git a/3rd_party/libdisasm/ia32_implicit.cpp b/3rd_party/libdisasm/ia32_implicit.cpp index db8c0d7..0d42fae 100644 --- a/3rd_party/libdisasm/ia32_implicit.cpp +++ b/3rd_party/libdisasm/ia32_implicit.cpp @@ -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; } diff --git a/3rd_party/libdisasm/ia32_insn.cpp b/3rd_party/libdisasm/ia32_insn.cpp index dcba347..9be12e9 100644 --- a/3rd_party/libdisasm/ia32_insn.cpp +++ b/3rd_party/libdisasm/ia32_insn.cpp @@ -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 ) { diff --git a/3rd_party/libdisasm/ia32_invariant.cpp b/3rd_party/libdisasm/ia32_invariant.cpp index 0991b0f..cd611bf 100644 --- a/3rd_party/libdisasm/ia32_invariant.cpp +++ b/3rd_party/libdisasm/ia32_invariant.cpp @@ -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 ) ); } diff --git a/3rd_party/libdisasm/ia32_opcode_tables.cpp b/3rd_party/libdisasm/ia32_opcode_tables.cpp index 3bf2005..41e21f7 100644 --- a/3rd_party/libdisasm/ia32_opcode_tables.cpp +++ b/3rd_party/libdisasm/ia32_opcode_tables.cpp @@ -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 } }; diff --git a/3rd_party/libdisasm/ia32_reg.cpp b/3rd_party/libdisasm/ia32_reg.cpp index fe78a0d..da6dde3 100644 --- a/3rd_party/libdisasm/ia32_reg.cpp +++ b/3rd_party/libdisasm/ia32_reg.cpp @@ -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; } diff --git a/3rd_party/libdisasm/libdis.h b/3rd_party/libdisasm/libdis.h index de8a087..10f66d4 100644 --- a/3rd_party/libdisasm/libdis.h +++ b/3rd_party/libdisasm/libdis.h @@ -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; diff --git a/3rd_party/libdisasm/x86_disasm.cpp b/3rd_party/libdisasm/x86_disasm.cpp index 73ad252..883cdb3 100644 --- a/3rd_party/libdisasm/x86_disasm.cpp +++ b/3rd_party/libdisasm/x86_disasm.cpp @@ -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); } diff --git a/include/BasicBlock.h b/include/BasicBlock.h index fa78663..7be8cd0 100644 --- a/include/BasicBlock.h +++ b/include/BasicBlock.h @@ -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 { + 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 &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); diff --git a/include/ast.h b/include/ast.h index 696e6d0..52c7b60 100644 --- a/include/ast.h +++ b/include/ast.h @@ -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: diff --git a/include/symtab.h b/include/symtab.h index 4f7e866..f310351 100644 --- a/include/symtab.h +++ b/include/symtab.h @@ -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 public: typedef typename std::vector::iterator iterator; typedef typename std::vector::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;}); diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index fab47f0..7f62cd0 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -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", diff --git a/src/control.cpp b/src/control.cpp index 14d87ab..b0281c2 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -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 */ diff --git a/src/graph.cpp b/src/graph.cpp index e947c54..b0dc454 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -3,11 +3,17 @@ * (C) Cristina Cifuentes ****************************************************************************/ -#include "dcc.h" #include -#include /* For free() */ +#include +#include +#include + +#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); +} } diff --git a/src/project.cpp b/src/project.cpp index 501d761..c292741 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -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; } diff --git a/src/proplong.cpp b/src/proplong.cpp index 18297a4..34bf54b 100644 --- a/src/proplong.cpp +++ b/src/proplong.cpp @@ -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; } } } diff --git a/src/reducible.cpp b/src/reducible.cpp index 8e1cb10..84b5ea8 100644 --- a/src/reducible.cpp +++ b/src/reducible.cpp @@ -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 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; } diff --git a/src/scanner.cpp b/src/scanner.cpp index 54929e1..378e8e3 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -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); diff --git a/src/tests/comwrite.cpp b/src/tests/comwrite.cpp index c0f6be6..61822c2 100644 --- a/src/tests/comwrite.cpp +++ b/src/tests/comwrite.cpp @@ -1,6 +1,6 @@ +#include "dcc.h" #include #include -#include "dcc.h" TEST(CowriteTest, HandlesZeroInput) { EXPECT_EQ(1, 1); diff --git a/src/tests/project.cpp b/src/tests/project.cpp index 9feece7..72a3e40 100644 --- a/src/tests/project.cpp +++ b/src/tests/project.cpp @@ -13,8 +13,8 @@ TEST(Project, NewProjectIsInitalized) { TEST(Project, CreatedProjectHasValidNames) { Project p; - std::vector strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro ject3"}; - std::vector expected = {"Project1","Project2","Pro ject3"}; + std::vector strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro\\ ject3"}; + std::vector expected = {"Project1","Project2","Pro\\ ject3"}; for(size_t i=0; i