removed most of clang warnings / errors

This commit is contained in:
Artur K 2012-03-29 22:02:25 +02:00
parent 9cc5202ff7
commit ba110a64cb
60 changed files with 4285 additions and 4085 deletions

4
.gitignore vendored
View File

@ -4,4 +4,6 @@ tests/prev
tests/outputs/* tests/outputs/*
tests/errors tests/errors
*.autosave *.autosave
bld* bld*
*.user
*.idb

View File

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

View File

@ -240,7 +240,7 @@ void Ia32_Decoder::ia32_handle_prefix( unsigned int prefixes ) {
} }
static void reg_32_to_16( x86_op_t *op, x86_insn_t *insn, void *arg ) { static void reg_32_to_16( x86_op_t *op, x86_insn_t */*insn*/, void */*arg*/ ) {
/* if this is a 32-bit register and it is a general register ... */ /* if this is a 32-bit register and it is a general register ... */
if ( op->type == op_register && op->data.reg.size == 4 && if ( op->type == op_register && op->data.reg.size == 4 &&
@ -539,12 +539,12 @@ size_t ia32_table_lookup( unsigned char *buf, size_t buf_len,
size_t Ia32_Decoder::handle_insn_suffix( unsigned char *buf, size_t buf_len, size_t Ia32_Decoder::handle_insn_suffix( unsigned char *buf, size_t buf_len,
ia32_insn_t *raw_insn ) { ia32_insn_t *raw_insn ) {
ia32_table_desc_t *table_desc; // ia32_table_desc_t *table_desc;
ia32_insn_t *sfx_insn; ia32_insn_t *sfx_insn;
size_t size; size_t size;
unsigned int prefixes = 0; unsigned int prefixes = 0;
table_desc = &ia32_tables[raw_insn->table]; // table_desc = &ia32_tables[raw_insn->table];
size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn, size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn,
&prefixes ); &prefixes );
if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) { if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) {

View File

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

View File

@ -155,12 +155,12 @@ static size_t modrm_decode16( unsigned char *buf, unsigned int buf_len,
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3); ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3);
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7); ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7);
case MOD16_RM_BPSI: case MOD16_RM_BPSI:
op->flags.op_seg = x86_op_flags::op_ss_seg; op->flags.op_seg = x86_op_flags::op_ss_seg>>8;
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5); ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5);
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6); ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6);
break; break;
case MOD16_RM_BPDI: case MOD16_RM_BPDI:
op->flags.op_seg = x86_op_flags::op_ss_seg; op->flags.op_seg = x86_op_flags::op_ss_seg>>8;
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5); ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5);
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7); ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7);
break; break;
@ -172,7 +172,7 @@ static size_t modrm_decode16( unsigned char *buf, unsigned int buf_len,
break; break;
case MOD16_RM_BP: case MOD16_RM_BP:
if ( modrm->mod != MOD16_MOD_NODISP ) { if ( modrm->mod != MOD16_MOD_NODISP ) {
op->flags.op_seg = x86_op_flags::op_ss_seg; op->flags.op_seg = x86_op_flags::op_ss_seg>>8;
ia32_handle_register(&ea->base, ia32_handle_register(&ea->base,
REG_WORD_OFFSET + 5); REG_WORD_OFFSET + 5);
} }

File diff suppressed because it is too large Load Diff

View File

@ -20,17 +20,17 @@ static void apply_seg( x86_op_t *op, unsigned int prefixes ) {
switch ( prefixes & PREFIX_REG_MASK ) { switch ( prefixes & PREFIX_REG_MASK ) {
/* NOTE: that op->flags for segment override are not a bitfield */ /* NOTE: that op->flags for segment override are not a bitfield */
case PREFIX_CS: case PREFIX_CS:
op->flags.op_seg = x86_op_flags::op_cs_seg; break; op->flags.op_seg = x86_op_flags::op_cs_seg>>8; break;
case PREFIX_SS: case PREFIX_SS:
op->flags.op_seg = x86_op_flags::op_ss_seg; break; op->flags.op_seg = x86_op_flags::op_ss_seg>>8; break;
case PREFIX_DS: case PREFIX_DS:
op->flags.op_seg = x86_op_flags::op_ds_seg; break; op->flags.op_seg = x86_op_flags::op_ds_seg>>8; break;
case PREFIX_ES: case PREFIX_ES:
op->flags.op_seg = x86_op_flags::op_es_seg; break; op->flags.op_seg = x86_op_flags::op_es_seg>>8; break;
case PREFIX_FS: case PREFIX_FS:
op->flags.op_seg = x86_op_flags::op_fs_seg; break; op->flags.op_seg = x86_op_flags::op_fs_seg>>8; break;
case PREFIX_GS: case PREFIX_GS:
op->flags.op_seg = x86_op_flags::op_gs_seg; break; op->flags.op_seg = x86_op_flags::op_gs_seg>>8; break;
} }
return; return;
@ -172,7 +172,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
case ADDRMETH_X: /* Memory addressed by DS:SI [string] */ case ADDRMETH_X: /* Memory addressed by DS:SI [string] */
op->type = op_expression; op->type = op_expression;
op->flags.op_hardcode = true; op->flags.op_hardcode = true;
op->flags.op_seg = x86_op_flags::op_ds_seg; op->flags.op_seg = x86_op_flags::op_ds_seg>>8;
op->flags.op_pointer = true; op->flags.op_pointer = true;
op->flags.op_string = true; op->flags.op_string = true;
ia32_handle_register( &op->data.expression.base, ia32_handle_register( &op->data.expression.base,
@ -181,7 +181,7 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */ case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */
op->type = op_expression; op->type = op_expression;
op->flags.op_hardcode = true; op->flags.op_hardcode = true;
op->flags.op_seg = x86_op_flags::op_es_seg; op->flags.op_seg = x86_op_flags::op_es_seg>>8;
op->flags.op_pointer = true; op->flags.op_pointer = true;
op->flags.op_string = true; op->flags.op_string = true;
ia32_handle_register( &op->data.expression.base, ia32_handle_register( &op->data.expression.base,

View File

@ -71,126 +71,126 @@ static struct {
unsigned int alias; unsigned int alias;
char mnemonic[8]; char mnemonic[8];
} ia32_reg_table[NUM_X86_REGS + 2] = { } ia32_reg_table[NUM_X86_REGS + 2] = {
{ 0, reg_undef, 0, "" }, { 0, reg_undef, 0, "" },
/* REG_DWORD_OFFSET */ /* REG_DWORD_OFFSET */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_ret), 0, "eax" }, { 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, (x86_reg_type)(reg_gen | reg_count), 0, "ecx" },
{ REG_DWORD_SIZE, reg_gen, 0, "edx" }, { REG_DWORD_SIZE, reg_gen, 0, "edx" },
{ REG_DWORD_SIZE, reg_gen, 0, "ebx" }, { REG_DWORD_SIZE, reg_gen, 0, "ebx" },
/* REG_ESP_INDEX */ /* REG_ESP_INDEX */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_sp), 0, "esp" }, { 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_fp), 0, "ebp" },
{ REG_DWORD_SIZE, (x86_reg_type)(reg_gen | reg_src), 0, "esi" }, { 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_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_ret), 3, "ax" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_count), 6, "cx" }, { REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_count), 6, "cx" },
{ REG_WORD_SIZE, reg_gen, 9, "dx" }, { REG_WORD_SIZE, reg_gen, 9, "dx" },
{ REG_WORD_SIZE, reg_gen, 12, "bx" }, { 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_sp), 13, "sp" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_fp), 14, "bp" }, { 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_src), 15, "si" },
{ REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_dest), 16, "di" }, { REG_WORD_SIZE, (x86_reg_type)(reg_gen | reg_dest), 16, "di" },
/* REG_BYTE_OFFSET */ /* REG_BYTE_OFFSET */
{ REG_BYTE_SIZE, reg_gen, 1, "al" }, { REG_BYTE_SIZE, reg_gen, 1, "al" },
{ REG_BYTE_SIZE, reg_gen, 4, "cl" }, { REG_BYTE_SIZE, reg_gen, 4, "cl" },
{ REG_BYTE_SIZE, reg_gen, 7, "dl" }, { REG_BYTE_SIZE, reg_gen, 7, "dl" },
{ REG_BYTE_SIZE, reg_gen, 10, "bl" }, { REG_BYTE_SIZE, reg_gen, 10, "bl" },
{ REG_BYTE_SIZE, reg_gen, 2, "ah" }, { REG_BYTE_SIZE, reg_gen, 2, "ah" },
{ REG_BYTE_SIZE, reg_gen, 5, "ch" }, { REG_BYTE_SIZE, reg_gen, 5, "ch" },
{ REG_BYTE_SIZE, reg_gen, 8, "dh" }, { REG_BYTE_SIZE, reg_gen, 8, "dh" },
{ REG_BYTE_SIZE, reg_gen, 11, "bh" }, { REG_BYTE_SIZE, reg_gen, 11, "bh" },
/* REG_MMX_OFFSET */ /* REG_MMX_OFFSET */
{ REG_MMX_SIZE, reg_simd, 18, "mm0" }, { REG_MMX_SIZE, reg_simd, 18, "mm0" },
{ REG_MMX_SIZE, reg_simd, 19, "mm1" }, { REG_MMX_SIZE, reg_simd, 19, "mm1" },
{ REG_MMX_SIZE, reg_simd, 20, "mm2" }, { REG_MMX_SIZE, reg_simd, 20, "mm2" },
{ REG_MMX_SIZE, reg_simd, 21, "mm3" }, { REG_MMX_SIZE, reg_simd, 21, "mm3" },
{ REG_MMX_SIZE, reg_simd, 22, "mm4" }, { REG_MMX_SIZE, reg_simd, 22, "mm4" },
{ REG_MMX_SIZE, reg_simd, 23, "mm5" }, { REG_MMX_SIZE, reg_simd, 23, "mm5" },
{ REG_MMX_SIZE, reg_simd, 24, "mm6" }, { REG_MMX_SIZE, reg_simd, 24, "mm6" },
{ REG_MMX_SIZE, reg_simd, 25, "mm7" }, { REG_MMX_SIZE, reg_simd, 25, "mm7" },
/* REG_SIMD_OFFSET */ /* REG_SIMD_OFFSET */
{ REG_SIMD_SIZE, reg_simd, 0, "xmm0" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm0" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm1" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm1" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm2" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm2" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm3" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm3" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm4" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm4" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm5" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm5" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm6" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm6" },
{ REG_SIMD_SIZE, reg_simd, 0, "xmm7" }, { REG_SIMD_SIZE, reg_simd, 0, "xmm7" },
/* REG_DEBUG_OFFSET */ /* REG_DEBUG_OFFSET */
{ REG_DEBUG_SIZE, reg_sys, 0, "dr0" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr0" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr1" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr1" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr2" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr2" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr3" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr3" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr4" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr4" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr5" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr5" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr6" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr6" },
{ REG_DEBUG_SIZE, reg_sys, 0, "dr7" }, { REG_DEBUG_SIZE, reg_sys, 0, "dr7" },
/* REG_CTRL_OFFSET */ /* REG_CTRL_OFFSET */
{ REG_CTRL_SIZE, reg_sys, 0, "cr0" }, { REG_CTRL_SIZE, reg_sys, 0, "cr0" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr1" }, { REG_CTRL_SIZE, reg_sys, 0, "cr1" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr2" }, { REG_CTRL_SIZE, reg_sys, 0, "cr2" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr3" }, { REG_CTRL_SIZE, reg_sys, 0, "cr3" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr4" }, { REG_CTRL_SIZE, reg_sys, 0, "cr4" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr5" }, { REG_CTRL_SIZE, reg_sys, 0, "cr5" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr6" }, { REG_CTRL_SIZE, reg_sys, 0, "cr6" },
{ REG_CTRL_SIZE, reg_sys, 0, "cr7" }, { REG_CTRL_SIZE, reg_sys, 0, "cr7" },
/* REG_TEST_OFFSET */ /* REG_TEST_OFFSET */
{ REG_TEST_SIZE, reg_sys, 0, "tr0" }, { REG_TEST_SIZE, reg_sys, 0, "tr0" },
{ REG_TEST_SIZE, reg_sys, 0, "tr1" }, { REG_TEST_SIZE, reg_sys, 0, "tr1" },
{ REG_TEST_SIZE, reg_sys, 0, "tr2" }, { REG_TEST_SIZE, reg_sys, 0, "tr2" },
{ REG_TEST_SIZE, reg_sys, 0, "tr3" }, { REG_TEST_SIZE, reg_sys, 0, "tr3" },
{ REG_TEST_SIZE, reg_sys, 0, "tr4" }, { REG_TEST_SIZE, reg_sys, 0, "tr4" },
{ REG_TEST_SIZE, reg_sys, 0, "tr5" }, { REG_TEST_SIZE, reg_sys, 0, "tr5" },
{ REG_TEST_SIZE, reg_sys, 0, "tr6" }, { REG_TEST_SIZE, reg_sys, 0, "tr6" },
{ REG_TEST_SIZE, reg_sys, 0, "tr7" }, { REG_TEST_SIZE, reg_sys, 0, "tr7" },
/* REG_SEG_OFFSET */ /* REG_SEG_OFFSET */
{ REG_SEG_SIZE, reg_seg, 0, "es" }, { REG_SEG_SIZE, reg_seg, 0, "es" },
{ REG_SEG_SIZE, reg_seg, 0, "cs" }, { REG_SEG_SIZE, reg_seg, 0, "cs" },
{ REG_SEG_SIZE, reg_seg, 0, "ss" }, { REG_SEG_SIZE, reg_seg, 0, "ss" },
{ REG_SEG_SIZE, reg_seg, 0, "ds" }, { REG_SEG_SIZE, reg_seg, 0, "ds" },
{ REG_SEG_SIZE, reg_seg, 0, "fs" }, { REG_SEG_SIZE, reg_seg, 0, "fs" },
{ REG_SEG_SIZE, reg_seg, 0, "gs" }, { REG_SEG_SIZE, reg_seg, 0, "gs" },
/* REG_LDTR_INDEX */ /* REG_LDTR_INDEX */
{ REG_DWORD_SIZE, reg_sys, 0, "ldtr" }, { REG_DWORD_SIZE, reg_sys, 0, "ldtr" },
/* REG_GDTR_INDEX */ /* REG_GDTR_INDEX */
{ REG_DWORD_SIZE, reg_sys, 0, "gdtr" }, { REG_DWORD_SIZE, reg_sys, 0, "gdtr" },
/* REG_FPU_OFFSET */ /* REG_FPU_OFFSET */
{ REG_FPU_SIZE, reg_fpu, 0, "st(0)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(0)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(1)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(1)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(2)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(2)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(3)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(3)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(4)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(4)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(5)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(5)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(6)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(6)" },
{ REG_FPU_SIZE, reg_fpu, 0, "st(7)" }, { REG_FPU_SIZE, reg_fpu, 0, "st(7)" },
/* REG_FLAGS_INDEX : 81 */ /* REG_FLAGS_INDEX : 81 */
{ REG_FLAGS_SIZE, reg_cond, 0, "eflags" }, { REG_FLAGS_SIZE, reg_cond, 0, "eflags" },
/* REG_FPCTRL_INDEX : 82*/ /* REG_FPCTRL_INDEX : 82*/
{ REG_FPCTRL_SIZE, (x86_reg_type)(reg_fpu | reg_sys), 0, "fpctrl" }, { 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_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_FPTAG_SIZE, (x86_reg_type)(reg_fpu | reg_sys), 0, "fptag" },
/* REG_EIP_INDEX : 85 */ /* REG_EIP_INDEX : 85 */
{ REG_EIP_SIZE, reg_pc, 0, "eip" }, { REG_EIP_SIZE, reg_pc, 0, "eip" },
/* REG_IP_INDEX : 86 */ /* REG_IP_INDEX : 86 */
{ REG_IP_SIZE, reg_pc, 17, "ip" }, { REG_IP_SIZE, reg_pc, 17, "ip" },
/* REG_IDTR_INDEX : 87 */ /* REG_IDTR_INDEX : 87 */
{ REG_DWORD_SIZE, reg_sys, 0, "idtr" }, { REG_DWORD_SIZE, reg_sys, 0, "idtr" },
/* REG_MXCSG_INDEX : SSE Control Reg : 88 */ /* REG_MXCSG_INDEX : SSE Control Reg : 88 */
{ REG_DWORD_SIZE, (x86_reg_type)(reg_sys | reg_simd), 0, "mxcsr" }, { REG_DWORD_SIZE, (x86_reg_type)(reg_sys | reg_simd), 0, "mxcsr" },
/* REG_TR_INDEX : Task Register : 89 */ /* REG_TR_INDEX : Task Register : 89 */
{ 16 + 64, reg_sys, 0, "tr" }, { 16 + 64, reg_sys, 0, "tr" },
/* REG_CSMSR_INDEX : SYSENTER_CS_MSR : 90 */ /* REG_CSMSR_INDEX : SYSENTER_CS_MSR : 90 */
{ REG_DWORD_SIZE, reg_sys, 0, "cs_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "cs_msr" },
/* REG_ESPMSR_INDEX : SYSENTER_ESP_MSR : 91 */ /* REG_ESPMSR_INDEX : SYSENTER_ESP_MSR : 91 */
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */ /* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
{ 0 } { 0,reg_undef,0,{0} }
}; };
static size_t sz_regtable = NUM_X86_REGS + 1; static size_t sz_regtable = NUM_X86_REGS + 1;

View File

@ -89,7 +89,7 @@ enum x86_options { /* these can be ORed together */
opt_none= 0, opt_none= 0,
opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */ opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */
opt_16_bit=2, /* 16-bit/DOS disassembly */ opt_16_bit=2, /* 16-bit/DOS disassembly */
opt_att_mnemonics=4, /* use AT&T syntax names for alternate opcode mnemonics */ opt_att_mnemonics=4 /* use AT&T syntax names for alternate opcode mnemonics */
}; };
/* ========================================= Instruction Representation */ /* ========================================= Instruction Representation */
@ -133,12 +133,12 @@ enum x86_reg_type { /* NOTE: these may be ORed together */
/* x86_reg_t : an X86 CPU register */ /* x86_reg_t : an X86 CPU register */
struct x86_reg_t { struct x86_reg_t {
char name[MAX_REGNAME]; char name[MAX_REGNAME];
enum x86_reg_type type; /* what register is used for */ enum x86_reg_type type; /* what register is used for */
unsigned int size; /* size of register in bytes */ unsigned int size; /* size of register in bytes */
unsigned int id; /* register ID #, for quick compares */ unsigned int id; /* register ID #, for quick compares */
unsigned int alias; /* ID of reg this is an alias for */ unsigned int alias; /* ID of reg this is an alias for */
unsigned int shift; /* amount to shift aliased reg by */ unsigned int shift; /* amount to shift aliased reg by */
x86_reg_t * aliased_reg( ) { x86_reg_t * aliased_reg( ) {
x86_reg_t * reg = (x86_reg_t * )calloc( sizeof(x86_reg_t), 1 ); x86_reg_t * reg = (x86_reg_t * )calloc( sizeof(x86_reg_t), 1 );
reg->x86_reg_from_id( id ); reg->x86_reg_from_id( id );
@ -158,11 +158,11 @@ typedef struct {
/* x86_absolute_t : an X86 segment:offset address (descriptor) */ /* x86_absolute_t : an X86 segment:offset address (descriptor) */
typedef struct { typedef struct {
unsigned short segment; /* loaded directly into CS */ unsigned short segment; /* loaded directly into CS */
union { union {
unsigned short off16; /* loaded directly into IP */ unsigned short off16; /* loaded directly into IP */
uint32_t off32; /* loaded directly into EIP */ uint32_t off32; /* loaded directly into EIP */
} offset; } offset;
} x86_absolute_t; } x86_absolute_t;
enum x86_op_type { /* mutually exclusive */ enum x86_op_type { /* mutually exclusive */
@ -250,39 +250,43 @@ struct x86_op_flags { /* ORed together, but segs are mutually exclusive */
/* x86_op_t : an X86 instruction operand */ /* x86_op_t : an X86 instruction operand */
struct x86_op_t{ struct x86_op_t{
friend struct x86_insn_t; friend struct x86_insn_t;
enum x86_op_type type; /* operand type */ enum x86_op_type type; /* operand type */
enum x86_op_datatype datatype; /* operand size */ enum x86_op_datatype datatype; /* operand size */
enum x86_op_access access; /* operand access [RWX] */ enum x86_op_access access; /* operand access [RWX] */
x86_op_flags flags; /* misc flags */ x86_op_flags flags; /* misc flags */
union { union {
/* sizeof will have to work on these union members! */ /* sizeof will have to work on these union members! */
/* immediate values */ /* immediate values */
char sbyte; char sbyte;
short sword; short sword;
int32_t sdword; int32_t sdword;
qword_t sqword; qword_t sqword;
unsigned char byte; unsigned char byte;
unsigned short word; unsigned short word;
uint32_t dword; uint32_t dword;
qword_t qword; qword_t qword;
float sreal; float sreal;
double dreal; double dreal;
/* misc large/non-native types */ /* misc large/non-native types */
unsigned char extreal[10]; unsigned char extreal[10];
unsigned char bcd[10]; unsigned char bcd[10];
qword_t dqword[2]; qword_t dqword[2];
unsigned char simd[16]; unsigned char simd[16];
unsigned char fpuenv[28]; unsigned char fpuenv[28];
/* offset from segment */ /* offset from segment */
uint32_t offset; uint32_t offset;
x86_reg_t reg; /* ID of CPU register */ /* ID of CPU register */
char relative_near; /* offsets from current insn */ x86_reg_t reg;
int32_t relative_far; /* offsets from current insn */
x86_absolute_t absolute; /* segment:offset */ char relative_near;
x86_ea_t expression; /* effective address [expression] */ int32_t relative_far;
} data; /* segment:offset */
/* this is needed to make formatting operands more sane */ x86_absolute_t absolute;
void * insn; /* pointer to x86_insn_t owning operand */ /* effective address [expression] */
x86_ea_t expression;
} data;
/* this is needed to make formatting operands more sane */
void * insn; /* pointer to x86_insn_t owning operand */
size_t size() size_t size()
{ {
return operand_size(); return operand_size();
@ -301,6 +305,7 @@ struct x86_op_t{
x86_op_t * copy() x86_op_t * copy()
{ {
x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 ); x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 );
if ( op ) { if ( op ) {
memcpy( op, this, sizeof(x86_op_t) ); memcpy( op, this, sizeof(x86_op_t) );
} }
@ -439,7 +444,7 @@ enum x86_insn_note {
insn_note_smm = 2, /* "" in System Management Mode */ insn_note_smm = 2, /* "" in System Management Mode */
insn_note_serial = 4, /* Serializing instruction */ insn_note_serial = 4, /* Serializing instruction */
insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */ insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */
insn_note_nosuffix = 16, /* Does not have size suffix in att-style formatting */ insn_note_nosuffix = 16 /* Does not have size suffix in att-style formatting */
}; };
/* This specifies what effects the instruction has on the %eflags register */ /* This specifies what effects the instruction has on the %eflags register */
@ -520,7 +525,6 @@ enum x86_insn_prefix {
/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */ /* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */
/* FOREACH types: these are used to limit the foreach results to /* FOREACH types: these are used to limit the foreach results to
* operands which match a certain "type" (implicit or explicit) * operands which match a certain "type" (implicit or explicit)
* or which are accessed in certain ways (e.g. read or write). Note * or which are accessed in certain ways (e.g. read or write). Note
@ -572,8 +576,8 @@ private:
void x86_oplist_append(x86_oplist_t *op); void x86_oplist_append(x86_oplist_t *op);
public: public:
/* information about the instruction */ /* information about the instruction */
uint32_t addr; /* load address */ uint32_t addr; /* load address */
uint32_t offset; /* offset into file/buffer */ uint32_t offset; /* offset into file/buffer */
x86_insn_group group; /* meta-type, e.g. INS_EXEC */ x86_insn_group group; /* meta-type, e.g. INS_EXEC */
x86_insn_type type; /* type, e.g. INS_BRANCH */ x86_insn_type type; /* type, e.g. INS_BRANCH */
x86_insn_note note; /* note, e.g. RING0 */ x86_insn_note note; /* note, e.g. RING0 */
@ -604,29 +608,36 @@ public:
void *block; /* code block containing this insn */ void *block; /* code block containing this insn */
void *function; /* function containing this insn */ void *function; /* function containing this insn */
int tag; /* tag the insn as seen/processed */ int tag; /* tag the insn as seen/processed */
x86_op_t * x86_operand_new(); x86_op_t *x86_operand_new();
size_t x86_operand_count( enum x86_op_foreach_type type ); /* convenience routine: returns count of operands matching 'type' */
size_t x86_operand_count( enum x86_op_foreach_type type );
/* accessor functions for the operands */ /* accessor functions for the operands */
x86_op_t * x86_operand_1st( ); x86_op_t * x86_operand_1st( );
x86_op_t * x86_operand_2nd( ); x86_op_t * x86_operand_2nd( );
x86_op_t * x86_operand_3rd( ); x86_op_t * x86_operand_3rd( );
x86_op_t * get_dest(); x86_op_t * get_dest();
int32_t x86_get_rel_offset( ); int32_t x86_get_rel_offset( );
x86_op_t * x86_get_branch_target( ); x86_op_t * x86_get_branch_target( );
x86_op_t * x86_get_imm( ); x86_op_t * x86_get_imm( );
uint8_t * x86_get_raw_imm( );
/* More accessor fuctions, this time for user-defined info... */ /* More accessor fuctions, this time for user-defined info... */
void x86_set_insn_addr( uint32_t addr ); uint8_t * x86_get_raw_imm( );
int x86_format_mnemonic( char *buf, int len, enum x86_asm_format format); /* set the address (usually RVA) of the insn */
int x86_format_insn( char *buf, int len, enum x86_asm_format); void x86_set_insn_addr( uint32_t addr );
void x86_oplist_free( ); /* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
int x86_format_mnemonic( char *buf, int len, enum x86_asm_format format);
int x86_format_insn( char *buf, int len, enum x86_asm_format);
void x86_oplist_free( );
/* returns 0 if an instruction is invalid, 1 if valid */
bool is_valid( ); bool is_valid( );
uint32_t x86_get_address( ); uint32_t x86_get_address( );
void make_invalid(unsigned char *buf); void make_invalid(unsigned char *buf);
/* instruction tagging: these routines allow the programmer to mark /* instruction tagging: these routines allow the programmer to mark
* instructions as "seen" in a DFS, for example. libdisasm does not use * instructions as "seen" in a DFS, for example. libdisasm does not use
* the tag field.*/ * the tag field.*/
/* set insn->tag to 1 */
void x86_tag_insn( ); void x86_tag_insn( );
/* return insn->tag */
int x86_insn_is_tagged(); int x86_insn_is_tagged();
/* set insn->tag to 0 */ /* set insn->tag to 0 */
void x86_untag_insn(); void x86_untag_insn();
@ -803,9 +814,10 @@ public:
* void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg ) * void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
* where 'alias_reg' is a reg operand and 'output_reg' is filled with the * where 'alias_reg' is a reg operand and 'output_reg' is filled with the
* register that the operand is an alias for */ * register that the operand is an alias for */
//#define x86_get_aliased_reg( alias_reg, output_reg ) \ /*
// 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 Instruction Representation */
/* Invariant instructions are used for generating binary signatures; /* Invariant instructions are used for generating binary signatures;

View File

@ -52,7 +52,7 @@ unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len,
/* copy enough bytes for disassembly into buffer : this /* copy enough bytes for disassembly into buffer : this
* helps prevent buffer overruns at the end of a file */ * helps prevent buffer overruns at the end of a file */
memset( bytes, 0, MAX_INSTRUCTION_SIZE ); memset( bytes, 0, MAX_INSTRUCTION_SIZE );
memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE) ? len : memcpy( bytes, &buf[offset], (len < MAX_INSTRUCTION_SIZE) ? len :
MAX_INSTRUCTION_SIZE ); MAX_INSTRUCTION_SIZE );
/* actually do the disassembly */ /* actually do the disassembly */
@ -104,7 +104,7 @@ unsigned int X86_Disasm::x86_disasm_range( unsigned char *buf, uint32_t buf_rva,
bytes++; /* try next byte */ bytes++; /* try next byte */
} }
insn.x86_oplist_free(); insn.x86_oplist_free();
} }
return( count ); return( count );
@ -127,9 +127,9 @@ static int32_t internal_resolver( x86_op_t *op, x86_insn_t *insn ){
if ( x86_optype_is_address(op->type) ) { if ( x86_optype_is_address(op->type) ) {
next_addr = op->data.sdword; next_addr = op->data.sdword;
} else if ( op->type == op_relative_near ) { } else if ( op->type == op_relative_near ) {
next_addr = insn->addr + insn->size + op->data.relative_near; next_addr = insn->addr + insn->size + op->data.relative_near;
} else if ( op->type == op_relative_far ) { } else if ( op->type == op_relative_far ) {
next_addr = insn->addr + insn->size + op->data.relative_far; next_addr = insn->addr + insn->size + op->data.relative_far;
} }
return( next_addr ); return( next_addr );
} }
@ -141,7 +141,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
x86_insn_t insn; x86_insn_t insn;
x86_op_t *op; x86_op_t *op;
int32_t next_addr; int32_t next_addr;
uint32_t next_offset; int32_t next_offset;
unsigned int size, count = 0, bytes = 0, cont = 1; unsigned int size, count = 0, bytes = 0, cont = 1;
while ( cont && bytes < buf_len ) { while ( cont && bytes < buf_len ) {
@ -175,8 +175,8 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
if (next_addr != -1 ) { if (next_addr != -1 ) {
next_offset = next_addr - buf_rva; next_offset = next_addr - buf_rva;
/* if offset is in this buffer... */ /* if offset is in this buffer... */
if ( next_offset >= 0 && if ( next_offset >= 0 && next_offset < int(buf_len) )
next_offset < buf_len ) { {
/* go ahead and disassemble */ /* go ahead and disassemble */
count += x86_disasm_forward( buf, count += x86_disasm_forward( buf,
buf_len, buf_len,
@ -197,24 +197,24 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
cont = 0; cont = 0;
} }
insn.x86_oplist_free( ); insn.x86_oplist_free( );
} }
return( count ); return( count );
} }
/* invariant instruction representation */ /* invariant instruction representation */
size_t x86_invariant_disasm( unsigned char *buf, int buf_len, size_t x86_invariant_disasm( unsigned char *buf, int buf_len,
x86_invariant_t *inv ){ x86_invariant_t *inv ){
if (! buf || ! buf_len || ! inv ) { if (! buf || ! buf_len || ! inv ) {
return(0); 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 ) { size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ) {
if (! buf || ! buf_len ) { if (! buf || ! buf_len ) {
return(0); return(0);
} }
return ia32_disasm_size(buf, buf_len); return ia32_disasm_size(buf, buf_len);
} }

View File

@ -46,7 +46,7 @@
} \ } \
} while( 0 ) } while( 0 )
static char *prefix_strings[] = { static const char *prefix_strings[] = {
"", /* no prefix */ "", /* no prefix */
"repz ", /* the trailing spaces make it easy to prepend to mnemonic */ "repz ", /* the trailing spaces make it easy to prepend to mnemonic */
"repnz ", "repnz ",
@ -115,7 +115,7 @@ static void get_operand_data_str( x86_op_t *op, char *str, int len ){
static void get_operand_regtype_str( int regtype, char *str, int len ) static void get_operand_regtype_str( int regtype, char *str, int len )
{ {
static struct { static struct {
char *name; const char *name;
int value; int value;
} operand_regtypes[] = { } operand_regtypes[] = {
{"reg_gen" , 0x00001}, {"reg_gen" , 0x00001},
@ -284,7 +284,7 @@ static int format_expr( x86_ea_t *ea, char *buf, int len,
static int format_seg( x86_op_t *op, char *buf, int len, static int format_seg( x86_op_t *op, char *buf, int len,
enum x86_asm_format format ) { enum x86_asm_format format ) {
int len_orig = len; int len_orig = len;
char *reg = ""; const char *reg = "";
if (! op || ! buf || ! len || ! op->flags.whole) { if (! op || ! buf || ! len || ! op->flags.whole) {
return(0); return(0);
@ -295,8 +295,9 @@ static int format_seg( x86_op_t *op, char *buf, int len,
if (! (int) op->flags.op_seg) { if (! (int) op->flags.op_seg) {
return(0); return(0);
} }
uint16_t seg_ov=uint16_t(op->flags.op_seg)<<8;
switch (op->flags.op_seg) { switch (seg_ov)
{
case x86_op_flags::op_es_seg: reg = "es"; break; case x86_op_flags::op_es_seg: reg = "es"; break;
case x86_op_flags::op_cs_seg: reg = "cs"; break; case x86_op_flags::op_cs_seg: reg = "cs"; break;
case x86_op_flags::op_ss_seg: reg = "ss"; break; case x86_op_flags::op_ss_seg: reg = "ss"; break;
@ -328,9 +329,9 @@ static int format_seg( x86_op_t *op, char *buf, int len,
return( len_orig - len ); /* return length of appended string */ return( len_orig - len ); /* return length of appended string */
} }
static char *get_operand_datatype_str( x86_op_t *op ){ static const char *get_operand_datatype_str( x86_op_t *op ){
static char *types[] = { static const char *types[] = {
"sbyte", /* 0 */ "sbyte", /* 0 */
"sword", "sword",
"sqword", "sqword",
@ -405,7 +406,7 @@ static int format_insn_eflags_str( enum x86_flag_status flags, char *buf,
int len) { int len) {
static struct { static struct {
char *name; const char *name;
int value; int value;
} insn_flags[] = { } insn_flags[] = {
{ "carry_set ", 0x0001 }, { "carry_set ", 0x0001 },
@ -440,9 +441,9 @@ static int format_insn_eflags_str( enum x86_flag_status flags, char *buf,
return( len_orig - len ); return( len_orig - len );
} }
static char *get_insn_group_str( enum x86_insn_t::x86_insn_group gp ) { static const char *get_insn_group_str( enum x86_insn_t::x86_insn_group gp ) {
static char *types[] = { static const char *types[] = {
"", // 0 "", // 0
"controlflow",// 1 "controlflow",// 1
"arithmetic", // 2 "arithmetic", // 2
@ -467,10 +468,10 @@ static char *get_insn_group_str( enum x86_insn_t::x86_insn_group gp ) {
return types[gp]; return types[gp];
} }
static char *get_insn_type_str( enum x86_insn_type type ) { static const char *get_insn_type_str( enum x86_insn_type type ) {
static struct { static struct {
char *name; const char *name;
int value; int value;
} types[] = { } types[] = {
/* insn_controlflow */ /* insn_controlflow */
@ -592,8 +593,8 @@ static char *get_insn_type_str( enum x86_insn_type type ) {
return ""; return "";
} }
static char *get_insn_cpu_str( enum x86_insn_cpu cpu ) { static const char *get_insn_cpu_str( enum x86_insn_cpu cpu ) {
static char *intel[] = { static const char *intel[] = {
"", // 0 "", // 0
"8086", // 1 "8086", // 1
"80286", // 2 "80286", // 2
@ -620,8 +621,8 @@ static char *get_insn_cpu_str( enum x86_insn_cpu cpu ) {
return ""; return "";
} }
static char *get_insn_isa_str( enum x86_insn_isa isa ) { static const char *get_insn_isa_str( enum x86_insn_isa isa ) {
static char *subset[] = { static const char *subset[] = {
NULL, // 0 NULL, // 0
"General Purpose", // 1 "General Purpose", // 1
"Floating Point", // 2 "Floating Point", // 2
@ -880,11 +881,11 @@ static int format_operand_xml( x86_op_t *op, x86_insn_t *insn, char *buf,
return( strlen( buf ) ); return( strlen( buf ) );
} }
static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf, static int format_operand_raw( x86_op_t *op, x86_insn_t */*insn*/, char *buf,
int len){ int len){
char str[MAX_OP_RAW_STRING]; char str[MAX_OP_RAW_STRING];
char *datatype = get_operand_datatype_str(op); const char *datatype = get_operand_datatype_str(op);
switch (op->type) { switch (op->type) {
case op_register: case op_register:
@ -1042,7 +1043,7 @@ char * x86_op_t::format( enum x86_asm_format format ) {
static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) { static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
int size = 0; int size = 0;
char *suffix; const char *suffix;
if (! insn || ! buf || ! len ) if (! insn || ! buf || ! len )
return(0); return(0);
@ -1094,7 +1095,6 @@ static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
return ( strlen( buf ) ); return ( strlen( buf ) );
} }
/** format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
enum x86_asm_format format){ enum x86_asm_format format){
char str[MAX_OP_STRING]; char str[MAX_OP_STRING];
@ -1137,7 +1137,7 @@ static int format_insn_note(x86_insn_t *insn, char *buf, int len){
return( len_orig - len ); return( len_orig - len );
} }
static int format_raw_insn( x86_insn_t *insn, char *buf, int len ){ static int format_raw_insn( x86_insn_t *insn, char *buf, size_t len ){
struct op_string opstr = { buf, len }; struct op_string opstr = { buf, len };
int i; int i;

View File

@ -17,7 +17,6 @@ int x86_insn_is_valid( x86_insn_t *insn ) {
return 0; return 0;
} }
/** \returns false if an instruction is invalid, true if valid */
bool x86_insn_t::is_valid( ) bool x86_insn_t::is_valid( )
{ {
if ( this && this->type != insn_invalid && this->size > 0 ) if ( this && this->type != insn_invalid && this->size > 0 )
@ -203,13 +202,12 @@ size_t x86_op_t::operand_size() {
return(4); /* default size */ return(4); /* default size */
} }
/** set the address (usually RVA) of the insn */
void x86_insn_t::x86_set_insn_addr( uint32_t _addr ) { void x86_insn_t::x86_set_insn_addr( uint32_t _addr ) {
addr = _addr; addr = _addr;
} }
void x86_insn_t::x86_set_insn_offset( unsigned int offset ){ void x86_insn_t::x86_set_insn_offset( unsigned int _offset ){
offset = offset; offset = _offset;
} }
void x86_insn_t::x86_set_insn_function( void * func ){ void x86_insn_t::x86_set_insn_function( void * func ){
@ -220,7 +218,6 @@ void x86_insn_t::x86_set_insn_block( void * _block ){
block = _block; block = _block;
} }
/** set insn->tag to 1 */
void x86_insn_t::x86_tag_insn(){ void x86_insn_t::x86_tag_insn(){
tag = 1; tag = 1;
} }
@ -229,7 +226,6 @@ void x86_insn_t::x86_untag_insn(){
tag = 0; tag = 0;
} }
/** \return insn->tag */
int x86_insn_t::x86_insn_is_tagged(){ int x86_insn_t::x86_insn_is_tagged(){
return tag; return tag;
} }

View File

@ -4,31 +4,31 @@
void x86_insn_t::x86_oplist_append( x86_oplist_t *op ) { void x86_insn_t::x86_oplist_append( x86_oplist_t *op ) {
x86_oplist_t *list; x86_oplist_t *list;
assert(this); assert(this);
list = operands; list = operands;
if (! list ) { if (! list ) {
operand_count = 1; operand_count = 1;
/* Note that we have no way of knowing if this is an /* Note that we have no way of knowing if this is an
* exlicit operand or not, since the caller fills * exlicit operand or not, since the caller fills
* the x86_op_t after we return. We increase the * the x86_op_t after we return. We increase the
* explicit count automatically, and ia32_insn_implicit_ops * explicit count automatically, and ia32_insn_implicit_ops
* decrements it */ * decrements it */
explicit_count = 1; explicit_count = 1;
operands = op; operands = op;
return;
}
/* get to end of list */
for ( ; list->next; list = list->next )
;
operand_count = operand_count + 1;
explicit_count = explicit_count + 1;
list->next = op;
return; return;
}
/* get to end of list */
for ( ; list->next; list = list->next )
;
operand_count = operand_count + 1;
explicit_count = explicit_count + 1;
list->next = op;
return;
} }
bool x86_insn_t::containsFlag(x86_eflags tofind, x86_flag_status in) bool x86_insn_t::containsFlag(x86_eflags tofind, x86_flag_status in)
@ -48,7 +48,7 @@ bool x86_insn_t::containsFlag(x86_eflags tofind, x86_flag_status in)
return (in & (insn_dir_set | insn_dir_clear))!=0; return (in & (insn_dir_set | insn_dir_clear))!=0;
case insn_eflag_sign: case insn_eflag_sign:
return (in & (insn_sign_set | insn_sign_clear | insn_zero_set_or_sign_ne_oflow | return (in & (insn_sign_set | insn_sign_clear | insn_zero_set_or_sign_ne_oflow |
insn_sign_eq_oflow | insn_sign_ne_oflow))!=0; insn_sign_eq_oflow | insn_sign_ne_oflow))!=0;
case insn_eflag_parity: case insn_eflag_parity:
return (in & (insn_parity_set | insn_parity_clear))!=0; return (in & (insn_parity_set | insn_parity_clear))!=0;
} }
@ -56,31 +56,31 @@ bool x86_insn_t::containsFlag(x86_eflags tofind, x86_flag_status in)
} }
x86_op_t * x86_insn_t::x86_operand_new( ) { x86_op_t * x86_insn_t::x86_operand_new( ) {
x86_oplist_t *op; x86_oplist_t *op;
assert(this); assert(this);
op = (x86_oplist_t *)calloc( sizeof(x86_oplist_t), 1 ); op = (x86_oplist_t *)calloc( sizeof(x86_oplist_t), 1 );
op->op.insn = this; op->op.insn = this;
x86_oplist_append( op ); x86_oplist_append( op );
return( &(op->op) ); return( &(op->op) );
} }
/** free the operand list associated with an instruction -- useful for /** free the operand list associated with an instruction -- useful for
* preventing memory leaks when free()ing an x86_insn_t */ * preventing memory leaks when free()ing an x86_insn_t */
void x86_insn_t::x86_oplist_free( ) void x86_insn_t::x86_oplist_free( )
{ {
x86_oplist_t *op, *list; x86_oplist_t *op, *list;
assert(this); assert(this);
for ( list = operands; list; ) { for ( list = operands; list; ) {
op = list; op = list;
list = list->next; list = list->next;
free(op); free(op);
} }
operands = NULL; operands = NULL;
operand_count = 0; operand_count = 0;
explicit_count = 0; explicit_count = 0;
return; return;
} }
/* ================================================== LIBDISASM API */ /* ================================================== LIBDISASM API */
@ -88,122 +88,121 @@ void x86_insn_t::x86_oplist_free( )
enum... yet one more confusing thing in the API */ enum... yet one more confusing thing in the API */
int x86_insn_t::x86_operand_foreach( x86_operand_fn func, void *arg, enum x86_op_foreach_type type ) int x86_insn_t::x86_operand_foreach( x86_operand_fn func, void *arg, enum x86_op_foreach_type type )
{ {
x86_oplist_t *list; x86_oplist_t *list;
char _explicit = 1, implicit = 1; char _explicit = 1, implicit = 1;
assert(this); assert(this);
if ( ! func ) { if ( ! func ) {
return 0; return 0;
} }
/* note: explicit and implicit can be ORed together to /* note: explicit and implicit can be ORed together to
* allow an "all" limited by access type, even though the * allow an "all" limited by access type, even though the
* user is stupid to do this since it is default behavior :) */ * user is stupid to do this since it is default behavior :) */
if ( (type & op_explicit) && ! (type & op_implicit) ) { if ( (type & op_explicit) && ! (type & op_implicit) ) {
implicit = 0; implicit = 0;
} }
if ( (type & op_implicit) && ! (type & op_explicit) ) { if ( (type & op_implicit) && ! (type & op_explicit) ) {
_explicit = 0; _explicit = 0;
}
type = (x86_op_foreach_type)((int)type & 0x0F); /* mask out explicit/implicit operands */
for ( list = operands; list; list = list->next ) {
if (! implicit && (list->op.flags.op_implied) ) {
/* operand is implicit */
continue;
} }
if (! _explicit && ! (list->op.flags.op_implied) ) { type = (x86_op_foreach_type)((int)type & 0x0F); /* mask out explicit/implicit operands */
/* operand is not implicit */
continue; for ( list = operands; list; list = list->next ) {
if (! implicit && (list->op.flags.op_implied) ) {
/* operand is implicit */
continue;
}
if (! _explicit && ! (list->op.flags.op_implied) ) {
/* operand is not implicit */
continue;
}
switch ( type ) {
case op_any:
break;
case op_dest:
if (! (list->op.access & op_write) ) {
continue;
}
break;
case op_src:
if (! (list->op.access & op_read) ) {
continue;
}
break;
case op_ro:
if (! (list->op.access & op_read) ||
(list->op.access & op_write ) ) {
continue;
}
break;
case op_wo:
if (! (list->op.access & op_write) ||
(list->op.access & op_read ) ) {
continue;
}
break;
case op_xo:
if (! (list->op.access & op_execute) ) {
continue;
}
break;
case op_rw:
if (! (list->op.access & op_write) ||
! (list->op.access & op_read ) ) {
continue;
}
break;
case op_implicit: case op_explicit: /* make gcc happy */
break;
}
/* any non-continue ends up here: invoke the callback */
(*func)( &list->op, this, arg );
} }
switch ( type ) { return 1;
case op_any:
break;
case op_dest:
if (! (list->op.access & op_write) ) {
continue;
}
break;
case op_src:
if (! (list->op.access & op_read) ) {
continue;
}
break;
case op_ro:
if (! (list->op.access & op_read) ||
(list->op.access & op_write ) ) {
continue;
}
break;
case op_wo:
if (! (list->op.access & op_write) ||
(list->op.access & op_read ) ) {
continue;
}
break;
case op_xo:
if (! (list->op.access & op_execute) ) {
continue;
}
break;
case op_rw:
if (! (list->op.access & op_write) ||
! (list->op.access & op_read ) ) {
continue;
}
break;
case op_implicit: case op_explicit: /* make gcc happy */
break;
}
/* any non-continue ends up here: invoke the callback */
(*func)( &list->op, this, arg );
}
return 1;
} }
static void count_operand( x86_op_t *op, x86_insn_t *insn, void *arg ) { static void count_operand( x86_op_t */*op*/, x86_insn_t */*insn*/, void *arg ) {
size_t * count = (size_t *) arg; size_t * count = (size_t *) arg;
*count = *count + 1; *count = *count + 1;
} }
/** convenience routine: returns count of operands matching 'type' */
size_t x86_insn_t::x86_operand_count( enum x86_op_foreach_type type ) { size_t x86_insn_t::x86_operand_count( enum x86_op_foreach_type type ) {
size_t count = 0; size_t count = 0;
/* save us a list traversal for common counts... */ /* save us a list traversal for common counts... */
if ( type == op_any ) { if ( type == op_any ) {
return operand_count; return operand_count;
} else if ( type == op_explicit ) { } else if ( type == op_explicit ) {
return explicit_count; return explicit_count;
} }
x86_operand_foreach( count_operand, &count, type ); x86_operand_foreach( count_operand, &count, type );
return count; return count;
} }
/* accessor functions */ /* accessor functions */
x86_op_t * x86_insn_t::x86_operand_1st() { x86_op_t * x86_insn_t::x86_operand_1st() {
if (! explicit_count ) { if (! explicit_count ) {
return NULL; return NULL;
} }
return &(operands->op); return &(operands->op);
} }
x86_op_t * x86_insn_t::x86_operand_2nd( ) { x86_op_t * x86_insn_t::x86_operand_2nd( ) {
if ( explicit_count < 2 ) { if ( explicit_count < 2 ) {
return NULL; return NULL;
} }
return &(operands->next->op); return &(operands->next->op);
} }
x86_op_t * x86_insn_t::x86_operand_3rd( ) { x86_op_t * x86_insn_t::x86_operand_3rd( ) {
if ( explicit_count < 3 ) { if ( explicit_count < 3 ) {
return NULL; return NULL;
} }
return &(operands->next->next->op); return &(operands->next->next->op);
} }

View File

@ -8,8 +8,9 @@ IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
ADD_DEFINITIONS(/W4) ADD_DEFINITIONS(/W4)
ELSE() ELSE()
#-D_GLIBCXX_DEBUG
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG " ) #--coverage SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} " ) #--coverage
ENDIF() ENDIF()
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH}) SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
@ -17,6 +18,7 @@ SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
FIND_PACKAGE(LLVM) FIND_PACKAGE(LLVM)
FIND_PACKAGE(Boost) FIND_PACKAGE(Boost)
IF(dcc_build_tests) IF(dcc_build_tests)
enable_testing()
FIND_PACKAGE(GMock) FIND_PACKAGE(GMock)
ENDIF() ENDIF()
@ -30,9 +32,7 @@ INCLUDE_DIRECTORIES(
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${LLVM_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS}
) )
set(dcc_LIB_SOURCES
set(dcc_SOURCES
src/dcc.cpp
src/ast.cpp src/ast.cpp
src/backend.cpp src/backend.cpp
src/bundle.cpp src/bundle.cpp
@ -46,6 +46,7 @@ set(dcc_SOURCES
src/frontend.cpp src/frontend.cpp
src/graph.cpp src/graph.cpp
src/hlicode.cpp src/hlicode.cpp
src/hltype.cpp
src/machine_x86.cpp src/machine_x86.cpp
src/icode.cpp src/icode.cpp
src/idioms.cpp src/idioms.cpp
@ -70,6 +71,9 @@ set(dcc_SOURCES
src/udm.cpp src/udm.cpp
src/BasicBlock.cpp src/BasicBlock.cpp
) )
set(dcc_SOURCES
src/dcc.cpp
)
set(dcc_HEADERS set(dcc_HEADERS
include/ast.h include/ast.h
include/bundle.h include/bundle.h
@ -105,8 +109,12 @@ set(dcc_HEADERS
SOURCE_GROUP(Source FILES ${dcc_SOURCES}) SOURCE_GROUP(Source FILES ${dcc_SOURCES})
SOURCE_GROUP(Headers FILES ${dcc_HEADERS}) SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS}) ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
TARGET_LINK_LIBRARIES(dcc_original disasm_s ${REQ_LLVM_LIBRARIES}) ADD_DEPENDENCIES(dcc_original dcc_lib)
TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES})
if(dcc_build_tests) if(dcc_build_tests)
ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(src)
endif() endif()

View File

@ -114,7 +114,7 @@ public:
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc); void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
BB * rmJMP(int marker, BB *pBB); BB * rmJMP(int marker, BB *pBB);
void genDU1(); void genDU1();
int findBBExps(LOCAL_ID &locals, Function *f); void findBBExps(LOCAL_ID &locals, Function *f);
bool valid() {return 0==(flg & INVALID_BB); } bool valid() {return 0==(flg & INVALID_BB); }
bool wasTraversedAtLevel(int l) const {return traversed==l;} bool wasTraversedAtLevel(int l) const {return traversed==l;}
ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond); ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond);

View File

@ -57,33 +57,33 @@ enum opLoc
enum eLLFlags enum eLLFlags
{ {
B =0x0000001, /* uint8_t operands (value implicitly used) */ B = 0x0000001, /* uint8_t operands (value implicitly used) */
I =0x0000002, /* Immed. source */ I = 0x0000002, /* Immed. source */
NOT_HLL =0x0000004, /* Not HLL inst. */ NOT_HLL = 0x0000004, /* Not HLL inst. */
FLOAT_OP =0x0000008, /* ESC or WAIT */ FLOAT_OP = 0x0000008, /* ESC or WAIT */
SEG_IMMED =0x0000010, /* Number is relocated segment value */ SEG_IMMED = 0x0000010, /* Number is relocated segment value */
IMPURE =0x0000020, /* Instruction modifies code */ IMPURE = 0x0000020, /* Instruction modifies code */
WORD_OFF =0x0000040, /* Inst has uint16_t offset ie.could be address */ WORD_OFF = 0x0000040, /* Inst has uint16_t offset ie.could be address */
TERMINATES =0x0000080, /* Instruction terminates program */ TERMINATES = 0x0000080, /* Instruction terminates program */
CASE =0x0000100, /* Label as case part of switch */ CASE = 0x0000100, /* Label as case part of switch */
SWITCH =0x0000200, /* Treat indirect JMP as switch stmt */ SWITCH = 0x0000200, /* Treat indirect JMP as switch stmt */
TARGET =0x0000400, /* Jump target */ TARGET = 0x0000400, /* Jump target */
SYNTHETIC =0x0000800, /* Synthetic jump instruction */ SYNTHETIC = 0x0000800, /* Synthetic jump instruction */
NO_LABEL =0x0001000, /* Immed. jump cannot be linked to a label */ NO_LABEL = 0x0001000, /* Immed. jump cannot be linked to a label */
NO_CODE =0x0002000, /* Hole in Icode array */ NO_CODE = 0x0002000, /* Hole in Icode array */
SYM_USE =0x0004000, /* Instruction uses a symbol */ SYM_USE = 0x0004000, /* Instruction uses a symbol */
SYM_DEF =0x0008000, /* Instruction defines a symbol */ SYM_DEF = 0x0008000, /* Instruction defines a symbol */
NO_SRC =0x0010000, /* Opcode takes no source */ NO_SRC = 0x0010000, /* Opcode takes no source */
NO_OPS =0x0020000, /* Opcode takes no operands */ NO_OPS = 0x0020000, /* Opcode takes no operands */
IM_OPS =0x0040000, /* Opcode takes implicit operands */ IM_OPS = 0x0040000, /* Opcode takes implicit operands */
SRC_B =0x0080000, /* Source operand is uint8_t (dest is uint16_t) */ SRC_B = 0x0080000, /* Source operand is uint8_t (dest is uint16_t) */
HLL_LABEL =0x0100000, /* Icode has a high level language label */ HLL_LABEL = 0x0100000, /* Icode has a high level language label */
IM_DST =0x0200000, /* Implicit DST for opcode (SIGNEX) */ IM_DST = 0x0200000, /* Implicit DST for opcode (SIGNEX) */
IM_SRC =0x0400000, /* Implicit SRC for opcode (dx:ax) */ IM_SRC = 0x0400000, /* Implicit SRC for opcode (dx:ax) */
IM_TMP_DST =0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */ IM_TMP_DST = 0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */
JMP_ICODE =0x1000000, /* Jmp dest immed.op converted to icode index */ JMP_ICODE = 0x1000000, /* Jmp dest immed.op converted to icode index */
JX_LOOP =0x2000000, /* Cond jump is part of loop conditional exp */ JX_LOOP = 0x2000000, /* Cond jump is part of loop conditional exp */
REST_STK =0x4000000 /* Stack needs to be restored after CALL */ REST_STK = 0x4000000 /* Stack needs to be restored after CALL */
#define ICODEMASK 0x0FF00FF /* Masks off parser flags */ #define ICODEMASK 0x0FF00FF /* Masks off parser flags */
}; };
/* Types of icodes */ /* Types of icodes */
@ -237,7 +237,7 @@ enum hlFirst
/* HIGH_LEVEL icodes opcodes */ /* HIGH_LEVEL icodes opcodes */
enum hlIcode enum hlIcode
{ {
HLI_INVALID, HLI_INVALID=0,
HLI_ASSIGN, /* := */ HLI_ASSIGN, /* := */
HLI_CALL, /* Call procedure */ HLI_CALL, /* Call procedure */
HLI_JCOND, /* Conditional jump */ HLI_JCOND, /* Conditional jump */

View File

@ -122,12 +122,12 @@ public:
std::bitset<32> liveOut; /* Registers that may be used in successors */ std::bitset<32> liveOut; /* Registers that may be used in successors */
bool liveAnal; /* Procedure has been analysed already */ bool liveAnal; /* Procedure has been analysed already */
Function(void *ty=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0), Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0) hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
{ {
} }
public: public:
static Function *Create(void *ty=0,int Linkage=0,const std::string &nm="",void *module=0) static Function *Create(void *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
{ {
Function *r=new Function(ty); Function *r=new Function(ty);
r->name = nm; r->name = nm;

View File

@ -13,7 +13,7 @@ struct STKFRAME : public SymbolTableCommon<STKSYM>
int16_t maxOff; /* Maximum offset in stack frame*/ int16_t maxOff; /* Maximum offset in stack frame*/
int cb; /* Number of bytes in arguments */ int cb; /* Number of bytes in arguments */
int numArgs; /* No. of arguments in the table*/ int numArgs; /* No. of arguments in the table*/
void adjustForArgType(int numArg_, hlType actType_); void adjustForArgType(size_t numArg_, hlType actType_);
STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0) STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
{ {

View File

@ -123,10 +123,10 @@ struct BinaryOperator : public COND_EXPR
} }
static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r); static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r);
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r); static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
virtual COND_EXPR *inverse(); virtual COND_EXPR *inverse() const;
virtual COND_EXPR *clone(); virtual COND_EXPR *clone() const;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym); virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
COND_EXPR *lhs() COND_EXPR *lhs()
@ -157,8 +157,8 @@ struct UnaryOperator : public COND_EXPR
{ {
condOp op; condOp op;
COND_EXPR *unaryExp; COND_EXPR *unaryExp;
virtual COND_EXPR *inverse(); virtual COND_EXPR *inverse() const;
virtual COND_EXPR *clone(); virtual COND_EXPR *clone() const;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr) static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
{ {

View File

@ -20,7 +20,7 @@
#include "bundle.h" #include "bundle.h"
#include "Procedure.h" #include "Procedure.h"
#include "BasicBlock.h" #include "BasicBlock.h"
struct Project; class Project;
/* CALL GRAPH NODE */ /* CALL GRAPH NODE */
struct CALL_GRAPH struct CALL_GRAPH
{ {
@ -116,7 +116,7 @@ void parse (CALL_GRAPH * *); /* parser.c */
int strSize (uint8_t *, char); /* parser.c */ int strSize (uint8_t *, char); /* parser.c */
//void disassem(int pass, Function * pProc); /* disassem.c */ //void disassem(int pass, Function * pProc); /* disassem.c */
void interactDis(Function * initProc, int initIC); /* disassem.c */ void interactDis(Function *, int initIC); /* disassem.c */
bool JmpInst(llIcode opcode); /* idioms.c */ bool JmpInst(llIcode opcode); /* idioms.c */
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */ queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */

View File

@ -25,12 +25,13 @@ struct LOCAL_ID;
struct BB; struct BB;
struct Function; struct Function;
struct STKFRAME; struct STKFRAME;
struct CIcodeRec; class CIcodeRec;
struct ICODE; struct ICODE;
struct bundle; struct bundle;
typedef std::list<ICODE>::iterator iICODE; typedef std::list<ICODE>::iterator iICODE;
typedef std::list<ICODE>::reverse_iterator riICODE; typedef std::list<ICODE>::reverse_iterator riICODE;
typedef boost::iterator_range<iICODE> rCODE; typedef boost::iterator_range<iICODE> rCODE;
extern std::bitset<32> duReg[30]; extern std::bitset<32> duReg[30];
/* uint8_t and uint16_t registers */ /* uint8_t and uint16_t registers */
@ -65,7 +66,7 @@ struct CallType : public HlTypeSupport
void placeStkArg(COND_EXPR *exp, int pos); void placeStkArg(COND_EXPR *exp, int pos);
virtual COND_EXPR * toId(); virtual COND_EXPR * toId();
public: public:
bool removeRegFromLong(eReg regi, LOCAL_ID *locId) bool removeRegFromLong(eReg /*regi*/, LOCAL_ID */*locId*/)
{ {
printf("CallType : removeRegFromLong not supproted"); printf("CallType : removeRegFromLong not supproted");
return false; return false;
@ -106,34 +107,16 @@ public:
hlIcode opcode; /* hlIcode opcode */ hlIcode opcode; /* hlIcode opcode */
AssignType asgn; AssignType asgn;
CallType call; CallType call;
HlTypeSupport *get() HlTypeSupport *get();
{
switch(opcode)
{
case HLI_ASSIGN: return &asgn;
case HLI_RET:
case HLI_POP:
case HLI_JCOND:
case HLI_PUSH: return &exp;
case HLI_CALL: return &call;
default:
return 0;
}
}
void expr(COND_EXPR *e) void expr(COND_EXPR *e)
{ {
assert(e); assert(e);
exp.v=e; exp.v=e;
} }
void replaceExpr(COND_EXPR *e) void replaceExpr(COND_EXPR *e);
{
assert(e);
delete exp.v;
exp.v=e;
}
COND_EXPR * expr() { return exp.v;} COND_EXPR * expr() { return exp.v;}
const COND_EXPR * const expr() const { return exp.v;} const COND_EXPR * expr() const { return exp.v;}
void set(hlIcode i,COND_EXPR *e) void set(hlIcode i,COND_EXPR *e)
{ {
if(i!=HLI_RET) if(i!=HLI_RET)
@ -180,7 +163,7 @@ struct LLOperand
Function *proc; /* pointer to target proc (for CALL(F))*/ Function *proc; /* pointer to target proc (for CALL(F))*/
int cb; /* # actual arg bytes */ int cb; /* # actual arg bytes */
} proc; } proc;
LLOperand() : seg(rUNDEF),segValue(0),segOver(rUNDEF),regi(rUNDEF),off(0),opz(0) LLOperand() : seg(rUNDEF),segOver(rUNDEF),segValue(0),regi(rUNDEF),off(0),opz(0)
{ {
proc.proc=0; proc.proc=0;
proc.cb=0; proc.cb=0;
@ -214,6 +197,11 @@ struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
{ {
protected: protected:
uint32_t flg; /* icode flags */ uint32_t flg; /* icode flags */
// LLOperand &get(int idx)
// {
// assert(idx<size());
// return getOperand(idx);
// }
LLOperand m_src; /* source operand */ LLOperand m_src; /* source operand */
public: public:
int codeIdx; /* Index into cCode.code */ int codeIdx; /* Index into cCode.code */
@ -456,7 +444,7 @@ public:
{ {
return hl()->call.newStkArg(exp,opcode,pproc); return hl()->call.newStkArg(exp,opcode,pproc);
} }
ICODE() : m_ll(this),type(NOT_SCANNED),Parent(0),loc_ip(0),invalid(false) ICODE() : m_ll(this),Parent(0),invalid(false),type(NOT_SCANNED),loc_ip(0)
{ {
} }
public: public:
@ -485,6 +473,6 @@ public:
void SetInBB(rCODE &rang, BB* pnewBB); void SetInBB(rCODE &rang, BB* pnewBB);
bool labelSrch(uint32_t target, uint32_t &pIndex); bool labelSrch(uint32_t target, uint32_t &pIndex);
iterator labelSrch(uint32_t target); iterator labelSrch(uint32_t target);
ICODE * GetIcode(int ip); ICODE * GetIcode(size_t ip);
bool alreadyDecoded(uint32_t target); bool alreadyDecoded(uint32_t target);
}; };

11
include/loader.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
class ILoader
{
};
class LoaderManger
{
};

View File

@ -99,7 +99,7 @@ struct ID
void setLocalName(int i) void setLocalName(int i)
{ {
char buf[32]; char buf[32];
sprintf (buf, "loc%ld", i); sprintf (buf, "loc%d", i);
name=buf; name=buf;
} }
}; };
@ -121,7 +121,7 @@ public:
std::vector<ID>::iterator end() {return id_arr.end();} std::vector<ID>::iterator end() {return id_arr.end();}
int newByteWordReg(hlType t, eReg regi); int newByteWordReg(hlType t, eReg regi);
int newByteWordStk(hlType t, int off, uint8_t regOff); int newByteWordStk(hlType t, int off, uint8_t regOff);
int newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t); int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t);
int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_); int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_);
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off); int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset); int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);

View File

@ -6,55 +6,40 @@
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include "symtab.h" #include "symtab.h"
#include "BinaryImage.h" #include "BinaryImage.h"
struct Function; #include "Procedure.h"
struct SourceMachine; class SourceMachine;
struct CALL_GRAPH; struct CALL_GRAPH;
class IProject
{
virtual PROG *binary()=0;
virtual const std::string & project_name() const =0;
virtual const std::string & binary_path() const =0;
};
class Project : public IProject
{
static Project *s_instance;
std::string m_fname;
std::string m_project_name;
public:
typedef llvm::iplist<Function> FunctionListType; typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction; typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction; typedef FunctionListType::iterator ilFunction;
struct Project
{
SYMTAB symtab; /* Global symbol table */ SYMTAB symtab; /* Global symbol table */
std::string m_fname;
FunctionListType pProcList; FunctionListType pProcList;
CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */ CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
PROG prog; /* Loaded program image parameters */ PROG prog; /* Loaded program image parameters */
Project() {}
// no copies // no copies
Project(const Project&) = delete; Project(const Project&) = delete;
const Project &operator=(const Project & l) =delete; const Project &operator=(const Project & l) =delete;
// only moves // only moves
Project(Project && l) Project(); // default constructor,
{
m_fname =l.m_fname;
size_t before=l.pProcList.size();
pProcList.splice(pProcList.end(),l.pProcList);
callGraph=l.callGraph;
l.m_fname.clear();
l.pProcList.clear();
l.callGraph=0;
assert(before==pProcList.size());
}
Project &operator=(Project && l)
{
if(this == &l)
return *this;
m_fname =l.m_fname;
size_t before=l.pProcList.size();
pProcList.splice(pProcList.end(),l.pProcList);
callGraph=l.callGraph;
l.m_fname.clear();
l.pProcList.clear();
l.callGraph=0;
assert(before==pProcList.size());
return *this;
}
public: public:
void create(const std::string & a);
const std::string &project_name() const {return m_project_name;}
const std::string &binary_path() const {return m_fname;}
ilFunction funcIter(Function *to_find); ilFunction funcIter(Function *to_find);
ilFunction findByEntry(uint32_t entry); ilFunction findByEntry(uint32_t entry);
ilFunction createFunction(); ilFunction createFunction();
@ -72,6 +57,7 @@ public:
SourceMachine *machine(); SourceMachine *machine();
protected: protected:
void initialize();
void writeGlobSymTable(); void writeGlobSymTable();
}; };
//extern Project g_proj; //extern Project g_proj;

View File

@ -4,9 +4,9 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include "error.h" #include "error.h"
/* Extracts reg bits from middle of mod-reg-rm uint8_t */
#define REG(x) ((uint8_t)(x & 0x38) >> 3) #define REG(x) ((uint8_t)(x & 0x38) >> 3)
//#define LH(p) ((int)((uint8_t *)(p))[0] + ((int)((uint8_t *)(p))[1] << 8))
struct ICODE; struct ICODE;
/* Extracts reg bits from middle of mod-reg-rm uint8_t */
extern eErrorId scan(uint32_t ip, ICODE &p); extern eErrorId scan(uint32_t ip, ICODE &p);

View File

@ -27,7 +27,7 @@ struct SYM : public SymbolCommon
{ {
} }
int32_t label; /* physical address (20 bit) */ uint32_t label; /* physical address (20 bit) */
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */ uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
}; };
/* STACK FRAME */ /* STACK FRAME */
@ -60,13 +60,13 @@ class SymbolTableCommon : public std::vector<T>
public: public:
typedef typename std::vector<T>::iterator iterator; typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator; typedef typename std::vector<T>::const_iterator const_iterator;
iterator findByLabel(int lab) iterator findByLabel(uint32_t lab)
{ {
auto iter = std::find_if(this->begin(),this->end(), auto iter = std::find_if(this->begin(),this->end(),
[lab](T &s)->bool {return s.label==lab;}); [lab](T &s)->bool {return s.label==lab;});
return iter; return iter;
} }
const_iterator findByLabel(int lab) const const_iterator findByLabel(uint32_t lab) const
{ {
auto iter = std::find_if(this->begin(),this->end(), auto iter = std::find_if(this->begin(),this->end(),
[lab](const T &s)->bool {return s.label==lab;}); [lab](const T &s)->bool {return s.label==lab;});
@ -102,9 +102,9 @@ struct SYMTABLE
enum tableType /* The table types */ enum tableType /* The table types */
{ {
Label=0, /* The label table */ Label=0, /* The label table */
Comment, /* The comment table */ Comment /* The comment table */
NUM_TABLE_TYPES /* Number of entries: must be last */
}; };
constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be last */
void createSymTables(void); void createSymTables(void);
void destroySymTables(void); void destroySymTables(void);

View File

@ -53,9 +53,9 @@ struct eDuVal
USE=2, USE=2,
VAL=4 VAL=4
}; };
int def :1; /* Variable was first defined than used */ uint8_t def :1; /* Variable was first defined than used */
int use :1; /* Variable was first used than defined */ uint8_t use :1; /* Variable was first used than defined */
int val :1; /* Variable has an initial value. 2 cases: uint8_t val :1; /* Variable has an initial value. 2 cases:
* 1. When variable is used first (ie. global) * 1. When variable is used first (ie. global)
* 2. When a value is moved into the variable * 2. When a value is moved into the variable
* for the first time. */ * for the first time. */
@ -65,7 +65,7 @@ struct eDuVal
use = x&USE; use = x&USE;
val = x&VAL; val = x&VAL;
} }
bool isUSE_VAL() {return use&&val;} /* Use and Val */ bool isUSE_VAL() {return use&&val;} /* Use and Val */
}; };
static constexpr const char * hlTypes[13] = { static constexpr const char * hlTypes[13] = {
"", "char", "unsigned char", "int", "unsigned int", "", "char", "unsigned char", "int", "unsigned int",
@ -88,6 +88,12 @@ struct TypeContainer
return 2; return 2;
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
return 1; return 1;
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
return 4;
case TYPE_FLOAT:
return 4;
default:
return ~0;
} }
return 0; return 0;
} }

View File

@ -9,7 +9,7 @@
using namespace std; using namespace std;
using namespace boost; using namespace boost;
BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore) BB *BB::Create(void */*ctx*/, const string &/*s*/, Function *parent, BB */*insertBefore*/)
{ {
BB *pnewBB = new BB; BB *pnewBB = new BB;
pnewBB->Parent = parent; pnewBB->Parent = parent;
@ -81,14 +81,14 @@ static const char *const s_loopType[] = {"noLoop", "while", "repeat", "loop", "f
void BB::display() void BB::display()
{ {
printf("\nnode type = %s, ", s_nodeType[nodeType]); printf("\nnode type = %s, ", s_nodeType[nodeType]);
printf("start = %ld, length = %ld, #out edges = %ld\n", begin()->loc_ip, size(), edges.size()); printf("start = %d, length = %zd, #out edges = %zd\n", begin()->loc_ip, size(), edges.size());
for (size_t i = 0; i < edges.size(); i++) for (size_t i = 0; i < edges.size(); i++)
{ {
if(edges[i].BBptr==0) if(edges[i].BBptr==0)
printf(" outEdge[%2d] = Unlinked out edge to %d\n",i, edges[i].ip); printf(" outEdge[%2zd] = Unlinked out edge to %d\n",i, edges[i].ip);
else else
printf(" outEdge[%2d] = %d\n",i, edges[i].BBptr->begin()->loc_ip); printf(" outEdge[%2zd] = %d\n",i, edges[i].BBptr->begin()->loc_ip);
} }
} }
/***************************************************************************** /*****************************************************************************
@ -101,29 +101,29 @@ void BB::displayDfs()
traversed = DFS_DISP; traversed = DFS_DISP;
printf("node type = %s, ", s_nodeType[nodeType]); printf("node type = %s, ", s_nodeType[nodeType]);
printf("start = %ld, length = %ld, #in-edges = %ld, #out-edges = %ld\n", printf("start = %d, length = %zd, #in-edges = %zd, #out-edges = %zd\n",
begin()->loc_ip, size(), inEdges.size(), edges.size()); begin()->loc_ip, size(), inEdges.size(), edges.size());
printf("dfsFirst = %ld, dfsLast = %ld, immed dom = %ld\n", printf("dfsFirst = %d, dfsLast = %d, immed dom = %d\n",
dfsFirstNum, dfsLastNum, dfsFirstNum, dfsLastNum,
immedDom == MAX ? -1 : immedDom); immedDom == MAX ? -1 : immedDom);
printf("loopType = %s, loopHead = %ld, latchNode = %ld, follow = %ld\n", printf("loopType = %s, loopHead = %d, latchNode = %d, follow = %d\n",
s_loopType[loopType], s_loopType[loopType],
loopHead == MAX ? -1 : loopHead, loopHead == MAX ? -1 : loopHead,
latchNode == MAX ? -1 : latchNode, latchNode == MAX ? -1 : latchNode,
loopFollow == MAX ? -1 : loopFollow); loopFollow == MAX ? -1 : loopFollow);
printf ("ifFollow = %ld, caseHead = %ld, caseTail = %ld\n", printf ("ifFollow = %d, caseHead = %d, caseTail = %d\n",
ifFollow == MAX ? -1 : ifFollow, ifFollow == MAX ? -1 : ifFollow,
caseHead == MAX ? -1 : caseHead, caseHead == MAX ? -1 : caseHead,
caseTail == MAX ? -1 : caseTail); caseTail == MAX ? -1 : caseTail);
if (nodeType == INTERVAL_NODE) if (nodeType == INTERVAL_NODE)
printf("corresponding interval = %ld\n", correspInt->numInt); printf("corresponding interval = %d\n", correspInt->numInt);
else else
{ {
int edge_idx=0; int edge_idx=0;
for(BB *node : inEdges) for(BB *node : inEdges)
{ {
printf (" inEdge[%ld] = %ld\n", edge_idx, node->begin()->loc_ip); printf (" inEdge[%d] = %d\n", edge_idx, node->begin()->loc_ip);
edge_idx++; edge_idx++;
} }
} }
@ -132,9 +132,9 @@ void BB::displayDfs()
for(TYPEADR_TYPE &edg : edges) for(TYPEADR_TYPE &edg : edges)
{ {
if (nodeType == INTERVAL_NODE) if (nodeType == INTERVAL_NODE)
printf(" outEdge[%ld] = %ld\n", i, edg.BBptr->correspInt->numInt); printf(" outEdge[%d] = %d\n", i, edg.BBptr->correspInt->numInt);
else else
printf(" outEdge[%d] = %ld\n", i, edg.BBptr->begin()->loc_ip); printf(" outEdge[%d] = %d\n", i, edg.BBptr->begin()->loc_ip);
++i; ++i;
} }
printf("----\n"); printf("----\n");

View File

@ -1,7 +1,13 @@
SET(dcc_test_SOURCES tests/comwrite.cpp) SET(dcc_test_SOURCES
tests/comwrite.cpp
tests/project.cpp
tests/loader.cpp
)
include_directories(${GMOCK_INCLUDE_DIRS} ${GMOCK_ROOT}/gtest/include) include_directories(${GMOCK_INCLUDE_DIRS} ${GMOCK_ROOT}/gtest/include)
enable_testing()
add_executable(tester ${dcc_test_SOURCES}) add_executable(tester ${dcc_test_SOURCES})
target_link_libraries(tester ADD_DEPENDENCIES(tester dcc_lib)
target_link_libraries(tester dcc_lib disasm_s
${GMOCK_BOTH_LIBRARIES} ${REQ_LLVM_LIBRARIES}) ${GMOCK_BOTH_LIBRARIES} ${REQ_LLVM_LIBRARIES})
add_test(dcc-tests tester) add_test(dcc-tests tester)

View File

@ -13,7 +13,6 @@
#include "dcc.h" #include "dcc.h"
#include "machine_x86.h" #include "machine_x86.h"
#include "project.h" #include "project.h"
extern Project g_proj;
using namespace std; using namespace std;
// Conditional operator symbols in C. Index by condOp enumeration type // Conditional operator symbols in C. Index by condOp enumeration type
static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ", static const char * const condOpSym[] = { " <= ", " < ", " == ", " != ", " > ", " >= ",
@ -122,8 +121,8 @@ COND_EXPR *GlobalVariable::Create(int16_t segValue, int16_t off)
newExp = new COND_EXPR(IDENTIFIER); newExp = new COND_EXPR(IDENTIFIER);
newExp->expr.ident.idType = GLOB_VAR; newExp->expr.ident.idType = GLOB_VAR;
adr = opAdr(segValue, off); adr = opAdr(segValue, off);
auto i=g_proj.getSymIdxByAdd(adr); auto i=Project::get()->getSymIdxByAdd(adr);
if ( not g_proj.validSymIdx(i) ) if ( not Project::get()->validSymIdx(i) )
{ {
printf ("Error, glob var not found in symtab\n"); printf ("Error, glob var not found in symtab\n");
delete newExp; delete newExp;
@ -477,7 +476,7 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc)
switch (expr->expr.ident.idType) switch (expr->expr.ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
return (g_proj.symbolSize(expr->expr.ident.idNode.globIdx)); return (Project::get()->symbolSize(expr->expr.ident.idNode.globIdx));
case REGISTER: case REGISTER:
if (expr->expr.ident.regiType == BYTE_REG) if (expr->expr.ident.regiType == BYTE_REG)
return (1); return (1);
@ -501,6 +500,9 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc)
return (2); return (2);
} /* eos */ } /* eos */
break; break;
default:
fprintf(stderr,"hlTypeSize queried for Unkown type %d \n",expr->m_type);
break;
} }
return 2; // CC: is this correct? return 2; // CC: is this correct?
} }
@ -540,7 +542,7 @@ hlType COND_EXPR::expType(Function * pproc) const
switch (expr.ident.idType) switch (expr.ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
return g_proj.symbolType(expr.ident.idNode.globIdx); return Project::get()->symbolType(expr.ident.idNode.globIdx);
case REGISTER: case REGISTER:
if (expr.ident.regiType == BYTE_REG) if (expr.ident.regiType == BYTE_REG)
return (TYPE_BYTE_SIGN); return (TYPE_BYTE_SIGN);
@ -580,23 +582,26 @@ void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *t
eReg otherRegi; /* high or low part of long register */ eReg otherRegi; /* high or low part of long register */
switch (tree->m_type) { switch (tree->m_type) {
case BOOLEAN_OP: case BOOLEAN_OP:
break; break;
case POST_INC: case POST_DEC: case POST_INC: case POST_DEC:
case PRE_INC: case PRE_DEC: case PRE_INC: case PRE_DEC:
case NEGATION: case ADDRESSOF: case NEGATION: case ADDRESSOF:
case DEREFERENCE: case DEREFERENCE:
break; break;
case IDENTIFIER: case IDENTIFIER:
ident = &tree->expr.ident; ident = &tree->expr.ident;
if (ident->idType == LONG_VAR) if (ident->idType == LONG_VAR)
{ {
otherRegi = otherLongRegi (regi, ident->idNode.longIdx, locId); otherRegi = otherLongRegi (regi, ident->idNode.longIdx, locId);
ident->idType = REGISTER; ident->idType = REGISTER;
ident->regiType = WORD_REG; ident->regiType = WORD_REG;
ident->idNode.regiIdx = locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi); ident->idNode.regiIdx = locId->newByteWordReg(TYPE_WORD_SIGN,otherRegi);
} }
break; break;
default:
fprintf(stderr,"performLongRemoval attemped on %d\n",tree->m_type);
break;
} }
} }
@ -634,154 +639,159 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
needBracket = true; needBracket = true;
switch (expr->m_type) switch (expr->m_type)
{ {
case BOOLEAN_OP: case BOOLEAN_OP:
outStr << "(";
outStr << walkCondExpr(expr->lhs(), pProc, numLoc);
outStr << condOpSym[expr->op()];
outStr << walkCondExpr(expr->rhs(), pProc, numLoc);
outStr << ")";
break;
case NEGATION:
if (expr->expr.unaryExp->m_type == IDENTIFIER)
{
needBracket = false;
outStr << "!";
}
else
outStr << "! (";
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
if (needBracket == true)
outStr << ")";
break;
case ADDRESSOF:
if (expr->expr.unaryExp->m_type == IDENTIFIER)
{
needBracket = false;
outStr << "&";
}
else
outStr << "&(";
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
if (needBracket == true)
outStr << ")";
break;
case DEREFERENCE:
outStr << "*";
if (expr->expr.unaryExp->m_type == IDENTIFIER)
needBracket = false;
else
outStr << "("; outStr << "(";
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc); outStr << walkCondExpr(expr->lhs(), pProc, numLoc);
if (needBracket == true) outStr << condOpSym[expr->op()];
outStr << walkCondExpr(expr->rhs(), pProc, numLoc);
outStr << ")"; outStr << ")";
break; break;
case POST_INC: case NEGATION:
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "++"; if (expr->expr.unaryExp->m_type == IDENTIFIER)
break; {
needBracket = false;
outStr << "!";
}
else
outStr << "! (";
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
if (needBracket == true)
outStr << ")";
break;
case POST_DEC: case ADDRESSOF:
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "--"; if (expr->expr.unaryExp->m_type == IDENTIFIER)
break; {
needBracket = false;
outStr << "&";
}
else
outStr << "&(";
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
if (needBracket == true)
outStr << ")";
break;
case PRE_INC: case DEREFERENCE:
outStr << "++"<< walkCondExpr (expr->expr.unaryExp, pProc, numLoc); outStr << "*";
break; if (expr->expr.unaryExp->m_type == IDENTIFIER)
needBracket = false;
else
outStr << "(";
outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
if (needBracket == true)
outStr << ")";
break;
case PRE_DEC: case POST_INC:
outStr << "--"<< walkCondExpr (expr->expr.unaryExp, pProc, numLoc); outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "++";
break; break;
case IDENTIFIER: case POST_DEC:
std::ostringstream o; outStr << walkCondExpr (expr->expr.unaryExp, pProc, numLoc) << "--";
switch (expr->expr.ident.idType) break;
case PRE_INC:
outStr << "++"<< walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
break;
case PRE_DEC:
outStr << "--"<< walkCondExpr (expr->expr.unaryExp, pProc, numLoc);
break;
case IDENTIFIER:
{ {
case GLOB_VAR: std::ostringstream o;
o << g_proj.symtab[expr->expr.ident.idNode.globIdx].name; switch (expr->expr.ident.idType)
break;
case REGISTER:
id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];
if (id->name[0] == '\0') /* no name */
{ {
id->setLocalName(++(*numLoc)); case GLOB_VAR:
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; "; o << Project::get()->symtab[expr->expr.ident.idNode.globIdx].name;
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n"; break;
} case REGISTER:
if (id->hasMacro) id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];
o << id->macro << "("<<id->name<<")"; if (id->name[0] == '\0') /* no name */
else {
o << id->name; id->setLocalName(++(*numLoc));
break; codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
}
if (id->hasMacro)
o << id->macro << "("<<id->name<<")";
else
o << id->name;
break;
case LOCAL_VAR: case LOCAL_VAR:
o << pProc->localId.id_arr[expr->expr.ident.idNode.localIdx].name; o << pProc->localId.id_arr[expr->expr.ident.idNode.localIdx].name;
break; break;
case PARAM: case PARAM:
psym = &pProc->args[expr->expr.ident.idNode.paramIdx]; psym = &pProc->args[expr->expr.ident.idNode.paramIdx];
if (psym->hasMacro) if (psym->hasMacro)
o << psym->macro<<"("<<psym->name<< ")"; o << psym->macro<<"("<<psym->name<< ")";
else else
o << psym->name; o << psym->name;
break; break;
case GLOB_VAR_IDX: case GLOB_VAR_IDX:
bwGlb = &pProc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].id.bwGlb; bwGlb = &pProc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].id.bwGlb;
o << (bwGlb->seg << 4) + bwGlb->off << "["<<Machine_X86::regName(bwGlb->regi)<<"]"; o << (bwGlb->seg << 4) + bwGlb->off << "["<<Machine_X86::regName(bwGlb->regi)<<"]";
break; break;
case CONSTANT: case CONSTANT:
if (expr->expr.ident.idNode.kte.kte < 1000) if (expr->expr.ident.idNode.kte.kte < 1000)
o << expr->expr.ident.idNode.kte.kte; o << expr->expr.ident.idNode.kte.kte;
else else
o << "0x"<<std::hex << expr->expr.ident.idNode.kte.kte; o << "0x"<<std::hex << expr->expr.ident.idNode.kte.kte;
break; break;
case STRING: case STRING:
o << getString (expr->expr.ident.idNode.strIdx); o << getString (expr->expr.ident.idNode.strIdx);
break; break;
case LONG_VAR: case LONG_VAR:
id = &pProc->localId.id_arr[expr->expr.ident.idNode.longIdx]; id = &pProc->localId.id_arr[expr->expr.ident.idNode.longIdx];
if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/ if (id->name[0] != '\0') /* STK_FRAME & REG w/name*/
o << id->name; o << id->name;
else if (id->loc == REG_FRAME) else if (id->loc == REG_FRAME)
{ {
id->setLocalName(++(*numLoc)); id->setLocalName(++(*numLoc));
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; "; codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" << codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" <<
Machine_X86::regName(id->id.longId.l) << " */\n"; Machine_X86::regName(id->id.longId.l) << " */\n";
o << id->name; o << id->name;
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str()); pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str());
} }
else /* GLB_FRAME */ else /* GLB_FRAME */
{ {
if (id->id.longGlb.regi == 0) /* not indexed */ if (id->id.longGlb.regi == 0) /* not indexed */
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]"; o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"]";
else if (id->id.longGlb.regi == rBX) else if (id->id.longGlb.regi == rBX)
o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]"; o << "[" << (id->id.longGlb.seg<<4) + id->id.longGlb.offH <<"][bx]";
} }
break; break;
case FUNCTION: case FUNCTION:
o << writeCall (expr->expr.ident.idNode.call.proc,*expr->expr.ident.idNode.call.args, pProc, numLoc); o << writeCall (expr->expr.ident.idNode.call.proc,*expr->expr.ident.idNode.call.args, pProc, numLoc);
break; break;
case OTHER: case OTHER:
off = expr->expr.ident.idNode.other.off; off = expr->expr.ident.idNode.other.off;
o << Machine_X86::regName(expr->expr.ident.idNode.other.seg)<< "["; o << Machine_X86::regName(expr->expr.ident.idNode.other.seg)<< "[";
o << Machine_X86::regName(expr->expr.ident.idNode.other.regi); o << Machine_X86::regName(expr->expr.ident.idNode.other.regi);
if (off < 0) if (off < 0)
o << "-"<< hexStr (-off); o << "-"<< hexStr (-off);
else if (off>0) else if (off>0)
o << "+"<< hexStr (off); o << "+"<< hexStr (off);
o << "]"; o << "]";
} /* eos */ } /* eos */
outStr << o.str(); outStr << o.str();
break; break;
}
default:
fprintf(stderr,"walkCondExpr attemped on %d\n",expr->m_type);
break;
} }
cCode.appendDecl(codeOut.str()); cCode.appendDecl(codeOut.str());
return outStr.str(); return outStr.str();
@ -796,21 +806,23 @@ COND_EXPR *COND_EXPR::clone() const
switch (m_type) switch (m_type)
{ {
case BOOLEAN_OP: case BOOLEAN_OP:
newExp = new COND_EXPR(*this); newExp = new COND_EXPR(*this);
newExp->boolExpr.lhs = lhs()->clone(); newExp->boolExpr.lhs = lhs()->clone();
newExp->boolExpr.rhs = rhs()->clone(); newExp->boolExpr.rhs = rhs()->clone();
break; break;
case NEGATION: case NEGATION:
case ADDRESSOF: case ADDRESSOF:
case DEREFERENCE: case DEREFERENCE:
newExp = new COND_EXPR(*this); newExp = new COND_EXPR(*this);
newExp->expr.unaryExp = expr.unaryExp->clone(); newExp->expr.unaryExp = expr.unaryExp->clone();
break; break;
case IDENTIFIER: case IDENTIFIER:
return new COND_EXPR(*this); return new COND_EXPR(*this);
default:
fprintf(stderr,"Clone attempt on unhandled type %d\n",m_type);
} }
return (newExp); return (newExp);
} }
@ -857,7 +869,7 @@ COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,const LOCAL_
return _expr; return _expr;
} }
} }
return false; return nullptr;
case BOOLEAN_OP: case BOOLEAN_OP:
temp = lhs()->insertSubTreeReg( _expr, regi, locsym); temp = lhs()->insertSubTreeReg( _expr, regi, locsym);
@ -884,11 +896,14 @@ COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,const LOCAL_
return this; return this;
} }
return nullptr; return nullptr;
default:
fprintf(stderr,"insertSubTreeReg attempt on unhandled type %d\n",m_type);
} }
return nullptr; return nullptr;
} }
COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym) COND_EXPR *BinaryOperator::insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym)
{ {
COND_EXPR *r; COND_EXPR *r;
r=m_lhs->insertSubTreeReg(_expr,regi,locsym); r=m_lhs->insertSubTreeReg(_expr,regi,locsym);
@ -957,6 +972,8 @@ COND_EXPR *COND_EXPR::insertSubTreeLongReg(COND_EXPR *_expr, int longIdx)
return this; return this;
} }
return nullptr; return nullptr;
default:
fprintf(stderr,"insertSubTreeLongReg attempt on unhandled type %d\n",m_type);
} }
return nullptr; return nullptr;
} }
@ -993,13 +1010,15 @@ void COND_EXPR::release()
case DEREFERENCE: case DEREFERENCE:
expr.unaryExp->release(); expr.unaryExp->release();
break; break;
default:
fprintf(stderr,"release attempt on unhandled type %d\n",m_type);
} }
delete (this); delete (this);
} }
/* Makes a copy of the given expression. Allocates newExp storage for each /* Makes a copy of the given expression. Allocates newExp storage for each
* node. Returns the copy. */ * node. Returns the copy. */
COND_EXPR *BinaryOperator::clone() COND_EXPR *BinaryOperator::clone() const
{ {
BinaryOperator* newExp=new BinaryOperator(m_op); /* Expression node copy */ BinaryOperator* newExp=new BinaryOperator(m_op); /* Expression node copy */
newExp->m_lhs = m_lhs->clone(); newExp->m_lhs = m_lhs->clone();
@ -1007,7 +1026,7 @@ COND_EXPR *BinaryOperator::clone()
return newExp; return newExp;
} }
COND_EXPR *BinaryOperator::inverse() COND_EXPR *BinaryOperator::inverse() const
{ {
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL, static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY, LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
@ -1030,6 +1049,8 @@ COND_EXPR *BinaryOperator::inverse()
res->m_lhs=m_lhs->inverse (); res->m_lhs=m_lhs->inverse ();
res->m_rhs=m_rhs->inverse (); res->m_rhs=m_rhs->inverse ();
return res; return res;
default:
fprintf(stderr,"BinaryOperator::inverse attempt on unhandled op %d\n",m_op);
} /* eos */ } /* eos */
assert(false); assert(false);
return res; return res;

