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

2
.gitignore vendored
View File

@ -5,3 +5,5 @@ tests/outputs/*
tests/errors tests/errors
*.autosave *.autosave
bld* bld*
*.user
*.idb

View File

@ -20,81 +20,81 @@ typedef struct {
static op_implicit_list_t list_aaa[] = static op_implicit_list_t list_aaa[] =
/* 37 : AAA : rw AL */ /* 37 : AAA : rw AL */
/* 3F : AAS : rw AL */ /* 3F : AAS : rw AL */
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* 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) */
@ -109,7 +109,7 @@ static op_implicit_list_t list_f2xm1[] =
/* D9 FE : FSIN : rw ST(0) */ /* D9 FE : FSIN : rw ST(0) */
/* D9 FA : FSQRT : rw ST(0) */ /* D9 FA : FSQRT : rw ST(0) */
/* D9 F4 : FXTRACT : rw ST(0) */ /* D9 F4 : FXTRACT : rw ST(0) */
{{ OP_R | OP_W, REG_FPU_OFFSET }, {0}}; /* f2xm1 */ {{ OP_R | OP_W, REG_FPU_OFFSET }, {0,0}}; /* f2xm1 */
static op_implicit_list_t list_fcom[] = static op_implicit_list_t list_fcom[] =
/* D8, DC, DE D9 : FCOM : r ST(0) */ /* D8, DC, DE D9 : FCOM : r ST(0) */
@ -117,17 +117,17 @@ static op_implicit_list_t list_fcom[] =
/* DF, D8 : FIST : r ST(0) */ /* DF, D8 : FIST : r ST(0) */
/* D9 E4 : FTST : r ST(0) */ /* D9 E4 : FTST : r ST(0) */
/* D9 E5 : FXAM : r ST(0) */ /* D9 E5 : FXAM : r ST(0) */
{{ OP_R, REG_FPU_OFFSET }, {0}}; /* 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) */
@ -135,67 +135,67 @@ static op_implicit_list_t list_faddp[] =
/* 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 */
@ -206,12 +206,12 @@ static op_implicit_list_t list_popad[] =
{ 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 */
@ -223,102 +223,102 @@ static op_implicit_list_t list_pushad[] =
{ 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

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

@ -137,7 +137,7 @@ static int ia32_invariant_modrm( unsigned char *in, unsigned char *out,
} }
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) {
@ -251,13 +251,13 @@ static int ia32_decode_invariant( unsigned char *buf, size_t buf_len,
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:
@ -307,6 +307,7 @@ size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len,
} }
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;
memset(&inv,0,sizeof(x86_invariant_t));
return( ia32_disasm_invariant( buf, buf_len, &inv ) ); 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);
} }

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

@ -189,7 +189,7 @@ static struct {
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */ /* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" }, { REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
{ 0 } { 0,reg_undef,0,{0} }
}; };

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 */
@ -275,11 +275,15 @@ struct x86_op_t{
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;
/* offsets from current insn */
char relative_near;
int32_t relative_far; int32_t relative_far;
x86_absolute_t absolute; /* segment:offset */ /* segment:offset */
x86_ea_t expression; /* effective address [expression] */ x86_absolute_t absolute;
/* effective address [expression] */
x86_ea_t expression;
} data; } data;
/* this is needed to make formatting operands more sane */ /* this is needed to make formatting operands more sane */
void * insn; /* pointer to x86_insn_t owning operand */ void * insn; /* pointer to x86_insn_t owning operand */
@ -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
@ -605,6 +609,7 @@ public:
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();
/* convenience routine: returns count of operands matching 'type' */
size_t x86_operand_count( enum x86_op_foreach_type 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( );
@ -614,19 +619,25 @@ public:
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... */
uint8_t * x86_get_raw_imm( );
/* set the address (usually RVA) of the insn */
void x86_set_insn_addr( uint32_t addr ); void x86_set_insn_addr( uint32_t addr );
/* 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_mnemonic( char *buf, int len, enum x86_asm_format format);
int x86_format_insn( char *buf, int len, enum x86_asm_format); int x86_format_insn( char *buf, int len, enum x86_asm_format);
void x86_oplist_free( ); 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

@ -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,

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

@ -164,12 +164,11 @@ int x86_insn_t::x86_operand_foreach( x86_operand_fn func, void *arg, enum x86_op
return 1; 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;

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

@ -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. */
@ -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);
@ -597,6 +599,9 @@ void HlTypeSupport::performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *t
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;
} }
} }
@ -696,11 +701,12 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
break; break;
case IDENTIFIER: case IDENTIFIER:
{
std::ostringstream o; std::ostringstream o;
switch (expr->expr.ident.idType) switch (expr->expr.ident.idType)
{ {
case GLOB_VAR: case GLOB_VAR:
o << g_proj.symtab[expr->expr.ident.idNode.globIdx].name; o << Project::get()->symtab[expr->expr.ident.idNode.globIdx].name;
break; break;
case REGISTER: case REGISTER:
id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx]; id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];
@ -783,6 +789,10 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
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();
} }
@ -811,6 +821,8 @@ COND_EXPR *COND_EXPR::clone() const
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