View File

@ -178,11 +178,12 @@ static void writeHeader (std::ostream &_ios, char *fileName)
} }
// Note: Not currently called! // Note: Not currently called!
/* Checks the given icode to determine whether it has a label associated /** Checks the given icode to determine whether it has a label associated
* to it. If so, a goto is emitted to this label; otherwise, a new label * to it. If so, a goto is emitted to this label; otherwise, a new label
* is created and a goto is also emitted. * is created and a goto is also emitted.
* Note: this procedure is to be used when the label is to be forward on * Note: this procedure is to be used when the label is to be forward on
* the code; that is, the target code has not been traversed yet. */ * the code; that is, the target code has not been traversed yet. */
#if 0
static void emitFwdGotoLabel (ICODE * pt, int indLevel) static void emitFwdGotoLabel (ICODE * pt, int indLevel)
{ {
if ( not pt->ll()->testFlags(HLL_LABEL)) /* node hasn't got a lab */ if ( not pt->ll()->testFlags(HLL_LABEL)) /* node hasn't got a lab */
@ -193,7 +194,7 @@ static void emitFwdGotoLabel (ICODE * pt, int indLevel)
} }
cCode.appendCode( "%sgoto l%ld;\n", indentStr(indLevel), pt->ll()->hllLabNum); cCode.appendCode( "%sgoto l%ld;\n", indentStr(indLevel), pt->ll()->hllLabNum);
} }
#endif
/* Writes the procedure's declaration (including arguments), local variables, /* Writes the procedure's declaration (including arguments), local variables,
* and invokes the procedure that writes the code of the given record *hli */ * and invokes the procedure that writes the code of the given record *hli */

View File

@ -26,7 +26,7 @@ void strTable::addLabelBundle (int idx, int label)
if(at(idx).size()<4) if(at(idx).size()<4)
at(idx)=s; at(idx)=s;
else else
at(idx) = string(s)+at(idx).substr(4); at(idx) = string(s)+at(idx).substr(4);
} }

View File

@ -219,8 +219,8 @@ static uint8_t pattMainSmall[] =
0xFF, 0x36, WILD, WILD, /* Push argv */ 0xFF, 0x36, WILD, WILD, /* Push argv */
0xFF, 0x36, WILD, WILD, /* Push argc */ 0xFF, 0x36, WILD, WILD, /* Push argc */
0xE8, WILD, WILD /* call _main */ 0xE8, WILD, WILD /* call _main */
/* 0x50, /* push ax... not in Borland V3 */ // 0x50, /* push ax... not in Borland V3 */
/* 0xE8 /* call _exit */ // 0xE8 /* call _exit */
}; };
/* Num bytes from start pattern to the relative offset of main() */ /* Num bytes from start pattern to the relative offset of main() */
#define OFFMAINSMALL 13 #define OFFMAINSMALL 13
@ -232,9 +232,9 @@ static uint8_t pattMainMedium[] =
0xFF, 0x36, WILD, WILD, /* Push argv */ 0xFF, 0x36, WILD, WILD, /* Push argv */
0xFF, 0x36, WILD, WILD, /* Push argc */ 0xFF, 0x36, WILD, WILD, /* Push argc */
0x9A, WILD, WILD, WILD, WILD /* call far _main */ 0x9A, WILD, WILD, WILD, WILD /* call far _main */
/* 0x50 /* push ax */ // 0x50 /* push ax */
/* 0x0E, /* push cs NB not tested Borland */ // 0x0E, /* push cs NB not tested Borland */
/* 0xE8 /* call _exit */ // 0xE8 /* call _exit */
}; };
/* Num bytes from start pattern to the relative offset of main() */ /* Num bytes from start pattern to the relative offset of main() */
#define OFFMAINMEDIUM 13 #define OFFMAINMEDIUM 13
@ -248,8 +248,8 @@ static uint8_t pattMainCompact[] =
0xFF, 0x36, WILD, WILD, /* Push argv hi */ 0xFF, 0x36, WILD, WILD, /* Push argv hi */
0xFF, 0x36, WILD, WILD, /* Push argc */ 0xFF, 0x36, WILD, WILD, /* Push argc */
0xE8, WILD, WILD, /* call _main */ 0xE8, WILD, WILD, /* call _main */
/* 0x50, /* push ax */ // 0x50, /* push ax */
/* 0xE8 /* call _exit */ // 0xE8 /* call _exit */
}; };
/* Num bytes from start pattern to the relative offset of main() */ /* Num bytes from start pattern to the relative offset of main() */
#define OFFMAINCOMPACT 21 #define OFFMAINCOMPACT 21
@ -263,9 +263,9 @@ static uint8_t pattMainLarge[] =
0xFF, 0x36, WILD, WILD, /* Push argv hi */ 0xFF, 0x36, WILD, WILD, /* Push argv hi */
0xFF, 0x36, WILD, WILD, /* Push argc */ 0xFF, 0x36, WILD, WILD, /* Push argc */
0x9A, WILD, WILD, WILD, WILD /* call far _main */ 0x9A, WILD, WILD, WILD, WILD /* call far _main */
/* 0x50 /* push ax */ // 0x50 /* push ax */
/* 0x0E, /* push cs */ // 0x0E, /* push cs */
/* 0xE8 /* call _exit */ // 0xE8 /* call _exit */
}; };
/* Num bytes from start pattern to the relative offset of main() */ /* Num bytes from start pattern to the relative offset of main() */
#define OFFMAINLARGE 21 #define OFFMAINLARGE 21
@ -502,6 +502,8 @@ bool LibCheck(Function & pProc)
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
pProc.liveOut = duReg[rAL]; pProc.liveOut = duReg[rAL];
break; break;
default:
fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type);
/*** other types are not considered yet ***/ /*** other types are not considered yet ***/
} }
} }
@ -569,12 +571,12 @@ readFileSection(uint16_t* p, int len, FILE* f)
} }
/* The following two functions are dummies, since we don't call map() */ /* The following two functions are dummies, since we don't call map() */
void getKey(int i, uint8_t **keys) void getKey(int /*i*/, uint8_t **/*keys*/)
{ {
} }
void dispKey(int i) void dispKey(int /*i*/)
{ {
} }
@ -695,7 +697,7 @@ void STATE::checkStartup()
but decides the model required. Note: must do the far data models but decides the model required. Note: must do the far data models
(large and compact) before the others, since they are the same pattern (large and compact) before the others, since they are the same pattern
as near data, just more pushes at the start. */ as near data, just more pushes at the start. */
if(prog.cbImage>startOff+0x180+sizeof(pattMainLarge)) if(prog.cbImage>int(startOff+0x180+sizeof(pattMainLarge)))
{ {
if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i)) if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i))
{ {

View File

@ -244,6 +244,9 @@ void Function::writeProcComments(std::ostream &ostr)
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
ostr << " * Return value in registers dx:ax.\n"; ostr << " * Return value in registers dx:ax.\n";
break; break;
default:
fprintf(stderr,"Unknown retval type %d",this->retVal.type);
break;
} /* eos */ } /* eos */
} }