@ -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,11 +300,10 @@ 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)
{
if (pred->dfsLastNum > latchNode->dfsLastNum)
latchNode = pred; latchNode = pred;
} }
} }
@ -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,29 +372,31 @@ 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)
{ {
caseHeader = m_dfsLast[i]; if ((m_dfsLast[i]->nodeType != MULTI_BRANCH))
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)) &&
(m_dfsLast[j]->immedDom == i))
if (exitNode == NO_NODE) 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; m_dfsLast[i]->caseTail = exitNode;
/* Tag nodes that belong to the case by recording the /* Tag nodes that belong to the case by recording the
@ -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();
@ -653,6 +656,9 @@ bool COND_EXPR::xClear (rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID
if(0==expr.unaryExp) if(0==expr.unaryExp)
return false; return false;
return expr.unaryExp->xClear ( range_to_check, lastBBinst, locId); return expr.unaryExp->xClear ( range_to_check, lastBBinst, locId);
default:
fprintf(stderr,"COND_EXPR::xClear unhandled type %d\n",m_type);
} /* 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())
@ -697,6 +704,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 */
{ {
if (pp->args.numArgs > 0) if (pp->args.numArgs > 0)
@ -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,10 +372,12 @@ 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) if (edges[i].BBptr->traversed != DFS_MERGE)
edges[i].BBptr->mergeFallThrough(Icode); 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;
@ -45,6 +45,8 @@ bool Idiom11::match (iICODE picode)
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

@ -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);
} }

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();
@ -735,6 +739,7 @@ static void process_MOV(LLInst & ll, STATE * pstate)
} }
} }
} }
}
@ -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())
@ -758,7 +761,7 @@ void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag)
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,19 +930,23 @@ 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
{
psym = lookupAddr(const_cast<LLOperand *>(pm), pstate, size, eDuVal::USE);
if( nullptr != psym )
{ {
setBits (BM_DATA, psym->label, (uint32_t)size); setBits (BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_USE); pIcode.ll()->setFlags(SYM_USE);
pIcode.ll()->caseEntry = distance(&g_proj.symtab[0],psym); //WARNING: was setting case count pIcode.ll()->caseEntry = distance(&Project::get()->symtab[0],psym); //WARNING: was setting case count
} }
} }
}
/* Use of register */ /* Use of register */
else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I)))) else if ((d == DST) || ((d == SRC) && (not pIcode.ll()->testFlags(I))))
@ -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);
if (pm->regi==0)
{
SYM * psym; SYM * psym;
psym = lookupAddr(pm, pstate, size, eDEF);
if (pm->regi == 0 || pm->regi >= INDEX_BX_SI) 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,12 +226,14 @@ 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;
} }
} }
}
/* Place register argument on the argument list */ /* Place register argument on the argument list */
STKSYM newsym; STKSYM newsym;
@ -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)
{ {
@ -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/