View File

@ -300,13 +300,12 @@ void Function::structLoops(derSeq *derivedG)
{ {
pred = intHead->inEdges[i]; pred = intHead->inEdges[i];
if (inInt(pred, intNodes) && isBackEdge(pred, intHead)) if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
{
if (! latchNode) if (! latchNode)
latchNode = pred; latchNode = pred;
else else if (pred->dfsLastNum > latchNode->dfsLastNum)
{ latchNode = pred;
if (pred->dfsLastNum > latchNode->dfsLastNum) }
latchNode = pred;
}
} }
/* Find nodes in the loop and the type of loop */ /* Find nodes in the loop and the type of loop */
@ -352,8 +351,7 @@ static bool successor (int s, int h, Function * pProc)
* case). */ * case). */
static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail) static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
{ {
int current, /* index to current node */ int current; /* index to current node */
i;
pBB->traversed = DFS_CASE; pBB->traversed = DFS_CASE;
current = pBB->dfsLastNum; current = pBB->dfsLastNum;
@ -374,44 +372,46 @@ static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
* has a case node. */ * has a case node. */
void Function::structCases() void Function::structCases()
{ {
int i, j;
BB * caseHeader; /* case header node */
int exitNode = NO_NODE; /* case exit node */ int exitNode = NO_NODE; /* case exit node */
nodeList caseNodes; /* temporary: list of nodes in case */ nodeList caseNodes; /* temporary: list of nodes in case */
/* Linear scan of the nodes in reverse dfsLast order, searching for /* Linear scan of the nodes in reverse dfsLast order, searching for
* case nodes */ * case nodes */
for (i = numBBs - 1; i >= 0; i--) for (int i = numBBs - 1; i >= 0; i--)
if (m_dfsLast[i]->nodeType == MULTI_BRANCH) {
{ if ((m_dfsLast[i]->nodeType != MULTI_BRANCH))
caseHeader = m_dfsLast[i]; continue;
BB * caseHeader = m_dfsLast[i];; /* case header node */
/* Find descendant node which has as immediate predecessor /* Find descendant node which has as immediate predecessor
* the current header node, and is not a successor. */ * the current header node, and is not a successor. */
for (j = i + 2; j < numBBs; j++) for (size_t j = i + 2; j < numBBs; j++)
{
if ((!successor(j, i, this)) && (m_dfsLast[j]->immedDom == i))
{ {
if ((!successor(j, i, this)) && if (exitNode == NO_NODE)
(m_dfsLast[j]->immedDom == i)) {
if (exitNode == NO_NODE) exitNode = j;
exitNode = j; }
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size()) else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
exitNode = j; exitNode = j;
} }
m_dfsLast[i]->caseTail = exitNode;
/* Tag nodes that belong to the case by recording the
* header field with caseHeader. */
insertList (caseNodes, i);
m_dfsLast[i]->caseHead = i;
for(TYPEADR_TYPE &pb : caseHeader->edges)
{
tagNodesInCase(pb.BBptr, caseNodes, i, exitNode);
}
//for (j = 0; j < caseHeader->edges[j]; j++)
// tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i, exitNode);
if (exitNode != NO_NODE)
m_dfsLast[exitNode]->caseHead = i;
} }
m_dfsLast[i]->caseTail = exitNode;
/* Tag nodes that belong to the case by recording the
* header field with caseHeader. */
insertList (caseNodes, i);
m_dfsLast[i]->caseHead = i;
for(TYPEADR_TYPE &pb : caseHeader->edges)
{
tagNodesInCase(pb.BBptr, caseNodes, i, exitNode);
}
//for (j = 0; j < caseHeader->edges[j]; j++)
// tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i, exitNode);
if (exitNode != NO_NODE)
m_dfsLast[exitNode]->caseHead = i;
}
} }
@ -432,7 +432,7 @@ static void flagNodes (nodeList &l, int f, Function * pProc)
void Function::structIfs () void Function::structIfs ()
{ {
int curr, /* Index for linear scan of nodes */ int curr, /* Index for linear scan of nodes */
desc, /* Index for descendant */ /*desc,*/ /* Index for descendant */
followInEdges, /* Largest # in-edges so far */ followInEdges, /* Largest # in-edges so far */
follow; /* Possible follow node */ follow; /* Possible follow node */
nodeList domDesc, /* List of nodes dominated by curr */ nodeList domDesc, /* List of nodes dominated by curr */
@ -454,7 +454,7 @@ void Function::structIfs ()
follow = 0; follow = 0;
/* Find all nodes that have this node as immediate dominator */ /* Find all nodes that have this node as immediate dominator */
for (desc = curr+1; desc < numBBs; desc++) for (size_t desc = curr+1; desc < numBBs; desc++)
{ {
if (m_dfsLast[desc]->immedDom == curr) if (m_dfsLast[desc]->immedDom == curr)
{ {
@ -603,7 +603,7 @@ void Function::compoundCond()
/* Traverse nodes in postorder, this way, the header node of a /* Traverse nodes in postorder, this way, the header node of a
* compound condition is analysed first */ * compound condition is analysed first */
for (int i = 0; i < this->numBBs; i++) for (size_t i = 0; i < this->numBBs; i++)
{ {
pbb = this->m_dfsLast[i]; pbb = this->m_dfsLast[i];
if (pbb->flg & INVALID_BB) if (pbb->flg & INVALID_BB)

View File

@ -114,7 +114,7 @@ static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i,
/* Eliminates all condition codes and generates new hlIcode instructions */ /* Eliminates all condition codes and generates new hlIcode instructions */
void Function::elimCondCodes () void Function::elimCondCodes ()
{ {
int i; // int i;
uint8_t use; /* Used flags bit vector */ uint8_t use; /* Used flags bit vector */
uint8_t def; /* Defined flags bit vector */ uint8_t def; /* Defined flags bit vector */
@ -122,15 +122,19 @@ void Function::elimCondCodes ()
COND_EXPR *rhs; /* Source operand */ COND_EXPR *rhs; /* Source operand */
COND_EXPR *lhs; /* Destination operand */ COND_EXPR *lhs; /* Destination operand */
COND_EXPR *_expr; /* Boolean expression */ COND_EXPR *_expr; /* Boolean expression */
BB * pBB; /* Pointer to BBs in dfs last ordering */ //BB * pBB; /* Pointer to BBs in dfs last ordering */
riICODE useAt; /* Instruction that used flag */ riICODE useAt; /* Instruction that used flag */
riICODE defAt; /* Instruction that defined flag */ riICODE defAt; /* Instruction that defined flag */
//lhs=rhs=_expr=0; //lhs=rhs=_expr=0;
for (i = 0; i < numBBs; i++) auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
for( BB * pBB : valid_reversed_bbs)
{ {
pBB = m_dfsLast[i];
if (pBB->flg & INVALID_BB) // for (size_t i = 0; i < numBBs; i++)
continue; /* Do not process invalid BBs */ // {
// pBB = m_dfsLast[i];
// if (pBB->flg & INVALID_BB)
// continue; /* Do not process invalid BBs */
// auto v(pBB | boost::adaptors::reversed); // auto v(pBB | boost::adaptors::reversed);
// for (const ICODE &useAt : v) // for (const ICODE &useAt : v)
// {} // {}
@ -245,11 +249,10 @@ void Function::elimCondCodes ()
* is not really meant to be a register that is used before defined). */ * is not really meant to be a register that is used before defined). */
void Function::genLiveKtes () void Function::genLiveKtes ()
{ {
int i;
BB * pbb; BB * pbb;
bitset<32> liveUse, def; bitset<32> liveUse, def;
for (i = 0; i < numBBs; i++) for (size_t i = 0; i < numBBs; i++)
{ {
liveUse.reset(); liveUse.reset();
def.reset(); def.reset();
@ -617,42 +620,45 @@ bool COND_EXPR::xClear (rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID
switch (m_type) switch (m_type)
{ {
case IDENTIFIER: case IDENTIFIER:
if (expr.ident.idType == REGISTER) if (expr.ident.idType == REGISTER)
{ {
regi= locId.id_arr[expr.ident.idNode.regiIdx].id.regi; regi= locId.id_arr[expr.ident.idNode.regiIdx].id.regi;
range_to_check.advance_begin(1); range_to_check.advance_begin(1);
auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level); auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level);
for (ICODE &i : all_valid_and_high_level_after_start) for (ICODE &i : all_valid_and_high_level_after_start)
if ((i.du.def & duReg[regi]).any()) if ((i.du.def & duReg[regi]).any())
return false; return false;
if (all_valid_and_high_level_after_start.end().base() != lastBBinst) if (all_valid_and_high_level_after_start.end().base() != lastBBinst)
return true;
return false;
}
else
return true; return true;
return false; /* else if (rhs->expr.ident.idType == LONG_VAR)
}
else
return true;
/* else if (rhs->expr.ident.idType == LONG_VAR)
{ {
missing all other identifiers **** missing all other identifiers ****
} */ } */
case BOOLEAN_OP: case BOOLEAN_OP:
if(0==rhs()) if(0==rhs())
return false; return false;
res = rhs()->xClear ( range_to_check, lastBBinst, locId); res = rhs()->xClear ( range_to_check, lastBBinst, locId);
if (res == false) if (res == false)
return false; return false;
if(0==lhs()) if(0==lhs())
return false; return false;
return lhs()->xClear ( range_to_check, lastBBinst, locId); return lhs()->xClear ( range_to_check, lastBBinst, locId);
case NEGATION:
case ADDRESSOF:
case DEREFERENCE:
if(0==expr.unaryExp)
return false;
return expr.unaryExp->xClear ( range_to_check, lastBBinst, locId);
default:
fprintf(stderr,"COND_EXPR::xClear unhandled type %d\n",m_type);
case NEGATION:
case ADDRESSOF:
case DEREFERENCE:
if(0==expr.unaryExp)
return false;
return expr.unaryExp->xClear ( range_to_check, lastBBinst, locId);
} /* eos */ } /* eos */
return false; return false;
} }
@ -677,7 +683,7 @@ bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCA
* whenever possible, and then places the actual argument on the procedure's * whenever possible, and then places the actual argument on the procedure's
* argument list. */ * argument list. */
/// @returns the type size of the stored Arg /// @returns the type size of the stored Arg
static int processCArg (Function * pp, Function * pProc, ICODE * picode, int numArgs) static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs)
{ {
COND_EXPR *_exp; COND_EXPR *_exp;
bool res; bool res;
@ -689,6 +695,7 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num
if (pp->flg & PROC_ISLIB) /* library function */ if (pp->flg & PROC_ISLIB) /* library function */
{ {
if (pp->args.numArgs > 0) if (pp->args.numArgs > 0)
{
if (pp->flg & PROC_VARARG) if (pp->flg & PROC_VARARG)
{ {
if (numArgs < pp->args.size()) if (numArgs < pp->args.size())
@ -696,6 +703,7 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num
} }
else else
adjustActArgType (_exp, pp->args[numArgs].type, pProc); adjustActArgType (_exp, pp->args[numArgs].type, pProc);
}
} }
else /* user function */ else /* user function */
{ {
@ -765,6 +773,9 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
break; break;
default:
fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode);
} }
} }
@ -831,7 +842,7 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
} }
int BB::findBBExps(LOCAL_ID &locals,Function *fnc) void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
{ {
bool res; bool res;
@ -907,12 +918,15 @@ int BB::findBBExps(LOCAL_ID &locals,Function *fnc)
} }
break; break;
/****case HLI_CALL: /* register arguments /****case HLI_CALL: // register arguments
newRegArg (pProc, picode, ticode); newRegArg (pProc, picode, ticode);
picode->invalidate(); picode->invalidate();
numHlIcodes--; numHlIcodes--;
break; */ break; */
} /* eos */ default:
fprintf(stderr,"unhandled BB::findBBExps target opcode %d\n",ticode->hl()->opcode);
} // eos
break; break;
case HLI_CALL: case HLI_CALL:
@ -953,8 +967,12 @@ int BB::findBBExps(LOCAL_ID &locals,Function *fnc)
picode->setAsgn(lhs, _exp); picode->setAsgn(lhs, _exp);
} }
break; break;
default:
fprintf(stderr,"unhandled BB::findBBExps HLI_CALL target opcode %d\n",ti_hl->opcode);
} /* eos */ } /* eos */
break; break;
default:
fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode);
} /* eos */ } /* eos */
} }
} }
@ -1009,6 +1027,8 @@ int BB::findBBExps(LOCAL_ID &locals,Function *fnc)
break; break;
case HLI_CALL: /*** missing ***/ case HLI_CALL: /*** missing ***/
break; break;
default:
fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode);
} /* eos */ } /* eos */
} }
break; break;
@ -1052,7 +1072,13 @@ int BB::findBBExps(LOCAL_ID &locals,Function *fnc)
picode->setAsgn(lhs, _exp); picode->setAsgn(lhs, _exp);
} }
break; break;
default:
fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode);
} /* eos */ } /* eos */
break;
default:
fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode);
} /* eos */ } /* eos */
} }
} }
@ -1115,7 +1141,7 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
{ {
if (_liveOut.any()) if (_liveOut.any())
{ {
int idx; // int idx;
bool isAx, isBx, isCx, isDx; bool isAx, isBx, isCx, isDx;
flg |= PROC_IS_FUNC; flg |= PROC_IS_FUNC;
isAx = _liveOut.test(rAX - rAX); isAx = _liveOut.test(rAX - rAX);
@ -1157,7 +1183,7 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
retVal.loc = REG_FRAME; retVal.loc = REG_FRAME;
retVal.id.longId.h = rDX; retVal.id.longId.h = rDX;
retVal.id.longId.l = rAX; retVal.id.longId.l = rAX;
idx = localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/); /*idx = */localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
localId.propLongId (rAX, rDX, "\0"); localId.propLongId (rAX, rDX, "\0");
} }
else if (isAx || isBx || isCx || isDx) /* uint16_t */ else if (isAx || isBx || isCx || isDx) /* uint16_t */
@ -1172,7 +1198,7 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
retVal.id.regi = rCX; retVal.id.regi = rCX;
else else
retVal.id.regi = rDX; retVal.id.regi = rDX;
idx = localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi); /*idx = */localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi);
} }
else if(isAL||isBL||isCL||isDL) else if(isAL||isBL||isCL||isDL)
{ {
@ -1186,7 +1212,7 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
retVal.id.regi = rCL; retVal.id.regi = rCL;
else else
retVal.id.regi = rDL; retVal.id.regi = rDL;
idx = localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi); /*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
} }
} }

View File

@ -9,11 +9,11 @@
#include <string.h> #include <string.h>
/* Global variables - extern to other modules */ /* Global variables - extern to other modules */
char *asm1_name, *asm2_name; /* Assembler output filenames */ extern char *asm1_name, *asm2_name; /* Assembler output filenames */
SYMTAB symtab; /* Global symbol table */ extern SYMTAB symtab; /* Global symbol table */
STATS stats; /* cfg statistics */ extern STATS stats; /* cfg statistics */
//PROG prog; /* programs fields */ //PROG prog; /* programs fields */
OPTION option; /* Command line options */ extern OPTION option; /* Command line options */
//Function * pProcList; /* List of procedures, topologically sort */ //Function * pProcList; /* List of procedures, topologically sort */
//Function * pLastProc; /* Pointer to last node in procedure list */ //Function * pLastProc; /* Pointer to last node in procedure list */
//FunctionListType pProcList; //FunctionListType pProcList;
@ -27,7 +27,6 @@ static void displayTotalStats(void);
* main * main
***************************************************************************/ ***************************************************************************/
#include <iostream> #include <iostream>
extern Project g_proj;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// llvm::MCOperand op=llvm::MCOperand::CreateImm(11); // llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
@ -56,9 +55,9 @@ int main(int argc, char *argv[])
* analysis, data flow etc. and outputs it to output file ready for * analysis, data flow etc. and outputs it to output file ready for
* re-compilation. * re-compilation.
*/ */
BackEnd(option.filename, g_proj.callGraph); BackEnd(option.filename, Project::get()->callGraph);
g_proj.callGraph->write(); Project::get()->callGraph->write();
if (option.Stats) if (option.Stats)
displayTotalStats(); displayTotalStats();
@ -153,8 +152,8 @@ displayTotalStats ()
/* Displays final statistics for the complete program */ /* Displays final statistics for the complete program */
{ {
printf ("\nFinal Program Statistics\n"); printf ("\nFinal Program Statistics\n");
printf (" Total number of low-level Icodes : %ld\n", stats.totalLL); printf (" Total number of low-level Icodes : %d\n", stats.totalLL);
printf (" Total number of high-level Icodes: %ld\n", stats.totalHL); printf (" Total number of high-level Icodes: %d\n", stats.totalHL);
printf (" Total reduction of instructions : %2.2f%%\n", 100.0 - printf (" Total reduction of instructions : %2.2f%%\n", 100.0 -
(stats.totalHL * 100.0) / stats.totalLL); (stats.totalHL * 100.0) / stats.totalLL);
} }

View File

@ -94,7 +94,7 @@ struct POSSTACK_ENTRY
Function * pProc; /* A pointer to a PROCEDURE structure */ Function * pProc; /* A pointer to a PROCEDURE structure */
} ; } ;
static vector<POSSTACK_ENTRY> posStack; /* position stack */ static vector<POSSTACK_ENTRY> posStack; /* position stack */
static uint8_t iPS; /* Index into the stack */ //static uint8_t iPS; /* Index into the stack */
// These are "curses equivalent" functions. (Used to use curses for all this, // These are "curses equivalent" functions. (Used to use curses for all this,
@ -552,7 +552,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
/**************************************************************************** /****************************************************************************
* formatRM * formatRM
***************************************************************************/ ***************************************************************************/
static void formatRM(std::ostringstream &p, uint32_t flg, const LLOperand &pm) static void formatRM(std::ostringstream &p, uint32_t /*flg*/, const LLOperand &pm)
{ {
//char seg[4]; //char seg[4];
@ -627,14 +627,14 @@ static char *strHex(uint32_t d)
static char buf[10]; static char buf[10];
d &= 0xFFFF; d &= 0xFFFF;
sprintf(buf, "0%lX%s", d, (d > 9)? "h": ""); sprintf(buf, "0%X%s", d, (d > 9)? "h": "");
return (buf + (buf[1] <= '9')); return (buf + (buf[1] <= '9'));
} }
/**************************************************************************** /****************************************************************************
* interactDis - interactive disassembler * * interactDis - interactive disassembler *
****************************************************************************/ ****************************************************************************/
void interactDis(Function * initProc, int initIC) void interactDis(Function * /*initProc*/, int /*initIC*/)
{ {
printf("Sorry - interactive disasassembler option not available for Unix\n"); printf("Sorry - interactive disasassembler option not available for Unix\n");
return; return;
@ -643,7 +643,7 @@ void interactDis(Function * initProc, int initIC)
/* Handle the floating point opcodes (icode iESC) */ /* Handle the floating point opcodes (icode iESC) */
void LLInst::flops(std::ostringstream &out) void LLInst::flops(std::ostringstream &out)
{ {
char bf[30]; //char bf[30];
uint8_t op = (uint8_t)src().getImm2(); uint8_t op = (uint8_t)src().getImm2();
/* Note that op is set to the escape number, e.g. /* Note that op is set to the escape number, e.g.

View File

@ -3,14 +3,20 @@
* Loads a program into simulated main memory and builds the procedure list. * Loads a program into simulated main memory and builds the procedure list.
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#define __STDC_FORMAT_MACROS
#include "dcc.h" #include "dcc.h"
#include "disassem.h" #include "disassem.h"
#include <stdio.h> #include <stdio.h>
#include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <malloc.h> /* For malloc, free, realloc */ #include <malloc.h> /* For malloc, free, realloc */
#include "project.h" #include "project.h"
class Loader
{
bool loadIntoProject(IProject *);
};
typedef struct { /* PSP structure */ typedef struct { /* PSP structure */
uint16_t int20h; /* interrupt 20h */ uint16_t int20h; /* interrupt 20h */
uint16_t eof; /* segment, end of allocation block */ uint16_t eof; /* segment, end of allocation block */
@ -50,7 +56,7 @@ static struct { /* EXE file header */
#define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */ #define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */
static void LoadImage(char *filename); //static void LoadImage(char *filename);
static void displayLoadInfo(void); static void displayLoadInfo(void);
static void displayMemMap(void); static void displayMemMap(void);
@ -58,22 +64,20 @@ static void displayMemMap(void);
* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode * FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
* rewritter, and displays any useful information. * rewritter, and displays any useful information.
****************************************************************************/ ****************************************************************************/
extern Project g_proj;
bool DccFrontend::FrontEnd () bool DccFrontend::FrontEnd ()
{ {
Project::get()->callGraph = 0;
g_proj.callGraph = 0; Project::get()->create(m_fname);
g_proj.m_fname = m_fname;
/* Load program into memory */ /* Load program into memory */
LoadImage(g_proj); LoadImage(*Project::get());
if (option.verbose) if (option.verbose)
displayLoadInfo(); displayLoadInfo();
/* Do depth first flow analysis building call graph and procedure list, /* Do depth first flow analysis building call graph and procedure list,
* and attaching the I-code to each procedure */ * and attaching the I-code to each procedure */
parse (g_proj); parse (*Project::get());
if (option.asm1) if (option.asm1)
{ {
@ -82,7 +86,7 @@ bool DccFrontend::FrontEnd ()
/* Search through code looking for impure references and flag them */ /* Search through code looking for impure references and flag them */
Disassembler ds(1); Disassembler ds(1);
for(Function &f : g_proj.pProcList) for(Function &f : Project::get()->pProcList)
{ {
f.markImpure(); f.markImpure();
if (option.asm1) if (option.asm1)
@ -92,11 +96,11 @@ bool DccFrontend::FrontEnd ()
} }
if (option.Interact) if (option.Interact)
{ {
interactDis(&g_proj.pProcList.front(), 0); /* Interactive disassembler */ interactDis(&Project::get()->pProcList.front(), 0); /* Interactive disassembler */
} }
/* Converts jump target addresses to icode offsets */ /* Converts jump target addresses to icode offsets */
for(Function &f : g_proj.pProcList) for(Function &f : Project::get()->pProcList)
{ {
f.bindIcodeOff(); f.bindIcodeOff();
} }
@ -125,7 +129,7 @@ static void displayLoadInfo(void)
printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc)); printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc));
printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc)); printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc));
} }
printf("Load image size = %04X\n", prog.cbImage - sizeof(PSP)); printf("Load image size = %04" PRIiPTR "\n", prog.cbImage - sizeof(PSP));
printf("Initial SS:SP = %04X:%04X\n", prog.initSS, prog.initSP); printf("Initial SS:SP = %04X:%04X\n", prog.initSS, prog.initSP);
printf("Initial CS:IP = %04X:%04X\n", prog.initCS, prog.initIP); printf("Initial CS:IP = %04X:%04X\n", prog.initCS, prog.initIP);
@ -208,15 +212,15 @@ void DccFrontend::LoadImage(Project &proj)
uint8_t buf[4]; uint8_t buf[4];
/* Open the input file */ /* Open the input file */
if ((fp = fopen(proj.m_fname.c_str(), "rb")) == NULL) if ((fp = fopen(proj.binary_path().c_str(), "rb")) == NULL)
{ {
fatalError(CANNOT_OPEN, proj.m_fname.c_str()); fatalError(CANNOT_OPEN, proj.binary_path().c_str());
} }
/* Read in first 2 bytes to check EXE signature */ /* Read in first 2 bytes to check EXE signature */
if (fread(&header, 1, 2, fp) != 2) if (fread(&header, 1, 2, fp) != 2)
{ {
fatalError(CANNOT_READ, proj.m_fname.c_str()); fatalError(CANNOT_READ, proj.binary_path().c_str());
} }
if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) { if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
@ -224,7 +228,7 @@ void DccFrontend::LoadImage(Project &proj)
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
if (fread(&header, sizeof(header), 1, fp) != 1) if (fread(&header, sizeof(header), 1, fp) != 1)
{ {
fatalError(CANNOT_READ, proj.m_fname.c_str()); fatalError(CANNOT_READ, proj.binary_path().c_str());
} }
/* This is a typical DOS kludge! */ /* This is a typical DOS kludge! */
@ -305,7 +309,7 @@ void DccFrontend::LoadImage(Project &proj)
/* Read in the image past where a PSP would go */ /* Read in the image past where a PSP would go */
if (cb != (int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp)) if (cb != (int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp))
{ {
fatalError(CANNOT_READ, proj.m_fname.c_str()); fatalError(CANNOT_READ, proj.binary_path().c_str());
} }
/* Set up memory map */ /* Set up memory map */

View File

@ -10,8 +10,8 @@
#include "project.h" #include "project.h"
extern Project g_proj; extern Project g_proj;
//static BB * rmJMP(Function * pProc, int marker, BB * pBB); //static BB * rmJMP(Function * pProc, int marker, BB * pBB);
static void mergeFallThrough(Function * pProc, BB * pBB); //static void mergeFallThrough(Function * pProc, BB * pBB);
static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last); //static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
/***************************************************************************** /*****************************************************************************
* createCFG - Create the basic control flow graph * createCFG - Create the basic control flow graph
@ -30,7 +30,6 @@ void Function::createCFG()
* 6) End of procedure * 6) End of procedure
*/ */
int i; int i;
int ip;
BB * psBB; BB * psBB;
BB * pBB; BB * pBB;
iICODE pIcode = Icode.begin(); iICODE pIcode = Icode.begin();
@ -85,7 +84,7 @@ CondJumps:
{ {
//pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this); //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(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
for (i = 0; i < ll->caseTbl2.size(); i++) for (size_t i = 0; i < ll->caseTbl2.size(); i++)
pBB->edges[i].ip = ll->caseTbl2[i]; pBB->edges[i].ip = ll->caseTbl2[i];
hasCase = true; hasCase = true;
} }
@ -153,7 +152,7 @@ CondJumps:
pBB = *iter; pBB = *iter;
for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++) for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++)
{ {
uint32_t ip = pBB->edges[edeg_idx].ip; int32_t ip = pBB->edges[edeg_idx].ip;
if (ip >= SYNTHESIZED_MIN) if (ip >= SYNTHESIZED_MIN)
{ {
fatalError (INVALID_SYNTHETIC_BB); fatalError (INVALID_SYNTHETIC_BB);
@ -179,8 +178,8 @@ void Function::markImpure()
continue; continue;
//assert that case tbl has less entries then symbol table ???? //assert that case tbl has less entries then symbol table ????
//WARNING: Case entries are held in symbol table ! //WARNING: Case entries are held in symbol table !
assert(g_proj.validSymIdx(icod.ll()->caseEntry)); assert(Project::get()->validSymIdx(icod.ll()->caseEntry));
const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseEntry)); const SYM &psym(Project::get()->getSymByIdx(icod.ll()->caseEntry));
for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++) for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
{ {
if (BITMAP(c, BM_CODE)) if (BITMAP(c, BM_CODE))
@ -335,8 +334,6 @@ BB *BB::rmJMP(int marker, BB * pBB)
void BB::mergeFallThrough( CIcodeRec &Icode) void BB::mergeFallThrough( CIcodeRec &Icode)
{ {
BB * pChild; BB * pChild;
int i;
if (!this) if (!this)
{ {
printf("mergeFallThrough on empty BB!\n"); printf("mergeFallThrough on empty BB!\n");
@ -375,9 +372,11 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
traversed = DFS_MERGE; traversed = DFS_MERGE;
/* Process all out edges recursively */ /* Process all out edges recursively */
for (i = 0; i < edges.size(); i++) for (size_t i = 0; i < edges.size(); i++)
if (edges[i].BBptr->traversed != DFS_MERGE) {
edges[i].BBptr->mergeFallThrough(Icode); if (edges[i].BBptr->traversed != DFS_MERGE)
edges[i].BBptr->mergeFallThrough(Icode);
}
} }
@ -399,7 +398,7 @@ void BB::dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last)
pChild->inEdges[pChild->index++] = this; pChild->inEdges[pChild->index++] = this;
/* Is this the last visit? */ /* Is this the last visit? */
if (pChild->index == pChild->inEdges.size()) if (pChild->index == int(pChild->inEdges.size()))
pChild->index = UN_INIT; pChild->index = UN_INIT;
if (pChild->traversed != DFS_NUM) if (pChild->traversed != DFS_NUM)

View File

@ -282,7 +282,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
* refines the HIGH_LEVEL icodes. */ * refines the HIGH_LEVEL icodes. */
void Function::highLevelGen() void Function::highLevelGen()
{ {
int numIcode; /* number of icode instructions */ size_t numIcode; /* number of icode instructions */
iICODE pIcode; /* ptr to current icode node */ iICODE pIcode; /* ptr to current icode node */
COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */ COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */
uint32_t _flg; /* icode flags */ uint32_t _flg; /* icode flags */
@ -473,6 +473,8 @@ COND_EXPR *COND_EXPR::inverse () const
res->boolExpr.lhs=lhs()->inverse (); res->boolExpr.lhs=lhs()->inverse ();
res->boolExpr.rhs=rhs()->inverse (); res->boolExpr.rhs=rhs()->inverse ();
return res; return res;
default:
fprintf(stderr,"COND_EXPR::inverse unhandled op %d",op());
} /* eos */ } /* eos */
} }
@ -488,8 +490,7 @@ COND_EXPR *COND_EXPR::inverse () const
* actual parameters) */ * actual parameters) */
std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc) std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc)
{ {
int i; /* counter of # arguments */ //string condExp;
string condExp;
ostringstream ostr; ostringstream ostr;
ostr<<tproc->name<<" ("; ostr<<tproc->name<<" (";
for(const STKSYM &sym : args) for(const STKSYM &sym : args)
@ -585,6 +586,10 @@ string HLTYPE::write1HlIcode (Function * pProc, int *numLoc)
ostr << p->writeOut(pProc,numLoc); ostr << p->writeOut(pProc,numLoc);
ostr << "\n"; ostr << "\n";
break; break;
case HLI_JCOND: //Handled elsewhere
break;
default:
fprintf(stderr," HLTYPE::write1HlIcode - Unhandled opcode %d\n",opcode);
} }
return ostr.str(); return ostr.str();
} }

26
src/hltype.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "icode.h"
#include "ast.h"
void HLTYPE::replaceExpr(COND_EXPR *e)
{
assert(e);
delete exp.v;
exp.v=e;
}
HlTypeSupport *HLTYPE::get()
{
switch(opcode)
{
case HLI_ASSIGN: return &asgn;
case HLI_RET:
case HLI_POP:
case HLI_JCOND:
case HLI_PUSH: return &exp;
case HLI_CALL: return &call;
default:
return 0;
}
}

View File

@ -57,9 +57,9 @@ CIcodeRec::iterator CIcodeRec::labelSrch(uint32_t target)
{ {
return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ll()->label==target;}); return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ll()->label==target;});
} }
ICODE * CIcodeRec::GetIcode(int ip) ICODE * CIcodeRec::GetIcode(size_t ip)
{ {
assert(ip>=0 && ip<size()); assert(ip<size());
iICODE res=begin(); iICODE res=begin();
advance(res,ip); advance(res,ip);
return &(*res); return &(*res);

View File

@ -207,7 +207,9 @@ bool Idiom19::match(iICODE picode)
return true; return true;
} }
else /* indexed */ else /* indexed */
/* not supported yet */ ; {
/* not supported yet */
}
return false; return false;
} }
int Idiom19::action() int Idiom19::action()

View File

@ -2,7 +2,7 @@
#include "dcc.h" #include "dcc.h"
/***************************************************************************** /*****************************************************************************
/* checkStkVars - Checks for PUSH SI * checkStkVars - Checks for PUSH SI
* [PUSH DI] * [PUSH DI]
* or PUSH DI * or PUSH DI
* [PUSH SI] * [PUSH SI]
@ -115,7 +115,7 @@ bool Idiom1::match(iICODE picode)
else // push di [push si] / push si [push di] else // push di [push si] / push si [push di]
{ {
size_t n = checkStkVars (picode); size_t n = checkStkVars (picode);
for(int i=0; i<n; ++i) for(size_t i=0; i<n; ++i)
m_icodes.push_back(picode++); m_icodes.push_back(picode++);
} }

View File

@ -16,7 +16,7 @@ using namespace std;
****************************************************************************/ ****************************************************************************/
bool Idiom11::match (iICODE picode) bool Idiom11::match (iICODE picode)
{ {
const char *matchstring="(oNEG rH) (oNEG rL) (SBB \rH i0)"; //const char *matchstring="(oNEG rH) (oNEG rL) (SBB \rH i0)";
condId type; /* type of argument */ condId type; /* type of argument */
if(distance(picode,m_end)<3) if(distance(picode,m_end)<3)
return false; return false;
@ -31,20 +31,22 @@ bool Idiom11::match (iICODE picode)
return false; return false;
switch (type) switch (type)
{ {
case GLOB_VAR: case GLOB_VAR:
if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) && if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
(m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)) (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
return true; return true;
break; break;
case REGISTER: case REGISTER:
if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi) if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi)
return true; return true;
break; break;
case PARAM: case PARAM:
case LOCAL_VAR: case LOCAL_VAR:
if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off) if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)
return true; return true;
break; break;
default:
fprintf(stderr,"Idiom11::match unhandled type %d\n",type);
} }
return false; return false;
} }
@ -73,7 +75,7 @@ int Idiom11::action()
****************************************************************************/ ****************************************************************************/
bool Idiom16::match (iICODE picode) bool Idiom16::match (iICODE picode)
{ {
const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)"; //const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)";
if(distance(picode,m_end)<3) if(distance(picode,m_end)<3)
return false; return false;
for(int i=0; i<3; ++i) for(int i=0; i<3; ++i)

View File

@ -12,7 +12,7 @@ bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
{ {
return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h); return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h);
} }
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false) ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
{ {
@ -72,7 +72,6 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
* flagging this entry as illegal is all that can be done. */ * flagging this entry as illegal is all that can be done. */
void LOCAL_ID::flagByteWordId (int off) void LOCAL_ID::flagByteWordId (int off)
{ {
int idx;
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool { auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
//if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) && //if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) &&
if ((en.typeBitsize()<=16) && if ((en.typeBitsize()<=16) &&
@ -121,12 +120,10 @@ int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
* regi: indexed register into global variable * regi: indexed register into global variable
* ix: index into icode array * ix: index into icode array
* t: HIGH_LEVEL type */ * t: HIGH_LEVEL type */
int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t) int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
{ {
int idx;
/* Check for entry in the table */ /* Check for entry in the table */
for (idx = 0; idx < id_arr.size(); idx++) for (size_t idx = 0; idx < id_arr.size(); idx++)
{ {
if (/*(locSym->id[idx].type == t) && Not checking type */ if (/*(locSym->id[idx].type == t) && Not checking type */
(id_arr[idx].id.bwGlb.seg == seg) && (id_arr[idx].id.bwGlb.seg == seg) &&
@ -137,11 +134,10 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t)
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
newIdent (t, GLB_FRAME); newIdent (t, GLB_FRAME);
idx = id_arr.size() - 1; id_arr.back().id.bwGlb.seg = seg;
id_arr[idx].id.bwGlb.seg = seg; id_arr.back().id.bwGlb.off = off;
id_arr[idx].id.bwGlb.off = off; id_arr.back().id.bwGlb.regi = regi;
id_arr[idx].id.bwGlb.regi = regi; return id_arr.size() - 1;
return (idx);
} }
@ -279,7 +275,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
{ {
size_t idx; size_t idx;
const LLOperand *pmH, *pmL; const LLOperand *pmH, *pmL;
LLInst &p_ll(*pIcode->ll()); LLInst &p_ll(*pIcode->ll());
if (f == LOW_FIRST) if (f == LOW_FIRST)
{ {
pmL = p_ll.get(sd); pmL = p_ll.get(sd);

View File

@ -2,7 +2,8 @@
* dcc project procedure list builder * dcc project procedure list builder
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
****************************************************************************/ ****************************************************************************/
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <stdlib.h> /* For exit() */ #include <stdlib.h> /* For exit() */
#include <sstream> #include <sstream>
@ -12,9 +13,8 @@
#include "dcc.h" #include "dcc.h"
#include "project.h" #include "project.h"
using namespace std; using namespace std;
extern Project g_proj;
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate); //static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph);
static void setBits(int16_t type, uint32_t start, uint32_t len); static void setBits(int16_t type, uint32_t start, uint32_t len);
static void process_MOV(LLInst &ll, STATE * pstate); static void process_MOV(LLInst &ll, STATE * pstate);
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag); static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
@ -38,7 +38,7 @@ void DccFrontend::parse(Project &proj)
SynthLab = SYNTHESIZED_MIN; SynthLab = SYNTHESIZED_MIN;
// default-construct a Function object ! // default-construct a Function object !
auto func = proj.createFunction(); /*auto func = */proj.createFunction();
/* Check for special settings of initial state, based on idioms of the /* Check for special settings of initial state, based on idioms of the
startup code */ startup code */
@ -102,7 +102,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
uint32_t offset; uint32_t offset;
eErrorId err; eErrorId err;
bool done = false; bool done = false;
SYMTAB &global_symbol_table(g_proj.symtab); SYMTAB &global_symbol_table(Project::get()->symtab);
if (name.find("chkstk") != string::npos) if (name.find("chkstk") != string::npos)
{ {
// Danger! Dcc will likely fall over in this code. // Danger! Dcc will likely fall over in this code.
@ -115,7 +115,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
} }
if (option.VeryVerbose) if (option.VeryVerbose)
{ {
printf("Parsing proc %s at %lX\n", name.c_str(), pstate->IP); printf("Parsing proc %s at %X\n", name.c_str(), pstate->IP);
} }
while (! done && ! (err = scan(pstate->IP, _Icode))) while (! done && ! (err = scan(pstate->IP, _Icode)))
@ -337,10 +337,12 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate)
case iSHL: case iSHL:
if (pstate->JCond.regi == ll->dst.regi) if (pstate->JCond.regi == ll->dst.regi)
{
if ((ll->testFlags(I)) && ll->src().getImm2() == 1) if ((ll->testFlags(I)) && ll->src().getImm2() == 1)
pstate->JCond.immed *= 2; pstate->JCond.immed *= 2;
else else
pstate->JCond.regi = 0; pstate->JCond.regi = 0;
}
break; break;
case iLEA: case iLEA:
@ -404,7 +406,7 @@ bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcod
pIcode.ll()->caseTbl2.resize( table.size() ); pIcode.ll()->caseTbl2.resize( table.size() );
assert(pIcode.ll()->caseTbl2.size()<512); assert(pIcode.ll()->caseTbl2.size()<512);
uint32_t k=0; uint32_t k=0;
for (int i = table.start; i < table.finish; i += 2) for (size_t i = table.start; i < table.finish; i += 2)
{ {
StCopy = *pstate; StCopy = *pstate;
StCopy.IP = cs + LH(&prog.Image[i]); StCopy.IP = cs + LH(&prog.Image[i]);
@ -417,6 +419,7 @@ bool Function::followAllTableEntries(JumpTable &table, uint32_t cs, ICODE& pIcod
last_current_insn->ll()->setFlags(CASE); last_current_insn->ll()->setFlags(CASE);
pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() ); pIcode.ll()->caseTbl2.push_back( last_current_insn->ll()->GetLlLabel() );
} }
return true;
} }
bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph) bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGraph)
@ -426,14 +429,14 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
ICODE _Icode; ICODE _Icode;
uint32_t cs, offTable, endTable; uint32_t cs, offTable, endTable;
uint32_t i, k, seg, target; uint32_t i, k, seg, target;
uint32_t tmp;
if (pIcode.ll()->testFlags(I)) if (pIcode.ll()->testFlags(I))
{ {
if (pIcode.ll()->getOpcode() == iJMPF) if (pIcode.ll()->getOpcode() == iJMPF)
pstate->setState( rCS, LH(prog.Image + pIcode.ll()->label + 3)); pstate->setState( rCS, LH(prog.Image + pIcode.ll()->label + 3));
uint32_t i = pstate->IP = pIcode.ll()->src().getImm2(); pstate->IP = pIcode.ll()->src().getImm2();
if ((long)i < 0) int64_t i = pIcode.ll()->src().getImm2();
if (i < 0)
{ {
exit(1); exit(1);
} }
@ -501,8 +504,8 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
{ {
assert(((endTable - offTable) / 2)<512); assert(((endTable - offTable) / 2)<512);
STATE StCopy; STATE StCopy;
int ip; //int ip;
uint32_t *psw; //uint32_t *psw;
setBits(BM_DATA, offTable, endTable - offTable); setBits(BM_DATA, offTable, endTable - offTable);
@ -514,7 +517,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra
StCopy = *pstate; StCopy = *pstate;
StCopy.IP = cs + LH(&prog.Image[i]); StCopy.IP = cs + LH(&prog.Image[i]);
iICODE last_current_insn = (++Icode.rbegin()).base(); iICODE last_current_insn = (++Icode.rbegin()).base();
ip = Icode.size(); //ip = Icode.size();
FollowCtrl (pcallGraph, &StCopy); FollowCtrl (pcallGraph, &StCopy);
++last_current_insn; ++last_current_insn;
@ -600,9 +603,9 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
* previous offset into the program image */ * previous offset into the program image */
uint32_t tgtAddr=0; uint32_t tgtAddr=0;
if (pIcode.ll()->getOpcode() == iCALLF) if (pIcode.ll()->getOpcode() == iCALLF)
tgtAddr= LH(&prog.Image[off]) + (uint32_t)(LH(&prog.Image[off+2])) << 4; tgtAddr= LH(&prog.Image[off]) + ((uint32_t)(LH(&prog.Image[off+2])) << 4);
else else
tgtAddr= LH(&prog.Image[off]) + (uint32_t)(uint16_t)state.r[rCS] << 4; tgtAddr= LH(&prog.Image[off]) + ((uint32_t)(uint16_t)state.r[rCS] << 4);
pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) ); pIcode.ll()->replaceSrc(LLOperand::CreateImm2( tgtAddr ) );
pIcode.ll()->setFlags(I); pIcode.ll()->setFlags(I);
indirect = true; indirect = true;
@ -612,12 +615,12 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
if (pIcode.ll()->testFlags(I)) if (pIcode.ll()->testFlags(I))
{ {
/* Search procedure list for one with appropriate entry point */ /* Search procedure list for one with appropriate entry point */
ilFunction iter = g_proj.findByEntry(pIcode.ll()->src().getImm2()); ilFunction iter = Project::get()->findByEntry(pIcode.ll()->src().getImm2());
/* Create a new procedure node and save copy of the state */ /* Create a new procedure node and save copy of the state */
if ( not g_proj.valid(iter) ) if ( not Project::get()->valid(iter) )
{ {
iter = g_proj.createFunction(); iter = Project::get()->createFunction();
Function &x(*iter); Function &x(*iter);
x.procEntry = pIcode.ll()->src().getImm2(); x.procEntry = pIcode.ll()->src().getImm2();
LibCheck(x); LibCheck(x);
@ -665,7 +668,7 @@ boolT Function::process_CALL (ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *ps
} }
else else
g_proj.callGraph->insertCallGraph (this, iter); Project::get()->callGraph->insertCallGraph (this, iter);
last_insn.ll()->src().proc.proc = &(*iter); // ^ target proc last_insn.ll()->src().proc.proc = &(*iter); // ^ target proc
@ -707,6 +710,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
size=1; size=1;
psym = lookupAddr (&ll.dst, pstate, size, eDEF); psym = lookupAddr (&ll.dst, pstate, size, eDEF);
if (psym && ! (psym->duVal.val)) /* no initial value yet */ if (psym && ! (psym->duVal.val)) /* no initial value yet */
{
if (ll.testFlags(I)) /* immediate */ if (ll.testFlags(I)) /* immediate */
{ {
prog.Image[psym->label] = (uint8_t)ll.src().getImm2(); prog.Image[psym->label] = (uint8_t)ll.src().getImm2();
@ -733,6 +737,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
prog.Image[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8); prog.Image[psym->label+1] = (uint8_t)(pstate->r[srcReg] >> 8);
psym->duVal.setFlags(eDuVal::DEF); psym->duVal.setFlags(eDuVal::DEF);
} }
}
} }
} }
@ -742,8 +747,6 @@ static void process_MOV(LLInst & ll, STATE * pstate)
* and returns a pointer to such entry. */ * and returns a pointer to such entry. */
void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag) void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag)
{ {
int i;
/* Check for symbol in stack frame table */ /* Check for symbol in stack frame table */
auto iter=findByLabel(off); auto iter=findByLabel(off);
if(iter!=end()) if(iter!=end())
@ -751,14 +754,14 @@ void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag)
if (iter->size < _size) if (iter->size < _size)
{ {
iter->size = _size; iter->size = _size;
}
} }
}
else else
{ {
char nm[16]; char nm[16];
STKSYM new_sym; STKSYM new_sym;
sprintf (nm, "arg%ld", size()); sprintf (nm, "arg%" PRIu64, uint64_t(size()));
new_sym.name = nm; new_sym.name = nm;
new_sym.label= off; new_sym.label= off;
new_sym.size = _size; new_sym.size = _size;
@ -800,13 +803,13 @@ static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag
if (pm->segValue) /* there is a value in the seg field */ if (pm->segValue) /* there is a value in the seg field */
{ {
operand = opAdr (pm->segValue, pm->off); operand = opAdr (pm->segValue, pm->off);
psym = g_proj.symtab.updateGlobSym (operand, size, duFlag,created_new); psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new);
} }
else if (pstate->f[pm->seg]) /* new value */ else if (pstate->f[pm->seg]) /* new value */
{ {
pm->segValue = pstate->r[pm->seg]; pm->segValue = pstate->r[pm->seg];
operand = opAdr(pm->segValue, pm->off); operand = opAdr(pm->segValue, pm->off);
psym = g_proj.symtab.updateGlobSym (operand, size, duFlag,created_new); psym = Project::get()->symtab.updateGlobSym (operand, size, duFlag,created_new);
/* Flag new memory locations that are segment values */ /* Flag new memory locations that are segment values */
if (created_new) if (created_new)
@ -821,7 +824,7 @@ static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag
} }
} }
/* Check for out of bounds */ /* Check for out of bounds */
if (psym && (psym->label>=0) and (psym->label < (uint32_t)prog.cbImage)) if (psym and (psym->label < (uint32_t)prog.cbImage))
return psym; return psym;
return nullptr; return nullptr;
} }
@ -903,7 +906,7 @@ std::bitset<32> duReg[] = { 0x00,
* pstate: ptr to current procedure state * pstate: ptr to current procedure state
* size : size of the operand * size : size of the operand
* ix : current index into icode array */ * ix : current index into icode array */
static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size, int ix) static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size)
{ {
const LLOperand * pm = pIcode.ll()->get(d) ; const LLOperand * pm = pIcode.ll()->get(d) ;
SYM * psym; SYM * psym;
@ -927,17 +930,21 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */ if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */
{ {
if (pm->off > 0) /* global indexed variable */ if (pm->off > 0) /* global indexed variable */
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,ix, TYPE_WORD_SIGN); pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
} }
pIcode.du.use |= duReg[pm->regi]; pIcode.du.use |= duReg[pm->regi];
} }
else if (psym = lookupAddr(const_cast<LLOperand *>(pm), pstate, size, eDuVal::USE)) else
{ {
setBits (BM_DATA, psym->label, (uint32_t)size); psym = lookupAddr(const_cast<LLOperand *>(pm), pstate, size, eDuVal::USE);
pIcode.ll()->setFlags(SYM_USE); if( nullptr != psym )
pIcode.ll()->caseEntry = distance(&g_proj.symtab[0],psym); //WARNING: was setting case count {
setBits (BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_USE);
pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); //WARNING: was setting case count
}
} }
} }
@ -950,13 +957,21 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
/* Checks which registers were defined (ie. got a new value) and updates the /* Checks which registers were defined (ie. got a new value) and updates the
* du.d flag. * du.d flag.
* Places local variables in the local symbol table. */ * Places local variables in the local symbol table. */
static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size, static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int size)
int ix)
{ {
LLOperand *pm = pIcode.ll()->get(d); LLOperand *pm = pIcode.ll()->get(d);
SYM * psym; if (pm->regi==0)
{
if (pm->regi == 0 || pm->regi >= INDEX_BX_SI) SYM * psym;
psym = lookupAddr(pm, pstate, size, eDEF);
if (nullptr!=psym)
{
setBits(BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_DEF);
pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); // WARNING: was setting Case count
}
}
else if (pm->regi >= INDEX_BX_SI)
{ {
if (pm->regi == INDEX_BP) /* indexed on bp */ if (pm->regi == INDEX_BP) /* indexed on bp */
{ {
@ -977,19 +992,11 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */ if ((pm->seg == rDS) && (pm->regi == INDEX_BX)) /* bx */
{ {
if (pm->off > 0) /* global var */ if (pm->off > 0) /* global var */
pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,ix, TYPE_WORD_SIGN); pProc->localId.newIntIdx(pm->segValue, pm->off, rBX,TYPE_WORD_SIGN);
} }
pIcode.du.use |= duReg[pm->regi]; pIcode.du.use |= duReg[pm->regi];
} }
else if (psym = lookupAddr(pm, pstate, size, eDEF))
{
setBits(BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_DEF);
pIcode.ll()->caseEntry = distance(&g_proj.symtab[0],psym); // WARNING: was setting Case count
}
} }
/* Definition of register */ /* Definition of register */
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I)))) else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
{ {
@ -1002,12 +1009,11 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
/* use_def - operand is both use and def'd. /* use_def - operand is both use and def'd.
* Note: the destination will always be a register, stack variable, or global * Note: the destination will always be a register, stack variable, or global
* variable. */ * variable. */
static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int cb, static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int cb)
int ix)
{ {
const LLOperand * pm = pIcode.ll()->get(d); const LLOperand * pm = pIcode.ll()->get(d);
use (d, pIcode, pProc, pstate, cb, ix); use (d, pIcode, pProc, pstate, cb);
if (pm->regi < INDEX_BX_SI) /* register */ if (pm->regi < INDEX_BX_SI) /* register */
{ {
@ -1022,7 +1028,6 @@ static void use_def(opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, i
extern LLOperand convertOperand(const x86_op_t &from); extern LLOperand convertOperand(const x86_op_t &from);
void Function::process_operands(ICODE & pIcode, STATE * pstate) void Function::process_operands(ICODE & pIcode, STATE * pstate)
{ {
int ix=Icode.size();
LLInst &ll_ins(*pIcode.ll()); LLInst &ll_ins(*pIcode.ll());
int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS; int sseg = (ll_ins.src().seg)? ll_ins.src().seg: rDS;
@ -1036,39 +1041,39 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
case iRCL: case iRCR: case iROL: case iROR: case iRCL: case iRCR: case iROL: case iROR:
case iADD: case iADC: case iSUB: case iSBB: case iADD: case iADC: case iSUB: case iSBB:
if (! Imm) { if (! Imm) {
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
} }
case iINC: case iDEC: case iNEG: case iNOT: case iINC: case iDEC: case iNEG: case iNOT:
case iAAA: case iAAD: case iAAM: case iAAS: case iAAA: case iAAD: case iAAM: case iAAS:
case iDAA: case iDAS: case iDAA: case iDAS:
use_def(DST, pIcode, this, pstate, cb, ix); use_def(DST, pIcode, this, pstate, cb);
break; break;
case iXCHG: case iXCHG:
/* This instruction is replaced by 3 instructions, only need /* This instruction is replaced by 3 instructions, only need
* to define the src operand and use the destination operand * to define the src operand and use the destination operand
* in the mean time. */ * in the mean time. */
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
def(DST, pIcode, this, pstate, cb, ix); def(DST, pIcode, this, pstate, cb);
break; break;
case iTEST: case iCMP: case iTEST: case iCMP:
if (! Imm) if (! Imm)
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
use(DST, pIcode, this, pstate, cb, ix); use(DST, pIcode, this, pstate, cb);
break; break;
case iDIV: case iIDIV: case iDIV: case iIDIV:
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
if (cb == 1) if (cb == 1)
pIcode.du.use |= duReg[rTMP]; pIcode.du.use |= duReg[rTMP];
break; break;
case iMUL: case iIMUL: case iMUL: case iIMUL:
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
if (! Imm) if (! Imm)
{ {
use (DST, pIcode, this, pstate, cb, ix); use (DST, pIcode, this, pstate, cb);
if (cb == 1) if (cb == 1)
{ {
pIcode.du.def |= duReg[rAX]; pIcode.du.def |= duReg[rAX];
@ -1081,7 +1086,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
} }
} }
else else
def (DST, pIcode, this, pstate, cb, ix); def (DST, pIcode, this, pstate, cb);
break; break;
case iSIGNEX: case iSIGNEX:
@ -1105,14 +1110,14 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
case iCALL: case iPUSH: case iPOP: case iCALL: case iPUSH: case iPOP:
if (! Imm) { if (! Imm) {
if (pIcode.ll()->getOpcode() == iPOP) if (pIcode.ll()->getOpcode() == iPOP)
def(DST, pIcode, this, pstate, cb, ix); def(DST, pIcode, this, pstate, cb);
else else
use(DST, pIcode, this, pstate, cb, ix); use(DST, pIcode, this, pstate, cb);
} }
break; break;
case iESC: /* operands may be larger */ case iESC: /* operands may be larger */
use(DST, pIcode, this, pstate, cb, ix); use(DST, pIcode, this, pstate, cb);
break; break;
case iLDS: case iLES: case iLDS: case iLES:
@ -1120,25 +1125,25 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
cb = 4; cb = 4;
case iMOV: case iMOV:
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
def(DST, pIcode, this, pstate, cb, ix); def(DST, pIcode, this, pstate, cb);
break; break;
case iLEA: case iLEA:
use(SRC, pIcode, this, pstate, 2, ix); use(SRC, pIcode, this, pstate, 2);
def(DST, pIcode, this, pstate, 2, ix); def(DST, pIcode, this, pstate, 2);
break; break;
case iBOUND: case iBOUND:
use(SRC, pIcode, this, pstate, 4, ix); use(SRC, pIcode, this, pstate, 4);
use(DST, pIcode, this, pstate, cb, ix); use(DST, pIcode, this, pstate, cb);
break; break;
case iJMPF: case iJMPF:
cb = 4; cb = 4;
case iJMP: case iJMP:
if (! Imm) if (! Imm)
use(SRC, pIcode, this, pstate, cb, ix); use(SRC, pIcode, this, pstate, cb);
break; break;
case iLOOP: case iLOOPE: case iLOOPNE: case iLOOP: case iLOOPE: case iLOOPNE:
@ -1194,7 +1199,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
break; break;
case iIN: case iOUT: case iIN: case iOUT:
def(DST, pIcode, this, pstate, cb, ix); def(DST, pIcode, this, pstate, cb);
if (! Imm) if (! Imm)
{ {
pIcode.du.use |= duReg[rDX]; pIcode.du.use |= duReg[rDX];

View File

@ -14,14 +14,14 @@
static uint16_t *T1, *T2; /* Pointers to T1[i], T2[i] */ static uint16_t *T1, *T2; /* Pointers to T1[i], T2[i] */
static short *g; /* g[] */ static short *g; /* g[] */
static int numEdges; /* An edge counter */ //static int numEdges; /* An edge counter */
//static bool *visited; /* Array of bools: whether visited */ //static bool *visited; /* Array of bools: whether visited */
/* Private prototypes */ /* Private prototypes */
static void initGraph(void); //static void initGraph(void);
static void addToGraph(int e, int v1, int v2); //static void addToGraph(int e, int v1, int v2);
static bool isCycle(void); //static bool isCycle(void);
static void duplicateKeys(int v1, int v2); //static void duplicateKeys(int v1, int v2);
PatternHasher g_pattern_hasher; PatternHasher g_pattern_hasher;
void void

View File

@ -43,8 +43,6 @@ void CALL_GRAPH::insertArc (ilFunction newProc)
/* Inserts a (caller, callee) arc in the call graph tree. */ /* Inserts a (caller, callee) arc in the call graph tree. */
bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee) bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
{ {
int i;
if (proc == caller) if (proc == caller)
{ {
insertArc (callee); insertArc (callee);
@ -52,8 +50,8 @@ bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
} }
else else
{ {
for (i = 0; i < outEdges.size(); i++) for (CALL_GRAPH *edg : outEdges)
if (outEdges[i]->insertCallGraph (caller, callee)) if (edg->insertCallGraph (caller, callee))
return true; return true;
return (false); return (false);
} }
@ -61,7 +59,7 @@ bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee) bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
{ {
return insertCallGraph(g_proj.funcIter(caller),callee); return insertCallGraph(Project::get()->funcIter(caller),callee);
} }
@ -69,11 +67,9 @@ bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
* the nodes the procedure invokes. */ * the nodes the procedure invokes. */
void CALL_GRAPH::writeNodeCallGraph(int indIdx) void CALL_GRAPH::writeNodeCallGraph(int indIdx)
{ {
int i;
printf ("%s%s\n", indentStr(indIdx), proc->name.c_str()); printf ("%s%s\n", indentStr(indIdx), proc->name.c_str());
for (i = 0; i < outEdges.size(); i++) for (CALL_GRAPH *cg : outEdges)
outEdges[i]->writeNodeCallGraph (indIdx + 1); cg->writeNodeCallGraph (indIdx + 1);
} }
@ -205,6 +201,8 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
picode->du.def &= maskDuReg[id->id.longId.l]; picode->du.def &= maskDuReg[id->id.longId.l];
newsym.type = TYPE_LONG_SIGN; newsym.type = TYPE_LONG_SIGN;
break; break;
default:
fprintf(stderr,"LOCAL_ID::newRegArg unhandled type %d in masking low\n",type);
} }
call_args_stackframe->push_back(newsym); call_args_stackframe->push_back(newsym);
call_args_stackframe->numArgs++; call_args_stackframe->numArgs++;
@ -228,10 +226,12 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
{ {
regi = pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi; regi = pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi;
if ((regi >= rES) && (regi <= rDS)) if ((regi >= rES) && (regi <= rDS))
{
if (opcode == iCALLF) if (opcode == iCALLF)
return false; return false;
else else
return true; return true;
}
} }
} }
@ -308,8 +308,12 @@ void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc)
case TYPE_WORD_SIGN: case TYPE_WORD_SIGN:
break; break;
default:
fprintf(stderr,"adjustForArgType unhandled actType_ %d \n",actType);
} /* eos */ } /* eos */
break; break;
default:
fprintf(stderr,"adjustForArgType unhandled forType %d \n",forType);
} }
} }
@ -317,11 +321,11 @@ void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc)
/* Determines whether the formal argument has the same type as the given /* Determines whether the formal argument has the same type as the given
* type (type of the actual argument). If not, the formal argument is * type (type of the actual argument). If not, the formal argument is
* changed its type */ * changed its type */
void STKFRAME::adjustForArgType(int numArg_, hlType actType_) void STKFRAME::adjustForArgType(size_t numArg_, hlType actType_)
{ {
hlType forType; hlType forType;
STKSYM * psym, * nsym; STKSYM * psym, * nsym;
int off, i; int off;
/* If formal argument does not exist, do not create new ones, just /* If formal argument does not exist, do not create new ones, just
* ignore actual argument * ignore actual argument
*/ */
@ -330,7 +334,7 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
/* Find stack offset for this argument */ /* Find stack offset for this argument */
off = m_minOff; off = m_minOff;
i=0; size_t i=0;
for(STKSYM &s : *this) // walk formal arguments upto numArg_ for(STKSYM &s : *this) // walk formal arguments upto numArg_
{ {
if(i>=numArg_) if(i>=numArg_)
@ -343,7 +347,7 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
//psym = &at(numArg_); //psym = &at(numArg_);
//i = numArg_; //i = numArg_;
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;}); //auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {s.label==off;}); auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {return s.label==off;});
if(iter==end()) // symbol not found if(iter==end()) // symbol not found
return; return;
psym = &(*iter); psym = &(*iter);
@ -380,6 +384,8 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
case TYPE_CONST: case TYPE_CONST:
case TYPE_STR: case TYPE_STR:
break; break;
default:
fprintf(stderr,"STKFRAME::adjustForArgType unhandled actType_ %d \n",actType_);
} /* eos */ } /* eos */
} }
} }

View File

@ -1,7 +1,38 @@
#include <utility> #include <utility>
#include "dcc.h"
#include "project.h" #include "project.h"
#include "Procedure.h" #include "Procedure.h"
Project g_proj; using namespace std;
//Project g_proj;
char *asm1_name, *asm2_name; /* Assembler output filenames */
SYMTAB symtab; /* Global symbol table */
STATS stats; /* cfg statistics */
//PROG prog; /* programs fields */
OPTION option; /* Command line options */
Project *Project::s_instance = 0;
Project::Project() : callGraph(nullptr)
{
}
void Project::initialize()
{
delete callGraph;
callGraph = nullptr;
}
void Project::create(const string &a)
{
m_fname=a;
string::size_type ext_loc=a.find_last_of('.');
string::size_type slash_loc=a.find_last_of('/',ext_loc);
if(slash_loc==string::npos)
slash_loc=0;
else
slash_loc++;
if(ext_loc!=string::npos)
m_project_name = a.substr(slash_loc,(ext_loc-slash_loc));
else
m_project_name = a.substr(slash_loc);
}
bool Project::valid(ilFunction iter) bool Project::valid(ilFunction iter)
{ {
return iter!=pProcList.end(); return iter!=pProcList.end();
@ -63,7 +94,10 @@ const std::string &Project::symbolName(size_t idx)
} }
Project *Project::get() Project *Project::get()
{ {
return &g_proj; //WARNING: poor man's singleton, not thread safe
if(s_instance==0)
s_instance=new Project;
return s_instance;
} }
@ -71,3 +105,4 @@ SourceMachine *Project::machine()
{ {
return nullptr; return nullptr;
} }

View File

@ -236,7 +236,7 @@ void Function::propLongStk (int i, const ID &pLocId)
iICODE l23; iICODE l23;
/* Check all icodes for offHi:offLo */ /* Check all icodes for offHi:offLo */
pEnd = Icode.end(); pEnd = Icode.end();
int stat_size=Icode.size(); size_t stat_size=Icode.size();
// for (idx = 0; idx < (Icode.size() - 1); idx++) // for (idx = 0; idx < (Icode.size() - 1); idx++)
for(auto pIcode = Icode.begin(); ;++pIcode) for(auto pIcode = Icode.begin(); ;++pIcode)
{ {
@ -459,7 +459,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
{ {
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll())) if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
{ {
// reduce the advance by 1 here (loop increases) ? // reduce the advance by 1 here (loop increases) ?
advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc)); advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
} }
} }
@ -476,9 +476,9 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
} }
/* Check for OR regH, regL /* Check for OR regH, regL
* JX lab * JX lab
* => HLI_JCOND (regH:regL X 0) lab * => HLI_JCOND (regH:regL X 0) lab
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */ * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode()))) else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
{ {
if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode)) if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode))
@ -492,6 +492,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
} }
} }
} /* end for */ } /* end for */
return 0;
} }
/** Finds the definition of the long register pointed to by pLocId, and /** Finds the definition of the long register pointed to by pLocId, and
@ -504,8 +505,8 @@ void Function::propLongReg (int loc_ident_idx, const ID &pLocId)
{ {
/* Process all definitions/uses of long registers at an icode position */ /* Process all definitions/uses of long registers at an icode position */
// WARNING: this loop modifies the iterated-over container. // WARNING: this loop modifies the iterated-over container.
size_t initial_size=pLocId.idx.size(); //size_t initial_size=pLocId.idx.size();
for (int j = 0; j < pLocId.idx.size(); j++) for (size_t j = 0; j < pLocId.idx.size(); j++)
{ {
auto idx_iter=pLocId.idx.begin(); auto idx_iter=pLocId.idx.begin();
std::advance(idx_iter,j); std::advance(idx_iter,j);
@ -524,7 +525,7 @@ void Function::propLongReg (int loc_ident_idx, const ID &pLocId)
/* Propagates the long global address across all LOW_LEVEL icodes. /* Propagates the long global address across all LOW_LEVEL icodes.
* Transforms some LOW_LEVEL icodes into HIGH_LEVEL */ * Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
void Function::propLongGlb (int i, const ID &pLocId) void Function::propLongGlb (int /*i*/, const ID &/*pLocId*/)
{ {
printf("WARN: Function::propLongGlb not implemented"); printf("WARN: Function::propLongGlb not implemented");
} }
@ -534,10 +535,9 @@ void Function::propLongGlb (int i, const ID &pLocId)
* into HIGH_LEVEL icodes. */ * into HIGH_LEVEL icodes. */
void Function::propLong() void Function::propLong()
{ {
int i;
/* Pointer to current local identifier */ /* Pointer to current local identifier */
//TODO: change into range based for
for (i = 0; i < localId.csym(); i++) for (size_t i = 0; i < localId.csym(); i++)
{ {
const ID &pLocId(localId.id_arr[i]); const ID &pLocId(localId.id_arr[i]);
if ((pLocId.type==TYPE_LONG_SIGN) || (pLocId.type==TYPE_LONG_UNSIGN)) if ((pLocId.type==TYPE_LONG_SIGN) || (pLocId.type==TYPE_LONG_UNSIGN))

View File

@ -103,7 +103,7 @@ void derSeq_Entry::findIntervals (Function *c)
BB *h, /* Node being processed */ BB *h, /* Node being processed */
*header, /* Current interval's header node */ *header, /* Current interval's header node */
*succ; /* Successor basic block */ *succ; /* Successor basic block */
int i; /* Counter */ //int i; /* Counter */
queue H; /* Queue of possible header nodes */ queue H; /* Queue of possible header nodes */
boolT first = true; /* First pass through the loop */ boolT first = true; /* First pass through the loop */
@ -125,7 +125,7 @@ void derSeq_Entry::findIntervals (Function *c)
while ((h = pI->firstOfInt()) != NULL) while ((h = pI->firstOfInt()) != NULL)
{ {
/* Check all immediate successors of h */ /* Check all immediate successors of h */
for (i = 0; i < h->edges.size(); i++) for (size_t i = 0; i < h->edges.size(); i++)
{ {
succ = h->edges[i].BBptr; succ = h->edges[i].BBptr;
succ->inEdgeCount--; succ->inEdgeCount--;
@ -176,11 +176,11 @@ static void displayIntervals (interval *pI)
while (pI) while (pI)
{ {
printf (" Interval #: %ld\t#OutEdges: %ld\n", pI->numInt, pI->numOutEdges); printf (" Interval #: %d\t#OutEdges: %d\n", pI->numInt, pI->numOutEdges);
for(BB *node : pI->nodes) for(BB *node : pI->nodes)
{ {
if (node->correspInt == NULL) /* real BBs */ if (node->correspInt == NULL) /* real BBs */
printf (" Node: %ld\n", node->begin()->loc_ip); printf (" Node: %d\n", node->begin()->loc_ip);
else // BBs represent intervals else // BBs represent intervals
printf (" Node (corresp int): %d\n", node->correspInt->numInt); printf (" Node (corresp int): %d\n", node->correspInt->numInt);
} }
@ -190,17 +190,17 @@ static void displayIntervals (interval *pI)
/* Allocates space for a new derSeq node. */ /* Allocates space for a new derSeq node. */
static derSeq_Entry *newDerivedSeq() //static derSeq_Entry *newDerivedSeq()
{ //{
return new derSeq_Entry; // return new derSeq_Entry;
} //}
/* Frees the storage allocated for the queue q*/ /* Frees the storage allocated for the queue q*/
static void freeQueue (queue &q) //static void freeQueue (queue &q)
{ //{
q.clear(); // q.clear();
} //}
/* Frees the storage allocated for the interval pI */ /* Frees the storage allocated for the interval pI */
@ -237,12 +237,12 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
{ {
interval *Ii; /* Interval being processed */ interval *Ii; /* Interval being processed */
BB *BBnode, /* New basic block of intervals */ BB *BBnode, /* New basic block of intervals */
*curr, /* BB being checked for out edges */ //*curr, /* BB being checked for out edges */
*succ /* Successor node */ *succ /* Successor node */
; ;
//queue *listIi; /* List of intervals */ //queue *listIi; /* List of intervals */
int i, /* Index to outEdges array */ int i; /* Index to outEdges array */
j; /* Index to successors */ /*j;*/ /* Index to successors */
boolT sameGraph; /* Boolean, isomorphic graphs */ boolT sameGraph; /* Boolean, isomorphic graphs */
/* Process Gi's intervals */ /* Process Gi's intervals */
@ -271,7 +271,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
{ {
for(BB *curr : listIi) for(BB *curr : listIi)
{ {
for (j = 0; j < curr->edges.size(); j++) for (size_t j = 0; j < curr->edges.size(); j++)
{ {
succ = curr->edges[j].BBptr; succ = curr->edges[j].BBptr;
if (succ->inInterval != curr->inInterval) if (succ->inInterval != curr->inInterval)
@ -287,7 +287,8 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
/* Convert list of pointers to intervals into a real graph. /* Convert list of pointers to intervals into a real graph.
* Determines the number of in edges to each new BB, and places it * Determines the number of in edges to each new BB, and places it
* in numInEdges and inEdgeCount for later interval processing. */ * in numInEdges and inEdgeCount for later interval processing. */
curr = new_entry.Gi = bbs.front(); //curr = new_entry.Gi = bbs.front();
new_entry.Gi = bbs.front();
for(BB *curr : bbs) for(BB *curr : bbs)
{ {
for(TYPEADR_TYPE &edge : curr->edges) for(TYPEADR_TYPE &edge : curr->edges)
@ -315,6 +316,7 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi)
BB *Gi; /* Current derived sequence graph */ BB *Gi; /* Current derived sequence graph */
derSeq::iterator iter=derivedGi.begin(); derSeq::iterator iter=derivedGi.begin();
assert(iter!=derivedGi.end());
Gi = iter->Gi; Gi = iter->Gi;
while (! trivialGraph (Gi)) while (! trivialGraph (Gi))
{ {
@ -343,7 +345,7 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi)
/* Converts the irreducible graph G into an equivalent reducible one, by /* Converts the irreducible graph G into an equivalent reducible one, by
* means of node splitting. */ * means of node splitting. */
static void nodeSplitting (std::list<BB *> &G) static void nodeSplitting (std::list<BB *> &/*G*/)
{ {
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n"); fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
} }
@ -356,7 +358,7 @@ void derSeq::display()
derSeq::iterator iter=this->begin(); derSeq::iterator iter=this->begin();
while (iter!=this->end()) while (iter!=this->end())
{ {
printf ("\nIntervals for G%lX\n", n++); printf ("\nIntervals for G%X\n", n++);
displayIntervals (iter->Ii); displayIntervals (iter->Ii);
++iter; ++iter;
} }

View File

@ -14,7 +14,7 @@
#define S_EXT 0x000200 /* sign extend */ #define S_EXT 0x000200 /* sign extend */
#define OP386 0x000400 /* 386 op-code */ #define OP386 0x000400 /* 386 op-code */
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */ #define NSP 0x000800 /* NOT_HLL if SP is src or dst */
#define ICODEMASK 0xFF00FF /* Masks off parser flags */ // defined in Enums.h #define ICODEMASK 0xFF00FF /* Masks off parser flags */
static void rm(int i); static void rm(int i);
static void modrm(int i); static void modrm(int i);
@ -408,7 +408,12 @@ LLOperand convertOperand(const x86_op_t &from)
break; break;
case op_register: case op_register:
return LLOperand::CreateReg2(convertRegister(from.data.reg)); return LLOperand::CreateReg2(convertRegister(from.data.reg));
case op_immediate:
return LLOperand::CreateImm2(from.data.sdword);
default:
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
} }
return LLOperand::CreateImm2(0);
} }
eErrorId scan(uint32_t ip, ICODE &p) eErrorId scan(uint32_t ip, ICODE &p)
{ {

View File

@ -133,7 +133,7 @@ void destroySymTables(void)
} }
/* Using the value, read the symbolic name */ /* Using the value, read the symbolic name */
boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc) boolT readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
{ {
return false; // no symbolic names for now return false; // no symbolic names for now
} }
@ -142,7 +142,6 @@ boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc)
* if necessary (0 means no update necessary). */ * if necessary (0 means no update necessary). */
void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc) void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
{ {
int i;
auto iter=findByLabel(symbol); auto iter=findByLabel(symbol);
if(iter==end()) if(iter==end())
return; return;

View File

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

14
src/tests/loader.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "project.h"
#include "loader.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
TEST(Loader, NewProjectIsInitalized) {
Project p;
EXPECT_EQ(nullptr,p.callGraph);
ASSERT_TRUE(p.pProcList.empty());
ASSERT_TRUE(p.binary_path().empty());
ASSERT_TRUE(p.project_name().empty());
ASSERT_TRUE(p.symtab.empty());
}

27
src/tests/project.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "project.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
TEST(Project, NewProjectIsInitalized) {
Project p;
EXPECT_EQ(nullptr,p.callGraph);
ASSERT_TRUE(p.pProcList.empty());
ASSERT_TRUE(p.binary_path().empty());
ASSERT_TRUE(p.project_name().empty());
ASSERT_TRUE(p.symtab.empty());
}
TEST(Project, CreatedProjectHasValidNames) {
Project p;
std::vector<std::string> strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro ject3"};
std::vector<std::string> expected = {"Project1","Project2","Pro ject3"};
for(size_t i=0; i<strs.size(); i++)
{
p.create(strs[i]);
EXPECT_EQ(nullptr,p.callGraph);
ASSERT_TRUE(p.pProcList.empty());
EXPECT_EQ(expected[i],p.project_name());
EXPECT_EQ(strs[i],p.binary_path());
ASSERT_TRUE(p.symtab.empty());
}
}

View File

@ -12,8 +12,8 @@
#include "project.h" #include "project.h"
extern Project g_proj; extern Project g_proj;
static void displayCFG(Function * pProc); //static void displayCFG(Function * pProc);
static void displayDfs(BB * pBB); //static void displayDfs(BB * pBB);
/**************************************************************************** /****************************************************************************
* udm * udm
@ -73,7 +73,7 @@ void udm(void)
/* Build the control flow graph, find idioms, and convert low-level /* Build the control flow graph, find idioms, and convert low-level
* icodes to high-level ones */ * icodes to high-level ones */
Disassembler ds(2); Disassembler ds(2);
for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter) for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter)
{ {
iter->buildCFG(ds); iter->buildCFG(ds);
} }
@ -83,10 +83,10 @@ void udm(void)
* and intermediate instructions. Find expressions by forward * and intermediate instructions. Find expressions by forward
* substitution algorithm */ * substitution algorithm */
std::bitset<32> live_regs; std::bitset<32> live_regs;
g_proj.pProcList.front().dataFlow (live_regs); Project::get()->pProcList.front().dataFlow (live_regs);
/* Control flow analysis - structuring algorithm */ /* Control flow analysis - structuring algorithm */
for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter) for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter)
{ {
iter->controlFlowAnalysis(); iter->controlFlowAnalysis();
} }

6
valgrind_base.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
cd bld
make -j5
cd ..
./test_use_base.sh
./valgrind_tester ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/