11 Commits

Author SHA1 Message Date
nemerle
50950028e0 Pre-qt5 2014-03-07 19:42:27 +01:00
nemerle
1c5e1c2fce replace boolT with plain old bool in a few places 2014-02-28 11:26:02 +01:00
nemerle
5c7799b778 Const fixes and name updates for libdis.h 2014-02-28 11:24:09 +01:00
Artur K
0209b7ceb2 Changes 2012-07-20 18:18:25 +02:00
Artur K
f6118dc0c4 Fixes to libdisasm, also use it a bit more 2012-07-19 19:50:34 +02:00
Artur K
d5e1fc733f Fixes to libdisasm, also use it a bit more 2012-07-19 19:37:30 +02:00
Artur K
c1eb8df114 Split COND_EXPR into Unary/Binary/AstIdent subclasses 2012-07-16 19:31:29 +02:00
Artur K
ca129c5177 Fix to idiom19 and fixFloatEmulation() 2012-07-15 20:17:16 +02:00
Artur K
c19231a1bd extracted FunctionCfg as it's own class 2012-07-15 16:52:59 +02:00
Artur K
5087a051b5 More simplifications on BB creation 2012-07-14 23:04:09 +02:00
Artur K
ba110a64cb removed most of clang warnings / errors 2012-03-29 22:02:25 +02:00
90 changed files with 10239 additions and 6447 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
@@ -407,6 +407,20 @@ unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
if (!op) { if (!op) {
op = m_decoded->x86_operand_new(); op = m_decoded->x86_operand_new();
/* all implicit operands are registers */ /* all implicit operands are registers */
if(m_decoded->addr_size==2)
{
if(list->operand==REG_EIP_INDEX)
handle_impl_reg( op, REG_IP_INDEX );
else if(list->operand<REG_WORD_OFFSET)
{
handle_impl_reg( op, (list->operand-REG_DWORD_OFFSET)+REG_WORD_OFFSET);
assert((list->operand-REG_DWORD_OFFSET)<REG_WORD_OFFSET-REG_DWORD_OFFSET);
}
else
handle_impl_reg( op, list->operand);
}
else
handle_impl_reg( op, list->operand ); handle_impl_reg( op, list->operand );
/* decrement the 'explicit count' incremented by default in /* decrement the 'explicit count' incremented by default in
* x86_operand_new */ * x86_operand_new */

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,11 @@ 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;
@@ -107,19 +107,17 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
/* No MODRM : note these set operand type explicitly */ /* No MODRM : note these set operand type explicitly */
case ADDRMETH_A: /* No modR/M -- direct addr */ case ADDRMETH_A: /* No modR/M -- direct addr */
op->type = op_absolute; op->type = op_absolute;
//according to Intel Manuals, offset goes first
/* segment:offset address used in far calls */ /* segment:offset address used in far calls */
x86_imm_sized( buf, buf_len,
&op->data.absolute.segment, 2 );
if ( m_decoded->addr_size == 4 ) { if ( m_decoded->addr_size == 4 ) {
x86_imm_sized( buf, buf_len, x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 );
&op->data.absolute.offset.off32, 4 );
size = 6;
} else {
x86_imm_sized( buf, buf_len,
&op->data.absolute.offset.off16, 2 );
size = 4; size = 4;
} else {
x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off16, 2 );
size = 2;
} }
x86_imm_sized( buf+size, buf_len-size, &op->data.absolute.segment, 2 );
size+=2;
break; break;
case ADDRMETH_I: /* Immediate val */ case ADDRMETH_I: /* Immediate val */
@@ -140,17 +138,24 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
op->data.far_offset depending on the size of op->data.far_offset depending on the size of
the operand */ the operand */
op->flags.op_signed = true; op->flags.op_signed = true;
if ( op_size == 1 ) { switch(op_size)
{
case 1:
/* one-byte near offset */ /* one-byte near offset */
op->type = op_relative_near; op->type = op_relative_near;
x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1); size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
} else { break;
case 2:
/* far offset...is this truly signed? */ /* far offset...is this truly signed? */
op->type = op_relative_far; op->type = op_relative_far;
x86_imm_signsized(buf, buf_len, int16_t offset_val; // easier upcast to int32_t
&op->data.relative_far, op_size ); size = x86_imm_signsized(buf, buf_len, &offset_val, 2 );
op->data.relative_far=offset_val;
break;
default:
assert(false);
size=0;
} }
size = op_size;
break; break;
case ADDRMETH_O: /* No ModR/M; op is word/dword offset */ case ADDRMETH_O: /* No ModR/M; op is word/dword offset */
/* NOTE: these are actually RVAs not offsets to seg!! */ /* NOTE: these are actually RVAs not offsets to seg!! */
@@ -172,20 +177,20 @@ 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,
REG_DWORD_OFFSET + 6 ); gen_regs + 6 );
break; break;
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,
REG_DWORD_OFFSET + 7 ); gen_regs + 7 );
break; break;
case ADDRMETH_RR: /* Gen Register hard-coded in opcode */ case ADDRMETH_RR: /* Gen Register hard-coded in opcode */
op->type = op_register; op->type = op_register;
@@ -258,7 +263,7 @@ size_t Ia32_Decoder::decode_operand_size( unsigned int op_type, x86_op_t *op ) {
* value s a 16:16 pointer or a 16:32 pointer, where * value s a 16:16 pointer or a 16:32 pointer, where
* the first '16' is a segment */ * the first '16' is a segment */
size = (m_decoded->addr_size == 4) ? 6 : 4; size = (m_decoded->addr_size == 4) ? 6 : 4;
op->datatype = (size == 4) ? op_descr32 : op_descr16; op->datatype = (size == 6) ? op_descr32 : op_descr16;
break; break;
case OPTYPE_b: /* byte, ignore op-size */ case OPTYPE_b: /* byte, ignore op-size */
size = 1; size = 1;

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,"" }
}; };

View File

@@ -6,6 +6,7 @@
#endif #endif
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include <cassert>
#include <stdint.h> #include <stdint.h>
/* 'NEW" types /* 'NEW" types
@@ -89,7 +90,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,32 +276,59 @@ 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 */
size_t size() size_t size() const
{ {
return operand_size(); return operand_size();
} }
/* get size of operand data in bytes */ /* get size of operand data in bytes */
size_t operand_size(); size_t operand_size() const;
/* format (sprintf) an operand into 'buf' using specified syntax */ /* format (sprintf) an operand into 'buf' using specified syntax */
int x86_format_operand(char *buf, int len, enum x86_asm_format format ); int x86_format_operand(char *buf, int len, enum x86_asm_format format );
bool is_address( ) { bool is_address( ) const {
return ( type == op_absolute || type == op_offset ); return ( type == op_absolute || type == op_offset );
} }
bool is_relative( ) { bool is_relative( ) const {
return ( type == op_relative_near || type == op_relative_far ); return ( type == op_relative_near || type == op_relative_far );
} }
bool is_immediate( ) const { return ( type == op_immediate ); }
int32_t getAddress()
{
assert(is_address()||is_relative());
switch ( type ) {
case op_relative_near:
return (int32_t) data.relative_near;
case op_absolute:
if(datatype==op_descr16)
return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off16;
else
return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off32;
case op_offset:
return data.offset;
case op_relative_far:
return (int32_t) data.relative_far;
default:
assert(false);
break;
}
return ~0;
}
char * format( enum x86_asm_format format ); char * format( enum x86_asm_format format );
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 +467,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 +548,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,28 +632,35 @@ 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 * operand_1st( );
x86_op_t * x86_operand_2nd( ); x86_op_t * operand_2nd( );
x86_op_t * x86_operand_3rd( ); x86_op_t * operand_3rd( );
x86_op_t * get_dest(); const x86_op_t * get_dest() const;
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();
@@ -722,7 +756,7 @@ public:
* offset : Offset in buffer to disassemble * offset : Offset in buffer to disassemble
* insn : Structure to fill with disassembled instruction * insn : Structure to fill with disassembled instruction
*/ */
unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len, unsigned int x86_disasm(const unsigned char *buf, unsigned int buf_len,
uint32_t buf_rva, unsigned int offset, uint32_t buf_rva, unsigned int offset,
x86_insn_t * insn ); x86_insn_t * insn );
/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer, /* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
@@ -803,7 +837,7 @@ public:
* void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg ) * void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
* where 'alias_reg' is a reg operand and 'output_reg' is filled with the * where 'alias_reg' is a reg operand and 'output_reg' is filled with the
* register that the operand is an alias for */ * register that the operand is an alias for */
//#define x86_get_aliased_reg( alias_reg, output_reg ) \ //#define x86_get_aliased_reg( alias_reg, output_reg )
// x86_reg_from_id( alias_reg->alias, output_reg ) // x86_reg_from_id( alias_reg->alias, output_reg )

View File

@@ -21,7 +21,7 @@ void x86_insn_t::make_invalid(unsigned char *buf)
type = insn_invalid; type = insn_invalid;
memcpy( bytes, buf, 1 ); memcpy( bytes, buf, 1 );
} }
unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len, unsigned int X86_Disasm::x86_disasm( const unsigned char *buf, unsigned int buf_len,
uint32_t buf_rva, unsigned int offset, uint32_t buf_rva, unsigned int offset,
x86_insn_t *insn ){ x86_insn_t *insn ){
int len, size; int len, size;
@@ -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 ) {
@@ -161,7 +161,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
} }
if ( follow_insn_dest(&insn) ) { if ( follow_insn_dest(&insn) ) {
op = insn.x86_operand_1st();//x86_get_dest_operand op = insn.operand_1st();//x86_get_dest_operand
next_addr = -1; next_addr = -1;
/* if caller supplied a resolver, use it to determine /* if caller supplied a resolver, use it to determine
@@ -175,8 +175,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
if (next_addr != -1 ) { if (next_addr != -1 ) {
next_offset = next_addr - buf_rva; next_offset = next_addr - buf_rva;
/* if offset is in this buffer... */ /* if offset is in this buffer... */
if ( next_offset >= 0 && if ( next_offset >= 0 && next_offset < 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);
@@ -1051,8 +1052,8 @@ static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
/* do long jump/call prefix */ /* do long jump/call prefix */
if ( insn->type == insn_jmp || insn->type == insn_call ) { if ( insn->type == insn_jmp || insn->type == insn_call ) {
if (! is_imm_jmp( insn->x86_operand_1st() ) || if (! is_imm_jmp( insn->operand_1st() ) ||
(insn->x86_operand_1st())->datatype != op_byte ) { (insn->operand_1st())->datatype != op_byte ) {
/* far jump/call, use "l" prefix */ /* far jump/call, use "l" prefix */
STRNCAT( buf, "l", len ); STRNCAT( buf, "l", len );
} }
@@ -1076,11 +1077,11 @@ static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
insn->type == insn_out insn->type == insn_out
)) { )) {
if ( insn->x86_operand_count( op_explicit ) > 0 && if ( insn->x86_operand_count( op_explicit ) > 0 &&
is_memory_op( insn->x86_operand_1st() ) ){ is_memory_op( insn->operand_1st() ) ){
size = insn->x86_operand_1st()->operand_size(); size = insn->operand_1st()->operand_size();
} else if ( insn->x86_operand_count( op_explicit ) > 1 && } else if ( insn->x86_operand_count( op_explicit ) > 1 &&
is_memory_op( insn->x86_operand_2nd() ) ){ is_memory_op( insn->operand_2nd() ) ){
size = insn->x86_operand_2nd()->operand_size(); size = insn->operand_2nd()->operand_size();
} }
} }
@@ -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;
@@ -1223,24 +1223,24 @@ static int format_xml_insn( x86_insn_t *insn, char *buf, int len ) {
len -= format_insn_eflags_str( insn->flags_tested, buf, len ); len -= format_insn_eflags_str( insn->flags_tested, buf, len );
STRNCAT( buf, "\"/>\n\t</flags>\n", len ); STRNCAT( buf, "\"/>\n\t</flags>\n", len );
if ( insn->x86_operand_1st() ) { if ( insn->operand_1st() ) {
insn->x86_operand_1st()->x86_format_operand(str, insn->operand_1st()->x86_format_operand(str,
sizeof str, xml_syntax); sizeof str, xml_syntax);
STRNCAT( buf, "\t<operand name=dest>\n", len ); STRNCAT( buf, "\t<operand name=dest>\n", len );
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
STRNCAT( buf, "\t</operand>\n", len ); STRNCAT( buf, "\t</operand>\n", len );
} }
if ( insn->x86_operand_2nd() ) { if ( insn->operand_2nd() ) {
insn->x86_operand_2nd()->x86_format_operand(str,sizeof str, insn->operand_2nd()->x86_format_operand(str,sizeof str,
xml_syntax); xml_syntax);
STRNCAT( buf, "\t<operand name=src>\n", len ); STRNCAT( buf, "\t<operand name=src>\n", len );
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
STRNCAT( buf, "\t</operand>\n", len ); STRNCAT( buf, "\t</operand>\n", len );
} }
if ( insn->x86_operand_3rd() ) { if ( insn->operand_3rd() ) {
insn->x86_operand_3rd()->x86_format_operand(str,sizeof str, insn->operand_3rd()->x86_format_operand(str,sizeof str,
xml_syntax); xml_syntax);
STRNCAT( buf, "\t<operand name=imm>\n", len ); STRNCAT( buf, "\t<operand name=imm>\n", len );
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
@@ -1342,13 +1342,13 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
STRNCAT( buf, "\t", len ); STRNCAT( buf, "\t", len );
/* dest */ /* dest */
if ( (dst = x86_operand_1st()) && !(dst->flags.op_implied) ) { if ( (dst = operand_1st()) && !(dst->flags.op_implied) ) {
dst->x86_format_operand(str, MAX_OP_STRING, format); dst->x86_format_operand(str, MAX_OP_STRING, format);
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
} }
/* src */ /* src */
if ( (src = x86_operand_2nd()) ) { if ( (src = operand_2nd()) ) {
if ( !(dst->flags.op_implied) ) { if ( !(dst->flags.op_implied) ) {
STRNCAT( buf, ", ", len ); STRNCAT( buf, ", ", len );
} }
@@ -1357,9 +1357,9 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
} }
/* imm */ /* imm */
if ( x86_operand_3rd()) { if ( operand_3rd()) {
STRNCAT( buf, ", ", len ); STRNCAT( buf, ", ", len );
x86_operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format); operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
} }
@@ -1373,8 +1373,8 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
/* not sure which is correct? sometimes GNU as requires /* not sure which is correct? sometimes GNU as requires
* an imm as the first operand, sometimes as the third... */ * an imm as the first operand, sometimes as the third... */
/* imm */ /* imm */
if ( x86_operand_3rd() ) { if ( operand_3rd() ) {
x86_operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format); operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
/* there is always 'dest' operand if there is 'src' */ /* there is always 'dest' operand if there is 'src' */
STRNCAT( buf, ", ", len ); STRNCAT( buf, ", ", len );
@@ -1382,13 +1382,13 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
if ( (note & insn_note_nonswap ) == 0 ) { if ( (note & insn_note_nonswap ) == 0 ) {
/* regular AT&T style swap */ /* regular AT&T style swap */
src = x86_operand_2nd(); src = operand_2nd();
dst = x86_operand_1st(); dst = operand_1st();
} }
else { else {
/* special-case instructions */ /* special-case instructions */
src = x86_operand_1st(); src = operand_1st();
dst = x86_operand_2nd(); dst = operand_2nd();
} }
/* src */ /* src */
@@ -1431,20 +1431,20 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
/* print operands */ /* print operands */
/* dest */ /* dest */
if ( x86_operand_1st() ) { if ( operand_1st() ) {
x86_operand_1st()->x86_format_operand(str, MAX_OP_STRING,format); operand_1st()->x86_format_operand(str, MAX_OP_STRING,format);
STRNCATF( buf, "%s\t", str, len ); STRNCATF( buf, "%s\t", str, len );
} }
/* src */ /* src */
if ( x86_operand_2nd() ) { if ( operand_2nd() ) {
x86_operand_2nd()->x86_format_operand(str, MAX_OP_STRING,format); operand_2nd()->x86_format_operand(str, MAX_OP_STRING,format);
STRNCATF( buf, "%s\t", str, len ); STRNCATF( buf, "%s\t", str, len );
} }
/* imm */ /* imm */
if ( x86_operand_3rd()) { if ( operand_3rd()) {
x86_operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format); operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
STRNCAT( buf, str, len ); STRNCAT( buf, str, len );
} }
} }

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 )
@@ -94,13 +93,12 @@ x86_op_t * x86_insn_t::x86_get_branch_target() {
return NULL; return NULL;
} }
x86_op_t * x86_insn_t::get_dest() { const x86_op_t * x86_insn_t::get_dest() const {
x86_oplist_t *op_lst; x86_oplist_t *op_lst;
assert(this); assert(this);
if ( ! operands ) { if ( ! operands ) {
return NULL; return NULL;
} }
assert(this->x86_operand_count(op_dest)==1);
for (op_lst = operands; op_lst; op_lst = op_lst->next ) { for (op_lst = operands; op_lst; op_lst = op_lst->next ) {
if ( op_lst->op.access & op_write) if ( op_lst->op.access & op_write)
return &(op_lst->op); return &(op_lst->op);
@@ -171,7 +169,7 @@ uint8_t *x86_insn_t::x86_get_raw_imm() {
} }
size_t x86_op_t::operand_size() { size_t x86_op_t::operand_size() const {
switch (datatype ) { switch (datatype ) {
case op_byte: return 1; case op_byte: return 1;
case op_word: return 2; case op_word: return 2;
@@ -203,13 +201,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 +217,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 +225,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;
@@ -185,7 +184,7 @@ size_t x86_insn_t::x86_operand_count( enum x86_op_foreach_type type ) {
} }
/* accessor functions */ /* accessor functions */
x86_op_t * x86_insn_t::x86_operand_1st() { x86_op_t * x86_insn_t::operand_1st() {
if (! explicit_count ) { if (! explicit_count ) {
return NULL; return NULL;
} }
@@ -193,7 +192,7 @@ x86_op_t * x86_insn_t::x86_operand_1st() {
return &(operands->op); return &(operands->op);
} }
x86_op_t * x86_insn_t::x86_operand_2nd( ) { x86_op_t * x86_insn_t::operand_2nd( ) {
if ( explicit_count < 2 ) { if ( explicit_count < 2 ) {
return NULL; return NULL;
} }
@@ -201,7 +200,7 @@ x86_op_t * x86_insn_t::x86_operand_2nd( ) {
return &(operands->next->op); return &(operands->next->op);
} }
x86_op_t * x86_insn_t::x86_operand_3rd( ) { x86_op_t * x86_insn_t::operand_3rd( ) {
if ( explicit_count < 3 ) { if ( explicit_count < 3 ) {
return NULL; return NULL;
} }

View File

@@ -2,27 +2,30 @@ PROJECT(dcc_original)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
OPTION(dcc_build_tests "Enable unit tests." OFF) OPTION(dcc_build_tests "Enable unit tests." OFF)
#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS)
IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)") 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})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
include(cotire)
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()
ADD_SUBDIRECTORY(3rd_party) ADD_SUBDIRECTORY(3rd_party)
llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support) llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support tablegen)
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
3rd_party/libdisasm 3rd_party/libdisasm
include include
@@ -30,9 +33,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,8 +47,10 @@ 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/RegisterNode
src/idioms.cpp src/idioms.cpp
src/idioms/idiom1.cpp src/idioms/idiom1.cpp
src/idioms/arith_idioms.cpp src/idioms/arith_idioms.cpp
@@ -58,6 +61,7 @@ set(dcc_SOURCES
src/idioms/shift_idioms.cpp src/idioms/shift_idioms.cpp
src/idioms/xor_idioms.cpp src/idioms/xor_idioms.cpp
src/locident.cpp src/locident.cpp
src/liveness_set.cpp
src/parser.cpp src/parser.cpp
src/perfhlib.cpp src/perfhlib.cpp
src/procs.cpp src/procs.cpp
@@ -69,6 +73,10 @@ set(dcc_SOURCES
src/symtab.cpp src/symtab.cpp
src/udm.cpp src/udm.cpp
src/BasicBlock.cpp src/BasicBlock.cpp
src/CallConvention.cpp
)
set(dcc_SOURCES
src/dcc.cpp
) )
set(dcc_HEADERS set(dcc_HEADERS
include/ast.h include/ast.h
@@ -101,12 +109,18 @@ set(dcc_HEADERS
include/Procedure.h include/Procedure.h
include/StackFrame.h include/StackFrame.h
include/BasicBlock.h include/BasicBlock.h
include/CallConvention.h
) )
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})
#cotire(dcc_lib)
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 LLVMSupport dcc_lib disasm_s ${REQ_LLVM_LIBRARIES} LLVMSupport)
if(dcc_build_tests) if(dcc_build_tests)
ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(src)
endif() endif()

2762
CMakeScripts/cotire.cmake Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
./test_use_all.sh ./test_use_all.sh
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ ./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/

View File

@@ -5,7 +5,7 @@
#include <string> #include <string>
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h> #include <llvm/ADT/ilist_node.h>
#include <boost/range.hpp> #include <boost/range/iterator_range.hpp>
#include "icode.h" #include "icode.h"
#include "types.h" #include "types.h"
#include "graph.h" #include "graph.h"
@@ -16,24 +16,28 @@ class CIcodeRec;
struct BB; struct BB;
struct LOCAL_ID; struct LOCAL_ID;
struct interval; struct interval;
//TODO: consider default address value -> INVALID
struct TYPEADR_TYPE struct TYPEADR_TYPE
{ {
uint32_t ip; /* Out edge icode address */ uint32_t ip; /* Out edge icode address */
BB * BBptr; /* Out edge pointer to next BB */ BB * BBptr; /* Out edge pointer to next BB */
interval *intPtr; /* Out edge ptr to next interval*/ interval *intPtr; /* Out edge ptr to next interval*/
TYPEADR_TYPE(uint32_t addr=0) : ip(addr),BBptr(nullptr),intPtr(nullptr)
{}
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
{}
}; };
struct BB : public llvm::ilist_node<BB> struct BB : public llvm::ilist_node<BB>
{ {
friend struct Function;
private: private:
BB(const BB&); BB(const BB&);
BB() : nodeType(0),traversed(DFS_NONE), BB() : nodeType(0),traversed(DFS_NONE),
numHlIcodes(0),flg(0), numHlIcodes(0),flg(0),
inEdges(0), inEdges(0),
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0), edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0), inInterval(0),correspInt(0),
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0), dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(NO_TYPE),latchNode(0),
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0) numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
{ {
@@ -41,6 +45,7 @@ private:
//friend class SymbolTableListTraits<BB, Function>; //friend class SymbolTableListTraits<BB, Function>;
typedef boost::iterator_range<iICODE> rCODE; typedef boost::iterator_range<iICODE> rCODE;
rCODE instructions; rCODE instructions;
rCODE &my_range() {return instructions;}
public: public:
struct ValidFunctor struct ValidFunctor
@@ -72,36 +77,31 @@ public:
interval *inInterval; /* Node's interval */ interval *inInterval; /* Node's interval */
/* For derived sequence construction */ /* For derived sequence construction */
interval *correspInt; /* Corresponding interval in interval *correspInt; //!< Corresponding interval in derived graph Gi-1
* derived graph Gi-1 */ // For live register analysis
// LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))
/* For live register analysis LivenessSet liveUse; /* LiveUse(b) */
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */ LivenessSet def; /* Def(b) */
std::bitset<32> liveUse; /* LiveUse(b) */ LivenessSet liveIn; /* LiveIn(b) */
std::bitset<32> def; /* Def(b) */ LivenessSet liveOut; /* LiveOut(b) */
std::bitset<32> liveIn; /* LiveIn(b) */
std::bitset<32> liveOut; /* LiveOut(b) */
/* For structuring analysis */ /* For structuring analysis */
int dfsFirstNum; /* DFS #: first visit of node */ int dfsFirstNum; /* DFS #: first visit of node */
int dfsLastNum; /* DFS #: last visit of node */ int dfsLastNum; /* DFS #: last visit of node */
int immedDom; /* Immediate dominator (dfsLast int immedDom; /* Immediate dominator (dfsLast index) */
* index) */
int ifFollow; /* node that ends the if */ int ifFollow; /* node that ends the if */
int loopType; /* Type of loop (if any) */ eNodeHeaderType loopType; /* Type of loop (if any) */
int latchNode; /* latching node of the loop */ int latchNode; /* latching node of the loop */
int numBackEdges; /* # of back edges */ size_t numBackEdges; /* # of back edges */
int loopHead; /* most nested loop head to which int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
* thcis node belongs (dfsLast) */
int loopFollow; /* node that follows the loop */ int loopFollow; /* node that follows the loop */
int caseHead; /* most nested case to which this int caseHead; /* most nested case to which this node belongs (dfsLast) */
node belongs (dfsLast) */
int caseTail; /* tail node for the case */ int caseTail; /* tail node for the case */
int index; /* Index, used in several ways */ int index; /* Index, used in several ways */
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0); static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent); static BB * CreateIntervalBB(Function *parent);
static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent); static BB * Create(const rCODE &r, eBBKind _nodeType, Function *parent);
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow); void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
void mergeFallThrough(CIcodeRec &Icode); void mergeFallThrough(CIcodeRec &Icode);
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last); void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
@@ -114,18 +114,23 @@ 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, bool &repCond);
void addOutEdge(uint32_t ip) // TODO: fix this void addOutEdge(uint32_t ip) // TODO: fix this
{ {
edges[0].ip = ip; edges.push_back(TYPEADR_TYPE(ip));
} }
void addOutEdgeInterval(interval *i) // TODO: fix this
{
edges.push_back(TYPEADR_TYPE(i));
}
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode); void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
private: private:
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at); bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
void ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode); void ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode);
bool isEndOfPath(int latch_node_idx) const; bool isEndOfPath(int latch_node_idx) const;
Function *Parent; Function *Parent;

View File

@@ -15,6 +15,8 @@ struct PROG /* Loaded program image parameters */
uint16_t segMain; /* The segment of the main() proc */ uint16_t segMain; /* The segment of the main() proc */
bool bSigs; /* True if signatures loaded */ bool bSigs; /* True if signatures loaded */
int cbImage; /* Length of image in bytes */ int cbImage; /* Length of image in bytes */
uint8_t * Image; /* Allocated by loader to hold entire program image */ const uint8_t *image() const {return Imagez;}
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
int addressingMode;
}; };

31
include/CallConvention.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include "ast.h"
struct CConv {
enum Type {
UNKNOWN=0,
C,
PASCAL
};
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
virtual void writeComments(std::ostream &)=0;
static CConv * create(Type v);
protected:
};
struct C_CallingConvention : public CConv {
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
virtual void writeComments(std::ostream &);
private:
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
};
struct Pascal_CallingConvention : public CConv {
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
virtual void writeComments(std::ostream &);
};
struct Unknown_CallingConvention : public CConv {
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
virtual void writeComments(std::ostream &);
};

View File

@@ -8,6 +8,7 @@ enum regType
}; };
enum condId enum condId
{ {
UNDEF=0,
GLOB_VAR, /* global variable */ GLOB_VAR, /* global variable */
REGISTER, /* register */ REGISTER, /* register */
LOCAL_VAR, /* negative disp */ LOCAL_VAR, /* negative disp */
@@ -176,7 +177,7 @@ enum llIcode
iPOP, iPOP,
iPOPA, iPOPA,
iPOPF, iPOPF,
iPUSH, iPUSH, // 77
iPUSHA, iPUSHA,
iPUSHF, iPUSHF,
iRCL, /* 80 */ iRCL, /* 80 */
@@ -216,6 +217,7 @@ enum condNodeType
{ {
UNKNOWN_OP=0, UNKNOWN_OP=0,
BOOLEAN_OP, /* condOps */ BOOLEAN_OP, /* condOps */
NEGATION, /* not (2's complement) */ NEGATION, /* not (2's complement) */
ADDRESSOF, /* addressOf (&) */ ADDRESSOF, /* addressOf (&) */
DEREFERENCE, /* contents of (*) */ DEREFERENCE, /* contents of (*) */
@@ -237,7 +239,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

@@ -2,32 +2,29 @@
#include "ast.h" #include "ast.h"
#include "types.h" #include "types.h"
#include "machine_x86.h" #include "machine_x86.h"
struct GlobalVariable;
struct AstIdent;
struct IDENTTYPE struct IDENTTYPE
{ {
friend struct GlobalVariable;
friend struct Constant;
friend struct AstIdent;
protected:
condId idType; condId idType;
regType regiType; /* for REGISTER only */ public:
condId type() {return idType;}
void type(condId t) {idType=t;}
union _idNode { union _idNode {
int regiIdx; /* index into localId, REGISTER */
int globIdx; /* index into symtab for GLOB_VAR */
int localIdx; /* idx into localId, LOCAL_VAR */ int localIdx; /* idx into localId, LOCAL_VAR */
int paramIdx; /* idx into args symtab, PARAMS */ int paramIdx; /* idx into args symtab, PARAMS */
int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
struct _kte
{ /* for CONSTANT only */
uint32_t kte; /* value of the constant */
uint8_t size; /* #bytes size constant */
} kte;
uint32_t strIdx; /* idx into image, for STRING */ uint32_t strIdx; /* idx into image, for STRING */
int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/ int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/
struct _call { /* for FUNCTION only */
Function *proc;
STKFRAME *args;
} call;
struct { /* for OTHER; tmp struct */ struct { /* for OTHER; tmp struct */
eReg seg; /* segment */ eReg seg; /* segment */
eReg regi; /* index mode */ eReg regi; /* index mode */
int16_t off; /* offset */ int16_t off; /* offset */
} other; } other;
} idNode; } idNode;
IDENTTYPE() : idType(UNDEF)
{}
}; };

View File

@@ -1,22 +1,23 @@
#pragma once #pragma once
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h> //#include <llvm/ADT/ilist_node.h>
#include <bitset> #include <bitset>
#include <map>
#include "BasicBlock.h" #include "BasicBlock.h"
#include "locident.h" #include "locident.h"
#include "state.h" #include "state.h"
#include "icode.h" #include "icode.h"
#include "StackFrame.h" #include "StackFrame.h"
#include "CallConvention.h"
/* PROCEDURE NODE */ /* PROCEDURE NODE */
struct CALL_GRAPH; struct CALL_GRAPH;
struct COND_EXPR; struct Expr;
struct Disassembler; struct Disassembler;
struct Function; struct Function;
struct CALL_GRAPH; struct CALL_GRAPH;
struct PROG;
typedef llvm::iplist<Function> FunctionListType; struct Function;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;
namespace llvm namespace llvm
{ {
@@ -48,9 +49,9 @@ enum PROC_FLAGS
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */ PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */ PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */ PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */ // CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
CALL_C =0x00004000, /* Proc uses C calling convention */ // CALL_C =0x00004000, /* Proc uses C calling convention */
CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */ // CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
PROC_NEAR =0x00010000, /* Proc exits with near return */ PROC_NEAR =0x00010000, /* Proc exits with near return */
PROC_FAR =0x00020000, /* Proc exits with far return */ PROC_FAR =0x00020000, /* Proc exits with far return */
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */ GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
@@ -58,24 +59,24 @@ enum PROC_FLAGS
DI_REGVAR =0x00400000, /* DI is used as a stack variable */ DI_REGVAR =0x00400000, /* DI is used as a stack variable */
PROC_IS_FUNC=0x00800000, /* Proc is a function */ PROC_IS_FUNC=0x00800000, /* Proc is a function */
REG_ARGS =0x01000000, /* Proc has registers as arguments */ REG_ARGS =0x01000000, /* Proc has registers as arguments */
PROC_VARARG =0x02000000, /* Proc has variable arguments */ // PROC_VARARG =0x02000000, /* Proc has variable arguments */
PROC_OUTPUT =0x04000000, /* C for this proc has been output */ PROC_OUTPUT =0x04000000, /* C for this proc has been output */
PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */ PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */
PROC_ISLIB =0x10000000, /* Proc is a library function */ PROC_ISLIB =0x10000000, /* Proc is a library function */
PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */ PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */
PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */ PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */
#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */ //#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
}; };
struct FunctionType struct FunctionType
{ {
bool m_vararg; bool m_vararg=false;
bool isVarArg() const {return m_vararg;} bool isVarArg() const {return m_vararg;}
}; };
struct Assignment struct Assignment
{ {
COND_EXPR *lhs; Expr *lhs;
COND_EXPR *rhs; Expr *rhs;
}; };
struct JumpTable struct JumpTable
{ {
@@ -86,17 +87,44 @@ struct JumpTable
size_t entrySize() { return 2;} size_t entrySize() { return 2;}
void pruneEntries(uint16_t cs); void pruneEntries(uint16_t cs);
}; };
class FunctionCfg
{
std::list<BB*> m_listBB; /* Ptr. to BB list/CFG */
public:
typedef std::list<BB*>::iterator iterator;
iterator begin() {
return m_listBB.begin();
}
iterator end() {
return m_listBB.end();
}
BB * &front() { return m_listBB.front();}
void nodeSplitting()
{
/* Converts the irreducible graph G into an equivalent reducible one, by
* means of node splitting. */
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
}
void push_back(BB *v) { m_listBB.push_back(v);}
};
struct Function : public llvm::ilist_node<Function> struct Function : public llvm::ilist_node<Function>
{ {
typedef llvm::iplist<BB> BasicBlockListType; typedef llvm::iplist<BB> BasicBlockListType;
// BasicBlock iterators... // BasicBlock iterators...
typedef BasicBlockListType::iterator iterator; typedef BasicBlockListType::iterator iterator;
typedef BasicBlockListType::const_iterator const_iterator; typedef BasicBlockListType::const_iterator const_iterator;
private: protected:
BasicBlockListType BasicBlocks; ///< The basic blocks BasicBlockListType BasicBlocks; ///< The basic blocks
Function(FunctionType */*ty*/) : procEntry(0),depth(0),flg(0),cbParam(0),m_dfsLast(0),numBBs(0),
hasCase(false),liveAnal(0)
{
type = new FunctionType;
callingConv(CConv::UNKNOWN);
}
public: public:
FunctionType * type;
CConv * m_call_conv;
uint32_t procEntry; /* label number */ uint32_t procEntry; /* label number */
std::string name; /* Meaningful name for this proc */ std::string name; /* Meaningful name for this proc */
STATE state; /* Entry state */ STATE state; /* Entry state */
@@ -109,38 +137,42 @@ public:
/* Icodes and control flow graph */ /* Icodes and control flow graph */
CIcodeRec Icode; /* Object with ICODE records */ CIcodeRec Icode; /* Object with ICODE records */
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */ FunctionCfg m_actual_cfg;
std::vector<BB*> m_dfsLast; std::vector<BB*> m_dfsLast;
std::list<BB*> heldBBs; std::map<int,BB*> m_ip_to_bb;
//BB * *dfsLast; /* Array of pointers to BBs in dfsLast
// * (reverse postorder) order */ // * (reverse postorder) order */
size_t numBBs; /* Number of BBs in the graph cfg */ size_t numBBs; /* Number of BBs in the graph cfg */
bool hasCase; /* Procedure has a case node */ bool hasCase; /* Procedure has a case node */
/* For interprocedural live analysis */ /* For interprocedural live analysis */
std::bitset<32> liveIn; /* Registers used before defined */ LivenessSet liveIn; /* Registers used before defined */
std::bitset<32> liveOut; /* Registers that may be used in successors */ LivenessSet 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), virtual ~Function() {
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0) delete type;
{
} }
public: public:
static Function *Create(void *ty=0,int Linkage=0,const std::string &nm="",void *module=0) static Function *Create(FunctionType *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;
return r; return r;
} }
bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;} FunctionType *getFunctionType() const {
return type;
}
CConv *callingConv() const { return m_call_conv;}
void callingConv(CConv::Type v);
// bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;} bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;} bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
void compoundCond(); void compoundCond();
void writeProcComments(); void writeProcComments();
void lowLevelAnalysis(); void lowLevelAnalysis();
void bindIcodeOff(); void bindIcodeOff();
void dataFlow(std::bitset<32> &liveOut); void dataFlow(LivenessSet &liveOut);
void compressCFG(); void compressCFG();
void highLevelGen(); void highLevelGen();
void structure(derSeq *derivedG); void structure(derSeq *derivedG);
@@ -151,7 +183,7 @@ public:
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate); void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
void process_operands(ICODE &pIcode, STATE *pstate); void process_operands(ICODE &pIcode, STATE *pstate);
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph); bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
void freeCFG(); void freeCFG();
void codeGen(std::ostream &fs); void codeGen(std::ostream &fs);
void mergeFallThrough(BB *pBB); void mergeFallThrough(BB *pBB);
@@ -164,9 +196,14 @@ public:
void displayCFG(); void displayCFG();
void displayStats(); void displayStats();
void processHliCall(COND_EXPR *exp, iICODE picode); void processHliCall(Expr *exp, iICODE picode);
void preprocessReturnDU(std::bitset<32> &_liveOut); void preprocessReturnDU(LivenessSet &_liveOut);
Expr * adjustActArgType(Expr *_exp, hlType forType);
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
void processDosInt(STATE *pstate, PROG &prog, bool done);
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
protected: protected:
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table); void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
@@ -190,10 +227,32 @@ protected:
void findExps(); void findExps();
void genDU1(); void genDU1();
void elimCondCodes(); void elimCondCodes();
void liveRegAnalysis(std::bitset<32> &in_liveOut); void liveRegAnalysis(LivenessSet &in_liveOut);
void findIdioms(); void findIdioms();
void propLong(); void propLong();
void genLiveKtes(); void genLiveKtes();
uint8_t findDerivedSeq (derSeq &derivedGi); bool findDerivedSeq(derSeq &derivedGi);
bool nextOrderGraph(derSeq &derivedGi); bool nextOrderGraph(derSeq &derivedGi);
}; };
namespace llvm {
template<> struct ilist_traits<typename ::Function>
: public ilist_default_traits<typename ::Function> {
// createSentinel is used to get hold of the node that marks the end of the
// list... (same trick used here as in ilist_traits<Instruction>)
typename ::Function *createSentinel() const {
return static_cast<typename ::Function*>(&Sentinel);
}
static void destroySentinel(typename ::Function*) {}
typename ::Function *provideInitialHead() const { return createSentinel(); }
typename ::Function *ensureHead(::Function*) const { return createSentinel(); }
static void noteHead(typename ::Function*, typename ::Function*) {}
private:
mutable ilist_node<typename ::Function> Sentinel;
};
}
typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;

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

@@ -5,10 +5,11 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
*/ */
#pragma once #pragma once
#include <stdint.h>
#include <cstring> #include <cstring>
#include <list> #include <list>
#include <boost/range/iterator_range.hpp>
#include "Enums.h" #include "Enums.h"
#include <boost/range.hpp>
static const int operandSize=20; static const int operandSize=20;
/* The following definitions and types define the Conditional Expression /* The following definitions and types define the Conditional Expression
* attributed syntax tree, as defined by the following EBNF: * attributed syntax tree, as defined by the following EBNF:
@@ -22,129 +23,160 @@ static const int operandSize=20;
static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER, static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER,
EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL, EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL,
LESS_EQUAL, GREATER, GREATER_EQUAL, LESS}; LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
struct AstIdent;
struct Function; struct Function;
struct STKFRAME; struct STKFRAME;
struct LOCAL_ID; struct LOCAL_ID;
struct ICODE; struct ICODE;
struct LLInst; struct LLInst;
struct LLOperand;
struct ID; struct ID;
typedef std::list<ICODE>::iterator iICODE; typedef std::list<ICODE>::iterator iICODE;
typedef boost::iterator_range<iICODE> rICODE; typedef boost::iterator_range<iICODE> rICODE;
#include "IdentType.h" #include "IdentType.h"
/* Expression data type */ /* Expression data type */
struct COND_EXPR struct Expr
{ {
protected:
struct /* for BOOLEAN_OP */
{
condOp op;
COND_EXPR *lhs;
COND_EXPR *rhs;
} boolExpr;
public: public:
condNodeType m_type; /* Conditional Expression Node Type */ condNodeType m_type; /* Conditional Expression Node Type */
union _exprNode { /* Different cond expr nodes */
COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/
IDENTTYPE ident; /* for IDENTIFIER */
} expr;
COND_EXPR *lhs()
{
assert(m_type==BOOLEAN_OP);
return boolExpr.lhs;
}
const COND_EXPR *lhs() const
{
assert(m_type==BOOLEAN_OP);
return boolExpr.lhs;
}
COND_EXPR *rhs()
{
assert(m_type==BOOLEAN_OP);
return boolExpr.rhs;
}
const COND_EXPR *rhs() const
{
assert(m_type==BOOLEAN_OP);
return boolExpr.rhs;
}
condOp op() const { return boolExpr.op;}
public: public:
static COND_EXPR *idRegIdx(int idx, regType reg_type); static bool insertSubTreeLongReg(Expr *exp, Expr *&tree, int longIdx);
static COND_EXPR *idKte(uint32_t kte, uint8_t size); static bool insertSubTreeReg(Expr *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
static COND_EXPR *idLoc(int off, LOCAL_ID *localId); static bool insertSubTreeReg(AstIdent *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
static COND_EXPR *idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
static COND_EXPR *idLongIdx(int idx);
static COND_EXPR *idOther(eReg seg, eReg regi, int16_t off);
static COND_EXPR *idParam(int off, const STKFRAME *argSymtab);
static COND_EXPR *unary(condNodeType t, COND_EXPR *sub_expr);
static COND_EXPR *idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static COND_EXPR *idFunc(Function *pproc, STKFRAME *args);
static COND_EXPR *idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
static COND_EXPR *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
public: public:
virtual COND_EXPR *clone() const;
void release(); virtual Expr *clone() const=0; //!< Makes a deep copy of the given expression
void changeBoolOp(condOp newOp); Expr(condNodeType t=UNKNOWN_OP) : m_type(t)
COND_EXPR(const COND_EXPR &other)
{ {
m_type=other.m_type;
expr=other.expr;
boolExpr=other.boolExpr;
}
COND_EXPR(condNodeType t=UNKNOWN_OP) : m_type(t)
{
memset(&expr,0,sizeof(_exprNode));
memset(&boolExpr,0,sizeof(boolExpr));
} }
virtual ~COND_EXPR() {} /** Recursively deallocates the abstract syntax tree rooted at *exp */
virtual ~Expr() {}
public: public:
virtual COND_EXPR *inverse() const; // return new COND_EXPR that is invarse of this virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId); virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym); virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
virtual hlType expType(Function *pproc) const; virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx)=0;
virtual hlType expType(Function *pproc) const=0;
virtual int hlTypeSize(Function *pproc) const=0;
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId) { return this; }
}; };
struct BinaryOperator : public COND_EXPR struct UnaryOperator : public Expr
{
UnaryOperator(condNodeType t=UNKNOWN_OP) : Expr(t),unaryExp(nullptr) {}
Expr *unaryExp;
virtual Expr *inverse() const
{
if (m_type == NEGATION) //TODO: memleak here
{
return unaryExp->clone();
}
return this->clone();
}
virtual Expr *clone() const
{
UnaryOperator *newExp = new UnaryOperator(*this);
newExp->unaryExp = unaryExp->clone();
return newExp;
}
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
static UnaryOperator *Create(condNodeType t, Expr *sub_expr)
{
UnaryOperator *newExp = new UnaryOperator();
newExp->m_type = t;
newExp->unaryExp = sub_expr;
return (newExp);
}
~UnaryOperator()
{
delete unaryExp;
unaryExp=nullptr;
}
public:
int hlTypeSize(Function *pproc) const;
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual hlType expType(Function *pproc) const;
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
};
struct BinaryOperator : public Expr
{ {
condOp m_op; condOp m_op;
COND_EXPR *m_lhs; Expr *m_lhs;
COND_EXPR *m_rhs; Expr *m_rhs;
BinaryOperator(condOp o) BinaryOperator(condOp o) : Expr(BOOLEAN_OP)
{ {
m_op = o; m_op = o;
m_lhs=m_rhs=nullptr; m_lhs=m_rhs=nullptr;
} }
static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r); BinaryOperator(condOp o,Expr *l,Expr *r) : Expr(BOOLEAN_OP)
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r); {
virtual COND_EXPR *inverse(); m_op = o;
virtual COND_EXPR *clone(); m_lhs=l;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs); m_rhs=r;
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym); }
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx); ~BinaryOperator()
{
assert(m_lhs!=m_rhs || m_lhs==nullptr);
delete m_lhs;
delete m_rhs;
m_lhs=m_rhs=nullptr;
}
static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
{
BinaryOperator *res = new BinaryOperator(o);
res->m_lhs = l;
res->m_rhs = r;
return res;
}
static BinaryOperator *LogicAnd(Expr *l,Expr *r)
{
return Create(DBL_AND,l,r);
}
static BinaryOperator *createSHL(Expr *l,Expr *r)
{
return Create(SHL,l,r);
}
static BinaryOperator *And(Expr *l,Expr *r)
{
return Create(AND,l,r);
}
static BinaryOperator *Or(Expr *l,Expr *r)
{
return Create(OR,l,r);
}
static BinaryOperator *LogicOr(Expr *l,Expr *r)
{
return Create(DBL_OR,l,r);
}
static BinaryOperator *CreateAdd(Expr *l,Expr *r) {
return Create(ADD,l,r);
COND_EXPR *lhs() }
void changeBoolOp(condOp newOp);
virtual Expr *inverse() const;
virtual Expr *clone() const;
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
const Expr *lhs() const
{
return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->lhs());
}
const Expr *rhs() const
{
return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->rhs());
}
Expr *lhs()
{ {
assert(m_type==BOOLEAN_OP); assert(m_type==BOOLEAN_OP);
return m_lhs; return m_lhs;
} }
const COND_EXPR *lhs() const Expr *rhs()
{
assert(m_type==BOOLEAN_OP);
return m_lhs;
}
COND_EXPR *rhs()
{
assert(m_type==BOOLEAN_OP);
return m_rhs;
}
const COND_EXPR *rhs() const
{ {
assert(m_type==BOOLEAN_OP); assert(m_type==BOOLEAN_OP);
return m_rhs; return m_rhs;
@@ -152,26 +184,134 @@ struct BinaryOperator : public COND_EXPR
condOp op() const { return m_op;} condOp op() const { return m_op;}
/* Changes the boolean conditional operator at the root of this expression */ /* Changes the boolean conditional operator at the root of this expression */
void op(condOp o) { m_op=o;} void op(condOp o) { m_op=o;}
std::string walkCondExpr (Function * pProc, int* numLoc) const;
public:
hlType expType(Function *pproc) const;
int hlTypeSize(Function *pproc) const;
}; };
struct UnaryOperator : public COND_EXPR struct AstIdent : public UnaryOperator
{ {
condOp op; AstIdent() : UnaryOperator(IDENTIFIER)
COND_EXPR *unaryExp;
virtual COND_EXPR *inverse();
virtual COND_EXPR *clone();
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
{ {
UnaryOperator *newExp = new UnaryOperator();
newExp->m_type=t;
newExp->unaryExp = sub_expr;
return (newExp);
} }
}; IDENTTYPE ident; /* for IDENTIFIER */
static AstIdent * Loc(int off, LOCAL_ID *localId);
static AstIdent * LongIdx(int idx);
static AstIdent * String(uint32_t idx);
static AstIdent * Other(eReg seg, eReg regi, int16_t off);
static AstIdent * Param(int off, const STKFRAME *argSymtab);
static AstIdent * Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
static AstIdent * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
static Expr * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
struct GlobalVariable : public COND_EXPR virtual Expr *clone() const
{ {
static COND_EXPR *Create(int16_t segValue, int16_t off); return new AstIdent(*this);
}
virtual int hlTypeSize(Function *pproc) const;
virtual hlType expType(Function *pproc) const;
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
protected:
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
};
struct GlobalVariable : public AstIdent
{
bool valid;
int globIdx;
virtual Expr *clone() const
{
return new GlobalVariable(*this);
}
GlobalVariable(int16_t segValue, int16_t off);
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct GlobalVariableIdx : public AstIdent
{
bool valid;
int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
virtual Expr *clone() const
{
return new GlobalVariableIdx(*this);
}
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct Constant : public AstIdent
{
struct _kte
{ /* for CONSTANT only */
uint32_t kte; /* value of the constant */
uint8_t size; /* #bytes size constant */
} kte;
Constant(uint32_t _kte, uint8_t size)
{
ident.idType = CONSTANT;
kte.kte = _kte;
kte.size = size;
}
virtual Expr *clone() const
{
return new Constant(*this);
}
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct FuncNode : public AstIdent
{
struct _call { /* for FUNCTION only */
Function *proc;
STKFRAME *args;
} call;
FuncNode(Function *pproc, STKFRAME *args)
{
call.proc = pproc;
call.args = args;
}
virtual Expr *clone() const
{
return new FuncNode(*this);
}
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *pproc) const;
hlType expType(Function *pproc) const;
};
struct RegisterNode : public AstIdent
{
const LOCAL_ID *m_syms;
regType regiType; /* for REGISTER only */
int regiIdx; /* index into localId, REGISTER */
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
RegisterNode(int idx, regType reg_type,const LOCAL_ID *syms)
{
m_syms= syms;
ident.type(REGISTER);
regiType = reg_type;
regiIdx = idx;
}
RegisterNode(const LLOperand &, LOCAL_ID *locsym);
//RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
virtual Expr *clone() const
{
return new RegisterNode(*this);
}
std::string walkCondExpr(Function *pProc, int *numLoc) const;
int hlTypeSize(Function *) const;
hlType expType(Function *pproc) const;
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
}; };
struct Constant : public COND_EXPR
{};

View File

@@ -33,7 +33,7 @@ public:
int current_indent; int current_indent;
}; };
extern bundle cCode;
#define lineSize 360 /* 3 lines in the mean time */ #define lineSize 360 /* 3 lines in the mean time */
//void newBundle (bundle *procCode); //void newBundle (bundle *procCode);

View File

@@ -20,27 +20,8 @@
#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
{
ilFunction proc; /* Pointer to procedure in pProcList */
std::vector<CALL_GRAPH *> outEdges; /* array of out edges */
public:
void write();
CALL_GRAPH() : outEdges(0)
{
}
public:
void writeNodeCallGraph(int indIdx);
bool insertCallGraph(ilFunction caller, ilFunction callee);
bool insertCallGraph(Function *caller, ilFunction callee);
void insertArc(ilFunction newProc);
};
//#define NUM_PROCS_DELTA 5 /* delta # procs a proc invokes */
//extern std::list<Function> pProcList;
//extern FunctionListType pProcList;
//extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
extern bundle cCode; /* Output C procedure's declaration and code */ extern bundle cCode; /* Output C procedure's declaration and code */
/**** Global variables ****/ /**** Global variables ****/
@@ -62,12 +43,8 @@ typedef struct { /* Command line option flags */
extern OPTION option; /* Command line options */ extern OPTION option; /* Command line options */
#include "BinaryImage.h" #include "BinaryImage.h"
extern std::bitset<32> duReg[30]; /* def/use bits for registers */
//extern uint32_t duReg[30]; /* def/use bits for registers */
extern std::bitset<32> maskDuReg[30]; /* masks off du bits for regs */
/* Registers used by icode instructions */
/* Memory map states */ /* Memory map states */
enum eAreaType enum eAreaType
@@ -110,13 +87,13 @@ void udm(void); /* udm.c */
void freeCFG(BB * cfg); /* graph.c */ void freeCFG(BB * cfg); /* graph.c */
BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */ BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */
void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */ void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */
char *cChar(uint8_t c); /* backend.c */ extern char *cChar(uint8_t c); /* backend.c */
eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */ eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */
void parse (CALL_GRAPH * *); /* parser.c */ void parse (CALL_GRAPH * *); /* parser.c */
int strSize (uint8_t *, char); /* parser.c */ extern int strSize (const 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 */
@@ -124,25 +101,15 @@ void SetupLibCheck(void); /* chklib.c */
void CleanupLibCheck(void); /* chklib.c */ void CleanupLibCheck(void); /* chklib.c */
bool LibCheck(Function &p); /* chklib.c */ bool LibCheck(Function &p); /* chklib.c */
/* Exported functions from procs.c */
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
void adjustActArgType (COND_EXPR *, hlType, Function *);
/* Exported functions from ast.c */
std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, int *);
int hlTypeSize (const COND_EXPR *, Function *);
//hlType expType (const COND_EXPR *, Function *);
/* Exported functions from hlicode.c */ /* Exported functions from hlicode.c */
std::string writeCall (Function *, STKFRAME &, Function *, int *); const char *writeJcond(const HLTYPE &, Function *, int *);
char *writeJcond (const HLTYPE &, Function *, int *); const char *writeJcondInv (HLTYPE, Function *, int *);
char *writeJcondInv (HLTYPE, Function *, int *);
/* Exported funcions from locident.c */ /* Exported funcions from locident.c */
boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset); bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &); bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
eReg otherLongRegi(eReg, int, LOCAL_ID *); eReg otherLongRegi(eReg, int, LOCAL_ID *);

View File

@@ -1,9 +1,10 @@
/**************************************************************************** /*
* dcc project disassembler header ***************************************************************************
* (C) Mike van Emmerik dcc project disassembler header
****************************************************************************/ (C) Mike van Emmerik
***************************************************************************
*/
#pragma once #pragma once
#include <sstream>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include "bundle.h" #include "bundle.h"
@@ -32,24 +33,6 @@ public:
#define EXT 0x100 /* "Extended" flag */ #define EXT 0x100 /* "Extended" flag */
#ifdef __MSDOS__
#define KEY_DOWN EXT+'P'
#define KEY_LEFT EXT+'K'
#define KEY_UP EXT+'H'
#define KEY_RIGHT EXT+'M'
#define KEY_NPAGE EXT+'Q'
#define KEY_PPAGE EXT+'I'
#endif
#ifdef _CONSOLE
#define KEY_DOWN 0x50 /* Same as keypad scancodes */
#define KEY_LEFT 0x4B
#define KEY_UP 0x48
#define KEY_RIGHT 0x4D
#define KEY_NPAGE 0x51
#define KEY_PPAGE 0x49
#endif
#ifdef __UNIX__ #ifdef __UNIX__
#define KEY_DOWN EXT+'B' #define KEY_DOWN EXT+'B'
#define KEY_LEFT EXT+'D' #define KEY_LEFT EXT+'D'

View File

@@ -1,8 +1,11 @@
/*************************************************************************** /*
=**************************************************************************
* File : dosdcc.h * File : dosdcc.h
* Purpose : include file for files decompiled by dcc. * Purpose : include file for files decompiled by dcc.
* Copyright (c) Cristina Cifuentes - QUT - 1992 * Copyright (c) Cristina Cifuentes - QUT - 1992
**************************************************************************/ *************************************************************************
*/
/* Type definitions for intel 80x86 architecture */ /* Type definitions for intel 80x86 architecture */
typedef unsigned int uint16_t; /* 16 bits */ typedef unsigned int uint16_t; /* 16 bits */

View File

@@ -1,7 +1,10 @@
/***************************************************************************** /*
****************************************************************************
* Error codes * Error codes
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ***************************************************************************
*/
#pragma once #pragma once
/* These definitions refer to errorMessage in error.c */ /* These definitions refer to errorMessage in error.c */

View File

@@ -1,10 +1,13 @@
/***************************************************************************** /*
****************************************************************************
* CFG, BB and interval related definitions * CFG, BB and interval related definitions
* ( C ) Cristina Cifuentes * ( C ) Cristina Cifuentes
****************************************************************************/ ****************************************************************************
*/
#pragma once #pragma once
#include <stdint.h>
#include <list> #include <list>
#include <vector>
struct Function; struct Function;
/* Types of basic block nodes */ /* Types of basic block nodes */
/* Real basic blocks: type defined according to their out-edges */ /* Real basic blocks: type defined according to their out-edges */
@@ -55,6 +58,7 @@ enum eNodeHeaderType
#define ELSE 1 /* else edge */ #define ELSE 1 /* else edge */
/* Basic Block (BB) flags */ /* Basic Block (BB) flags */
#define INVALID_BB 0x0001 /* BB is not valid any more */ #define INVALID_BB 0x0001 /* BB is not valid any more */
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */ #define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
@@ -64,30 +68,24 @@ typedef std::list<BB *> queue;
struct interval struct interval
{ {
uint8_t numInt; /* # of the interval */ uint8_t numInt=0; /* # of the interval */
uint8_t numOutEdges; /* Number of out edges */ uint8_t numOutEdges=0; /* Number of out edges */
queue nodes; /* Nodes of the interval*/ queue nodes; /* Nodes of the interval*/
queue::iterator currNode; /* Current node */ queue::iterator currNode; /* Current node */
interval *next; /* Next interval */ interval * next=0; /* Next interval */
BB * firstOfInt(); BB * firstOfInt();
interval() interval() : currNode(nodes.end()){
{
numInt=numOutEdges=0;
currNode=nodes.end();
next=0;
} }
void appendNodeInt(queue &pqH, BB *node);
}; };
/* Derived Sequence structure */ /* Derived Sequence structure */
struct derSeq_Entry struct derSeq_Entry
{ {
BB * Gi; /* Graph pointer */ BB * Gi=nullptr; /* Graph pointer */
interval * Ii; /* Interval list of Gi */ std::list<interval *> m_intervals;
derSeq_Entry() : Gi(0),Ii(0) interval * Ii=nullptr; /* Interval list of Gi */
{
}
~derSeq_Entry(); ~derSeq_Entry();
public: public:
void findIntervals(Function *c); void findIntervals(Function *c);

View File

@@ -7,17 +7,18 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <bitset> #include <bitset>
#include <set>
#include <algorithm>
#include <initializer_list>
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h> #include <llvm/ADT/ilist_node.h>
#include <llvm/CodeGen/MachineInstr.h>
#include <llvm/MC/MCInst.h> #include <llvm/MC/MCInst.h>
#include <llvm/MC/MCAsmInfo.h> #include <llvm/IR/Instruction.h>
#include <llvm/Value.h> #include <boost/range/iterator_range.hpp>
#include <llvm/Instruction.h>
#include <boost/range.hpp>
#include "libdis.h" #include "libdis.h"
#include "Enums.h" #include "Enums.h"
#include "state.h" // State depends on INDEXBASE, but later need STATE #include "state.h" // State depends on INDEXBASE, but later need STATE
#include "CallConvention.h"
//enum condId; //enum condId;
@@ -25,13 +26,102 @@ 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];
struct LivenessSet
{
std::set<eReg> registers;
public:
LivenessSet(const std::initializer_list<eReg> &init) : registers(init) {}
LivenessSet() {}
LivenessSet(const LivenessSet &other) : registers(other.registers)
{
}
void reset()
{
registers.clear();
}
// LivenessSet(LivenessSet &&other) : LivenessSet()
// {
// swap(*this,other);
// }
LivenessSet &operator=(LivenessSet other)
{
swap(*this,other);
return *this;
}
friend void swap(LivenessSet& first, LivenessSet& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.registers, second.registers);
}
LivenessSet &operator|=(const LivenessSet &other)
{
registers.insert(other.registers.begin(),other.registers.end());
return *this;
}
LivenessSet &operator&=(const LivenessSet &other)
{
std::set<eReg> res;
std::set_intersection(registers.begin(),registers.end(),
other.registers.begin(),other.registers.end(),
std::inserter(res, res.end()));
registers = res;
return *this;
}
LivenessSet &operator-=(const LivenessSet &other)
{
std::set<eReg> res;
std::set_difference(registers.begin(),registers.end(),
other.registers.begin(),other.registers.end(),
std::inserter(res, res.end()));
registers = res;
return *this;
}
LivenessSet operator-(const LivenessSet &other) const
{
return LivenessSet(*this) -= other;
}
LivenessSet operator+(const LivenessSet &other) const
{
return LivenessSet(*this) |= other;
}
LivenessSet operator &(const LivenessSet &other) const
{
return LivenessSet(*this) &= other;
}
bool any() const
{
return not registers.empty();
}
bool operator==(const LivenessSet &other) const
{
return registers==other.registers;
}
bool operator!=(const LivenessSet &other) const { return not(*this==other);}
LivenessSet &setReg(int r);
LivenessSet &addReg(int r);
bool testReg(int r) const
{
return registers.find(eReg(r))!=registers.end();
}
bool testRegAndSubregs(int r) const;
LivenessSet &clrReg(int r);
private:
void postProcessCompositeRegs();
};
/* uint8_t and uint16_t registers */ /* uint8_t and uint16_t registers */
/* Def/use of flags - low 4 bits represent flags */ /* Def/use of flags - low 4 bits represent flags */
@@ -45,14 +135,16 @@ struct DU
#define MAX_REGS_DEF 4 /* 2 regs def'd for long-reg vars */ #define MAX_REGS_DEF 4 /* 2 regs def'd for long-reg vars */
struct COND_EXPR; struct Expr;
struct AstIdent;
struct UnaryOperator;
struct HlTypeSupport struct HlTypeSupport
{ {
//hlIcode opcode; /* hlIcode opcode */ //hlIcode opcode; /* hlIcode opcode */
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0; virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
virtual std::string writeOut(Function *pProc, int *numLoc)=0; virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
protected: protected:
void performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree); Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
}; };
struct CallType : public HlTypeSupport struct CallType : public HlTypeSupport
@@ -61,41 +153,41 @@ struct CallType : public HlTypeSupport
Function * proc; Function * proc;
STKFRAME * args; // actual arguments STKFRAME * args; // actual arguments
void allocStkArgs (int num); void allocStkArgs (int num);
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc); bool newStkArg(Expr *exp, llIcode opcode, Function *pproc);
void placeStkArg(COND_EXPR *exp, int pos); void placeStkArg(Expr *exp, int pos);
virtual COND_EXPR * toId(); virtual Expr * toAst();
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;
} }
std::string writeOut(Function *pProc, int *numLoc); std::string writeOut(Function *pProc, int *numLoc) const;
}; };
struct AssignType : public HlTypeSupport struct AssignType : public HlTypeSupport
{ {
/* for HLI_ASSIGN */ /* for HLI_ASSIGN */
COND_EXPR *lhs; protected:
COND_EXPR *rhs; public:
AssignType() : lhs(0),rhs(0) {} Expr *m_lhs;
bool removeRegFromLong(eReg regi, LOCAL_ID *locId) Expr *rhs;
{ AssignType() {}
performLongRemoval(regi,locId,lhs); Expr *lhs() const {return m_lhs;}
return true; void lhs(Expr *l);
} bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
std::string writeOut(Function *pProc, int *numLoc); std::string writeOut(Function *pProc, int *numLoc) const;
}; };
struct ExpType : public HlTypeSupport struct ExpType : public HlTypeSupport
{ {
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/ /* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
COND_EXPR *v; Expr *v;
ExpType() : v(0) {} ExpType() : v(0) {}
bool removeRegFromLong(eReg regi, LOCAL_ID *locId) bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
{ {
performLongRemoval(regi,locId,v); v=performLongRemoval(regi,locId,v);
return true; return true;
} }
std::string writeOut(Function *pProc, int *numLoc); std::string writeOut(Function *pProc, int *numLoc) const;
}; };
struct HLTYPE struct HLTYPE
@@ -106,35 +198,27 @@ public:
hlIcode opcode; /* hlIcode opcode */ hlIcode opcode; /* hlIcode opcode */
AssignType asgn; AssignType asgn;
CallType call; CallType call;
HlTypeSupport *get() HlTypeSupport *get();
const HlTypeSupport *get() const
{ {
switch(opcode) return const_cast<const HlTypeSupport *>(const_cast<HLTYPE*>(this)->get());
{
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(Expr *e)
{ {
assert(e); assert(e);
exp.v=e; exp.v=e;
} }
void replaceExpr(COND_EXPR *e) Expr *getMyExpr()
{ {
assert(e); if(opcode==HLI_CALL)
delete exp.v; return call.toAst();
exp.v=e; return expr();
} }
COND_EXPR * expr() { return exp.v;} void replaceExpr(Expr *e);
const COND_EXPR * const expr() const { return exp.v;} Expr * expr() { return exp.v;}
void set(hlIcode i,COND_EXPR *e) const Expr * expr() const { return exp.v;}
void set(hlIcode i,Expr *e)
{ {
if(i!=HLI_RET) if(i!=HLI_RET)
assert(e); assert(e);
@@ -142,17 +226,12 @@ public:
opcode=i; opcode=i;
exp.v=e; exp.v=e;
} }
void set(COND_EXPR *l,COND_EXPR *r) void set(Expr *l,Expr *r);
{ void setCall(Function *proc);
assert(l);
assert(r);
opcode = HLI_ASSIGN;
assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
asgn.lhs=l;
asgn.rhs=r;
}
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op) HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
{} {}
// HLTYPE() // help valgrind find uninitialized HLTYPES
// {}
HLTYPE & operator=(const HLTYPE &l) HLTYPE & operator=(const HLTYPE &l)
{ {
exp = l.exp; exp = l.exp;
@@ -162,53 +241,78 @@ public:
return *this; return *this;
} }
public: public:
std::string write1HlIcode(Function *pProc, int *numLoc); std::string write1HlIcode(Function *pProc, int *numLoc) const;
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); void setAsgn(Expr *lhs, Expr *rhs);
} ; } ;
/* LOW_LEVEL icode operand record */ /* LOW_LEVEL icode operand record */
struct LLOperand struct LLOperand
{ {
llvm::MCOperand llvm_op;
eReg seg; /* CS, DS, ES, SS */ eReg seg; /* CS, DS, ES, SS */
eReg segOver; /* CS, DS, ES, SS if segment override */ eReg segOver; /* CS, DS, ES, SS if segment override */
int16_t segValue; /* Value of segment seg during analysis */ int16_t segValue; /* Value of segment seg during analysis */
eReg regi; /* 0 < regs < INDEXBASE <= index modes */ eReg regi; /* 0 < regs < INDEXBASE <= index modes */
int16_t off; /* memory address offset */ int16_t off; /* memory address offset */
uint32_t opz; /* idx of immed src op */ uint32_t opz; /* idx of immed src op */
bool immed;
bool is_offset; // set by jumps
bool is_compound;
size_t width;
//union {/* Source operand if (flg & I) */ //union {/* Source operand if (flg & I) */
struct { /* Call & # actual arg bytes */ struct { /* Call & # actual arg bytes */
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),immed(0),is_offset(false),is_compound(0),width(0)
{ {
proc.proc=0; proc.proc=0;
proc.cb=0; proc.cb=0;
} }
LLOperand(eReg r,size_t w) : LLOperand()
{
regi=r;
width=w;
}
bool operator==(const LLOperand &with) const
{
return (seg==with.seg) &&
(segOver==with.segOver) &&
(segValue==with.segValue) &&
(regi == with.regi) &&
(off == with.off) &&
(opz==with.opz) &&
(proc.proc==with.proc.proc);
}
int64_t getImm2() const {return opz;} int64_t getImm2() const {return opz;}
void SetImmediateOp(uint32_t dw) void SetImmediateOp(uint32_t dw)
{ {
opz=dw; opz=dw;
} }
eReg getReg2() {return regi;} eReg getReg2() const {return regi;}
bool isReg() const; bool isReg() const;
static LLOperand CreateImm2(int64_t Val) static LLOperand CreateImm2(int64_t Val,uint8_t wdth=2)
{ {
LLOperand Op; LLOperand Op;
//Op.Kind = kImmediate; Op.immed=true;
//Op.ImmVal = Val;
Op.opz = Val; Op.opz = Val;
Op.width = wdth;
return Op; return Op;
} }
static LLOperand CreateReg2(unsigned Val) static LLOperand CreateReg2(unsigned Val)
{ {
LLOperand Op; LLOperand Op;
// Op.Kind = kRegister;
// Op.RegVal = Reg;
Op.regi = (eReg)Val; Op.regi = (eReg)Val;
return Op; return Op;
} }
void addProcInformation(int param_count,uint32_t call_conv); bool isSet()
{
return not (*this == LLOperand());
}
void addProcInformation(int param_count, CConv::Type call_conv);
bool isImmediate() const { return immed;}
void setImmediate(bool x) { immed=x;}
bool compound() const {return is_compound;} // dx:ax pair
size_t byteWidth() const { assert(width<=4); return width;}
}; };
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst> struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
{ {
@@ -219,7 +323,7 @@ public:
int codeIdx; /* Index into cCode.code */ int codeIdx; /* Index into cCode.code */
uint8_t numBytes; /* Number of bytes this instr */ uint8_t numBytes; /* Number of bytes this instr */
uint32_t label; /* offset in image (20-bit adr) */ uint32_t label; /* offset in image (20-bit adr) */
LLOperand dst; /* destination operand */ LLOperand m_dst; /* destination operand */
DU flagDU; /* def/use of flags */ DU flagDU; /* def/use of flags */
int caseEntry; int caseEntry;
std::vector<uint32_t> caseTbl2; std::vector<uint32_t> caseTbl2;
@@ -239,8 +343,6 @@ public:
flg &= ~flag; flg &= ~flag;
} }
uint32_t getFlag() const {return flg;} uint32_t getFlag() const {return flg;}
//llIcode getOpcode() const { return opcode; }
uint32_t GetLlLabel() const { return label;} uint32_t GetLlLabel() const { return label;}
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);} void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
@@ -250,25 +352,29 @@ public:
{ {
return (getOpcode()==op); return (getOpcode()==op);
} }
bool matchWithRegDst(llIcode op)
{
return (getOpcode()==op) and m_dst.isReg();
}
bool match(llIcode op,eReg dest) bool match(llIcode op,eReg dest)
{ {
return (getOpcode()==op)&&dst.regi==dest; return (getOpcode()==op)&&m_dst.regi==dest;
} }
bool match(llIcode op,eReg dest,uint32_t flgs) bool match(llIcode op,eReg dest,uint32_t flgs)
{ {
return (getOpcode()==op) and (dst.regi==dest) and testFlags(flgs); return (getOpcode()==op) and (m_dst.regi==dest) and testFlags(flgs);
} }
bool match(llIcode op,eReg dest,eReg src_reg) bool match(llIcode op,eReg dest,eReg src_reg)
{ {
return (getOpcode()==op)&&(dst.regi==dest)&&(m_src.regi==src_reg); return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg);
} }
bool match(eReg dest,eReg src_reg) bool match(eReg dest,eReg src_reg)
{ {
return (dst.regi==dest)&&(m_src.regi==src_reg); return (m_dst.regi==dest)&&(m_src.regi==src_reg);
} }
bool match(eReg dest) bool match(eReg dest)
{ {
return (dst.regi==dest); return (m_dst.regi==dest);
} }
bool match(llIcode op,uint32_t flgs) bool match(llIcode op,uint32_t flgs)
{ {
@@ -279,6 +385,19 @@ public:
setOpcode(op); setOpcode(op);
flg =flags; flg =flags;
} }
void set(llIcode op,uint32_t flags,eReg dst_reg)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
flg =flags;
}
void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
m_src = src_op;
flg =flags;
}
void emitGotoLabel(int indLevel); void emitGotoLabel(int indLevel);
void findJumpTargets(CIcodeRec &_pc); void findJumpTargets(CIcodeRec &_pc);
void writeIntComment(std::ostringstream &s); void writeIntComment(std::ostringstream &s);
@@ -287,7 +406,6 @@ public:
void flops(std::ostringstream &out); void flops(std::ostringstream &out);
bool isJmpInst(); bool isJmpInst();
HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
HLTYPE createCall(); HLTYPE createCall();
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container) LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
{ {
@@ -309,16 +427,16 @@ public:
} }
void replaceDst(const LLOperand &with) void replaceDst(const LLOperand &with)
{ {
dst = with; m_dst = with;
}
void replaceDst(eReg r)
{
dst = LLOperand::CreateReg2(r);
} }
// void replaceDst(eReg r)
// {
// dst = LLOperand::CreateReg2(r);
// }
ICODE *m_link; ICODE *m_link;
condId idType(opLoc sd) const; condId idType(opLoc sd) const;
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; } const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &dst; } LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
}; };
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */ /* Icode definition: LOW_LEVEL and HIGH_LEVEL */
@@ -362,18 +480,21 @@ public:
use.reset(); use.reset();
lastDefRegi.reset(); lastDefRegi.reset();
} }
std::bitset<32> def; // For Registers: position in bitset is reg index LivenessSet def; // For Registers: position in bitset is reg index
std::bitset<32> use; // For Registers: position in uint32_t is reg index LivenessSet use; // For Registers: position in uint32_t is reg index
std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB LivenessSet lastDefRegi;// Bit set if last def of this register in BB
void addDefinedAndUsed(eReg r) void addDefinedAndUsed(eReg r)
{ {
def |= duReg[r]; def.addReg(r);
use |= duReg[r]; use.addReg(r);
} }
}; };
struct DU1 struct DU1
{ {
protected:
int numRegsDef; /* # registers defined by this inst */
public:
struct Use struct Use
{ {
int Reg; // used register int Reg; // used register
@@ -389,7 +510,6 @@ public:
} }
}; };
int numRegsDef; /* # registers defined by this inst */
uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */ uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */
Use idx[MAX_REGS_DEF+1]; Use idx[MAX_REGS_DEF+1];
//int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */ //int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
@@ -414,6 +534,11 @@ public:
Use &u(idx[regIdx]); Use &u(idx[regIdx]);
u.removeUser(ic); u.removeUser(ic);
} }
int getNumRegsDef() const {return numRegsDef;}
void clearAllDefs() {numRegsDef=0;}
DU1 &addDef(eReg r) {numRegsDef++; return *this;}
DU1 &setDef(eReg r) {numRegsDef=1; return *this;}
void removeDef(eReg r) {numRegsDef--;}
DU1() : numRegsDef(0) DU1() : numRegsDef(0)
{ {
} }
@@ -426,8 +551,16 @@ public:
LLInst * ll() { return &m_ll;} LLInst * ll() { return &m_ll;}
const LLInst * ll() const { return &m_ll;} const LLInst * ll() const { return &m_ll;}
HLTYPE * hl() { return &m_hl;} HLTYPE * hlU() {
const HLTYPE * hl() const { return &m_hl;} // assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
return &m_hl;
}
const HLTYPE * hl() const {
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
return &m_hl;
}
void hl(const HLTYPE &v) { m_hl=v;} void hl(const HLTYPE &v) { m_hl=v;}
void setRegDU(eReg regi, operDu du_in); void setRegDU(eReg regi, operDu du_in);
@@ -437,13 +570,13 @@ public:
condId idType(opLoc sd); condId idType(opLoc sd);
// HLL setting functions // HLL setting functions
// set this icode to be an assign // set this icode to be an assign
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs) void setAsgn(Expr *lhs, Expr *rhs)
{ {
type=HIGH_LEVEL; type=HIGH_LEVEL;
hl()->setAsgn(lhs,rhs); hlU()->setAsgn(lhs,rhs);
} }
void setUnary(hlIcode op, COND_EXPR *_exp); void setUnary(hlIcode op, Expr *_exp);
void setJCond(COND_EXPR *cexp); void setJCond(Expr *cexp);
void emitGotoLabel(int indLevel); void emitGotoLabel(int indLevel);
void copyDU(const ICODE &duIcode, operDu _du, operDu duDu); void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
@@ -452,11 +585,11 @@ public:
public: public:
bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId); bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId);
void checkHlCall(); void checkHlCall();
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc) bool newStkArg(Expr *exp, llIcode opcode, Function *pproc)
{ {
return hl()->call.newStkArg(exp,opcode,pproc); return hlU()->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 +618,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);
}; };

View File

@@ -37,6 +37,8 @@ struct Idiom18 : public Idiom
protected: protected:
iICODE m_icodes[4]; iICODE m_icodes[4];
bool m_is_dec; bool m_is_dec;
/* type of variable: 1 = reg-var, 2 = local */
int m_idiom_type;
public: public:
Idiom18(Function *f) : Idiom(f) Idiom18(Function *f) : Idiom(f)
{ {
@@ -64,7 +66,7 @@ struct Idiom20 : public Idiom
{ {
protected: protected:
iICODE m_icodes[4]; iICODE m_icodes[4];
bool m_is_dec; condNodeType m_is_dec;
public: public:
Idiom20(Function *f) : Idiom(f) Idiom20(Function *f) : Idiom(f)
{ {

11
include/loader.h Normal file
View File

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

View File

@@ -18,7 +18,8 @@
/* Type definition */ /* Type definition */
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> > // this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
// TODO: why ? // TODO: why ?
struct COND_EXPR; struct Expr;
struct AstIdent;
struct ICODE; struct ICODE;
struct LLInst; struct LLInst;
typedef std::list<ICODE>::iterator iICODE; typedef std::list<ICODE>::iterator iICODE;
@@ -30,37 +31,67 @@ struct IDX_ARRAY : public std::vector<iICODE>
} }
}; };
typedef enum enum frameType
{ {
STK_FRAME, /* For stack vars */ STK_FRAME, /* For stack vars */
REG_FRAME, /* For register variables */ REG_FRAME, /* For register variables */
GLB_FRAME /* For globals */ GLB_FRAME /* For globals */
} frameType; };
typedef struct struct BWGLB_TYPE
{ {
int16_t seg; /* segment value */ int16_t seg; /* segment value */
int16_t off; /* offset */ int16_t off; /* offset */
eReg regi; /* optional indexed register */ eReg regi; /* optional indexed register */
} BWGLB_TYPE;
typedef struct
{ /* For TYPE_LONG_(UN)SIGN on the stack */
int offH; /* high offset from BP */
int offL; /* low offset from BP */
} LONG_STKID_TYPE;
struct LONGID_TYPE
{ /* For TYPE_LONG_(UN)SIGN registers */
eReg h; /* high register */
eReg l; /* low register */
bool srcDstRegMatch(iICODE a,iICODE b) const;
} ; } ;
/* For TYPE_LONG_(UN)SIGN on the stack */
struct LONG_STKID_TYPE
{
int offH; /* high offset from BP */
int offL; /* low offset from BP */
LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
};
/* For TYPE_LONG_(UN)SIGN registers */
struct LONGID_TYPE
{
protected:
eReg m_h; /* high register */
eReg m_l; /* low register */
public:
void set(eReg highpart,eReg lowpart)
{
m_h = highpart;
m_l = lowpart;
}
eReg l() const { return m_l; }
eReg h() const { return m_h; }
bool srcDstRegMatch(iICODE a,iICODE b) const;
LONGID_TYPE() {} // uninitializing constructor to help valgrind catch uninit accesses
LONGID_TYPE(eReg h,eReg l) : m_h(h),m_l(l) {}
};
struct LONGGLB_TYPE /* For TYPE_LONG_(UN)SIGN globals */
{
int16_t seg; /* segment value */
int16_t offH; /* offset high */
int16_t offL; /* offset low */
uint8_t regi; /* optional indexed register */
LONGGLB_TYPE(int16_t _seg,int16_t _H,int16_t _L,int8_t _reg=0)
{
seg=_seg;
offH=_H;
offL=_L;
regi=_reg;
}
};
/* ID, LOCAL_ID */ /* ID, LOCAL_ID */
struct ID struct ID
{ {
protected:
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
public:
hlType type; /* Probable type */ hlType type; /* Probable type */
bool illegal; /* Boolean: not a valid field any more */ bool illegal; /* Boolean: not a valid field any more */
//std::vector<iICODE> idx; //std::vector<iICODE> idx;
@@ -69,37 +100,43 @@ struct ID
bool hasMacro; /* Identifier requires a macro */ bool hasMacro; /* Identifier requires a macro */
char macro[10]; /* Macro for this identifier */ char macro[10]; /* Macro for this identifier */
std::string name; /* Identifier's name */ std::string name; /* Identifier's name */
union { /* Different types of identifiers */ union ID_UNION { /* Different types of identifiers */
friend struct ID;
protected:
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
public:
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */ eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */ struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
uint8_t regOff; /* register offset (if any) */ uint8_t regOff; /* register offset (if any) */
int off; /* offset from BP */ int off; /* offset from BP */
} bwId; } bwId;
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */ BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers */ LONGGLB_TYPE longGlb;
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
struct { /* For TYPE_LONG_(UN)SIGN globals */
int16_t seg; /* segment value */
int16_t offH; /* offset high */
int16_t offL; /* offset low */
uint8_t regi; /* optional indexed register */
} longGlb;
struct { /* For TYPE_LONG_(UN)SIGN constants */ struct { /* For TYPE_LONG_(UN)SIGN constants */
uint32_t h; /* high uint16_t */ uint32_t h; /* high uint16_t */
uint32_t l; /* low uint16_t */ uint32_t l; /* low uint16_t */
} longKte; } longKte;
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
} id; } id;
LONGID_TYPE & longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
const LONGID_TYPE & longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
LONG_STKID_TYPE & longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
const LONG_STKID_TYPE & longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
ID(); ID();
ID(hlType t, frameType f); ID(hlType t, frameType f);
ID(hlType t, const LONGID_TYPE &s);
ID(hlType t, const LONG_STKID_TYPE &s);
ID(hlType t, const LONGGLB_TYPE &s);
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);} bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
uint16_t typeBitsize() const uint16_t typeBitsize() const
{ {
return TypeContainer::typeSize(type)*8; return TypeContainer::typeSize(type)*8;
} }
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
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,8 +158,8 @@ 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, const LONGID_TYPE &longT, 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);
void newIdent(hlType t, frameType f); void newIdent(hlType t, frameType f);
@@ -131,8 +168,8 @@ public:
size_t csym() const {return id_arr.size();} size_t csym() const {return id_arr.size();}
void newRegArg(iICODE picode, iICODE ticode) const; void newRegArg(iICODE picode, iICODE ticode) const;
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const; void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const; void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
COND_EXPR *createId(const ID *retVal, iICODE ix_); AstIdent *createId(const ID *retVal, iICODE ix_);
}; };

View File

@@ -4,6 +4,7 @@
#include <sstream> #include <sstream>
#include <bitset> #include <bitset>
struct LivenessSet;
/* Machine registers */ /* Machine registers */
enum eReg enum eReg
{ {
@@ -32,8 +33,9 @@ enum eReg
rBH = 20, rBH = 20,
rTMP= 21, /* temp register for DIV/IDIV/MOD */ rTMP= 21, /* temp register for DIV/IDIV/MOD */
rTMP2= 22, /* temp register for DIV/IDIV/MOD */
/* Indexed modes go from INDEXBASE to INDEXBASE+7 */ /* Indexed modes go from INDEXBASE to INDEXBASE+7 */
INDEX_BX_SI = 22, // "bx+si" INDEX_BX_SI = 23, // "bx+si"
INDEX_BX_DI, // "bx+di" INDEX_BX_DI, // "bx+di"
INDEX_BP_SI, // "bp+si" INDEX_BP_SI, // "bp+si"
INDEX_BP_DI, // "bp+di" INDEX_BP_DI, // "bp+di"
@@ -64,19 +66,14 @@ public:
bool physicalReg(eReg r); bool physicalReg(eReg r);
/* Writes the registers that are set in the bitvector */ /* Writes the registers that are set in the bitvector */
//TODO: move this into Machine_X86 ? //TODO: move this into Machine_X86 ?
static void writeRegVector (std::ostream &ostr,const std::bitset<32> &regi) static void writeRegVector (std::ostream &ostr,const LivenessSet &regi);
{ static eReg subRegH(eReg reg);
int j;
for (j = rAX; j < INDEX_BX_SI; j++)
{
if (regi.test(j-1))
ostr << regName(eReg(j))<<" ";
}
}
static eReg subRegH(eReg reg); //TODO: move these into machine_x86
static eReg subRegL(eReg reg); static eReg subRegL(eReg reg);
static bool isMemOff(eReg r); static bool isMemOff(eReg r);
static bool isSubRegisterOf(eReg reg, eReg parent); static bool isSubRegisterOf(eReg reg, eReg parent);
static bool hasSubregisters(eReg reg);
static bool isPartOfComposite(eReg reg);
static eReg compositeParent(eReg reg);
}; };

View File

@@ -3,10 +3,7 @@
hashing functions hashing functions
* (C) Mike van Emmerik * (C) Mike van Emmerik
*/ */
#include <stdint.h>
//#define bool unsigned char
#define uint8_t unsigned char
#define uint16_t unsigned short
/* Prototypes */ /* Prototypes */
void hashCleanup(void); /* Frees memory allocated by hashParams() */ void hashCleanup(void); /* Frees memory allocated by hashParams() */

View File

@@ -4,60 +4,49 @@
#include <cassert> #include <cassert>
#include <list> #include <list>
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <boost/icl/interval.hpp>
#include <boost/icl/interval_map.hpp>
#include <boost/icl/split_interval_map.hpp>
#include <unordered_set>
#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(FunctionType *f,const std::string &name);
bool valid(ilFunction iter); bool valid(ilFunction iter);
int getSymIdxByAdd(uint32_t adr); int getSymIdxByAdd(uint32_t adr);
@@ -72,6 +61,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

@@ -30,6 +30,10 @@ struct STATE
memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86 memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86
memset(f,0,sizeof(uint8_t)*INDEX_BX_SI); memset(f,0,sizeof(uint8_t)*INDEX_BX_SI);
} }
void setMemoryByte(uint32_t addr,uint8_t val)
{
//TODO: make this into a full scale value tracking class !
}
}; };

View File

@@ -7,7 +7,8 @@
#include <stdint.h> #include <stdint.h>
#include "Enums.h" #include "Enums.h"
#include "types.h" #include "types.h"
struct COND_EXPR; struct Expr;
struct AstIdent;
struct TypeContainer; struct TypeContainer;
/* * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * */
/* Symbol table structs and protos */ /* Symbol table structs and protos */
@@ -23,26 +24,29 @@ struct SymbolCommon
}; };
struct SYM : public SymbolCommon struct SYM : public SymbolCommon
{ {
typedef uint32_t tLabel;
SYM() : label(0),flg(0) SYM() : label(0),flg(0)
{ {
} }
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 */
struct STKSYM : public SymbolCommon struct STKSYM : public SymbolCommon
{ {
COND_EXPR *actual; /* Expression tree of actual parameter */ typedef int16_t tLabel;
COND_EXPR *regs; /* For register arguments only */ Expr *actual; /* Expression tree of actual parameter */
int16_t label; /* Immediate off from BP (+:args, -:params) */ AstIdent *regs; /* For register arguments only */
tLabel label; /* Immediate off from BP (+:args, -:params) */
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */ uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
bool hasMacro; /* This type needs a macro */ bool hasMacro; /* This type needs a macro */
std::string macro; /* Macro name */ std::string macro; /* Macro name */
bool invalid; /* Boolean: invalid entry in formal arg list*/ bool invalid; /* Boolean: invalid entry in formal arg list*/
STKSYM() STKSYM()
{ {
actual=regs=0; actual=0;
regs=0;
label=0; label=0;
regOff=0; regOff=0;
invalid=hasMacro = false; invalid=hasMacro = false;
@@ -60,13 +64,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(typename T::tLabel lab)
{ {
auto iter = std::find_if(this->begin(),this->end(), auto iter = std::find_if(this->begin(),this->end(),
[lab](T &s)->bool {return s.label==lab;}); [lab](T &s)->bool {return s.label==lab;});
return iter; return iter;
} }
const_iterator findByLabel(int lab) const const_iterator findByLabel(typename T::tLabel lab) const
{ {
auto iter = std::find_if(this->begin(),this->end(), auto iter = std::find_if(this->begin(),this->end(),
[lab](const T &s)->bool {return s.label==lab;}); [lab](const T &s)->bool {return s.label==lab;});
@@ -102,12 +106,12 @@ 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);
boolT readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc); bool readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
void selectTable(tableType); /* Select a particular table */ void selectTable(tableType); /* Select a particular table */

View File

@@ -1,7 +1,9 @@
/**************************************************************************** /*
***************************************************************************
* dcc project general header * dcc project general header
* (C) Cristina Cifuentes, Mike van Emmerik * (C) Cristina Cifuentes, Mike van Emmerik
****************************************************************************/ ***************************************************************************
*/
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <stdint.h> #include <stdint.h>
@@ -10,10 +12,6 @@
#define MAX 0x7FFFFFFF #define MAX 0x7FFFFFFF
/* Type definitions used in the program */ /* Type definitions used in the program */
typedef unsigned char byte; /* 8 bits */
typedef unsigned short word;/* 16 bits */
typedef short int16; /* 16 bits */
typedef unsigned char boolT; /* 8 bits */
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */ #define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
@@ -22,17 +20,17 @@ typedef unsigned char boolT; /* 8 bits */
#define PATLEN 23 /* Length of proc patterns */ #define PATLEN 23 /* Length of proc patterns */
#define WILD 0xF4 /* The wild byte */ #define WILD 0xF4 /* The wild byte */
/****** MACROS *******/ /* MACROS */
/* Macro reads a LH word from the image regardless of host convention */ // Macro reads a LH word from the image regardless of host convention
/* Returns a 16 bit quantity, e.g. C000 is read into an Int as C000 */ // Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8)) //#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
#define LH(p) ((word)((byte *)(p))[0] + ((word)((byte *)(p))[1] << 8)) #define LH(p) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(p))[1] << 8))
/* Macro reads a LH word from the image regardless of host convention */ /* Macro reads a LH word from the image regardless of host convention */
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */ /* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
#define LH_SIGNED(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8)) #define LH_SIGNED(p) (((uint8_t *)(p))[0] + (((char *)(p))[1] << 8))
/* Macro tests bit b for type t in prog.map */ /* Macro tests bit b for type t in prog.map */
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1))) #define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
@@ -53,19 +51,20 @@ 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.
*/
void setFlags(uint16_t x) void setFlags(uint16_t x)
{ {
def = x&DEF; def = x&DEF;
use = x&USE; use = x&USE;
val = x&VAL; val = x&VAL;
} }
bool isUSE_VAL() {return use&&val;} /* Use and Val */ bool isUSE_VAL() {return use&&val;} //Use and Val
}; };
static constexpr const char * hlTypes[13] = { static constexpr const char * hlTypes[13] = {
"", "char", "unsigned char", "int", "unsigned int", "", "char", "unsigned char", "int", "unsigned int",
@@ -88,6 +87,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

@@ -14,8 +14,10 @@ def perform_test(exepath,filepath,outname,args)
filepath=path_local(filepath) filepath=path_local(filepath)
joined_args = args.join(' ') joined_args = args.join(' ')
printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n") printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
STDERR << "Errors for : #{filepath}"
result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}` result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}` result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
result = `#{exepath} #{joined_args} -o#{output_path} #{filepath}`
puts result puts result
p $? p $?
end end

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;
@@ -19,7 +19,7 @@ BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
* @arg start - basic block starts here, might be parent->Icode.end() * @arg start - basic block starts here, might be parent->Icode.end()
* @arg fin - last of basic block's instructions * @arg fin - last of basic block's instructions
*/ */
BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent) BB *BB::Create(const rCODE &r,eBBKind _nodeType, Function *parent)
{ {
BB* pnewBB; BB* pnewBB;
pnewBB = new BB; pnewBB = new BB;
@@ -27,47 +27,30 @@ BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Fun
pnewBB->immedDom = NO_DOM; pnewBB->immedDom = NO_DOM;
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail = pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE; pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
pnewBB->instructions = make_iterator_range(start,fin); pnewBB->instructions = r;
if(start==parent->Icode.end()) int addr = pnewBB->begin()->loc_ip;
{
pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end());
}
else
{
pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive
}
if (numOutEdges)
pnewBB->edges.resize(numOutEdges);
/* Mark the basic block to which the icodes belong to, but only for /* Mark the basic block to which the icodes belong to, but only for
* real code basic blocks (ie. not interval bbs) */ * real code basic blocks (ie. not interval bbs) */
if(parent) if(parent)
{ {
if (start != parent->Icode.end()) //setInBB should automatically handle if our range is empty
parent->Icode.SetInBB(pnewBB->instructions, pnewBB); parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
parent->heldBBs.push_back(pnewBB);
parent->m_cfg.push_back(pnewBB); assert(parent->m_ip_to_bb.find(addr)==parent->m_ip_to_bb.end());
parent->m_ip_to_bb[addr] = pnewBB;
parent->m_actual_cfg.push_back(pnewBB);
pnewBB->Parent = parent; pnewBB->Parent = parent;
} }
if ( start != parent->Icode.end() ) /* Only for code BB's */
if ( r.begin() != parent->Icode.end() ) /* Only for code BB's */
stats.numBBbef++; stats.numBBbef++;
return pnewBB; return pnewBB;
} }
BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent) BB *BB::CreateIntervalBB(Function *parent)
{ {
iICODE st(parent->Icode.begin()); iICODE endOfParent = parent->Icode.end();
iICODE fin(parent->Icode.begin()); return Create(make_iterator_range(endOfParent,endOfParent),INTERVAL_NODE,nullptr);
if(start==-1)
{
st = parent->Icode.end();
fin = parent->Icode.end();
}
else
{
advance(st,start);
advance(fin,ip);
}
return Create(st,fin,_nodeType,numOutEdges,parent);
} }
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call", static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
@@ -81,14 +64,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==nullptr)
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 +84,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 +115,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");
@@ -146,14 +129,12 @@ void BB::displayDfs()
pb.BBptr->displayDfs(); pb.BBptr->displayDfs();
} }
} }
/* Recursive procedure that writes the code for the given procedure, pointed /** Recursive procedure that writes the code for the given procedure, pointed
* to by pBB. to by pBB.
* Parameters: pBB: pointer to the cfg. \param indLevel indentation level - used for formatting.
* Icode: pointer to the Icode array for the cfg graph of the \param numLoc: last # assigned to local variables
* current procedure. */
* indLevel: indentation level - used for formatting. ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, bool &repCond)
* numLoc: last # assigned to local variables */
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
{ {
latch = pProc->m_dfsLast[this->latchNode]; latch = pProc->m_dfsLast[this->latchNode];
std::ostringstream ostr; std::ostringstream ostr;
@@ -179,10 +160,10 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
* the THEN path of the header node */ * the THEN path of the header node */
if (edges[ELSE].BBptr->dfsLastNum == loopFollow) if (edges[ELSE].BBptr->dfsLastNum == loopFollow)
{ {
picode->hl()->replaceExpr(picode->hl()->expr()->inverse()); picode->hlU()->replaceExpr(picode->hl()->expr()->inverse());
} }
{ {
string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc); string e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n"; ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
} }
picode->invalidate(); picode->invalidate();
@@ -196,6 +177,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
case ENDLESS_TYPE: case ENDLESS_TYPE:
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n"; ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
picode = &latch->back();
} }
cCode.appendCode(ostr.str()); cCode.appendCode(ostr.str());
stats.numHLIcode += 1; stats.numHLIcode += 1;
@@ -212,8 +194,8 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
int follow; /* ifFollow */ int follow; /* ifFollow */
BB * succ, *latch; /* Successor and latching node */ BB * succ, *latch; /* Successor and latching node */
ICODE * picode; /* Pointer to HLI_JCOND instruction */ ICODE * picode; /* Pointer to HLI_JCOND instruction */
char *l; /* Pointer to HLI_JCOND expression */ std::string l; /* Pointer to HLI_JCOND expression */
boolT emptyThen, /* THEN clause is empty */ bool emptyThen, /* THEN clause is empty */
repCond; /* Repeat condition for while() */ repCond; /* Repeat condition for while() */
/* Check if this basic block should be analysed */ /* Check if this basic block should be analysed */
@@ -226,7 +208,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
/* Check for start of loop */ /* Check for start of loop */
repCond = false; repCond = false;
latch = NULL; latch = nullptr;
if (loopType) if (loopType)
{ {
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond); picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
@@ -282,12 +264,16 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel)); cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
else if (loopType == REPEAT_TYPE) else if (loopType == REPEAT_TYPE)
{ {
string e = "//*failed*//";
if (picode->hl()->opcode != HLI_JCOND) if (picode->hl()->opcode != HLI_JCOND)
reportError (REPEAT_FAIL);
{ {
string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc); reportError (REPEAT_FAIL);
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str());
} }
else
{
e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
}
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str());
} }
/* Recurse on the loop follow */ /* Recurse on the loop follow */
@@ -319,13 +305,13 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
if (succ->dfsLastNum != follow) /* THEN part */ if (succ->dfsLastNum != follow) /* THEN part */
{ {
l = writeJcond ( *back().hl(), pProc, numLoc); l = writeJcond ( *back().hl(), pProc, numLoc);
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l); cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow); succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
} }
else /* empty THEN part => negate ELSE part */ else /* empty THEN part => negate ELSE part */
{ {
l = writeJcondInv ( *back().hl(), pProc, numLoc); l = writeJcondInv ( *back().hl(), pProc, numLoc);
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l); cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow); edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
emptyThen = true; emptyThen = true;
} }
@@ -361,7 +347,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
else /* no follow => if..then..else */ else /* no follow => if..then..else */
{ {
l = writeJcond ( *back().hl(), pProc, numLoc); l = writeJcond ( *back().hl(), pProc, numLoc);
cCode.appendCode( "%s%s", indentStr(indLevel-1), l); cCode.appendCode( "%s%s", indentStr(indLevel-1), l.c_str());
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow); edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1)); cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow); edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
@@ -410,27 +396,26 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
iICODE BB::begin() iICODE BB::begin()
{ {
return instructions.begin();//range_start; return instructions.begin();
} }
iICODE BB::end() const iICODE BB::end() const
{ {
return instructions.end();//range_end return instructions.end();
} }
ICODE &BB::back() ICODE &BB::back()
{ {
return instructions.back();//*rbegin(); return instructions.back();
} }
size_t BB::size() size_t BB::size()
{ {
return distance(instructions.begin(),instructions.end()); return distance(instructions.begin(),instructions.end());
} }
ICODE &BB::front() ICODE &BB::front()
{ {
return instructions.front();//*begin(); return instructions.front();
} }
riICODE BB::rbegin() riICODE BB::rbegin()

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)

36
src/CallConvention.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <ostream>
#include <cassert>
#include "CallConvention.h"
CConv *CConv::create(Type v)
{
static C_CallingConvention *c_call = nullptr;
static Pascal_CallingConvention *p_call = nullptr;
static Unknown_CallingConvention *u_call= nullptr;
if(!c_call)
c_call = new C_CallingConvention;
if(!p_call)
p_call = new Pascal_CallingConvention;
if(!u_call)
u_call = new Unknown_CallingConvention;
switch(v) {
case UNKNOWN: return u_call;
case C: return c_call;
case PASCAL: return p_call;
}
assert(false);
return nullptr;
}
void C_CallingConvention::writeComments(std::ostream &ostr)
{
ostr << " * C calling convention.\n";
}
void Pascal_CallingConvention::writeComments(std::ostream &ostr)
{
ostr << " * Pascal calling convention.\n";
}
void Unknown_CallingConvention::writeComments(std::ostream &ostr)
{
ostr << " * Unknown calling convention.\n";
}

View File

@@ -14,7 +14,7 @@ void JumpTable::pruneEntries(uint16_t cs)
PROG *prg(Project::get()->binary()); PROG *prg(Project::get()->binary());
for (uint32_t i = start; i < finish; i += 2) for (uint32_t i = start; i < finish; i += 2)
{ {
uint32_t target = cs + LH(&prg->Image[i]); uint32_t target = cs + LH(&prg->image()[i]);
if (target < finish && target >= start) if (target < finish && target >= start)
finish = target; finish = target;
else if (target >= (uint32_t)prg->cbImage) else if (target >= (uint32_t)prg->cbImage)
@@ -23,10 +23,15 @@ void JumpTable::pruneEntries(uint16_t cs)
ICODE _Icode; // used as scan input ICODE _Icode; // used as scan input
for (uint32_t i = start; i < finish; i += 2) for (uint32_t i = start; i < finish; i += 2)
{ {
uint32_t target = cs + LH(&prg->Image[i]); uint32_t target = cs + LH(&prg->image()[i]);
/* Be wary of 00 00 as code - it's probably data */ /* Be wary of 00 00 as code - it's probably data */
if (! (prg->Image[target] || prg->Image[target+1]) || scan(target, _Icode)) if (! (prg->image()[target] || prg->image()[target+1]) || scan(target, _Icode))
finish = i; finish = i;
} }
} }
void Function::callingConv(CConv::Type v) {
m_call_conv=CConv::create(v);
}

121
src/RegisterNode.cpp Normal file
View File

@@ -0,0 +1,121 @@
#include <stdint.h>
#include <string>
#include <sstream>
#include <iostream>
#include <cassert>
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
//#include <boost/range/algorithm.hpp>
//#include <boost/assign.hpp>
#include "types.h"
#include "ast.h"
#include "bundle.h"
#include "machine_x86.h"
#include "project.h"
using namespace std;
using namespace boost::adaptors;
RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
{
m_syms = locsym;
ident.type(REGISTER);
hlType type_sel;
regType reg_type;
if (op.byteWidth()==1)
{
type_sel = TYPE_BYTE_SIGN;
reg_type = BYTE_REG;
}
else /* uint16_t */
{
type_sel = TYPE_WORD_SIGN;
reg_type = WORD_REG;
}
regiIdx = locsym->newByteWordReg(type_sel, op.regi);
regiType = reg_type;
}
//RegisterNode::RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym)
//{
// ident.type(REGISTER);
// hlType type_sel;
// regType reg_type;
// if ((icodeFlg & B) || (icodeFlg & SRC_B))
// {
// type_sel = TYPE_BYTE_SIGN;
// reg_type = BYTE_REG;
// }
// else /* uint16_t */
// {
// type_sel = TYPE_WORD_SIGN;
// reg_type = WORD_REG;
// }
// regiIdx = locsym->newByteWordReg(type_sel, regi);
// regiType = reg_type;
//}
string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
{
std::ostringstream codeOut;
std::ostringstream o;
assert(&pProc->localId==m_syms);
ID *id = &pProc->localId.id_arr[regiIdx];
if (id->name[0] == '\0') /* no name */
{
id->setLocalName(++(*numLoc));
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
}
if (id->hasMacro)
o << id->macro << "("<<id->name<<")";
else
o << id->name;
cCode.appendDecl(codeOut.str());
return o.str();
}
int RegisterNode::hlTypeSize(Function *) const
{
if (regiType == BYTE_REG)
return (1);
else
return (2);
}
hlType RegisterNode::expType(Function *pproc) const
{
if (regiType == BYTE_REG)
return (TYPE_BYTE_SIGN);
else
return (TYPE_WORD_SIGN);
}
Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
{
assert(locsym==m_syms);
eReg treeReg = locsym->id_arr[regiIdx].id.regi;
if (treeReg == regi) /* uint16_t reg */
{
return _expr;
}
else if(Machine_X86::isSubRegisterOf(treeReg,regi)) /* uint16_t/uint8_t reg */
{
return _expr;
}
return nullptr;
}
bool RegisterNode::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
{
uint8_t regi = locId.id_arr[regiIdx].id.regi;
range_to_check.advance_begin(1);
auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level);
for (ICODE &i : all_valid_and_high_level_after_start)
if (i.du.def.testRegAndSubregs(regi))
return false;
if (all_valid_and_high_level_after_start.end().base() != lastBBinst)
return true;
return false;
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,15 +6,21 @@
****************************************************************************/ ****************************************************************************/
#include <cassert> #include <cassert>
#include <string> #include <string>
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include "dcc.h"
#include "disassem.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "dcc.h"
#include "disassem.h"
#include "project.h" #include "project.h"
#include "CallGraph.h"
using namespace boost;
using namespace boost::adaptors;
bundle cCode; /* Procedure declaration and code */ bundle cCode; /* Procedure declaration and code */
using namespace std; using namespace std;
@@ -103,23 +109,23 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
switch (psym->size) switch (psym->size)
{ {
case 1: case 1:
ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n"; ostr << "uint8_t\t"<<psym->name<<" = "<<prog.image()[relocOp]<<";\n";
break; break;
case 2: case 2:
ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n"; ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.image()+relocOp)<<";\n";
break; break;
case 4: if (psym->type == TYPE_PTR) /* pointer */ case 4: if (psym->type == TYPE_PTR) /* pointer */
ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n"; ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.image()+relocOp)<<";\n";
else /* char */ else /* char */
ostr << "char\t"<<psym->name<<"[4] = \""<< ostr << "char\t"<<psym->name<<"[4] = \""<<
prog.Image[relocOp]<<prog.Image[relocOp+1]<< prog.image()[relocOp]<<prog.image()[relocOp+1]<<
prog.Image[relocOp+2]<<prog.Image[relocOp+3]<<";\n"; prog.image()[relocOp+2]<<prog.image()[relocOp+3]<<";\n";
break; break;
default: default:
{ {
ostringstream strContents; ostringstream strContents;
for (j=0; j < psym->size; j++) for (j=0; j < psym->size; j++)
strContents << cChar(prog.Image[relocOp + j]); strContents << cChar(prog.image()[relocOp + j]);
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n"; ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
} }
} }
@@ -178,11 +184,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 +200,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 */
@@ -214,12 +221,16 @@ void Function::codeGen (std::ostream &fs)
ostr<< "\nvoid "<<name<<" ("; ostr<< "\nvoid "<<name<<" (";
/* Write arguments */ /* Write arguments */
for (size_t i = 0; i < args.size(); i++) struct validArg
{ {
if ( args[i].invalid ) bool operator()(STKSYM &s) { return s.invalid==false;}
continue; };
ostr<<hlTypes[args[i].type]<<" "<<args[i].name; auto valid_args = args | filtered(validArg());
if (i < (args.size() - 1)) int count_valid = std::distance(valid_args.begin(),valid_args.end());
for (STKSYM &arg : valid_args)
{
ostr<<hlTypes[arg.type]<<" "<<arg.name;
if(--count_valid!=0)
ostr<<", "; ostr<<", ";
} }
ostr<<")\n"; ostr<<")\n";
@@ -265,7 +276,7 @@ void Function::codeGen (std::ostream &fs)
} }
else /* generate C */ else /* generate C */
{ {
m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT); m_actual_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
} }
cCode.appendCode( "}\n\n"); cCode.appendCode( "}\n\n");
@@ -296,7 +307,7 @@ void Function::codeGen (std::ostream &fs)
/* Recursive procedure. Displays the procedure's code in depth-first order /* Recursive procedure. Displays the procedure's code in depth-first order
* of the call graph. */ * of the call graph. */
static void backBackEnd (char *filename, CALL_GRAPH * pcallGraph, std::ostream &_ios) static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
{ {
// IFace.Yield(); /* This is a good place to yield to other apps */ // IFace.Yield(); /* This is a good place to yield to other apps */
@@ -308,9 +319,9 @@ static void backBackEnd (char *filename, CALL_GRAPH * pcallGraph, std::ostream &
pcallGraph->proc->flg |= PROC_OUTPUT; pcallGraph->proc->flg |= PROC_OUTPUT;
/* Dfs if this procedure has any successors */ /* Dfs if this procedure has any successors */
for (size_t i = 0; i < pcallGraph->outEdges.size(); i++) for (auto & elem : pcallGraph->outEdges)
{ {
backBackEnd (filename, pcallGraph->outEdges[i], _ios); backBackEnd (elem, _ios);
} }
/* Generate code for this procedure */ /* Generate code for this procedure */
@@ -345,14 +356,14 @@ void BackEnd (char *fileName, CALL_GRAPH * pcallGraph)
printf ("dcc: Writing C beta file %s\n", outNam.c_str()); printf ("dcc: Writing C beta file %s\n", outNam.c_str());
/* Header information */ /* Header information */
writeHeader (fs, fileName); writeHeader (fs, option.filename);
/* Initialize total Icode instructions statistics */ /* Initialize total Icode instructions statistics */
stats.totalLL = 0; stats.totalLL = 0;
stats.totalHL = 0; stats.totalHL = 0;
/* Process each procedure at a time */ /* Process each procedure at a time */
backBackEnd (fileName, pcallGraph, fs); backBackEnd (pcallGraph, fs);
/* Close output file */ /* Close output file */
fs.close(); fs.close();

View File

@@ -56,7 +56,7 @@ static uint16_t *T1base, *T2base; /* Pointers to start of T1, T2 */
static uint16_t *g; /* g[] */ static uint16_t *g; /* g[] */
static HT *ht; /* The hash table */ static HT *ht; /* The hash table */
static PH_FUNC_STRUCT *pFunc; /* Points to the array of func names */ static PH_FUNC_STRUCT *pFunc; /* Points to the array of func names */
static hlType *pArg=0; /* Points to the array of param types */ static hlType *pArg=nullptr; /* Points to the array of param types */
static int numFunc; /* Number of func names actually stored */ static int numFunc; /* Number of func names actually stored */
static int numArg; /* Number of param names actually stored */ static int numArg; /* Number of param names actually stored */
#define DCCLIBS "dcclibs.dat" /* Name of the prototypes data file */ #define DCCLIBS "dcclibs.dat" /* Name of the prototypes data file */
@@ -74,7 +74,7 @@ void checkHeap(char *msg); /* For debugging */
void fixWildCards(uint8_t pat[]); /* In fixwild.c */ void fixWildCards(uint8_t pat[]); /* In fixwild.c */
static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern, static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern,
int iPatLen, int *index); int iPatLen, int *index);
/* * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * *\
@@ -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
@@ -302,7 +302,7 @@ void SetupLibCheck(void)
uint16_t w, len; uint16_t w, len;
int i; int i;
if ((g_file = fopen(sSigName, "rb")) == NULL) if ((g_file = fopen(sSigName, "rb")) == nullptr)
{ {
printf("Warning: cannot open signature file %s\n", sSigName); printf("Warning: cannot open signature file %s\n", sSigName);
return; return;
@@ -337,8 +337,7 @@ void SetupLibCheck(void)
PatLen, /* The length of the pattern to be hashed */ PatLen, /* The length of the pattern to be hashed */
256, /* The character set of the pattern (0-FF) */ 256, /* The character set of the pattern (0-FF) */
0, /* Minimum pattern character value */ 0, /* Minimum pattern character value */
numVert); /* Specifies c, the sparseness of the graph. numVert); /* Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details */
See Czech, Havas and Majewski for details */
T1base = g_pattern_hasher.readT1(); T1base = g_pattern_hasher.readT1();
T2base = g_pattern_hasher.readT2(); T2base = g_pattern_hasher.readT2();
g = g_pattern_hasher.readG(); g = g_pattern_hasher.readG();
@@ -393,7 +392,7 @@ void SetupLibCheck(void)
/* This is now the hash table */ /* This is now the hash table */
/* First allocate space for the table */ /* First allocate space for the table */
ht = new HT[numKeys]; ht = new HT[numKeys];
if ( 0 == ht) if ( nullptr == ht)
{ {
printf("Could not allocate hash table\n"); printf("Could not allocate hash table\n");
exit(1); exit(1);
@@ -458,12 +457,13 @@ bool LibCheck(Function & pProc)
pProc.name = "main"; pProc.name = "main";
return false; return false;
} }
memcpy(pat, &prog.Image[fileOffset], PATLEN); if(fileOffset + PATLEN > prog.cbImage)
//memmove(pat, &prog.Image[fileOffset], PATLEN); return false;
memcpy(pat, &prog.image()[fileOffset], PATLEN);
//memmove(pat, &prog.image()[fileOffset], PATLEN);
fixWildCards(pat); /* Fix wild cards in the copy */ fixWildCards(pat); /* Fix wild cards in the copy */
h = g_pattern_hasher.hash(pat); /* Hash the found proc */ h = g_pattern_hasher.hash(pat); /* Hash the found proc */
/* We always have to compare keys, because the hash function will /* We always have to compare keys, because the hash function will always return a valid index */
always return a valid index */
if (memcmp(ht[h].htPat, pat, PATLEN) == 0) if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
{ {
/* We have a match. Save the name, if not already set */ /* We have a match. Save the name, if not already set */
@@ -477,6 +477,7 @@ bool LibCheck(Function & pProc)
if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL) if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL)
{ {
pProc.flg |= PROC_ISLIB; /* It's a lib function */ pProc.flg |= PROC_ISLIB; /* It's a lib function */
pProc.callingConv(CConv::C);
if (i != NIL) if (i != NIL)
{ {
/* Allocate space for the arg struct, and copy the hlType to /* Allocate space for the arg struct, and copy the hlType to
@@ -494,19 +495,24 @@ bool LibCheck(Function & pProc)
pProc.flg |= PROC_IS_FUNC; pProc.flg |= PROC_IS_FUNC;
switch (pProc.retVal.type) { switch (pProc.retVal.type) {
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
pProc.liveOut = duReg[rDX] | duReg[rAX]; pProc.liveOut.setReg(rDX).addReg(rAX);
break; break;
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
pProc.liveOut = duReg[rAX]; pProc.liveOut.setReg(rAX);
break; break;
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
pProc.liveOut = duReg[rAL]; pProc.liveOut.setReg(rAL);
break; break;
case TYPE_PTR:
fprintf(stderr,"Warning assuming Large memory model\n");
pProc.liveOut.setReg(rAX).addReg(rDS);
break;
default:
fprintf(stderr,"Unknown retval type %d for %s in LibCheck\n",pProc.retVal.type,pProc.name.c_str());
/*** other types are not considered yet ***/ /*** other types are not considered yet ***/
} }
} }
if (pFunc[i].bVararg) pProc.getFunctionType()->m_vararg = pFunc[i].bVararg;
pProc.flg |= PROC_VARARG;
} }
} }
else if (i == NIL) else if (i == NIL)
@@ -516,7 +522,7 @@ bool LibCheck(Function & pProc)
pProc.flg |= PROC_RUNTIME; /* => is a runtime routine */ pProc.flg |= PROC_RUNTIME; /* => is a runtime routine */
} }
} }
if (locatePattern(prog.Image, pProc.procEntry, if (locatePattern(prog.image(), pProc.procEntry,
pProc.procEntry+sizeof(pattMsChkstk), pProc.procEntry+sizeof(pattMsChkstk),
pattMsChkstk, sizeof(pattMsChkstk), &Idx)) pattMsChkstk, sizeof(pattMsChkstk), &Idx))
{ {
@@ -526,7 +532,7 @@ bool LibCheck(Function & pProc)
pProc.args.numArgs = 0; /* With no args */ pProc.args.numArgs = 0; /* With no args */
} }
return (boolT)((pProc.flg & PROC_ISLIB) != 0); return (bool)((pProc.flg & PROC_ISLIB) != 0);
} }
@@ -559,8 +565,7 @@ readFileShort(FILE *f)
} }
// Read a section of the file, considering endian issues // Read a section of the file, considering endian issues
void void readFileSection(uint16_t* p, int len, FILE* f)
readFileSection(uint16_t* p, int len, FILE* f)
{ {
for (int i=0; i < len; i += 2) for (int i=0; i < len; i += 2)
{ {
@@ -569,12 +574,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*/)
{ {
} }
@@ -583,11 +588,11 @@ void dispKey(int i)
iPatLen). The pattern can contain wild bytes; if you really want to match iPatLen). The pattern can contain wild bytes; if you really want to match
for the pattern that is used up by the WILD uint8_t, tough - it will match with for the pattern that is used up by the WILD uint8_t, tough - it will match with
everything else as well. */ everything else as well. */
static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen, static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
int *index) int *index)
{ {
int i, j; int i, j;
uint8_t *pSrc; /* Pointer to start of considered source */ const uint8_t *pSrc; /* Pointer to start of considered source */
int iLast; int iLast;
iLast = iMax - iPatLen; /* Last source uint8_t to consider */ iLast = iMax - iPatLen; /* Last source uint8_t to consider */
@@ -641,18 +646,18 @@ void STATE::checkStartup()
/* Check the Turbo Pascal signatures first, since they involve only the /* Check the Turbo Pascal signatures first, since they involve only the
first 3 bytes, and false positives may be founf with the others later */ first 3 bytes, and false positives may be founf with the others later */
if (locatePattern(prog.Image, startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i)) if (locatePattern(prog.image(), startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i))
{ {
/* The first 5 bytes are a far call. Follow that call and /* The first 5 bytes are a far call. Follow that call and
determine the version from that */ determine the version from that */
rel = LH(&prog.Image[startOff+1]); /* This is abs off of init */ rel = LH(&prog.image()[startOff+1]); /* This is abs off of init */
para= LH(&prog.Image[startOff+3]);/* This is abs seg of init */ para= LH(&prog.image()[startOff+3]);/* This is abs seg of init */
init = ((uint32_t)para << 4) + rel; init = ((uint32_t)para << 4) + rel;
if (locatePattern(prog.Image, init, init+26, pattBorl4Init, if (locatePattern(prog.image(), init, init+26, pattBorl4Init,
sizeof(pattBorl4Init), &i)) sizeof(pattBorl4Init), &i))
{ {
setState(rDS, LH(&prog.Image[i+1])); setState(rDS, LH(&prog.image()[i+1]));
printf("Borland Pascal v4 detected\n"); printf("Borland Pascal v4 detected\n");
chVendor = 't'; /* Trubo */ chVendor = 't'; /* Trubo */
chModel = 'p'; /* Pascal */ chModel = 'p'; /* Pascal */
@@ -661,11 +666,11 @@ void STATE::checkStartup()
prog.segMain = prog.initCS; /* At the 5 uint8_t jump */ prog.segMain = prog.initCS; /* At the 5 uint8_t jump */
goto gotVendor; /* Already have vendor */ goto gotVendor; /* Already have vendor */
} }
else if (locatePattern(prog.Image, init, init+26, pattBorl5Init, else if (locatePattern(prog.image(), init, init+26, pattBorl5Init,
sizeof(pattBorl5Init), &i)) sizeof(pattBorl5Init), &i))
{ {
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland Pascal v5.0 detected\n"); printf("Borland Pascal v5.0 detected\n");
chVendor = 't'; /* Trubo */ chVendor = 't'; /* Trubo */
chModel = 'p'; /* Pascal */ chModel = 'p'; /* Pascal */
@@ -674,11 +679,11 @@ void STATE::checkStartup()
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
goto gotVendor; /* Already have vendor */ goto gotVendor; /* Already have vendor */
} }
else if (locatePattern(prog.Image, init, init+26, pattBorl7Init, else if (locatePattern(prog.image(), init, init+26, pattBorl7Init,
sizeof(pattBorl7Init), &i)) sizeof(pattBorl7Init), &i))
{ {
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland Pascal v7 detected\n"); printf("Borland Pascal v7 detected\n");
chVendor = 't'; /* Trubo */ chVendor = 't'; /* Trubo */
chModel = 'p'; /* Pascal */ chModel = 'p'; /* Pascal */
@@ -695,45 +700,45 @@ 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))
{ {
rel = LH(&prog.Image[i+OFFMAINLARGE]); /* This is abs off of main */ rel = LH(&prog.image()[i+OFFMAINLARGE]); /* This is abs off of main */
para= LH(&prog.Image[i+OFFMAINLARGE+2]);/* This is abs seg of main */ para= LH(&prog.image()[i+OFFMAINLARGE+2]);/* This is abs seg of main */
/* Save absolute image offset */ /* Save absolute image offset */
prog.offMain = ((uint32_t)para << 4) + rel; prog.offMain = ((uint32_t)para << 4) + rel;
prog.segMain = (uint16_t)para; prog.segMain = (uint16_t)para;
chModel = 'l'; /* Large model */ chModel = 'l'; /* Large model */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact, else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainCompact,
sizeof(pattMainCompact), &i)) sizeof(pattMainCompact), &i))
{ {
rel = LH_SIGNED(&prog.Image[i+OFFMAINCOMPACT]);/* This is the rel addr of main */ rel = LH_SIGNED(&prog.image()[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */ prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
chModel = 'c'; /* Compact model */ chModel = 'c'; /* Compact model */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainMedium, else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainMedium,
sizeof(pattMainMedium), &i)) sizeof(pattMainMedium), &i))
{ {
rel = LH(&prog.Image[i+OFFMAINMEDIUM]); /* This is abs off of main */ rel = LH(&prog.image()[i+OFFMAINMEDIUM]); /* This is abs off of main */
para= LH(&prog.Image[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */ para= LH(&prog.image()[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */
prog.offMain = ((uint32_t)para << 4) + rel; prog.offMain = ((uint32_t)para << 4) + rel;
prog.segMain = (uint16_t)para; prog.segMain = (uint16_t)para;
chModel = 'm'; /* Medium model */ chModel = 'm'; /* Medium model */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall, else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainSmall,
sizeof(pattMainSmall), &i)) sizeof(pattMainSmall), &i))
{ {
rel = LH_SIGNED(&prog.Image[i+OFFMAINSMALL]); /* This is rel addr of main */ rel = LH_SIGNED(&prog.image()[i+OFFMAINSMALL]); /* This is rel addr of main */
prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */ prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
chModel = 's'; /* Small model */ chModel = 's'; /* Small model */
} }
else if (memcmp(&prog.Image[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0) else if (memcmp(&prog.image()[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
{ {
rel = LH_SIGNED(&prog.Image[startOff+1]); /* Get the jump offset */ rel = LH_SIGNED(&prog.image()[startOff+1]); /* Get the jump offset */
prog.offMain = rel+startOff+3; /* Save absolute image offset */ prog.offMain = rel+startOff+3; /* Save absolute image offset */
prog.offMain += 0x20; /* These first 32 bytes are setting up */ prog.offMain += 0x20; /* These first 32 bytes are setting up */
prog.segMain = prog.initCS; prog.segMain = prog.initCS;
@@ -757,30 +762,30 @@ void STATE::checkStartup()
} }
printf("Model: %c\n", chModel); printf("Model: %c\n", chModel);
prog.addressingMode = chModel;
/* Now decide the compiler vendor and version number */ /* Now decide the compiler vendor and version number */
if (memcmp(&prog.Image[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0) if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
{ {
/* Yes, this is Microsoft startup code. The DS is sitting right here /* Yes, this is Microsoft startup code. The DS is sitting right here
in the next 2 bytes */ in the next 2 bytes */
setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC5Start)])); setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC5Start)]));
chVendor = 'm'; /* Microsoft compiler */ chVendor = 'm'; /* Microsoft compiler */
chVersion = '5'; /* Version 5 */ chVersion = '5'; /* Version 5 */
printf("MSC 5 detected\n"); printf("MSC 5 detected\n");
} }
/* The C8 startup pattern is different from C5's */ /* The C8 startup pattern is different from C5's */
else if (memcmp(&prog.Image[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0) else if (memcmp(&prog.image()[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0)
{ {
setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC8Start)])); setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC8Start)]));
printf("MSC 8 detected\n"); printf("MSC 8 detected\n");
chVendor = 'm'; /* Microsoft compiler */ chVendor = 'm'; /* Microsoft compiler */
chVersion = '8'; /* Version 8 */ chVersion = '8'; /* Version 8 */
} }
/* The C8 .com startup pattern is different again! */ /* The C8 .com startup pattern is different again! */
else if (memcmp(&prog.Image[startOff], pattMsC8ComStart, else if (memcmp(&prog.image()[startOff], pattMsC8ComStart,
sizeof(pattMsC8ComStart)) == 0) sizeof(pattMsC8ComStart)) == 0)
{ {
printf("MSC 8 .com detected\n"); printf("MSC 8 .com detected\n");
@@ -788,27 +793,27 @@ void STATE::checkStartup()
chVersion = '8'; /* Version 8 */ chVersion = '8'; /* Version 8 */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl2Start, else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl2Start,
sizeof(pattBorl2Start), &i)) sizeof(pattBorl2Start), &i))
{ {
/* Borland startup. DS is at the second uint8_t (offset 1) */ /* Borland startup. DS is at the second uint8_t (offset 1) */
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland v2 detected\n"); printf("Borland v2 detected\n");
chVendor = 'b'; /* Borland compiler */ chVendor = 'b'; /* Borland compiler */
chVersion = '2'; /* Version 2 */ chVersion = '2'; /* Version 2 */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl3Start, else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl3Start,
sizeof(pattBorl3Start), &i)) sizeof(pattBorl3Start), &i))
{ {
/* Borland startup. DS is at the second uint8_t (offset 1) */ /* Borland startup. DS is at the second uint8_t (offset 1) */
setState( rDS, LH(&prog.Image[i+1])); setState( rDS, LH(&prog.image()[i+1]));
printf("Borland v3 detected\n"); printf("Borland v3 detected\n");
chVendor = 'b'; /* Borland compiler */ chVendor = 'b'; /* Borland compiler */
chVersion = '3'; /* Version 3 */ chVersion = '3'; /* Version 3 */
} }
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattLogiStart, else if (locatePattern(prog.image(), startOff, startOff+0x30, pattLogiStart,
sizeof(pattLogiStart), &i)) sizeof(pattLogiStart), &i))
{ {
/* Logitech modula startup. DS is 0, despite appearances */ /* Logitech modula startup. DS is 0, despite appearances */
@@ -884,7 +889,7 @@ void readProtoFile(void)
} }
strcat(szProFName, DCCLIBS); strcat(szProFName, DCCLIBS);
if ((fProto = fopen(szProFName, "rb")) == NULL) if ((fProto = fopen(szProFName, "rb")) == nullptr)
{ {
printf("Warning: cannot open library prototype data file %s\n", szProFName); printf("Warning: cannot open library prototype data file %s\n", szProFName);
return; return;
@@ -947,8 +952,7 @@ void readProtoFile(void)
} }
int int searchPList(char *name)
searchPList(char *name)
{ {
/* Search through the symbol names for the name */ /* Search through the symbol names for the name */
/* Use binary search */ /* Use binary search */
@@ -985,10 +989,7 @@ searchPList(char *name)
{ {
return mn; /* Found! */ return mn; /* Found! */
} }
else
{
return NIL; return NIL;
} }
}

View File

@@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
s<<"\t/* "; s<<"\t/* ";
if (src_immed == 0x21) if (src_immed == 0x21)
{ {
s <<int21h[dst.off]; s <<int21h[m_dst.off];
} }
else if (src_immed > 0x1F && src_immed < 0x2F) else if (src_immed > 0x1F && src_immed < 0x2F)
{ {
@@ -162,7 +162,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
} }
else if (src_immed == 0x2F) else if (src_immed == 0x2F)
{ {
switch (dst.off) switch (m_dst.off)
{ {
case 0x01 : case 0x01 :
s << "Print spooler"; s << "Print spooler";
@@ -207,16 +207,16 @@ void Function::writeProcComments(std::ostream &ostr)
{ {
psym = &this->args[i]; psym = &this->args[i];
ostr << " * "<<psym->name<<" = "; ostr << " * "<<psym->name<<" = ";
if (psym->regs->expr.ident.idType == REGISTER) if (psym->regs->ident.type() == REGISTER)
{ {
id = &this->localId.id_arr[psym->regs->expr.ident.idNode.regiIdx]; id = &this->localId.id_arr[((RegisterNode *)psym->regs)->regiIdx];
ostr << Machine_X86::regName(id->id.regi); ostr << Machine_X86::regName(id->id.regi);
} }
else /* long register */ else /* long register */
{ {
id = &this->localId.id_arr[psym->regs->expr.ident.idNode.longIdx]; id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx];
ostr << Machine_X86::regName(id->id.longId.h) << ":"; ostr << Machine_X86::regName(id->longId().h()) << ":";
ostr << Machine_X86::regName(id->id.longId.l); ostr << Machine_X86::regName(id->longId().l());
} }
ostr << ".\n"; ostr << ".\n";
@@ -244,17 +244,14 @@ 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 */
} }
/* Calling convention */ /* Calling convention */
if (this->flg & CALL_PASCAL) callingConv()->writeComments(ostr);
ostr << " * Pascal calling convention.\n";
else if (this->flg & CALL_C)
ostr << " * C calling convention.\n";
else if (this->flg & CALL_UNKNOWN)
ostr << " * Unknown calling convention.\n";
/* Other flags */ /* Other flags */
if (this->flg & (PROC_BADINST | PROC_IJMP)) if (this->flg & (PROC_BADINST | PROC_IJMP))
{ {

View File

@@ -105,7 +105,7 @@ static void freeList (nodeList &l)
/* Returns whether the node n belongs to the queue list q. */ /* Returns whether the node n belongs to the queue list q. */
static boolT inInt(BB * n, queue &q) static bool inInt(BB * n, queue &q)
{ {
return std::find(q.begin(),q.end(),n)!=q.end(); return std::find(q.begin(),q.end(),n)!=q.end();
} }
@@ -276,13 +276,13 @@ void Function::structLoops(derSeq *derivedG)
/* Structure loops */ /* Structure loops */
/* for all derived sequences Gi */ /* for all derived sequences Gi */
for(derSeq::iterator iter=derivedG->begin(); iter!=derivedG->end(); ++iter) for(auto & elem : *derivedG)
{ {
level++; level++;
Ii = iter->Ii; Ii = elem.Ii;
while (Ii) /* for all intervals Ii of Gi */ while (Ii) /* for all intervals Ii of Gi */
{ {
latchNode = NULL; latchNode = nullptr;
intNodes.clear(); intNodes.clear();
/* Find interval head (original BB node in G1) and create /* Find interval head (original BB node in G1) and create
@@ -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;
} }
} }
@@ -337,9 +336,7 @@ void Function::structLoops(derSeq *derivedG)
* h. Note that h is a case node. */ * h. Note that h is a case node. */
static bool successor (int s, int h, Function * pProc) static bool successor (int s, int h, Function * pProc)
{ {
BB * header; BB * header = pProc->m_dfsLast[h];
header = pProc->m_dfsLast[h];
auto iter = std::find_if(header->edges.begin(), auto iter = std::find_if(header->edges.begin(),
header->edges.end(), header->edges.end(),
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;}); [s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
@@ -352,8 +349,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 +370,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
@@ -431,9 +429,9 @@ static void flagNodes (nodeList &l, int f, Function * pProc)
/* Structures if statements */ /* Structures if statements */
void Function::structIfs () void Function::structIfs ()
{ {
size_t followInEdges; /* Largest # in-edges so far */
int curr, /* Index for linear scan of nodes */ int curr, /* Index for linear scan of nodes */
desc, /* Index for descendant */ /*desc,*/ /* Index for descendant */
followInEdges, /* Largest # in-edges so far */
follow; /* Possible follow node */ follow; /* Possible follow node */
nodeList domDesc, /* List of nodes dominated by curr */ nodeList domDesc, /* List of nodes dominated by curr */
unresolved /* List of unresolved if nodes */ unresolved /* List of unresolved if nodes */
@@ -454,7 +452,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)
{ {
@@ -507,14 +505,14 @@ void Function::replaceInEdge(BB* where, BB* which,BB* with)
} }
bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB) bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
{ {
HLTYPE &hl1(*pbb->back().hl()); HLTYPE &hl1(*pbb->back().hlU());
HLTYPE &hl2(*thenBB->back().hl()); HLTYPE &hl2(*thenBB->back().hlU());
BB* obb = elseBB->edges[THEN].BBptr; BB* obb = elseBB->edges[THEN].BBptr;
/* Construct compound DBL_OR expression */ /* Construct compound DBL_OR expression */
hl1.replaceExpr(hl1.expr()->inverse()); hl1.replaceExpr(hl1.expr()->inverse());
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR)); hl1.expr(BinaryOperator::Create(DBL_OR,hl1.expr(), hl2.expr()));
/* Replace in-edge to obb from e to pbb */ /* Replace in-edge to obb from e to pbb */
replaceInEdge(obb,elseBB,pbb); replaceInEdge(obb,elseBB,pbb);
@@ -528,12 +526,14 @@ bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
} }
bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB) bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
{ {
HLTYPE &hl1(*pbb->back().hl()); HLTYPE &hl1(*pbb->back().hlU());
HLTYPE &hl2(*thenBB->back().hl()); HLTYPE &hl2(*thenBB->back().hlU());
BB* obb = elseBB->edges[ELSE].BBptr; BB* obb = elseBB->edges[ELSE].BBptr;
Expr * hl2_expr = hl2.getMyExpr();
/* Construct compound DBL_AND expression */ /* Construct compound DBL_AND expression */
hl1.expr(COND_EXPR::boolOp (hl1.expr(),hl2.expr(), DBL_AND)); assert(hl1.expr());
assert(hl2_expr);
hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2_expr));
/* Replace in-edge to obb from e to pbb */ /* Replace in-edge to obb from e to pbb */
replaceInEdge(obb,elseBB,pbb); replaceInEdge(obb,elseBB,pbb);
@@ -547,15 +547,15 @@ bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB) bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
{ {
HLTYPE &hl1(*pbb->back().hl()); HLTYPE &hl1(*pbb->back().hlU());
HLTYPE &hl2(*thenBB->back().hl()); HLTYPE &hl2(*thenBB->back().hlU());
BB* obb = thenBB->edges[ELSE].BBptr; BB* obb = thenBB->edges[ELSE].BBptr;
/* Construct compound DBL_AND expression */ /* Construct compound DBL_AND expression */
hl1.replaceExpr(hl1.expr()->inverse()); hl1.replaceExpr(hl1.expr()->inverse());
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_AND)); hl1.expr(BinaryOperator::LogicAnd(hl1.expr(), hl2.expr()));
/* Replace in-edge to obb from t to pbb */ /* Replace in-edge to obb from t to pbb */
replaceInEdge(obb,thenBB,pbb); replaceInEdge(obb,thenBB,pbb);
@@ -570,13 +570,13 @@ bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB) bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
{ {
HLTYPE &hl1(*pbb->back().hl()); HLTYPE &hl1(*pbb->back().hlU());
HLTYPE &hl2(*thenBB->back().hl()); HLTYPE &hl2(*thenBB->back().hlU());
BB * obb = thenBB->edges[THEN].BBptr; BB * obb = thenBB->edges[THEN].BBptr;
/* Construct compound DBL_OR expression */ /* Construct compound DBL_OR expression */
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR)); hl1.expr(BinaryOperator::LogicOr(hl1.expr(), hl2.expr()));
/* Replace in-edge to obb from t to pbb */ /* Replace in-edge to obb from t to pbb */
@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -4,16 +4,17 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#include <cstring>
#include "dcc.h" #include "dcc.h"
#include "project.h" #include "project.h"
#include <string.h>
#include "CallGraph.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;
@@ -22,19 +23,97 @@ OPTION option; /* Command line options */
static char *initargs(int argc, char *argv[]); static char *initargs(int argc, char *argv[]);
static void displayTotalStats(void); static void displayTotalStats(void);
#include <llvm/Support/raw_os_ostream.h> #include <llvm/Support/raw_os_ostream.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/Host.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Target/TargetInstrInfo.h>
#include <llvm/MC/MCAsmInfo.h>
#include <llvm/CodeGen/MachineInstrBuilder.h>
#include <llvm/TableGen/Main.h>
#include <llvm/TableGen/TableGenBackend.h>
#include <llvm/TableGen/Record.h>
/**************************************************************************** /****************************************************************************
* main * main
***************************************************************************/ ***************************************************************************/
#include <iostream> #include <iostream>
extern Project g_proj; using namespace llvm;
int main(int argc, char *argv[]) bool TVisitor(raw_ostream &OS, RecordKeeper &Records)
{
Record *rec = Records.getDef("ADD8i8");
if(rec)
{
if(not rec->getTemplateArgs().empty())
std::cout << "Has template args\n";
auto classes(rec->getSuperClasses());
for(auto val : rec->getSuperClasses())
std::cout << "Super "<<val->getName()<<"\n";
// DagInit * in = rec->getValueAsDag(val.getName());
// in->dump();
for(const RecordVal &val : rec->getValues())
{
// val.dump();
}
rec->dump();
}
// rec = Records.getDef("CCR");
// if(rec)
// rec->dump();
for(auto val : Records.getDefs())
{
//std::cout<< "Def "<<val.first<<"\n";
}
return false;
}
int testTblGen(int argc, char **argv)
{
using namespace llvm;
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram(argc,argv);
cl::ParseCommandLineOptions(argc,argv);
return llvm::TableGenMain(argv[0],TVisitor);
InitializeNativeTarget();
Triple TheTriple;
std::string def = sys::getDefaultTargetTriple();
std::string MCPU="i386";
std::string MARCH="x86";
InitializeAllTargetInfos();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();
InitializeAllAsmParsers();
InitializeAllDisassemblers();
std::string TargetTriple("i386-pc-linux-gnu");
TheTriple = Triple(Triple::normalize(TargetTriple));
MCOperand op=llvm::MCOperand::CreateImm(11);
MCAsmInfo info;
raw_os_ostream wrap(std::cerr);
op.print(wrap,&info);
wrap.flush();
std::cerr<<"\n";
std::string lookuperr;
TargetRegistry::printRegisteredTargetsForVersion();
const Target *t = TargetRegistry::lookupTarget(MARCH,TheTriple,lookuperr);
TargetOptions opts;
std::string Features;
opts.PrintMachineCode=1;
TargetMachine *tm = t->createTargetMachine(TheTriple.getTriple(),MCPU,Features,opts);
std::cerr<<tm->getInstrInfo()->getName(97)<<"\n";
const MCInstrDesc &ds(tm->getInstrInfo()->get(97));
const MCOperandInfo *op1=ds.OpInfo;
uint16_t impl_def = ds.getImplicitDefs()[0];
std::cerr<<lookuperr<<"\n";
exit(0);
}
int main(int argc, char **argv)
{ {
// llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
// llvm::MCAsmInfo info;
// llvm::raw_os_ostream wrap(std::cerr);
// op.print(wrap,&info);
// wrap.flush();
/* Extract switches and filename */ /* Extract switches and filename */
strcpy(option.filename, initargs(argc, argv)); strcpy(option.filename, initargs(argc, argv));
@@ -45,20 +124,23 @@ int main(int argc, char *argv[])
DccFrontend fe(option.filename); DccFrontend fe(option.filename);
if(false==fe.FrontEnd ()) if(false==fe.FrontEnd ())
return -1; return -1;
if(option.asm1)
return 0;
/* In the middle is a so called Universal Decompiling Machine. /* In the middle is a so called Universal Decompiling Machine.
* It processes the procedure list and I-code and attaches where it can * It processes the procedure list and I-code and attaches where it can
* to each procedure an optimised cfg and ud lists * to each procedure an optimised cfg and ud lists
*/ */
udm(); udm();
if(option.asm2)
return 0;
/* Back end converts each procedure into C using I-code, interval /* Back end converts each procedure into C using I-code, interval
* 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(asm1_name ? asm1_name:option.filename, Project::get()->callGraph);
g_proj.callGraph->write(); Project::get()->callGraph->write();
if (option.Stats) if (option.Stats)
displayTotalStats(); displayTotalStats();
@@ -153,8 +235,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

@@ -70,21 +70,21 @@ static const char *szFlops3C[] =
static const char *szPtr[2] = { "word ptr ", "byte ptr " }; static const char *szPtr[2] = { "word ptr ", "byte ptr " };
static void formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm); static void formatRM(ostringstream &p, const LLOperand &pm);
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm); static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
static char *strHex(uint32_t d); static char *strHex(uint32_t d);
//static int checkScanned(uint32_t pcCur); //static int checkScanned(uint32_t pcCur);
//static void setProc(Function * proc); //static void setProc(Function * proc);
//static void dispData(uint16_t dataSeg); //static void dispData(uint16_t dataSeg);
boolT callArg(uint16_t off, char *temp); /* Check for procedure name */ bool callArg(uint16_t off, char *temp); /* Check for procedure name */
//static FILE *dis_g_fp; //static FILE *dis_g_fp;
static CIcodeRec pc; static CIcodeRec pc;
static int cb, j, numIcode, allocIcode; static int cb, j, numIcode, allocIcode;
static map<int,int> pl; static map<int,int> pl;
static uint32_t nextInst; static uint32_t nextInst;
static boolT fImpure; static bool fImpure;
//static int g_lab; //static int g_lab;
static Function * pProc; /* Points to current proc struct */ static Function * pProc; /* Points to current proc struct */
@@ -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,
@@ -247,7 +247,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
{ {
for (j = 0; j < cb; j++) for (j = 0; j < cb; j++)
{ {
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[inst.label + j]); hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.image()[inst.label + j]);
} }
hex_bytes << ' '; hex_bytes << ' ';
} }
@@ -258,7 +258,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
oper_stream << setw(5)<<left; // align for the labels oper_stream << setw(5)<<left; // align for the labels
{ {
ostringstream lab_contents; ostringstream lab_contents;
if (readVal(lab_contents, inst.label, 0)) if (readVal(lab_contents, inst.label, nullptr))
{ {
lab_contents << ':'; /* Also removes the null */ lab_contents << ':'; /* Also removes the null */
} }
@@ -283,7 +283,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
{ {
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR: case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG: case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
strDst(operands_s,inst.getFlag(), inst.dst); strDst(operands_s,inst.getFlag(), inst.m_dst);
inst.strSrc(operands_s); inst.strSrc(operands_s);
break; break;
@@ -293,7 +293,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL: case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
case iROR: case iROR:
strDst(operands_s,inst.getFlag() | I, inst.dst); strDst(operands_s,inst.getFlag() | I, inst.m_dst);
if(inst.testFlags(I)) if(inst.testFlags(I))
inst.strSrc(operands_s); inst.strSrc(operands_s);
else else
@@ -301,7 +301,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
break; break;
case iINC: case iDEC: case iNEG: case iNOT: case iPOP: case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
strDst(operands_s,inst.getFlag() | I, inst.dst); strDst(operands_s,inst.getFlag() | I, inst.m_dst);
break; break;
case iPUSH: case iPUSH:
@@ -311,15 +311,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
} }
else else
{ {
strDst(operands_s,inst.getFlag() | I, inst.dst); strDst(operands_s,inst.getFlag() | I, inst.m_dst);
} }
break; break;
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD: case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
if (inst.testFlags(I)) if (inst.testFlags(I))
{ {
strDst(operands_s,inst.getFlag(), inst.dst) <<", "; strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
formatRM(operands_s, inst.getFlag(), inst.src()); formatRM(operands_s, inst.src());
inst.strSrc(operands_s); inst.strSrc(operands_s);
} }
else else
@@ -327,7 +327,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
break; break;
case iLDS: case iLES: case iBOUND: case iLDS: case iLES: case iBOUND:
strDst(operands_s,inst.getFlag(), inst.dst)<<", dword ptr"; strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
inst.strSrc(operands_s,true); inst.strSrc(operands_s,true);
break; break;
@@ -343,7 +343,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
ICODE *lab=pc.GetIcode(inst.src().getImm2()); ICODE *lab=pc.GetIcode(inst.src().getImm2());
selectTable(Label); selectTable(Label);
if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */ if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */
readVal(operands_s, lab->ll()->label, 0)) readVal(operands_s, lab->ll()->label, nullptr))
{ {
break; /* Symbolic label. Done */ break; /* Symbolic label. Done */
} }
@@ -397,8 +397,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
break; break;
case iENTER: case iENTER:
operands_s<<strHex(inst.dst.off)<<", "; operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
operands_s<<strHex(inst.src().getImm2());
break; break;
case iRET: case iRETF: case iINT: case iRET: case iRETF: case iINT:
@@ -484,7 +483,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
/* Check for user supplied comment */ /* Check for user supplied comment */
selectTable(Comment); selectTable(Comment);
ostringstream cbuf; ostringstream cbuf;
if (readVal(cbuf, inst.label, 0)) if (readVal(cbuf, inst.label, nullptr))
{ {
result_stream <<"; "<<cbuf.str(); result_stream <<"; "<<cbuf.str();
} }
@@ -552,7 +551,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, const LLOperand &pm)
{ {
//char seg[4]; //char seg[4];
@@ -595,7 +594,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
//os << setw(WID_PTR); //os << setw(WID_PTR);
if ((flg & I) and not pm.isReg()) if ((flg & I) and not pm.isReg())
os << szPtr[flg & B]; os << szPtr[flg & B];
formatRM(os, flg, pm); formatRM(os, pm);
return os; return os;
} }
@@ -612,7 +611,7 @@ ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
else if (testFlags(IM_SRC)) /* level 2 */ else if (testFlags(IM_SRC)) /* level 2 */
os<<"dx:ax"; os<<"dx:ax";
else else
formatRM(os, getFlag(), src()); formatRM(os, src());
return os; return os;
} }
@@ -627,14 +626,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,13 +642,13 @@ 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.
esc 0x38 is FILD */ esc 0x38 is FILD */
if ( not dst.isReg() ) if ( not m_dst.isReg() )
{ {
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */ /* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
out<<Machine_X86::floatOpName(op)<<' '; out<<Machine_X86::floatOpName(op)<<' ';
@@ -685,7 +684,7 @@ void LLInst::flops(std::ostringstream &out)
} }
} }
formatRM(out, getFlag(), dst); formatRM(out, m_dst);
} }
else else
{ {
@@ -694,7 +693,7 @@ void LLInst::flops(std::ostringstream &out)
normal opcodes. Because the opcodes are slightly different for normal opcodes. Because the opcodes are slightly different for
this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
reg == 3), a separate table is used (szFlops2). */ reg == 3), a separate table is used (szFlops2). */
int destRegIdx=dst.regi - rAX; int destRegIdx=m_dst.regi - rAX;
switch (op) switch (op)
{ {
case 0x0C: case 0x0C:

View File

@@ -82,7 +82,8 @@ TwoWild(uint8_t pat[])
static bool static bool
FourWild(uint8_t pat[]) FourWild(uint8_t pat[])
{ {
TwoWild(pat); if(TwoWild(pat))
return true;
return TwoWild(pat); return TwoWild(pat);
} }
@@ -180,8 +181,7 @@ static bool op0F(uint8_t pat[])
processor is in 16 bit address mode (real mode). processor is in 16 bit address mode (real mode).
PATLEN bytes are scanned. PATLEN bytes are scanned.
*/ */
void void fixWildCards(uint8_t pat[])
fixWildCards(uint8_t pat[])
{ {
uint8_t op, quad, intArg; uint8_t op, quad, intArg;

View File

@@ -7,10 +7,17 @@
#include "dcc.h" #include "dcc.h"
#include "disassem.h" #include "disassem.h"
#include <stdio.h> #include <stdio.h>
#include <stdint.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 +57,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 +65,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 = nullptr;
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 +87,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 +97,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 +130,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);
@@ -134,7 +139,7 @@ static void displayLoadInfo(void)
printf("\nRelocation Table\n"); printf("\nRelocation Table\n");
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
{ {
printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.Image + prog.relocTable[i])); printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.image() + prog.relocTable[i]));
} }
} }
printf("\n"); printf("\n");
@@ -208,23 +213,23 @@ 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")) == nullptr)
{ {
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());
} }
prog.fCOM = (header.sigLo != 0x4D || header.sigHi != 0x5A);
if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) { if (! prog.fCOM ) {
/* Read rest of header */ /* Read rest of header */
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! */
@@ -298,14 +303,14 @@ void DccFrontend::LoadImage(Project &proj)
/* Allocate a block of memory for the program. */ /* Allocate a block of memory for the program. */
prog.cbImage = cb + sizeof(PSP); prog.cbImage = cb + sizeof(PSP);
prog.Image = new uint8_t [prog.cbImage]; prog.Imagez = new uint8_t [prog.cbImage];
prog.Image[0] = 0xCD; /* Fill in PSP int 20h location */ prog.Imagez[0] = 0xCD; /* Fill in PSP int 20h location */
prog.Image[1] = 0x20; /* for termination checking */ prog.Imagez[1] = 0x20; /* for termination checking */
/* 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.Imagez + 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 */
@@ -318,7 +323,7 @@ void DccFrontend::LoadImage(Project &proj)
{ {
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
{ {
uint8_t *p = &prog.Image[prog.relocTable[i]]; uint8_t *p = &prog.Imagez[prog.relocTable[i]];
uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION; uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION;
*p++ = (uint8_t)(w & 0x00FF); *p++ = (uint8_t)(w & 0x00FF);
*p = (uint8_t)((w & 0xFF00) >> 8); *p = (uint8_t)((w & 0xFF00) >> 8);

View File

@@ -3,15 +3,21 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#include "dcc.h"
#include <string.h> #include <string.h>
#include <malloc.h> /* For free() */ #include <boost/range/rbegin.hpp>
#include <boost/range/rend.hpp>
#include <boost/range/adaptors.hpp>
#include "dcc.h"
#include "graph.h" #include "graph.h"
#include "project.h" #include "project.h"
using namespace std;
using namespace boost;
extern Project g_proj; extern Project g_proj;
//static BB * rmJMP(Function * pProc, int marker, BB * pBB); //static BB * rmJMP(Function * pProc, int marker, BB * pBB);
static void mergeFallThrough(Function * pProc, BB * pBB); //static void mergeFallThrough(Function * pProc, BB * pBB);
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
@@ -29,17 +35,22 @@ void Function::createCFG()
* 5) Repeated string instructions * 5) Repeated string instructions
* 6) End of procedure * 6) End of procedure
*/ */
int i;
int ip;
BB * psBB; BB * psBB;
BB * pBB; BB * pBB;
iICODE pIcode = Icode.begin(); iICODE pIcode = Icode.begin();
iICODE iStart = Icode.begin();
stats.numBBbef = stats.numBBaft = 0; stats.numBBbef = stats.numBBaft = 0;
for (; pIcode!=Icode.end(); ++pIcode) rICODE current_range=make_iterator_range(pIcode,++iICODE(pIcode));
for (; pIcode!=Icode.end(); ++pIcode,current_range.advance_end(1))
{ {
iICODE nextIcode = ++iICODE(pIcode); iICODE nextIcode = ++iICODE(pIcode);
pBB = nullptr;
LLInst *ll = pIcode->ll(); LLInst *ll = pIcode->ll();
/* Only process icodes that have valid instructions */
if(ll->testFlags(NO_CODE))
continue;
/* Stick a NOWHERE_NODE on the end if we terminate /* Stick a NOWHERE_NODE on the end if we terminate
* with anything other than a ret, jump or terminate */ * with anything other than a ret, jump or terminate */
if (nextIcode == Icode.end() and if (nextIcode == Icode.end() and
@@ -47,124 +58,97 @@ void Function::createCFG()
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and (not ll->match(iJMP)) and (not ll->match(iJMPF)) and
(not ll->match(iRET)) and (not ll->match(iRETF))) (not ll->match(iRET)) and (not ll->match(iRETF)))
{ {
//pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this); pBB=BB::Create(current_range, NOWHERE_NODE, this);
pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
} }
else
/* Only process icodes that have valid instructions */
else if (not ll->testFlags(NO_CODE) )
{
switch (ll->getOpcode()) { switch (ll->getOpcode()) {
case iJB: case iJBE: case iJAE: case iJA: case iJB: case iJBE: case iJAE: case iJA:
case iJL: case iJLE: case iJGE: case iJG: case iJL: case iJLE: case iJGE: case iJG:
case iJE: case iJNE: case iJS: case iJNS: case iJE: case iJNE: case iJS: case iJNS:
case iJO: case iJNO: case iJP: case iJNP: case iJO: case iJNO: case iJP: case iJNP:
case iJCXZ: case iJCXZ:
pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this); pBB = BB::Create(current_range, TWO_BRANCH, this);
CondJumps: CondJumps:
//start = ip + 1; pBB->addOutEdge(nextIcode->loc_ip);
iStart = ++iICODE(pIcode); /* This is checking for jumps off into nowhere */
pBB->edges[0].ip = (uint32_t)iStart->loc_ip; if ( not ll->testFlags(NO_LABEL) )
/* This is for jumps off into nowhere */ pBB->addOutEdge(ll->src().getImm2());
if ( ll->testFlags(NO_LABEL) )
{
pBB->edges.pop_back();
}
else
pBB->edges[1].ip = ll->src().getImm2();
break; break;
case iLOOP: case iLOOPE: case iLOOPNE: case iLOOP: case iLOOPE: case iLOOPNE:
//pBB = BB::Create(start, ip, LOOP_NODE, 2, this); pBB = BB::Create(current_range, LOOP_NODE, this);
pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this);
goto CondJumps; goto CondJumps;
case iJMPF: case iJMP: case iJMPF: case iJMP:
if (ll->testFlags(SWITCH)) if (ll->testFlags(SWITCH))
{ {
//pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this); pBB = BB::Create(current_range, MULTI_BRANCH, this);
pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this); for (auto & elem : ll->caseTbl2)
for (i = 0; i < ll->caseTbl2.size(); i++) pBB->addOutEdge(elem);
pBB->edges[i].ip = ll->caseTbl2[i];
hasCase = true; hasCase = true;
} }
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
{ {
//pBB = BB::Create(start, ip, ONE_BRANCH, 1, this); pBB = BB::Create(current_range, ONE_BRANCH, this);
pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this); pBB->addOutEdge(ll->src().getImm2());
pBB->edges[0].ip = ll->src().getImm2();
} }
else else
BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this); pBB = BB::Create(current_range, NOWHERE_NODE, this);
iStart = ++iICODE(pIcode);
break; break;
case iCALLF: case iCALL: case iCALLF: case iCALL:
{ {
Function * p = ll->src().proc.proc; Function * p = ll->src().proc.proc;
if (p) pBB = BB::Create(current_range, CALL_NODE, this);
i = ((p->flg) & TERMINATES) ? 0 : 1; if (p && not ((p->flg) & TERMINATES) )
else pBB->addOutEdge(nextIcode->loc_ip);
i = 1;
pBB = BB::Create(iStart, pIcode, CALL_NODE, i, this);
iStart = ++iICODE(pIcode);//start = ip + 1;
if (i)
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
}
break; break;
}
case iRET: case iRETF: case iRET: case iRETF:
//BB::Create(start, ip, RETURN_NODE, 0, this); pBB = BB::Create(current_range, RETURN_NODE, this);
BB::Create(iStart, pIcode, RETURN_NODE, 0, this);
iStart = ++iICODE(pIcode);
break; break;
default: default:
/* Check for exit to DOS */ /* Check for exit to DOS */
iICODE next1=++iICODE(pIcode);
if ( ll->testFlags(TERMINATES) ) if ( ll->testFlags(TERMINATES) )
{ {
pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this); pBB = BB::Create(current_range, TERMINATE_NODE, this);
//pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
iStart = ++iICODE(pIcode); // start = ip + 1;
} }
/* Check for a fall through */ /* Check for a fall through */
else if (next1 != Icode.end()) else if (nextIcode != Icode.end())
{ {
if (next1->ll()->testFlags(TARGET | CASE)) if (nextIcode->ll()->testFlags(TARGET | CASE))
{ {
//pBB = BB::Create(start, ip, FALL_NODE, 1, this); pBB = BB::Create(current_range, FALL_NODE, this);
pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this); pBB->addOutEdge(nextIcode->loc_ip);
iStart = ++iICODE(pIcode); // start = ip + 1;
pBB->addOutEdge(iStart->loc_ip);
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
} }
} }
break; break;
} }
if(pBB!=nullptr) // created a new Basic block
{
// restart the range
// end iterator will be updated by expression in for statement
current_range=make_iterator_range(nextIcode,nextIcode);
} }
} }
auto iter=heldBBs.begin(); for (auto pr : m_ip_to_bb)
/* Convert list of BBs into a graph */
for (; iter!=heldBBs.end(); ++iter)
{ {
pBB = *iter; BB* pBB=pr.second;
for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++) for (auto & elem : pBB->edges)
{ {
uint32_t ip = pBB->edges[edeg_idx].ip; int32_t ip = elem.ip;
if (ip >= SYNTHESIZED_MIN) if (ip >= SYNTHESIZED_MIN)
{ {
fatalError (INVALID_SYNTHETIC_BB); fatalError (INVALID_SYNTHETIC_BB);
return; return;
} }
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(), auto iter2=m_ip_to_bb.find(ip);
[ip](BB *psBB)->bool {return psBB->begin()->loc_ip==ip;}); if(iter2==m_ip_to_bb.end())
if(iter2==heldBBs.end())
fatalError(NO_BB, ip, name.c_str()); fatalError(NO_BB, ip, name.c_str());
psBB = *iter2; psBB = iter2->second;
pBB->edges[edeg_idx].BBptr = psBB; elem.BBptr = psBB;
psBB->inEdges.push_back((BB *)nullptr); psBB->inEdges.push_back((BB *)nullptr);
} }
} }
@@ -179,8 +163,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))
@@ -194,21 +178,16 @@ void Function::markImpure()
} }
/*****************************************************************************
* newBB - Allocate new BB and link to end of list
*****************************************************************************/
/***************************************************************************** /*****************************************************************************
* freeCFG - Deallocates a cfg * freeCFG - Deallocates a cfg
****************************************************************************/ ****************************************************************************/
void Function::freeCFG() void Function::freeCFG()
{ {
for(BB *p : heldBBs) for(auto p : m_ip_to_bb)
{ {
delete p; delete p.second;
} }
m_ip_to_bb.clear();
} }
@@ -222,7 +201,7 @@ void Function::compressCFG()
/* First pass over BB list removes redundant jumps of the form /* First pass over BB list removes redundant jumps of the form
* (Un)Conditional -> Unconditional jump */ * (Un)Conditional -> Unconditional jump */
for (BB *pBB : m_cfg) for (BB *pBB : m_actual_cfg) //m_cfg
{ {
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH)) if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
continue; continue;
@@ -244,18 +223,17 @@ void Function::compressCFG()
/* Next is a depth-first traversal merging any FALL_NODE or /* Next is a depth-first traversal merging any FALL_NODE or
* ONE_BRANCH that fall through to a node with that as their only * ONE_BRANCH that fall through to a node with that as their only
* in-edge. */ * in-edge. */
m_cfg.front()->mergeFallThrough(Icode); m_actual_cfg.front()->mergeFallThrough(Icode);
/* Remove redundant BBs created by the above compressions /* Remove redundant BBs created by the above compressions
* and allocate in-edge arrays as required. */ * and allocate in-edge arrays as required. */
stats.numBBaft = stats.numBBbef; stats.numBBaft = stats.numBBbef;
bool entry_node=true;
for(auto iter=m_cfg.begin(); iter!=m_cfg.end(); ++iter) for(BB *pBB : m_actual_cfg)
{ {
BB * pBB = *iter;
if (pBB->inEdges.empty()) if (pBB->inEdges.empty())
{ {
if (iter == m_cfg.begin()) /* Init it misses out on */ if (entry_node) /* Init it misses out on */
pBB->index = UN_INIT; pBB->index = UN_INIT;
else else
{ {
@@ -267,15 +245,16 @@ void Function::compressCFG()
{ {
pBB->inEdgeCount = pBB->inEdges.size(); pBB->inEdgeCount = pBB->inEdges.size();
} }
entry_node=false;
} }
/* Allocate storage for dfsLast[] array */ /* Allocate storage for dfsLast[] array */
numBBs = stats.numBBaft; numBBs = stats.numBBaft;
m_dfsLast.resize(numBBs,0); // = (BB **)allocMem(numBBs * sizeof(BB *)) m_dfsLast.resize(numBBs,nullptr); // = (BB **)allocMem(numBBs * sizeof(BB *))
/* Now do a dfs numbering traversal and fill in the inEdges[] array */ /* Now do a dfs numbering traversal and fill in the inEdges[] array */
last = numBBs - 1; last = numBBs - 1;
m_cfg.front()->dfsNumbering(m_dfsLast, &first, &last); m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
} }
@@ -335,8 +314,6 @@ BB *BB::rmJMP(int marker, BB * pBB)
void BB::mergeFallThrough( CIcodeRec &Icode) void BB::mergeFallThrough( CIcodeRec &Icode)
{ {
BB * pChild; BB * pChild;
int i;
if (!this) if (!this)
{ {
printf("mergeFallThrough on empty BB!\n"); printf("mergeFallThrough on empty BB!\n");
@@ -375,9 +352,11 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
traversed = DFS_MERGE; traversed = DFS_MERGE;
/* Process all out edges recursively */ /* Process all out edges recursively */
for (i = 0; i < edges.size(); i++) for (auto & elem : edges)
if (edges[i].BBptr->traversed != DFS_MERGE) {
edges[i].BBptr->mergeFallThrough(Icode); if (elem.BBptr->traversed != DFS_MERGE)
elem.BBptr->mergeFallThrough(Icode);
}
} }
@@ -399,7 +378,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

@@ -10,26 +10,15 @@
#include <sstream> #include <sstream>
#include "dcc.h" #include "dcc.h"
using namespace std; using namespace std;
#define ICODE_DELTA 25
/* Masks off bits set by duReg[] */
std::bitset<32> maskDuReg[] = { 0x00,
0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
0xEFFFFF, /* tmp reg */
0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
static char buf[lineSize]; /* Line buffer for hl icode output */ static char buf[lineSize]; /* Line buffer for hl icode output */
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */ /* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
void HLTYPE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs) void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
{ {
assert(lhs);
set(lhs,rhs); set(lhs,rhs);
} }
@@ -41,14 +30,12 @@ void ICODE::checkHlCall()
void ICODE::newCallHl() void ICODE::newCallHl()
{ {
type = HIGH_LEVEL; type = HIGH_LEVEL;
hl()->opcode = HLI_CALL; hlU()->setCall(ll()->src().proc.proc);
hl()->call.proc = ll()->src().proc.proc;
hl()->call.args = new STKFRAME;
if (ll()->src().proc.cb != 0) if (ll()->src().proc.cb != 0)
hl()->call.args->cb = ll()->src().proc.cb; hlU()->call.args->cb = ll()->src().proc.cb;
else if(hl()->call.proc) else if(hl()->call.proc)
hl()->call.args->cb =hl()->call.proc->cbParam; hlU()->call.args->cb = hl()->call.proc->cbParam;
else else
{ {
printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n"); printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
@@ -59,18 +46,18 @@ void ICODE::newCallHl()
/* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode /* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
* array */ * array */
void ICODE::setUnary(hlIcode op, COND_EXPR *_exp) void ICODE::setUnary(hlIcode op, Expr *_exp)
{ {
type = HIGH_LEVEL; type = HIGH_LEVEL;
hl()->set(op,_exp); hlU()->set(op,_exp);
} }
/* Places the new HLI_JCOND high-level operand in the high-level icode array */ /* Places the new HLI_JCOND high-level operand in the high-level icode array */
void ICODE::setJCond(COND_EXPR *cexp) void ICODE::setJCond(Expr *cexp)
{ {
type = HIGH_LEVEL; type = HIGH_LEVEL;
hl()->set(HLI_JCOND,cexp); hlU()->set(HLI_JCOND,cexp);
} }
@@ -90,13 +77,13 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
{ {
int numDefs; int numDefs;
numDefs = du1.numRegsDef; numDefs = du1.getNumRegsDef();
if (numDefs == thisDefIdx) if (numDefs == thisDefIdx)
{ {
for ( ; numDefs > 0; numDefs--) for ( ; numDefs > 0; numDefs--)
{ {
if (du1.used(numDefs-1)||(du.lastDefRegi[regi])) if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
break; break;
} }
} }
@@ -106,11 +93,12 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
invalidate(); invalidate();
return true; return true;
} }
HlTypeSupport *p=hl()->get(); HlTypeSupport *p=hlU()->get();
if(p and p->removeRegFromLong(regi,locId)) if(p and p->removeRegFromLong(regi,locId))
{ {
du1.numRegsDef--; du1.removeDef(regi); //du1.numRegsDef--;
du.def &= maskDuReg[regi]; //du.def &= maskDuReg[regi];
du.def.clrReg(regi);
} }
return false; return false;
} }
@@ -158,7 +146,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
break; break;
case iDEC: case iDEC:
rhs = COND_EXPR::idKte (1, 2); rhs = AstIdent::idKte (1, 2);
rhs = COND_EXPR::boolOp (lhs, rhs, SUB); rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
res.setAsgn(lhs, rhs); res.setAsgn(lhs, rhs);
break; break;
@@ -168,12 +156,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
rhs = COND_EXPR::boolOp (lhs, rhs, DIV); rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
if ( ll->testFlags(B) ) if ( ll->testFlags(B) )
{ {
lhs = COND_EXPR::idReg (rAL, 0, &localId); lhs = AstIdent::idReg (rAL, 0, &localId);
pIcode->setRegDU( rAL, eDEF); pIcode->setRegDU( rAL, eDEF);
} }
else else
{ {
lhs = COND_EXPR::idReg (rAX, 0, &localId); lhs = AstIdent::idReg (rAX, 0, &localId);
pIcode->setRegDU( rAX, eDEF); pIcode->setRegDU( rAX, eDEF);
} }
res.setAsgn(lhs, rhs); res.setAsgn(lhs, rhs);
@@ -181,12 +169,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
case iIMUL: case iIMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL); rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
lhs = COND_EXPR::id (*pIcode, LHS_OP, func, i, *pIcode, NONE); lhs = AstIdent::id (*pIcode, LHS_OP, func, i, *pIcode, NONE);
res.setAsgn(lhs, rhs); res.setAsgn(lhs, rhs);
break; break;
case iINC: case iINC:
rhs = COND_EXPR::idKte (1, 2); rhs = AstIdent::idKte (1, 2);
rhs = COND_EXPR::boolOp (lhs, rhs, ADD); rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
res.setAsgn(lhs, rhs); res.setAsgn(lhs, rhs);
break; break;
@@ -200,12 +188,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
rhs = COND_EXPR::boolOp (lhs, rhs, MOD); rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
if ( ll->testFlags(B) ) if ( ll->testFlags(B) )
{ {
lhs = COND_EXPR::idReg (rAH, 0, &localId); lhs = AstIdent::idReg (rAH, 0, &localId);
pIcode->setRegDU( rAH, eDEF); pIcode->setRegDU( rAH, eDEF);
} }
else else
{ {
lhs = COND_EXPR::idReg (rDX, 0, &localId); lhs = AstIdent::idReg (rDX, 0, &localId);
pIcode->setRegDU( rDX, eDEF); pIcode->setRegDU( rDX, eDEF);
} }
res.setAsgn(lhs, rhs); res.setAsgn(lhs, rhs);
@@ -216,7 +204,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
case iMUL: case iMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL); rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE); lhs = AstIdent::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
res.setAsgn(lhs, rhs); res.setAsgn(lhs, rhs);
break; break;
@@ -277,42 +265,89 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
return res; return res;
} }
#endif #endif
static bool needsLhs(unsigned opc)
{
switch (opc)
{
case iCALL:
case iCALLF:
case iRET:
case iRETF:
default: return false;
case iADD:
case iAND:
case iDEC:
case iDIV:
case iIDIV:/* should be signed div */
case iIMUL:
case iINC:
case iLEA:
case iMOD:
case iMOV:
case iMUL:
case iNEG:
case iNOT:
case iOR:
case iPOP:
case iPUSH:
case iSHL:
case iSAR: /* signed */
case iSHR:
case iSIGNEX:
case iSUB:
case iXCHG:
case iXOR:
return true;
}
}
/* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage. /* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
* Note: this process should be done before data flow analysis, which * Note: this process should be done before data flow analysis, which
* 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 */ Expr *rhs; /* left- and right-hand side of expression */
uint32_t _flg; /* icode flags */ uint32_t _flg; /* icode flags */
numIcode = Icode.size(); numIcode = Icode.size();
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i) for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
{ {
Expr *lhs=nullptr;
assert(numIcode==Icode.size()); assert(numIcode==Icode.size());
pIcode = i; //Icode.GetIcode(i) pIcode = i; //Icode.GetIcode(i)
LLInst *ll = pIcode->ll(); LLInst *ll = pIcode->ll();
LLOperand *dst_ll = ll->get(DST);
LLOperand *src_ll = ll->get(SRC);
if ( ll->testFlags(NOT_HLL) ) if ( ll->testFlags(NOT_HLL) )
pIcode->invalidate(); pIcode->invalidate();
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() ) if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
continue; continue;
_flg = ll->getFlag(); _flg = ll->getFlag();
if ((_flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */ if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */ if ( not ll->testFlags(NO_OPS) ) /* if there are opers */
{ {
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */ if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE); rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE); if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD))
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
} }
if(ll->getOpcode()==iPUSH) {
if(ll->testFlags(I)) {
lhs = new Constant(src_ll->opz,src_ll->byteWidth());
}
// lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
}
if(needsLhs(ll->getOpcode()))
assert(lhs!=nullptr);
switch (ll->getOpcode()) switch (ll->getOpcode())
{ {
case iADD: case iADD:
rhs = COND_EXPR::boolOp (lhs, rhs, ADD); rhs = new BinaryOperator(ADD,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iAND: case iAND:
rhs = COND_EXPR::boolOp (lhs, rhs, AND); rhs = BinaryOperator::And(lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
@@ -323,101 +358,91 @@ void Function::highLevelGen()
break; break;
case iDEC: case iDEC:
rhs = COND_EXPR::idKte (1, 2); rhs = new BinaryOperator(SUB,lhs, new Constant(1, 2));
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iDIV: case iDIV:
case iIDIV:/* should be signed div */ case iIDIV:/* should be signed div */
rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
if ( ll->testFlags(B) )
{ {
lhs = COND_EXPR::idReg (rAL, 0, &localId); eReg v = ( dst_ll->byteWidth()==1) ? rAL:rAX;
pIcode->setRegDU( rAL, eDEF); rhs = new BinaryOperator(DIV,lhs, rhs);
} lhs = new RegisterNode(LLOperand(v, dst_ll->byteWidth()), &localId);
else pIcode->setRegDU( v, eDEF);
{
lhs = COND_EXPR::idReg (rAX, 0, &localId);
pIcode->setRegDU( rAX, eDEF);
}
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
}
break; break;
case iIMUL: case iIMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL); rhs = new BinaryOperator(MUL,lhs, rhs);
lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE); lhs = AstIdent::id (*ll, LHS_OP, this, i, *pIcode, NONE);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iINC: case iINC:
rhs = COND_EXPR::idKte (1, 2); rhs = new BinaryOperator(ADD,lhs, new Constant(1, 2));
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iLEA: case iLEA:
rhs = COND_EXPR::unary (ADDRESSOF, rhs); rhs =UnaryOperator::Create(ADDRESSOF, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iMOD: case iMOD:
rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
if ( ll->testFlags(B) )
{ {
lhs = COND_EXPR::idReg (rAH, 0, &localId); rhs = new BinaryOperator(MOD,lhs, rhs);
pIcode->setRegDU( rAH, eDEF); eReg lhs_reg = (dst_ll->byteWidth()==1) ? rAH : rDX;
} lhs = new RegisterNode(LLOperand(lhs_reg, dst_ll->byteWidth()), &localId);
else pIcode->setRegDU( lhs_reg, eDEF);
{
lhs = COND_EXPR::idReg (rDX, 0, &localId);
pIcode->setRegDU( rDX, eDEF);
}
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
}
break; break;
case iMOV: pIcode->setAsgn(lhs, rhs); case iMOV: pIcode->setAsgn(lhs, rhs);
break; break;
case iMUL: case iMUL:
rhs = COND_EXPR::boolOp (lhs, rhs, MUL); rhs = new BinaryOperator(MUL,lhs, rhs);
lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE); lhs = AstIdent::id (*ll, LHS_OP, this, i, *pIcode, NONE);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iNEG: case iNEG:
rhs = COND_EXPR::unary (NEGATION, lhs); rhs = UnaryOperator::Create(NEGATION, lhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iNOT: case iNOT:
rhs = COND_EXPR::boolOp (NULL, rhs, NOT); rhs = new BinaryOperator(NOT,nullptr, rhs); // TODO: change this to unary NOT ?
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iOR: case iOR:
rhs = COND_EXPR::boolOp (lhs, rhs, OR); rhs = new BinaryOperator(OR,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iPOP: pIcode->setUnary(HLI_POP, lhs); case iPOP:
pIcode->setUnary(HLI_POP, lhs);
break; break;
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs); case iPUSH:
pIcode->setUnary(HLI_PUSH, lhs);
break; break;
case iRET: case iRET:
case iRETF: pIcode->setUnary(HLI_RET, NULL); case iRETF: pIcode->setUnary(HLI_RET, nullptr);
break; break;
case iSHL: case iSHL:
rhs = COND_EXPR::boolOp (lhs, rhs, SHL); rhs = new BinaryOperator(SHL,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
case iSAR: /* signed */ case iSAR: /* signed */
case iSHR: case iSHR:
rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/ rhs = new BinaryOperator(SHR,lhs, rhs); /* unsigned*/
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
@@ -425,7 +450,7 @@ void Function::highLevelGen()
break; break;
case iSUB: case iSUB:
rhs = COND_EXPR::boolOp (lhs, rhs, SUB); rhs = new BinaryOperator(SUB,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
@@ -433,7 +458,7 @@ void Function::highLevelGen()
break; break;
case iXOR: case iXOR:
rhs = COND_EXPR::boolOp (lhs, rhs, XOR); rhs = new BinaryOperator(XOR,lhs, rhs);
pIcode->setAsgn(lhs, rhs); pIcode->setAsgn(lhs, rhs);
break; break;
} }
@@ -442,59 +467,27 @@ void Function::highLevelGen()
} }
/* Modifies the given conditional operator to its inverse. This is used /**
* in if..then[..else] statements, to reflect the condition that takes the \fn COND_EXPR::inverse
* then part. */ Modifies the given conditional operator to its inverse. This is used
COND_EXPR *COND_EXPR::inverse () const in if..then[..else] statements, to reflect the condition that takes the
{ then part.
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL, */
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
DUMMY, DBL_OR, DBL_AND};
COND_EXPR *res=0;
if (m_type == BOOLEAN_OP)
{
switch ( op() )
{
case LESS_EQUAL: case LESS: case EQUAL:
case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
res = this->clone();
res->boolExpr.op = invCondOp[op()];
return res;
case AND: case OR: case XOR: case NOT: case ADD:
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
return COND_EXPR::unary (NEGATION, this->clone());
case DBL_AND: case DBL_OR:
// Binary::Create(invertop,lhs->inverse(),rhs->inverse());
res = this->clone();
res->boolExpr.op = invCondOp[op()];
res->boolExpr.lhs=lhs()->inverse ();
res->boolExpr.rhs=rhs()->inverse ();
return res;
} /* eos */
}
else if (m_type == NEGATION) //TODO: memleak here
{
return expr.unaryExp->clone();
}
return this->clone();
/* other types are left unmodified */
}
/* Returns the string that represents the procedure call of tproc (ie. with /* Returns the string that represents the procedure call of tproc (ie. with
* actual parameters) */ * actual parameters) */
std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc) std::string Function::writeCall (Function * tproc, STKFRAME & args, 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)
{ {
ostr << walkCondExpr (sym.actual, pproc, numLoc); if(sym.actual)
ostr << sym.actual->walkCondExpr (this, numLoc);
else
ostr << "";
if((&sym)!=&(args.back())) if((&sym)!=&(args.back()))
ostr << ", "; ostr << ", ";
} }
@@ -504,15 +497,19 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int
/* Displays the output of a HLI_JCOND icode. */ /* Displays the output of a HLI_JCOND icode. */
char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc) const char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
{ {
assert(h.expr());
memset (buf, ' ', sizeof(buf)); memset (buf, ' ', sizeof(buf));
buf[0] = '\0'; buf[0] = '\0';
strcat (buf, "if "); strcat (buf, "if ");
COND_EXPR *inverted=h.expr()->inverse(); if(h.opcode==HLI_INVALID)
{
return "if (*HLI_INVALID*) {\n";
}
assert(h.expr());
Expr *inverted=h.expr()->inverse();
//inverseCondOp (&h.exp); //inverseCondOp (&h.exp);
std::string e = walkCondExpr (inverted, pProc, numLoc); std::string e = inverted->walkCondExpr (pProc, numLoc);
delete inverted; delete inverted;
strcat (buf, e.c_str()); strcat (buf, e.c_str());
strcat (buf, " {\n"); strcat (buf, " {\n");
@@ -523,47 +520,64 @@ char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case /* Displays the inverse output of a HLI_JCOND icode. This is used in the case
* when the THEN clause of an if..then..else is empty. The clause is * when the THEN clause of an if..then..else is empty. The clause is
* negated and the ELSE clause is used instead. */ * negated and the ELSE clause is used instead. */
char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc) const char *writeJcondInv(HLTYPE h, Function * pProc, int *numLoc)
{ {
memset (buf, ' ', sizeof(buf)); memset (buf, ' ', sizeof(buf));
buf[0] = '\0'; buf[0] = '\0';
strcat (buf, "if "); strcat (buf, "if ");
std::string e = walkCondExpr (h.expr(), pProc, numLoc); std::string e;
if(h.expr()==nullptr)
e = "( *failed condition recovery* )";
else
e = h.expr()->walkCondExpr (pProc, numLoc);
strcat (buf, e.c_str()); strcat (buf, e.c_str());
strcat (buf, " {\n"); strcat (buf, " {\n");
return (buf); return (buf);
} }
string AssignType::writeOut(Function *pProc, int *numLoc) string AssignType::writeOut(Function *pProc, int *numLoc) const
{ {
ostringstream ostr; ostringstream ostr;
ostr << walkCondExpr (lhs, pProc, numLoc); ostr << m_lhs->walkCondExpr (pProc, numLoc);
ostr << " = "; ostr << " = ";
ostr << walkCondExpr (rhs, pProc, numLoc); ostr << rhs->walkCondExpr (pProc, numLoc);
ostr << ";\n"; ostr << ";\n";
return ostr.str(); return ostr.str();
} }
string CallType::writeOut(Function *pProc, int *numLoc) string CallType::writeOut(Function *pProc, int *numLoc) const
{ {
ostringstream ostr; ostringstream ostr;
ostr << writeCall (proc, *args, pProc,numLoc); ostr << pProc->writeCall (proc, *args, numLoc);
ostr << ";\n"; ostr << ";\n";
return ostr.str(); return ostr.str();
} }
string ExpType::writeOut(Function *pProc, int *numLoc) string ExpType::writeOut(Function *pProc, int *numLoc) const
{ {
return walkCondExpr (v, pProc, numLoc); if(v==nullptr)
return "";
return v->walkCondExpr (pProc, numLoc);
} }
void HLTYPE::set(Expr *l, Expr *r)
{
assert(l);
assert(r);
opcode = HLI_ASSIGN;
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
assert(dynamic_cast<UnaryOperator *>(l));
asgn.m_lhs=l;
asgn.rhs=r;
}
/* Returns a string with the contents of the current high-level icode. /* Returns a string with the contents of the current high-level icode.
* Note: this routine does not output the contens of HLI_JCOND icodes. This is * Note: this routine does not output the contens of HLI_JCOND icodes. This is
* done in a separate routine to be able to support the removal of * done in a separate routine to be able to support the removal of
* empty THEN clauses on an if..then..else. */ * empty THEN clauses on an if..then..else. */
string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const
{ {
string e; string e;
ostringstream ostr; ostringstream ostr;
HlTypeSupport *p = get(); const HlTypeSupport *p = get();
switch (opcode) switch (opcode)
{ {
case HLI_ASSIGN: case HLI_ASSIGN:
@@ -585,6 +599,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();
} }
@@ -614,7 +632,7 @@ void ICODE::writeDU()
} }
/* Print du1 chain */ /* Print du1 chain */
printf ("# regs defined = %d\n", du1.numRegsDef); printf ("# regs defined = %d\n", du1.getNumRegsDef());
for (int i = 0; i < MAX_REGS_DEF; i++) for (int i = 0; i < MAX_REGS_DEF; i++)
{ {
if (not du1.used(i)) if (not du1.used(i))

25
src/hltype.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include "icode.h"
#include "ast.h"
void HLTYPE::replaceExpr(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 nullptr;
}
}

View File

@@ -2,15 +2,12 @@
// (C) 1997 Mike Van Emmerik // (C) 1997 Mike Van Emmerik
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include "dcc.h" #include "dcc.h"
#include "types.h" // Common types like uint8_t, etc #include "types.h" // Common types like uint8_t, etc
#include "ast.h" // Some icode types depend on these #include "ast.h" // Some icode types depend on these
#include "icode.h" #include "icode.h"
#define ICODE_DELTA 25 // Amount to allocate for new chunk
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level; ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level; ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
@@ -31,10 +28,8 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode)
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB) void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
{ {
for(ICODE &ic : rang) for(ICODE &ic : rang)
{
ic.setParent(pnewBB); ic.setParent(pnewBB);
} }
}
/* labelSrchRepl - Searches the icodes for instruction with label = target, and /* labelSrchRepl - Searches the icodes for instruction with label = target, and
replaces *pIndex with an icode index */ replaces *pIndex with an icode index */
@@ -57,9 +52,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);
@@ -94,9 +89,26 @@ bool LLOperand::isReg() const
{ {
return (regi>=rAX) && (regi<=rTMP); return (regi>=rAX) && (regi<=rTMP);
} }
void LLOperand::addProcInformation(int param_count, uint32_t call_conv) void LLOperand::addProcInformation(int param_count, CConv::Type call_conv)
{ {
proc.proc->cbParam = (int16_t)param_count; proc.proc->cbParam = (int16_t)param_count;
proc.cb = param_count; proc.cb = param_count;
proc.proc->flg |= call_conv; proc.proc->callingConv(call_conv);
} }
void HLTYPE::setCall(Function *proc)
{
opcode = HLI_CALL;
call.proc = proc;
call.args = new STKFRAME;
}
bool AssignType::removeRegFromLong(eReg regi, LOCAL_ID *locId)
{
m_lhs=lhs()->performLongRemoval(regi,locId);
return true;
}
void AssignType::lhs(Expr *l)
{
assert(dynamic_cast<UnaryOperator *>(l));
m_lhs=l;
}

View File

@@ -3,6 +3,8 @@
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#include <llvm/Support/PatternMatch.h>
#include <boost/iterator/filter_iterator.hpp>
#include <cstring> #include <cstring>
#include <deque> #include <deque>
#include "idiom.h" #include "idiom.h"
@@ -15,8 +17,6 @@
#include "shift_idioms.h" #include "shift_idioms.h"
#include "arith_idioms.h" #include "arith_idioms.h"
#include "dcc.h" #include "dcc.h"
#include <llvm/Support/PatternMatch.h>
#include <boost/iterator/filter_iterator.hpp>
/***************************************************************************** /*****************************************************************************
* JmpInst - Returns true if opcode is a conditional or unconditional jump * JmpInst - Returns true if opcode is a conditional or unconditional jump
****************************************************************************/ ****************************************************************************/
@@ -116,13 +116,13 @@ void Function::findIdioms()
case iCALL: case iCALLF: case iCALL: case iCALLF:
/* Check for library functions that return a long register. /* Check for library functions that return a long register.
* Propagate this result */ * Propagate this result */
if (pIcode->ll()->src().proc.proc != 0) if (pIcode->ll()->src().proc.proc != nullptr)
if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) && if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) &&
(pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC)) (pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC))
{ {
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN) if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|| (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN)) || (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, pIcode/*ip*/); localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
} }
/* Check for idioms */ /* Check for idioms */
@@ -211,7 +211,7 @@ void Function::findIdioms()
if (cbParam != delta) if (cbParam != delta)
{ {
cbParam = delta; cbParam = delta;
flg |= (CALL_MASK & CALL_UNKNOWN); callingConv(CConv::UNKNOWN);
} }
} }
} }

View File

@@ -25,10 +25,11 @@ bool Idiom5::match(iICODE pIcode)
int Idiom5::action() int Idiom5::action()
{ {
COND_EXPR *rhs,*lhs,*expr; AstIdent *rhs,*lhs;
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); Expr *expr;
rhs = COND_EXPR::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
expr = COND_EXPR::boolOp (lhs, rhs, ADD); rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
expr = new BinaryOperator(ADD,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@@ -58,10 +59,12 @@ bool Idiom6::match(iICODE pIcode)
int Idiom6::action() int Idiom6::action()
{ {
COND_EXPR *rhs,*lhs,*expr;
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll()); AstIdent *rhs,*lhs;
rhs = COND_EXPR::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll()); Expr *expr;
expr = COND_EXPR::boolOp (lhs, rhs, SUB); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
expr = new BinaryOperator(SUB,lhs, rhs);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@@ -95,64 +98,66 @@ bool Idiom18::match(iICODE picode)
for(int i=0; i<4; ++i) for(int i=0; i<4; ++i)
m_icodes[i] =picode++; m_icodes[i] =picode++;
m_idiom_type=-1;
m_is_dec = m_icodes[1]->ll()->match(iDEC); m_is_dec = m_icodes[1]->ll()->match(iDEC);
int type = -1; /* type of variable: 1 = reg-var, 2 = local */
uint8_t regi; /* register of the MOV */
uint8_t regi; /* register of the MOV */
if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
return false;
regi = m_icodes[0]->ll()->m_dst.regi;
if( not ( m_icodes[2]->ll()->match(iCMP,regi) &&
m_icodes[3]->ll()->conditionalJump() ) )
return false;
// Simple matching finished, select apropriate matcher based on dst type
/* Get variable */ /* Get variable */
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */ if (m_icodes[1]->ll()->m_dst.regi == 0) /* global variable */
{ {
/* not supported yet */ /* not supported yet */
type = 0; m_idiom_type = 0;
} }
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */ else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */
{ {
if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR)) m_idiom_type = 1;
type = 1; // if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR)) // m_idiom_type = 1;
type = 1; // else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
// m_idiom_type = 1;
} }
else if (m_icodes[1]->ll()->dst.off) /* local variable */ else if (m_icodes[1]->ll()->m_dst.off) /* local variable */
type = 2; m_idiom_type = 2;
else /* indexed */ else /* indexed */
{ {
type=3; m_idiom_type=3;
/* not supported yet */ /* not supported yet */
printf("Unsupported idiom18 type: indexed"); ICODE &ic(*picode);
const Function *my_proc(ic.getParent()->getParent());
printf("Unsupported idiom18 type at %x in %s:%x : indexed\n",ic.loc_ip,my_proc->name.c_str(),my_proc->procEntry);
} }
switch(type) switch(m_idiom_type)
{ {
case 0: // global case 0: // global
printf("Unsupported idiom18 type: global variable"); printf("Unsupported idiom18 type at %x : global variable\n",picode->loc_ip);
break; break;
case 1: /* register variable */ case 1: /* register variable */
/* Check previous instruction for a MOV */ /* Check previous instruction for a MOV */
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi)) if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
{ {
regi = m_icodes[0]->ll()->dst.regi;
if ( m_icodes[0]->ll()->dst.isReg() )
{
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() )
return true; return true;
} }
}
break; break;
case 2: /* local */ case 2: /* local */
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off)) if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
{ {
regi = m_icodes[0]->ll()->dst.regi;
if ( m_icodes[0]->ll()->dst.isReg() )
{
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
m_icodes[3]->ll()->conditionalJump() )
return true; return true;
} }
}
break; break;
case 3: // indexed case 3: // indexed
printf("Unsupported idiom18 type: indexed"); printf("Untested idiom18 type: indexed\n");
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->m_dst))
{
return true;
}
break; break;
} }
return false; return false;
@@ -160,12 +165,12 @@ bool Idiom18::match(iICODE picode)
int Idiom18::action() // action length int Idiom18::action() // action length
{ {
COND_EXPR *rhs, *lhs; /* Pointers to left and right hand side exps */ Expr *rhs,*lhs;/* Pointers to left and right hand side exps */
COND_EXPR *expr; Expr *expr;
lhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE); lhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE);
lhs = COND_EXPR::unary ( m_is_dec ? POST_DEC : POST_INC, lhs); lhs = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs);
rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE); rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE);
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]); expr = new BinaryOperator(condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB],lhs, rhs);
m_icodes[3]->setJCond(expr); m_icodes[3]->setJCond(expr);
m_icodes[0]->invalidate(); m_icodes[0]->invalidate();
@@ -188,35 +193,41 @@ bool Idiom19::match(iICODE picode)
{ {
if(std::distance(picode,m_end)<2) if(std::distance(picode,m_end)<2)
return false; return false;
ICODE &ic(*picode);
int type;
for(int i=0; i<2; ++i) for(int i=0; i<2; ++i)
m_icodes[i] =picode++; m_icodes[i] =picode++;
m_is_dec = m_icodes[0]->ll()->match(iDEC); m_is_dec = m_icodes[0]->ll()->match(iDEC);
if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */ if ( not m_icodes[1]->ll()->conditionalJump() )
return false;
if (m_icodes[0]->ll()->m_dst.regi == 0) /* global variable */
/* not supported yet */ ; /* not supported yet */ ;
else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */ else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
{ {
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) || // if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR))) // ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
if (m_icodes[1]->ll()->conditionalJump())
return true; return true;
} }
else if (m_icodes[0]->ll()->dst.off) /* stack variable */ else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */
{ {
if ( m_icodes[1]->ll()->conditionalJump() )
return true; return true;
} }
else /* indexed */ else /* indexed */
/* not supported yet */ ; {
fprintf(stderr,"idiom19 : Untested type [indexed]\n");
return true;
/* not supported yet */
}
return false; return false;
} }
int Idiom19::action() int Idiom19::action()
{ {
COND_EXPR *lhs,*rhs,*expr; Expr *lhs,*expr;
lhs = COND_EXPR::id (*m_icodes[1]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs); lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
rhs = COND_EXPR::idKte (0, 2); lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs);
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB]); expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, new Constant(0, 2));
m_icodes[1]->setJCond(expr); m_icodes[1]->setJCond(expr);
m_icodes[0]->invalidate(); m_icodes[0]->invalidate();
return 2; return 2;
@@ -245,10 +256,13 @@ bool Idiom20::match(iICODE picode)
return false; return false;
for(int i=0; i<4; ++i) for(int i=0; i<4; ++i)
m_icodes[i] =picode++; m_icodes[i] =picode++;
/* Check second instruction for a MOV */
if( not m_icodes[1]->ll()->matchWithRegDst(iMOV) )
return false;
m_is_dec = m_icodes[0]->ll()->match(iDEC); m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
LLOperand &ll_dest(m_icodes[0]->ll()->dst); const LLOperand &ll_dest(m_icodes[0]->ll()->m_dst);
/* Get variable */ /* Get variable */
if (ll_dest.regi == 0) /* global variable */ if (ll_dest.regi == 0) /* global variable */
{ {
@@ -256,57 +270,56 @@ bool Idiom20::match(iICODE picode)
} }
else if ( ll_dest.isReg() ) /* register */ else if ( ll_dest.isReg() ) /* register */
{ {
if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
type = 1;
else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
type = 1; type = 1;
// if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
// type = 1;
// else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
// type = 1;
} }
else if (ll_dest.off) /* local variable */ else if (ll_dest.off) /* local variable */
type = 2; type = 2;
else /* indexed */ else /* indexed */
{ {
printf("idiom20 : Unsupported type [indexed]\n"); printf("idiom20 : Untested type [indexed]\n");
type = 3;
/* not supported yet */ ; /* not supported yet */ ;
} }
regi = m_icodes[1]->ll()->m_dst.regi;
/* Check previous instruction for a MOV */ const LLOperand &mov_src(m_icodes[1]->ll()->src());
if (type == 1) /* register variable */ if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
{ {
if (m_icodes[1]->ll()->match(iMOV) && switch(type)
(m_icodes[1]->ll()->src().regi == ll_dest.regi))
{ {
regi = m_icodes[1]->ll()->dst.regi; case 1: /* register variable */
if ( m_icodes[1]->ll()->dst.isReg() ) if ((mov_src.regi == ll_dest.regi))
{ {
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
m_icodes[3]->ll()->conditionalJump())
return true; return true;
} }
} break;
} case 2: // local
else if (type == 2) /* local */ if ((mov_src.off == ll_dest.off))
{ {
if ( m_icodes[0]->ll()->match(iMOV) &&
(m_icodes[1]->ll()->src().off == ll_dest.off))
{
regi = m_icodes[1]->ll()->dst.regi;
if ( m_icodes[1]->ll()->dst.isReg() )
{
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
m_icodes[3]->ll()->conditionalJump())
return true; return true;
} }
break;
case 3:
fprintf(stderr,"Test 3 ");
if ((mov_src == ll_dest))
{
return true;
}
break;
} }
} }
return false; return false;
} }
int Idiom20::action() int Idiom20::action()
{ {
COND_EXPR *lhs,*rhs,*expr; Expr *lhs,*rhs,*expr;
lhs = COND_EXPR::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE); lhs = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs); lhs = UnaryOperator::Create(m_is_dec, lhs);
rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE); rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]); expr = new BinaryOperator(condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB],lhs, rhs);
m_icodes[3]->setJCond(expr); m_icodes[3]->setJCond(expr);
for(int i=0; i<3; ++i) for(int i=0; i<3; ++i)
m_icodes[i]->invalidate(); m_icodes[i]->invalidate();

View File

@@ -38,7 +38,7 @@ int Idiom3::action()
{ {
if (m_icodes[0]->ll()->testFlags(I) ) if (m_icodes[0]->ll()->testFlags(I) )
{ {
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C); m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
} }
else else
{ {
@@ -77,13 +77,13 @@ bool Idiom17::match(iICODE picode)
if (m_icodes[1]->ll()->match(iPOP)) if (m_icodes[1]->ll()->match(iPOP))
{ {
int i=0; int i=0;
regi = m_icodes[1]->ll()->dst.regi; regi = m_icodes[1]->ll()->m_dst.regi;
if ((regi >= rAX) && (regi <= rBX)) if ((regi >= rAX) && (regi <= rBX))
i++; i++;
while (picode != m_end && picode->ll()->match(iPOP)) while (picode != m_end && picode->ll()->match(iPOP))
{ {
if (picode->ll()->dst.regi != regi) if (picode->ll()->m_dst.regi != regi)
break; break;
i++; i++;
m_icodes.push_back(picode++); m_icodes.push_back(picode++);
@@ -96,7 +96,7 @@ int Idiom17::action()
{ {
if (m_icodes[0]->ll()->testFlags(I)) if (m_icodes[0]->ll()->testFlags(I))
{ {
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C); m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
for(size_t idx=1; idx<m_icodes.size(); ++idx) for(size_t idx=1; idx<m_icodes.size(); ++idx)
{ {
m_icodes[idx]->invalidate(); m_icodes[idx]->invalidate();

View File

@@ -146,7 +146,7 @@ int Idiom4::action()
if(m_param_count) if(m_param_count)
{ {
m_func->cbParam = (int16_t)m_param_count; m_func->cbParam = (int16_t)m_param_count;
m_func->flg |= CALL_PASCAL; m_func->callingConv(CConv::PASCAL);
} }
return 1; return 1;
} }

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

@@ -27,14 +27,15 @@ bool Idiom14::match(iICODE pIcode)
return false; return false;
m_icodes[0]=pIcode++; m_icodes[0]=pIcode++;
m_icodes[1]=pIcode++; m_icodes[1]=pIcode++;
LLInst * matched [] = {m_icodes[0]->ll(),m_icodes[1]->ll()};
/* Check for regL */ /* Check for regL */
m_regL = m_icodes[0]->ll()->dst.regi; m_regL = m_icodes[0]->ll()->m_dst.regi;
if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX))) if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
{ {
/* Check for XOR regH, regH */ /* Check for XOR regH, regH */
if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I)) if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
{ {
m_regH = m_icodes[1]->ll()->dst.regi; m_regH = m_icodes[1]->ll()->m_dst.regi;
if (m_regH == m_icodes[1]->ll()->src().getReg2()) if (m_regH == m_icodes[1]->ll()->src().getReg2())
{ {
if ((m_regL == rAX) && (m_regH == rDX)) if ((m_regL == rAX) && (m_regH == rDX))
@@ -49,11 +50,13 @@ bool Idiom14::match(iICODE pIcode)
int Idiom14::action() int Idiom14::action()
{ {
int idx; int idx;
COND_EXPR *lhs,*rhs; AstIdent *lhs;
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]); Expr *rhs;
lhs = COND_EXPR::idLongIdx (idx);
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( m_regH, eDEF); m_icodes[0]->setRegDU( m_regH, eDEF);
rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE); rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@@ -80,13 +83,13 @@ bool Idiom13::match(iICODE pIcode)
eReg regi; eReg regi;
/* Check for regL */ /* Check for regL */
regi = m_icodes[0]->ll()->dst.regi; regi = m_icodes[0]->ll()->m_dst.regi;
if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH)) if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
{ {
/* Check for MOV regH, 0 */ /* Check for MOV regH, 0 */
if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0)) if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
{ {
if (m_icodes[1]->ll()->dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc. if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
{ {
m_loaded_reg=(eReg)(regi - rAL + rAX); m_loaded_reg=(eReg)(regi - rAL + rAX);
return true; return true;
@@ -98,11 +101,14 @@ bool Idiom13::match(iICODE pIcode)
int Idiom13::action() int Idiom13::action()
{ {
COND_EXPR *lhs,*rhs; AstIdent *lhs;
lhs = COND_EXPR::idReg (m_loaded_reg, 0, &m_func->localId); Expr *rhs;
eReg regi = m_icodes[0]->ll()->m_dst.regi;
m_icodes[0]->du1.removeDef(regi);
//m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
lhs = new RegisterNode(LLOperand(m_loaded_reg, 0), &m_func->localId);
m_icodes[0]->setRegDU( m_loaded_reg, eDEF); m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */ rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;

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;
@@ -32,27 +32,30 @@ bool Idiom11::match (iICODE picode)
switch (type) switch (type)
{ {
case GLOB_VAR: case GLOB_VAR:
if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) && if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
(m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)) (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
return true; return true;
break; break;
case REGISTER: case REGISTER:
if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi) if (m_icodes[2]->ll()->m_dst.regi == m_icodes[0]->ll()->m_dst.regi)
return true; return true;
break; break;
case PARAM: case PARAM:
case LOCAL_VAR: case LOCAL_VAR:
if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off) if (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off)
return true; return true;
break; break;
default:
fprintf(stderr,"Idiom11::match unhandled type %d\n",type);
} }
return false; return false;
} }
int Idiom11::action() int Idiom11::action()
{ {
COND_EXPR *lhs,*rhs; AstIdent *lhs;
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll()); Expr *rhs;
rhs = COND_EXPR::unary (NEGATION, lhs); lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
rhs = UnaryOperator::Create(NEGATION, lhs);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
m_icodes[2]->invalidate(); m_icodes[2]->invalidate();
@@ -73,17 +76,17 @@ 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)
m_icodes[i]=picode++; m_icodes[i]=picode++;
uint8_t regi = m_icodes[0]->ll()->dst.regi; uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
if ((regi >= rAX) && (regi < INDEX_BX_SI)) if ((regi >= rAX) && (regi < INDEX_BX_SI))
{ {
if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC)) if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) && if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
m_icodes[1]->ll()->match((eReg)regi) && m_icodes[1]->ll()->match((eReg)regi) &&
m_icodes[2]->ll()->match((eReg)regi)) m_icodes[2]->ll()->match((eReg)regi))
return true; return true;
@@ -92,9 +95,10 @@ bool Idiom16::match (iICODE picode)
} }
int Idiom16::action() int Idiom16::action()
{ {
COND_EXPR *lhs,*rhs; AstIdent *lhs;
lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId); Expr *rhs;
rhs = COND_EXPR::unary (NEGATION, lhs->clone()); lhs = new RegisterNode(*m_icodes[0]->ll()->get(DST),&m_func->localId);
rhs = UnaryOperator::Create(NEGATION, lhs->clone());
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
m_icodes[2]->invalidate(); m_icodes[2]->invalidate();

View File

@@ -28,16 +28,16 @@ bool Idiom8::match(iICODE pIcode)
int Idiom8::action() int Idiom8::action()
{ {
int idx; int idx;
COND_EXPR *rhs,*lhs,*expr; AstIdent *lhs;
Expr *expr;
eReg regH,regL; eReg regH,regL;
regH=m_icodes[0]->ll()->dst.regi; regH=m_icodes[0]->ll()->m_dst.regi;
regL=m_icodes[1]->ll()->dst.regi; regL=m_icodes[1]->ll()->m_dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(regH,regL), m_icodes[0]);
lhs = COND_EXPR::idLongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regL, USE_DEF); m_icodes[0]->setRegDU( regL, USE_DEF);
rhs = COND_EXPR::idKte(1,2); expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
expr = COND_EXPR::boolOp(lhs, rhs, SHR);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1)) if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
return false; return false;
m_icodes.clear(); m_icodes.clear();
regi = pIcode->ll()->dst.regi; regi = pIcode->ll()->m_dst.regi;
m_icodes.push_back(pIcode++); m_icodes.push_back(pIcode++);
while( (pIcode!=m_end) and while( (pIcode!=m_end) and
pIcode->ll()->match(iSHL,(eReg)regi,I) and pIcode->ll()->match(iSHL,(eReg)regi,I) and
@@ -78,12 +78,12 @@ bool Idiom15::match(iICODE pIcode)
int Idiom15::action() int Idiom15::action()
{ {
COND_EXPR *lhs,*rhs,*_exp; AstIdent *lhs;
lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi,
m_icodes[0]->ll()->getFlag() & NO_SRC_B, Expr *rhs,*_exp;
&m_func->localId); lhs = new RegisterNode(*m_icodes[0]->ll()->get(DST), &m_func->localId);
rhs = COND_EXPR::idKte (m_icodes.size(), 2); rhs = new Constant(m_icodes.size(), 2);
_exp = COND_EXPR::boolOp (lhs, rhs, SHL); _exp = new BinaryOperator(SHL,lhs, rhs);
m_icodes[0]->setAsgn(lhs, _exp); m_icodes[0]->setAsgn(lhs, _exp);
for (size_t i=1; i<m_icodes.size()-1; ++i) for (size_t i=1; i<m_icodes.size()-1; ++i)
{ {
@@ -116,16 +116,17 @@ bool Idiom12::match(iICODE pIcode)
int Idiom12::action() int Idiom12::action()
{ {
int idx; int idx;
COND_EXPR *rhs,*lhs,*expr; Expr *expr;
eReg regH,regL; AstIdent *lhs;
regL=m_icodes[0]->ll()->dst.regi;
regH=m_icodes[1]->ll()->dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]); eReg regH,regL;
lhs = COND_EXPR::idLongIdx (idx); regL=m_icodes[0]->ll()->m_dst.regi;
regH=m_icodes[1]->ll()->m_dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, LONGID_TYPE(regH,regL),m_icodes[0]);
lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU( regH, USE_DEF); m_icodes[0]->setRegDU( regH, USE_DEF);
rhs = COND_EXPR::idKte (1, 2); expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
expr = COND_EXPR::boolOp (lhs, rhs, SHL);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
@@ -155,15 +156,15 @@ bool Idiom9::match(iICODE pIcode)
int Idiom9::action() int Idiom9::action()
{ {
int idx; int idx;
COND_EXPR *rhs,*lhs,*expr; AstIdent *lhs;
Expr *expr;
eReg regH,regL; eReg regH,regL;
regL=m_icodes[1]->ll()->dst.regi; regL=m_icodes[1]->ll()->m_dst.regi;
regH=m_icodes[0]->ll()->dst.regi; regH=m_icodes[0]->ll()->m_dst.regi;
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]); idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,LONGID_TYPE(regH,regL),m_icodes[0]);
lhs = COND_EXPR::idLongIdx (idx); lhs = AstIdent::LongIdx (idx);
m_icodes[0]->setRegDU(regL, USE_DEF); m_icodes[0]->setRegDU(regL, USE_DEF);
rhs = COND_EXPR::idKte (1, 2); expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
expr = COND_EXPR::boolOp (lhs, rhs, SHR);
m_icodes[0]->setAsgn(lhs, expr); m_icodes[0]->setAsgn(lhs, expr);
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;

View File

@@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
if (not m_icodes[1]->ll()->testFlags(I)) if (not m_icodes[1]->ll()->testFlags(I))
return false; return false;
dst = &m_icodes[0]->ll()->dst; dst = &m_icodes[0]->ll()->m_dst;
src = &m_icodes[0]->ll()->src(); src = &m_icodes[0]->ll()->src();
if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI)) if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
{ {
@@ -39,11 +39,13 @@ bool Idiom21::match (iICODE picode)
} }
int Idiom21::action() int Idiom21::action()
{ {
COND_EXPR *lhs,*rhs; Expr *rhs;
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll()); AstIdent *lhs;
rhs = COND_EXPR::idKte (m_icodes[1]->ll()->src().getImm2() , 4);
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
m_icodes[0]->setAsgn(lhs, rhs); m_icodes[0]->setAsgn(lhs, rhs);
m_icodes[0]->du.use = 0; /* clear register used in iXOR */ m_icodes[0]->du.use.reset(); /* clear register used in iXOR */
m_icodes[1]->invalidate(); m_icodes[1]->invalidate();
return 2; return 2;
} }
@@ -61,7 +63,7 @@ bool Idiom7::match(iICODE picode)
return false; return false;
const LLOperand *dst, *src; const LLOperand *dst, *src;
m_icode=picode; m_icode=picode;
dst = &picode->ll()->dst; dst = &picode->ll()->m_dst;
src = &picode->ll()->src(); src = &picode->ll()->src();
if (dst->regi == 0) /* global variable */ if (dst->regi == 0) /* global variable */
{ {
@@ -82,11 +84,10 @@ bool Idiom7::match(iICODE picode)
} }
int Idiom7::action() int Idiom7::action()
{ {
COND_EXPR *lhs,*rhs; Expr *lhs;
lhs = COND_EXPR::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE); lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
rhs = COND_EXPR::idKte (0, 2); m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
m_icode->setAsgn(lhs, rhs); m_icode->du.use.reset(); /* clear register used in iXOR */
m_icode->du.use = 0; /* clear register used in iXOR */
m_icode->ll()->setFlags(I); m_icode->ll()->setFlags(I);
return 1; return 1;
} }
@@ -115,7 +116,7 @@ bool Idiom10::match(iICODE pIcode)
/* Check OR reg, reg */ /* Check OR reg, reg */
if (not m_icodes[0]->ll()->testFlags(I) && if (not m_icodes[0]->ll()->testFlags(I) &&
m_icodes[0]->ll()->src().isReg() && m_icodes[0]->ll()->src().isReg() &&
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2())) (m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump() if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
{ {
return true; return true;
@@ -127,8 +128,9 @@ int Idiom10::action()
{ {
m_icodes[0]->ll()->set(iCMP,I); m_icodes[0]->ll()->set(iCMP,I);
m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0)); m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
m_icodes[0]->du.def = 0; m_icodes[0]->du.def.reset(); //TODO: this defines FLAGS
m_icodes[0]->du1.numRegsDef = 0; m_icodes[0]->du1.clearAllDefs();
//m_icodes[0]->du1.numRegsDef = 0;
return 2; return 2;
} }

54
src/liveness_set.cpp Normal file
View File

@@ -0,0 +1,54 @@
#include "BasicBlock.h"
#include "machine_x86.h"
/* DU bit definitions for each reg value - including index registers */
LivenessSet duReg[] = { {},
//AH AL . . AX, BH
{rAH,rAL,rAX},{rCH,rCL,rCX},{rDH,rDL,rDX},{rBH,rBL,rBX},
/* uint16_t regs */
{rSP},{rBP},{rSI},{rDI},
/* seg regs */
{rES},{rCS},{rSS},{rDS},
/* uint8_t regs */
{rAL},{rCL},{rDL},{rBL},
{rAH},{rCH},{rDH},{rBH},
/* tmp reg */
{rTMP},{rTMP2},
/* index regs */
{rBX,rSI},{rBX,rDI},{rBP,rSI},{rBP,rDI},
{rSI},{rDI},{rBP},{rBX}
};
LivenessSet &LivenessSet::setReg(int r)
{
this->reset();
*this |= duReg[r];
return *this;
}
LivenessSet &LivenessSet::clrReg(int r)
{
return *this -= duReg[r];
}
LivenessSet &LivenessSet::addReg(int r)
{
*this |= duReg[r];
// postProcessCompositeRegs();
return *this;
}
bool LivenessSet::testRegAndSubregs(int r) const
{
return (*this & duReg[r]).any();
}
void LivenessSet::postProcessCompositeRegs()
{
if(testReg(rAL) and testReg(rAH))
registers.insert(rAX);
if(testReg(rCL) and testReg(rCH))
registers.insert(rCX);
if(testReg(rDL) and testReg(rDH))
registers.insert(rDX);
if(testReg(rBL) and testReg(rBH))
registers.insert(rBX);
}

View File

@@ -10,22 +10,45 @@
#include "dcc.h" #include "dcc.h"
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
{ {
return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h); return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
} }
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false) ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
{ {
name[0]=0;
macro[0]=0; macro[0]=0;
memset(&id,0,sizeof(id)); memset(&id,0,sizeof(id));
} }
ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false) ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
{ {
name[0]=0;
macro[0]=0; macro[0]=0;
memset(&id,0,sizeof(id)); memset(&id,0,sizeof(id));
loc=f; loc=f;
assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)));
}
ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
{
macro[0]=0;
memset(&id,0,sizeof(id));
loc=REG_FRAME;
m_longId = s;
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
}
ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
{
macro[0]=0;
memset(&id,0,sizeof(id));
loc=STK_FRAME;
id.longStkId = s;
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
}
ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
{
macro[0]=0;
memset(&id,0,sizeof(id));
loc=GLB_FRAME;
id.longGlb = s;
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
} }
@@ -72,7 +95,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 +143,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,28 +157,32 @@ 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);
} }
/* Checks if the entry exists in the locSym, if so, returns the idx to this /* Checks if the entry exists in the locSym, if so, returns the idx to this
* entry; otherwise creates a new register identifier node of type * entry; otherwise creates a new register identifier node of type
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */ * TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_) int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
{ {
eReg regH,regL;
regL = longT.l();
regH = longT.h();
size_t idx; size_t idx;
//iICODE ix_; //iICODE ix_;
/* Check for entry in the table */ /* Check for entry in the table */
for (idx = 0; idx < id_arr.size(); idx++) for (idx = 0; idx < id_arr.size(); idx++)
{ {
ID &entry(id_arr[idx]); ID &entry(id_arr[idx]);
if(!entry.isLong() || (entry.loc != REG_FRAME))
continue;
if (/*(locSym->id[idx].type == t) && Not checking type */ if (/*(locSym->id[idx].type == t) && Not checking type */
(entry.id.longId.h == regH) && (entry.longId().h() == regH) &&
(entry.id.longId.l == regL)) (entry.longId().l() == regL))
{ {
/* Check for occurrence in the list */ /* Check for occurrence in the list */
if (entry.idx.inList(ix_)) if (entry.idx.inList(ix_))
@@ -167,25 +191,21 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
{ {
/* Insert icode index in list */ /* Insert icode index in list */
entry.idx.push_back(ix_); entry.idx.push_back(ix_);
//entry.idx.insert(ix_);
return (idx); return (idx);
} }
} }
} }
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
newIdent (t, REG_FRAME); id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
id_arr[id_arr.size()-1].idx.push_back(ix_);//insert(ix_); id_arr.back().idx.push_back(ix_);
idx = id_arr.size() - 1; return (id_arr.size() - 1);
id_arr[idx].id.longId.h = regH;
id_arr[idx].id.longId.l = regL;
return (idx);
} }
/* Returns an identifier conditional expression node of type TYPE_LONG or /* Returns an identifier conditional expression node of type TYPE_LONG or
* TYPE_WORD_SIGN */ * TYPE_WORD_SIGN */
COND_EXPR * LOCAL_ID::createId(const ID *retVal, iICODE ix_) AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
{ {
return COND_EXPR::idID(retVal,this,ix_); return AstIdent::idID(retVal,this,ix_);
} }
/* Checks if the entry exists in the locSym, if so, returns the idx to this /* Checks if the entry exists in the locSym, if so, returns the idx to this
@@ -204,14 +224,11 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
(id_arr[idx].id.longGlb.offL == offL)) (id_arr[idx].id.longGlb.offL == offL))
return (idx); return (idx);
} }
printf("%d",t);
/* Not in the table, create new identifier */ /* Not in the table, create new identifier */
newIdent (t, GLB_FRAME); id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
idx = id_arr.size() - 1; return (id_arr.size() - 1);
id_arr[idx].id.longGlb.seg = seg;
id_arr[idx].id.longGlb.offH = offH;
id_arr[idx].id.longGlb.offL = offL;
return (idx);
} }
@@ -253,9 +270,11 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
/* Check for entry in the table */ /* Check for entry in the table */
for (idx = 0; idx < id_arr.size(); idx++) for (idx = 0; idx < id_arr.size(); idx++)
{ {
if(id_arr[idx].loc!=STK_FRAME)
continue;
if ((id_arr[idx].type == t) && if ((id_arr[idx].type == t) &&
(id_arr[idx].id.longStkId.offH == offH) && (id_arr[idx].longStkId().offH == offH) &&
(id_arr[idx].id.longStkId.offL == offL)) (id_arr[idx].longStkId().offL == offL))
return (idx); return (idx);
} }
@@ -264,11 +283,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
flagByteWordId (offL); flagByteWordId (offL);
/* Create new identifier */ /* Create new identifier */
newIdent (t, STK_FRAME); id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
idx = id_arr.size() - 1; return (id_arr.size() - 1);
id_arr[idx].id.longStkId.offH = offH;
id_arr[idx].id.longStkId.offL = offL;
return (idx);
} }
@@ -277,7 +293,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
* number in an expression record. */ * number in an expression record. */
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset) int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
{ {
size_t idx; size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
const LLOperand *pmH, *pmL; const LLOperand *pmH, *pmL;
LLInst &p_ll(*pIcode->ll()); LLInst &p_ll(*pIcode->ll());
if (f == LOW_FIRST) if (f == LOW_FIRST)
@@ -296,7 +312,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
else if (pmL->regi < INDEX_BX_SI) /* register */ else if (pmL->regi < INDEX_BX_SI) /* register */
{ {
idx = newLongReg(TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix); idx = newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(pmH->regi, pmL->regi), ix);
if (f == HIGH_FIRST) if (f == HIGH_FIRST)
pIcode->setRegDU( pmL->regi, du); /* low part */ pIcode->setRegDU( pmL->regi, du); /* low part */
else else
@@ -332,30 +348,46 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
* idx : idx into icode array * idx : idx into icode array
* pProc : ptr to current procedure record * pProc : ptr to current procedure record
* rhs, lhs : return expressions if successful. */ * rhs, lhs : return expressions if successful. */
boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset) bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
{ {
/* pointers to LOW_LEVEL icodes */ /* pointers to LOW_LEVEL icodes */
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
pmHdst = &pIcode->ll()->dst; pmHdst = &pIcode->ll()->m_dst;
pmLdst = &atOffset.dst; pmLdst = &atOffset.m_dst;
pmHsrc = &pIcode->ll()->src(); pmHsrc = &pIcode->ll()->src();
pmLsrc = &atOffset.src(); pmLsrc = &atOffset.src();
// if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
// {
// asgn.lhs = AstIdent::LongIdx (i);
// if ( not pIcode->ll()->testFlags(NO_SRC) )
// {
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
// }
// return true;
// }
// else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
// {
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
// asgn.rhs = AstIdent::LongIdx (i);
// return true;
// }
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off)) if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
{ {
asgn.lhs = COND_EXPR::idLongIdx (i); asgn.lhs = AstIdent::LongIdx (i);
if ( not pIcode->ll()->testFlags(NO_SRC) ) if ( not pIcode->ll()->testFlags(NO_SRC) )
{ {
asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
} }
return true; return true;
} }
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off)) else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
{ {
asgn.lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset); asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
asgn.rhs = COND_EXPR::idLongIdx (i); asgn.rhs = AstIdent::LongIdx (i);
return true; return true;
} }
return false; return false;
@@ -371,30 +403,30 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
* idx : idx into icode array * idx : idx into icode array
* pProc : ptr to current procedure record * pProc : ptr to current procedure record
* rhs, lhs : return expressions if successful. */ * rhs, lhs : return expressions if successful. */
boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i, bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
Function * pProc, Assignment &asgn, LLInst &atOffset) Function * pProc, Assignment &asgn, LLInst &atOffset)
{ {
/* pointers to LOW_LEVEL icodes */ /* pointers to LOW_LEVEL icodes */
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc; const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
pmHdst = &pIcode->ll()->dst; pmHdst = &pIcode->ll()->m_dst;
pmLdst = &atOffset.dst; pmLdst = &atOffset.m_dst;
pmHsrc = &pIcode->ll()->src(); pmHsrc = &pIcode->ll()->src();
pmLsrc = &atOffset.src(); pmLsrc = &atOffset.src();
if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi)) if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi))
{ {
asgn.lhs = COND_EXPR::idLongIdx (i); asgn.lhs = AstIdent::LongIdx (i);
if ( not pIcode->ll()->testFlags(NO_SRC) ) if ( not pIcode->ll()->testFlags(NO_SRC) )
{ {
asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset); asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
} }
return true; return true;
} }
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi)) else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi))
{ {
asgn.lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset); asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
asgn.rhs = COND_EXPR::idLongIdx (i); asgn.rhs = AstIdent::LongIdx (i);
return true; return true;
} }
return false; return false;
@@ -413,10 +445,10 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) || if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
(id->type == TYPE_LONG_UNSIGN))) (id->type == TYPE_LONG_UNSIGN)))
{ {
if (id->id.longId.h == regi) if (id->longId().h() == regi)
return (id->id.longId.l); return (id->longId().l());
else if (id->id.longId.l == regi) else if (id->longId().l() == regi)
return (id->id.longId.h); return (id->longId().h());
} }
return rUNDEF; // Cristina: please check this! return rUNDEF; // Cristina: please check this!
} }

View File

@@ -1,5 +1,6 @@
#include <cassert> #include <cassert>
#include "machine_x86.h" #include "machine_x86.h"
#include "icode.h"
// Index registers **** temp solution // Index registers **** temp solution
static const std::string regNames[] = { static const std::string regNames[] = {
"undef", "undef",
@@ -8,7 +9,7 @@ static const std::string regNames[] = {
"es", "cs", "ss", "ds", "es", "cs", "ss", "ds",
"al", "cl", "dl", "bl", "al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh", "ah", "ch", "dh", "bh",
"tmp", "tmp","tmp2",
"bx+si", "bx+di", "bp+si", "bp+di", "bx+si", "bx+di", "bp+si", "bp+di",
"si", "di", "bp", "bx" "si", "di", "bp", "bx"
}; };
@@ -109,3 +110,35 @@ bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
return false; // only AX -> BX are coverede by subregisters return false; // only AX -> BX are coverede by subregisters
return ((reg==subRegH(parent)) || (reg == subRegL(parent))); return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
} }
bool Machine_X86::hasSubregisters(eReg reg)
{
return ((reg >= rAX) && (reg <= rBX));
}
bool Machine_X86::isPartOfComposite(eReg reg)
{
return ((reg >= rAL) && (reg <= rBH));
}
eReg Machine_X86::compositeParent(eReg reg)
{
switch(reg)
{
case rAL: case rAH: return rAX;
case rCL: case rCH: return rCX;
case rDL: case rDH: return rDX;
case rBL: case rBH: return rBX;
default:
return rUNDEF;
}
return rUNDEF;
}
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet &regi)
{
int j;
for (j = rAX; j < INDEX_BX_SI; j++)
{
if (regi.testReg(j))
ostr << regName(eReg(j))<<" ";
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,19 +14,17 @@
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 PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin, int _NumVert)
PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
int _NumVert)
{ {
/* These parameters are stored in statics so as to obviate the need for /* These parameters are stored in statics so as to obviate the need for
passing all these (or defererencing pointers) for every call to hash() passing all these (or defererencing pointers) for every call to hash()

View File

@@ -9,6 +9,7 @@
#include <cassert> #include <cassert>
#include "dcc.h" #include "dcc.h"
#include "project.h" #include "project.h"
#include "CallGraph.h"
extern Project g_proj; extern Project g_proj;
/* Static indentation buffer */ /* Static indentation buffer */
@@ -43,8 +44,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 +51,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 +60,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 +68,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);
} }
@@ -94,14 +91,15 @@ void CALL_GRAPH::write()
* Note: register(s) are only included once in the table. */ * Note: register(s) are only included once in the table. */
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
{ {
COND_EXPR *lhs; AstIdent *lhs;
STKFRAME * call_args_stackframe, *target_stackframe; STKFRAME * call_args_stackframe, *target_stackframe;
const ID *id; const ID *id;
int tidx; int tidx;
boolT regExist; bool regExist=false;
condId type; condId type;
Function * tproc; Function * tproc;
eReg regL, regH; /* Registers involved in arguments */ eReg regL = rUNDEF;
eReg regH; /* Registers involved in arguments */
/* Flag ticode as having register arguments */ /* Flag ticode as having register arguments */
tproc = ticode->hl()->call.proc; tproc = ticode->hl()->call.proc;
@@ -110,48 +108,56 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
/* Get registers and index into target procedure's local list */ /* Get registers and index into target procedure's local list */
call_args_stackframe = ticode->hl()->call.args; call_args_stackframe = ticode->hl()->call.args;
target_stackframe = &tproc->args; target_stackframe = &tproc->args;
lhs = picode->hl()->asgn.lhs; lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs());
type = lhs->expr.ident.idType; RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
assert(lhs);
type = lhs->ident.type();
if(type==REGISTER) if(type==REGISTER)
assert(lhs_reg);
if(type==LONG_VAR)
assert(!lhs_reg);
if (lhs_reg)
{ {
regL = id_arr[lhs->expr.ident.idNode.regiIdx].id.regi; regL = id_arr[lhs_reg->regiIdx].id.regi;
assert(regL!=rUNDEF);
if (regL < rAL) if (regL < rAL)
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL); tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
else else
tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL); tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL);
}
else if (type == LONG_VAR)
{
int longIdx = lhs->expr.ident.idNode.longIdx;
regL = id_arr[longIdx].id.longId.l;
regH = id_arr[longIdx].id.longId.h;
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
}
/* Check if register argument already on the formal argument list */ /* Check if register argument already on the formal argument list */
regExist = false;
for(STKSYM &tgt_sym : *target_stackframe) for(STKSYM &tgt_sym : *target_stackframe)
{ {
if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition RegisterNode *tgt_sym_regs = dynamic_cast<RegisterNode *>(tgt_sym.regs);
if( tgt_sym_regs == nullptr ) // both REGISTER and LONG_VAR require this precondition
continue; continue;
if (type == REGISTER) if ( tgt_sym_regs->regiIdx == tidx )
{
if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx )
{ {
regExist = true; regExist = true;
break;
}
} }
} }
else if (type == LONG_VAR) else if (type == LONG_VAR)
{ {
if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx ) int longIdx = lhs->ident.idNode.longIdx;
LONGID_TYPE regHL = id_arr[longIdx].longId();
regH=regHL.h();
regL=regHL.l();
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regHL, tproc->Icode.begin() /*0*/);
/* Check if register argument already on the formal argument list */
for(STKSYM &tgt_sym : *target_stackframe)
{
if( tgt_sym.regs == nullptr ) // both REGISTER and LONG_VAR require this precondition
continue;
if ( tgt_sym.regs->ident.idNode.longIdx == tidx )
{ {
regExist = true; regExist = true;
}
}
if(regExist == true)
break; break;
} }
}
}
else
;//regExist = false;
/* Do ts (formal arguments) */ /* Do ts (formal arguments) */
if (regExist == false) if (regExist == false)
{ {
@@ -161,22 +167,18 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
if (type == REGISTER) if (type == REGISTER)
{ {
if (regL < rAL) regType rType = WORD_REG;
{ if (regL >= rAL)
newsym.type = TYPE_WORD_SIGN; rType = BYTE_REG;
newsym.regs = COND_EXPR::idRegIdx(tidx, WORD_REG); newsym.type = (regL < rAL) ? TYPE_WORD_SIGN : TYPE_BYTE_SIGN;
} newsym.regs = new RegisterNode(tidx, rType,this);
else
{
newsym.type = TYPE_BYTE_SIGN;
newsym.regs = COND_EXPR::idRegIdx(tidx, BYTE_REG);
}
tproc->localId.id_arr[tidx].name = newsym.name; tproc->localId.id_arr[tidx].name = newsym.name;
} }
else if (type == LONG_VAR) else if (type == LONG_VAR)
{ {
newsym.regs = COND_EXPR::idLongIdx (tidx); newsym.regs = AstIdent::LongIdx (tidx);
newsym.type = TYPE_LONG_SIGN; newsym.type = TYPE_LONG_SIGN;
assert(regL!=rUNDEF);
tproc->localId.id_arr[tidx].name = newsym.name; tproc->localId.id_arr[tidx].name = newsym.name;
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str()); tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
} }
@@ -192,19 +194,21 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
/* Mask off high and low register(s) in picode */ /* Mask off high and low register(s) in picode */
switch (type) { switch (type) {
case REGISTER: case REGISTER:
id = &id_arr[lhs->expr.ident.idNode.regiIdx]; id = &id_arr[lhs_reg->regiIdx];
picode->du.def &= maskDuReg[id->id.regi]; picode->du.def.clrReg(id->id.regi);
if (id->id.regi < rAL) if (id->id.regi < rAL)
newsym.type = TYPE_WORD_SIGN; newsym.type = TYPE_WORD_SIGN;
else else
newsym.type = TYPE_BYTE_SIGN; newsym.type = TYPE_BYTE_SIGN;
break; break;
case LONG_VAR: case LONG_VAR:
id = &id_arr[lhs->expr.ident.idNode.longIdx]; id = &id_arr[lhs->ident.idNode.longIdx];
picode->du.def &= maskDuReg[id->id.longId.h]; picode->du.def.clrReg(id->longId().h());
picode->du.def &= maskDuReg[id->id.longId.l]; picode->du.def.clrReg(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++;
@@ -216,22 +220,20 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
* @return true if it was a near call that made use of a segment register. * @return true if it was a near call that made use of a segment register.
* false elsewhere * false elsewhere
*/ */
bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc) bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc)
{ {
RegisterNode *expr = dynamic_cast<RegisterNode *>(exp);
uint8_t regi; uint8_t regi;
/* Check for far procedure call, in which case, references to segment /* Check for far procedure call, in which case, references to segment
* registers are not be considered another parameter (i.e. they are * registers are not be considered another parameter (i.e. they are
* long references to another segment) */ * long references to another segment) */
if (exp) if (expr)
{ {
if ((exp->m_type == IDENTIFIER) && (exp->expr.ident.idType == REGISTER)) regi = pproc->localId.id_arr[expr->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) {
return false; return (opcode == iCALLF) ? false : true;
else
return true;
} }
} }
@@ -246,33 +248,34 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
/* Places the actual argument exp in the position given by pos in the /* Places the actual argument exp in the position given by pos in the
* argument list of picode. */ * argument list of picode. */
void CallType::placeStkArg (COND_EXPR *exp, int pos) void CallType::placeStkArg (Expr *exp, int pos)
{ {
(*args)[pos].actual = exp; (*args)[pos].actual = exp;
(*args)[pos].setArgName(pos); (*args)[pos].setArgName(pos);
} }
COND_EXPR *CallType::toId() Expr *CallType::toAst()
{ {
return COND_EXPR::idFunc( proc, args); return new FuncNode( proc, args);
} }
/* Checks to determine whether the expression (actual argument) has the /* Checks to determine whether the expression (actual argument) has the
* same type as the given type (from the procedure's formal list). If not, * same type as the given type (from the procedure's formal list). If not,
* the actual argument gets modified */ * the actual argument gets modified */
void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc) Expr *Function::adjustActArgType (Expr *_exp, hlType forType)
{ {
AstIdent *expr = dynamic_cast<AstIdent *>(_exp);
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
hlType actType; hlType actType;
int offset, offL; int offset, offL;
if (exp == NULL) if (expr == nullptr)
return; return _exp;
actType = exp-> expType (pproc); actType = expr-> expType (this);
if (((actType == forType) || (exp->m_type != IDENTIFIER))) if (actType == forType)
return; return _exp;
switch (forType) switch (forType)
{ {
case TYPE_UNKNOWN: case TYPE_BYTE_SIGN: case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
@@ -288,16 +291,20 @@ void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc)
case TYPE_STR: case TYPE_STR:
switch (actType) { switch (actType) {
case TYPE_CONST: case TYPE_CONST:
/* It's an offset into image where a string is /* It's an offset into image where a string is found. Point to the string. */
* found. Point to the string. */ {
offL = exp->expr.ident.idNode.kte.kte; Constant *c=dynamic_cast<Constant *>(expr);
assert(c);
offL = c->kte.kte;
if (prog.fCOM) if (prog.fCOM)
offset = (pproc->state.r[rDS]<<4) + offL + 0x100; offset = (state.r[rDS]<<4) + offL + 0x100;
else else
offset = (pproc->state.r[rDS]<<4) + offL; offset = (state.r[rDS]<<4) + offL;
exp->expr.ident.idNode.strIdx = offset; expr->ident.idNode.strIdx = offset;
exp->expr.ident.idType = STRING; expr->ident.type(STRING);
break; delete c;
return AstIdent::String(offset);
}
case TYPE_PTR: case TYPE_PTR:
/* It's a pointer to a char rather than a pointer to /* It's a pointer to a char rather than a pointer to
@@ -308,20 +315,25 @@ 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);
} }
return _exp;
} }
/* 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 +342,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 +355,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 +392,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 = nullptr;
Project::Project() : callGraph(nullptr)
{
memset(&prog,0,sizeof(prog));
}
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();
@@ -18,14 +49,13 @@ ilFunction Project::findByEntry(uint32_t entry)
{ {
/* Search procedure list for one with appropriate entry point */ /* Search procedure list for one with appropriate entry point */
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(), ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
[entry](const Function &f) -> [entry](const Function &f) { return f.procEntry==entry; });
bool { return f.procEntry==entry; });
return iter; return iter;
} }
ilFunction Project::createFunction() ilFunction Project::createFunction(FunctionType *f,const std::string &name)
{ {
pProcList.push_back(Function::Create()); pProcList.push_back(Function::Create(f,0,name,0));
return (++pProcList.rbegin()).base(); return (++pProcList.rbegin()).base();
} }
@@ -63,7 +93,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==nullptr)
s_instance=new Project;
return s_instance;
} }
@@ -71,3 +104,4 @@ SourceMachine *Project::machine()
{ {
return nullptr; return nullptr;
} }

View File

@@ -13,7 +13,7 @@
/* Returns whether the given icode opcode is within the range of valid /* Returns whether the given icode opcode is within the range of valid
* high-level conditional jump icodes (iJB..iJG) */ * high-level conditional jump icodes (iJB..iJG) */
static boolT isJCond (llIcode opcode) static bool isJCond (llIcode opcode)
{ {
if ((opcode >= iJB) && (opcode <= iJG)) if ((opcode >= iJB) && (opcode <= iJG))
return true; return true;
@@ -59,7 +59,7 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc)
/* Returns whether the conditions for a 2-2 long variable are satisfied */ /* Returns whether the conditions for a 2-2 long variable are satisfied */
static boolT isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off) static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
{ {
iICODE initial_icode=pIcode; iICODE initial_icode=pIcode;
if(distance(pIcode,pEnd)<4) if(distance(pIcode,pEnd)<4)
@@ -142,7 +142,8 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse
iICODE atOffset1(atOffset),next1(++iICODE(pIcode)); iICODE atOffset1(atOffset),next1(++iICODE(pIcode));
advance(atOffset1,1); advance(atOffset1,1);
/* Create new HLI_JCOND and condition */ /* Create new HLI_JCOND and condition */
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[atOffset1->ll()->getOpcode()-iJB]); condOp oper=condOpJCond[atOffset1->ll()->getOpcode()-iJB];
asgn.lhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs);
next1->setJCond(asgn.lhs); next1->setJCond(asgn.lhs);
next1->copyDU(*pIcode, eUSE, eUSE); next1->copyDU(*pIcode, eUSE, eUSE);
next1->du.use |= atOffset->du.use; next1->du.use |= atOffset->du.use;
@@ -177,7 +178,8 @@ static int longJCond22 (Assignment &asgn, iICODE pIcode,iICODE pEnd)
iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ }; iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ };
/* Form conditional expression */ /* Form conditional expression */
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[icodes[3]->ll()->getOpcode() - iJB]); condOp oper=condOpJCond[icodes[3]->ll()->getOpcode() - iJB];
asgn.lhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs);
icodes[1]->setJCond(asgn.lhs); icodes[1]->setJCond(asgn.lhs);
icodes[1]->copyDU (*icodes[0], eUSE, eUSE); icodes[1]->copyDU (*icodes[0], eUSE, eUSE);
icodes[1]->du.use |= icodes[2]->du.use; icodes[1]->du.use |= icodes[2]->du.use;
@@ -236,7 +238,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)
{ {
@@ -248,25 +250,32 @@ void Function::propLongStk (int i, const ID &pLocId)
continue; continue;
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode()) if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
{ {
if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *next1->ll()) == true) if (checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *next1->ll()) == true)
{ {
switch (pIcode->ll()->getOpcode()) switch (pIcode->ll()->getOpcode())
{ {
case iMOV: case iMOV:
pIcode->setAsgn(asgn.lhs, asgn.rhs); pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
next1->invalidate(); next1->invalidate();
break; break;
case iAND: case iOR: case iXOR: case iAND: case iOR: case iXOR:
{
condOp oper = DUMMY;
switch (pIcode->ll()->getOpcode()) switch (pIcode->ll()->getOpcode())
{ {
case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); break; case iAND: oper=AND; break;
case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); break; case iOR: oper=OR; break;
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); break; case iXOR: oper=XOR; break;
} }
pIcode->setAsgn(asgn.lhs, asgn.rhs); if(DUMMY!=oper)
{
asgn.rhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs);
}
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
next1->invalidate(); next1->invalidate();
break; break;
}
case iPUSH: case iPUSH:
pIcode->setUnary( HLI_PUSH, asgn.lhs); pIcode->setUnary( HLI_PUSH, asgn.lhs);
@@ -281,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
/* Check long conditional (i.e. 2 CMPs and 3 branches */ /* Check long conditional (i.e. 2 CMPs and 3 branches */
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc))) else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
{ {
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *l23->ll()) ) if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
{ {
advance(pIcode,longJCond23 (asgn, pIcode, arc, l23)); advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
} }
@@ -291,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
* 2 CMPs and 2 branches */ * 2 CMPs and 2 branches */
else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23)) else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
{ {
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, *l23->ll()) ) if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
{ {
advance(pIcode,longJCond22 (asgn, pIcode,pEnd)); advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
} }
@@ -320,14 +329,14 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
switch (icode.ll()->getOpcode()) switch (icode.ll()->getOpcode())
{ {
case iMOV: case iMOV:
pmH = &icode.ll()->dst; pmH = &icode.ll()->m_dst;
pmL = &next1->ll()->dst; pmL = &next1->ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
{ {
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
icode.setRegDU( pmL->regi, eDEF); icode.setRegDU( pmL->regi, eDEF);
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll()); asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll());
icode.setAsgn(asgn.lhs, asgn.rhs); icode.setAsgn(asgn.lhs, asgn.rhs);
next1->invalidate(); next1->invalidate();
forced_finish=true; /* to exit the loop */ forced_finish=true; /* to exit the loop */
@@ -335,15 +344,15 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
break; break;
case iPOP: case iPOP:
pmH = &next1->ll()->dst; pmH = &next1->ll()->m_dst;
pmL = &icode.ll()->dst; pmL = &icode.ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
{ {
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
icode.setRegDU( pmH->regi, eDEF); icode.setRegDU( pmH->regi, eDEF);
icode.setUnary(HLI_POP, asgn.lhs); icode.setUnary(HLI_POP, asgn.lhs);
next1->invalidate(); next1->invalidate();
asgn.lhs=0; asgn.lhs=nullptr;
forced_finish=true; /* to exit the loop */ forced_finish=true; /* to exit the loop */
} }
break; break;
@@ -351,23 +360,22 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
// /**** others missing ***/ // /**** others missing ***/
case iAND: case iOR: case iXOR: case iAND: case iOR: case iXOR:
pmL = &icode.ll()->dst; pmL = &icode.ll()->m_dst;
pmH = &next1->ll()->dst; pmH = &next1->ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi)) if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
{ {
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll()); asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
icode.setRegDU( pmH->regi, USE_DEF); icode.setRegDU( pmH->regi, USE_DEF);
condOp toCreate=DUMMY;
switch (icode.ll()->getOpcode()) switch (icode.ll()->getOpcode())
{ {
case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); case iAND: toCreate = AND; break;
break; case iOR: toCreate = OR; break;
case iOR: case iXOR: toCreate = XOR; break;
asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR);
break;
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR);
break;
} /* eos */ } /* eos */
if(toCreate != DUMMY)
asgn.rhs = new BinaryOperator(toCreate,asgn.lhs, asgn.rhs);
icode.setAsgn(asgn.lhs, asgn.rhs); icode.setAsgn(asgn.lhs, asgn.rhs);
next1->invalidate(); next1->invalidate();
forced_finish=true; /* to exit the loop */ forced_finish=true; /* to exit the loop */
@@ -398,53 +406,64 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
switch (pIcode->ll()->getOpcode()) switch (pIcode->ll()->getOpcode())
{ {
case iMOV: case iMOV:
if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) &&
(pLocId.id.longId.l == next1->ll()->src().getReg2()))
{ {
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); const LONGID_TYPE &ref_long(pLocId.longId());
const LLOperand &src_op1(pIcode->ll()->src());
const LLOperand &src_op2(next1->ll()->src());
eReg srcReg1=src_op1.getReg2();
eReg nextReg2=src_op2.getReg2();
if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2))
{
pIcode->setRegDU( nextReg2, eUSE);
asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx); asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
asgn.lhs = COND_EXPR::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll()); asgn.lhs = AstIdent::Long (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll());
pIcode->setAsgn(asgn.lhs, asgn.rhs); pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
next1->invalidate(); next1->invalidate();
forced_finish =true; /* to exit the loop */ forced_finish =true; /* to exit the loop */
} }
break; break;
}
case iPUSH: case iPUSH:
if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) &&
(pLocId.id.longId.l == next1->ll()->src().getReg2()))
{ {
asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx); const LONGID_TYPE &ref_long(pLocId.longId());
const LLOperand &src_op1(pIcode->ll()->src());
const LLOperand &src_op2(next1->ll()->src());
if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
{
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE); pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
pIcode->setUnary(HLI_PUSH, asgn.rhs); pIcode->setUnary(HLI_PUSH, asgn.rhs);
next1->invalidate(); next1->invalidate();
} }
forced_finish =true; /* to exit the loop */ forced_finish =true; /* to exit the loop */
break; break;
}
/*** others missing ****/ /*** others missing ****/
case iAND: case iOR: case iXOR: case iAND: case iOR: case iXOR:
pmL = &pIcode->ll()->dst; pmL = &pIcode->ll()->m_dst;
pmH = &next1->ll()->dst; pmH = &next1->ll()->m_dst;
if ((pLocId.id.longId.h == pmH->regi) && if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
(pLocId.id.longId.l == pmL->regi))
{ {
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
pIcode->setRegDU( pmH->regi, USE_DEF); pIcode->setRegDU( pmH->regi, USE_DEF);
asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode,
LOW_FIRST, pIcode, eUSE, *next1->ll()); LOW_FIRST, pIcode, eUSE, *next1->ll());
condOp toCreate=DUMMY;
switch (pIcode->ll()->getOpcode()) { switch (pIcode->ll()->getOpcode()) {
case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); case iAND: toCreate=AND; break;
break; case iOR: toCreate=OR; break;
case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); case iXOR: toCreate= XOR; break;
break;
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR);
break;
} }
pIcode->setAsgn(asgn.lhs, asgn.rhs); if(DUMMY!=toCreate)
{
asgn.rhs = new BinaryOperator(toCreate,asgn.lhs, asgn.rhs);
}
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
next1->invalidate(); next1->invalidate();
// ftw loop restart ???? // ftw loop restart ????
//idx = 0; //idx = 0;
@@ -457,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
/* Check long conditional (i.e. 2 CMPs and 3 branches */ /* Check long conditional (i.e. 2 CMPs and 3 branches */
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc))) else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
{ {
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll())) if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
{ {
// reduce the advance by 1 here (loop increases) ? // reduce the advance by 1 here (loop increases) ?
advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc)); advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
@@ -468,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
* 2 CMPs and 2 branches */ * 2 CMPs and 2 branches */
else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc))) else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
{ {
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) ) if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
{ {
// TODO: verify that removing -1 does not change anything ! // TODO: verify that removing -1 does not change anything !
advance(pIcode,longJCond22 (asgn, pIcode,pEnd)); advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
@@ -481,17 +500,18 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */ * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode()))) else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
{ {
if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode)) if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
{ {
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx); asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
asgn.rhs = COND_EXPR::idKte (0, 4); /* long 0 */ asgn.rhs = new Constant(0, 4); /* long 0 */
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[next1->ll()->getOpcode() - iJB]); asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs);
next1->setJCond(asgn.lhs); next1->setJCond(asgn.lhs);
next1->copyDU(*pIcode, eUSE, eUSE); next1->copyDU(*pIcode, eUSE, eUSE);
pIcode->invalidate(); pIcode->invalidate();
} }
} }
} /* 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 +524,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 +544,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,14 +554,13 @@ 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) and (pLocId.type!=TYPE_LONG_UNSIGN))
{ continue;
switch (pLocId.loc) switch (pLocId.loc)
{ {
case STK_FRAME: case STK_FRAME:
@@ -556,5 +575,4 @@ void Function::propLong()
} }
} }
} }
}

View File

@@ -5,10 +5,10 @@
********************************************************************/ ********************************************************************/
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstdio>
#include <cstring>
#include <stdint.h>
#include "dcc.h" #include "dcc.h"
#include <stdio.h>
#include <malloc.h> /* For free() */
#include <string.h>
static int numInt; /* Number of intervals */ static int numInt; /* Number of intervals */
@@ -54,7 +54,7 @@ BB *interval::firstOfInt ()
{ {
auto pq = currNode; auto pq = currNode;
if (pq == nodes.end()) if (pq == nodes.end())
return 0; return nullptr;
++currNode; ++currNode;
return *pq; return *pq;
} }
@@ -66,16 +66,16 @@ BB *interval::firstOfInt ()
* node->inInterval. * node->inInterval.
* Note: nodes are added to the interval list in interval order (which * Note: nodes are added to the interval list in interval order (which
* topsorts the dominance relation). */ * topsorts the dominance relation). */
static void appendNodeInt (queue &pqH, BB *node, interval *pI) void interval::appendNodeInt(queue &pqH, BB *node)
{ {
queue::iterator pq; /* Pointer to current node of the list */ queue::iterator pq; /* Pointer to current node of the list */
/* Append node if it is not already in the interval list */ /* Append node if it is not already in the interval list */
pq = appendQueue (pI->nodes, node); pq = appendQueue (nodes, node);
/* Update currNode if necessary */ /* Update currNode if necessary */
if (pI->currNode == pI->nodes.end()) if (currNode == nodes.end())
pI->currNode = pq; currNode = pq;
/* Check header list for occurrence of node, if found, remove it /* Check header list for occurrence of node, if found, remove it
* and decrement number of out-edges from this interval. */ * and decrement number of out-edges from this interval. */
@@ -84,12 +84,12 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI)
auto found_iter=std::find(pqH.begin(),pqH.end(),node); auto found_iter=std::find(pqH.begin(),pqH.end(),node);
if(found_iter!=pqH.end()) if(found_iter!=pqH.end())
{ {
pI->numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1; numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
pqH.erase(found_iter); pqH.erase(found_iter);
} }
} }
/* Update interval header information for this basic block */ /* Update interval header information for this basic block */
node->inInterval = pI; node->inInterval = this;
} }
@@ -103,13 +103,12 @@ 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 */
queue H; /* Queue of possible header nodes */ queue H; /* Queue of possible header nodes */
boolT first = true; /* First pass through the loop */ bool first = true; /* First pass through the loop */
appendQueue (H, Gi); /* H = {first node of G} */ appendQueue (H, Gi); /* H = {first node of G} */
Gi->beenOnH = true; Gi->beenOnH = true;
Gi->reachingInt = BB::Create(0,"",c); /* ^ empty BB */ Gi->reachingInt = BB::Create(nullptr,"",c); /* ^ empty BB */
/* Process header nodes list H */ /* Process header nodes list H */
while (!H.empty()) while (!H.empty())
@@ -118,23 +117,26 @@ void derSeq_Entry::findIntervals (Function *c)
pI = new interval; pI = new interval;
pI->numInt = (uint8_t)numInt++; pI->numInt = (uint8_t)numInt++;
if (first) /* ^ to first interval */ if (first) /* ^ to first interval */
{
Ii = J = pI; Ii = J = pI;
appendNodeInt (H, header, pI); /* pI(header) = {header} */ m_intervals.push_back(pI);
}
pI->appendNodeInt (H, header); /* pI(header) = {header} */
/* Process all nodes in the current interval list */ /* Process all nodes in the current interval list */
while ((h = pI->firstOfInt()) != NULL) while ((h = pI->firstOfInt()) != nullptr)
{ {
/* Check all immediate successors of h */ /* Check all immediate successors of h */
for (i = 0; i < h->edges.size(); i++) for (auto & elem : h->edges)
{ {
succ = h->edges[i].BBptr; succ = elem.BBptr;
succ->inEdgeCount--; succ->inEdgeCount--;
if (succ->reachingInt == NULL) /* first visit */ if (succ->reachingInt == nullptr) /* first visit */
{ {
succ->reachingInt = header; succ->reachingInt = header;
if (succ->inEdgeCount == 0) if (succ->inEdgeCount == 0)
appendNodeInt (H, succ, pI); pI->appendNodeInt (H, succ);
else if (! succ->beenOnH) /* out edge */ else if (! succ->beenOnH) /* out edge */
{ {
appendQueue (H, succ); appendQueue (H, succ);
@@ -148,7 +150,7 @@ void derSeq_Entry::findIntervals (Function *c)
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */ if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
{ {
if (succ != header) if (succ != header)
appendNodeInt (H, succ, pI); pI->appendNodeInt (H, succ);
} }
else /* out edge */ else /* out edge */
pI->numOutEdges++; pI->numOutEdges++;
@@ -161,6 +163,7 @@ void derSeq_Entry::findIntervals (Function *c)
/* Link interval I to list of intervals */ /* Link interval I to list of intervals */
if (! first) if (! first)
{ {
m_intervals.push_back(pI);
J->next = pI; J->next = pI;
J = pI; J = pI;
} }
@@ -176,11 +179,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 == nullptr) /* 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 +193,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 */
@@ -236,29 +239,23 @@ derSeq_Entry::~derSeq_Entry()
bool Function::nextOrderGraph (derSeq &derivedGi) bool Function::nextOrderGraph (derSeq &derivedGi)
{ {
interval *Ii; /* Interval being processed */ interval *Ii; /* Interval being processed */
BB *BBnode, /* New basic block of intervals */ BB *BBnode; /* New basic block of intervals */
*curr, /* BB being checked for out edges */ bool sameGraph; /* Boolean, isomorphic graphs */
*succ /* Successor node */
;
//queue *listIi; /* List of intervals */
int i, /* Index to outEdges array */
j; /* Index to successors */
boolT sameGraph; /* Boolean, isomorphic graphs */
/* Process Gi's intervals */ /* Process Gi's intervals */
derSeq_Entry &prev_entry(derivedGi.back()); derSeq_Entry &prev_entry(derivedGi.back());
derivedGi.push_back(derSeq_Entry()); derivedGi.push_back(derSeq_Entry());
derSeq_Entry &new_entry(derivedGi.back()); derSeq_Entry &new_entry(derivedGi.back());
Ii = prev_entry.Ii;
sameGraph = true; sameGraph = true;
BBnode = 0; BBnode = nullptr;
std::vector<BB *> bbs; std::vector<BB *> bbs;
while (Ii) for(Ii = prev_entry.Ii; Ii != nullptr; Ii = Ii->next)
{ {
i = 0;
bbs.push_back(BB::Create(-1, -1, INTERVAL_NODE, Ii->numOutEdges, this)); BBnode = BB::CreateIntervalBB(this);
BBnode = bbs.back();
BBnode->correspInt = Ii; BBnode->correspInt = Ii;
bbs.push_back(BBnode);
const queue &listIi(Ii->nodes); const queue &listIi(Ii->nodes);
/* Check for more than 1 interval */ /* Check for more than 1 interval */
@@ -267,27 +264,24 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
/* Find out edges */ /* Find out edges */
if (BBnode->edges.size() > 0) if (Ii->numOutEdges <= 0)
{ continue;
for(BB *curr : listIi) for(BB *curr : listIi)
{ {
for (j = 0; j < curr->edges.size(); j++) for (size_t j = 0; j < curr->edges.size(); j++)
{ {
succ = curr->edges[j].BBptr; BB *successor_node = curr->edges[j].BBptr;
if (succ->inInterval != curr->inInterval) if (successor_node->inInterval != curr->inInterval)
BBnode->edges[i++].intPtr = succ->inInterval; BBnode->addOutEdgeInterval(successor_node->inInterval);
} }
} }
} }
/* Next interval */
Ii = Ii->next;
}
/* Convert list of pointers to intervals into a real graph. /* Convert list of pointers to intervals into a real graph.
* Determines the number of in edges to each new BB, and places it * Determines the number of in edges to each new BB, and places it
* in numInEdges and inEdgeCount for later interval processing. */ * in numInEdges and inEdgeCount for later interval processing. */
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)
@@ -302,7 +296,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
(*iter)->inEdgeCount++; (*iter)->inEdgeCount++;
} }
} }
return (boolT)(! sameGraph); return not sameGraph;
} }
@@ -310,12 +304,11 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg). /* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
* Constructs the n-th order graph and places all the intermediate graphs * Constructs the n-th order graph and places all the intermediate graphs
* in the derivedG list sequence. */ * in the derivedG list sequence. */
uint8_t Function::findDerivedSeq (derSeq &derivedGi) bool Function::findDerivedSeq (derSeq &derivedGi)
{ {
BB *Gi; /* Current derived sequence graph */
derSeq::iterator iter=derivedGi.begin(); derSeq::iterator iter=derivedGi.begin();
Gi = iter->Gi; assert(iter!=derivedGi.end());
BB *Gi = iter->Gi; /* Current derived sequence graph */
while (! trivialGraph (Gi)) while (! trivialGraph (Gi))
{ {
/* Find the intervals of Gi and place them in derivedGi->Ii */ /* Find the intervals of Gi and place them in derivedGi->Ii */
@@ -341,13 +334,6 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi)
return true; return true;
} }
/* Converts the irreducible graph G into an equivalent reducible one, by
* means of node splitting. */
static void nodeSplitting (std::list<BB *> &G)
{
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
}
/* Displays the derived sequence and intervals of the graph G */ /* Displays the derived sequence and intervals of the graph G */
void derSeq::display() void derSeq::display()
{ {
@@ -356,7 +342,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;
} }
@@ -377,13 +363,13 @@ derSeq * Function::checkReducibility()
stats.nOrder = 1; /* nOrder(cfg) = 1 */ stats.nOrder = 1; /* nOrder(cfg) = 1 */
der_seq = new derSeq; der_seq = new derSeq;
der_seq->resize(1); der_seq->resize(1);
der_seq->back().Gi = m_cfg.front(); der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
reducible = findDerivedSeq(*der_seq); reducible = findDerivedSeq(*der_seq);
if (! reducible) if (! reducible)
{ {
flg |= GRAPH_IRRED; flg |= GRAPH_IRRED;
nodeSplitting (m_cfg); m_actual_cfg.nodeSplitting();
} }
return der_seq; return der_seq;
} }

View File

@@ -6,6 +6,8 @@
****************************************************************************/ ****************************************************************************/
#include <cstring> #include <cstring>
#include <map>
#include <string>
#include "dcc.h" #include "dcc.h"
#include "scanner.h" #include "scanner.h"
#include "project.h" #include "project.h"
@@ -14,7 +16,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);
@@ -314,14 +316,29 @@ static struct {
} ; } ;
static uint16_t SegPrefix, RepPrefix; static uint16_t SegPrefix, RepPrefix;
static uint8_t *pInst; /* Ptr. to current uint8_t of instruction */ static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */ static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
/***************************************************************************** static void decodeBranchTgt(x86_insn_t &insn)
Scans one machine instruction at offset ip in prog.Image and returns error. {
At the same time, fill in low-level icode details for the scanned inst. x86_op_t *tgt_op = insn.x86_get_branch_target();
****************************************************************************/ if(tgt_op->type==op_expression)
return; // unhandled for now
if(tgt_op->type==op_register)
return; // unhandled for now
int32_t addr = tgt_op->getAddress();
if(tgt_op->is_relative())
{
addr += insn.addr+insn.size;
}
pIcode->ll()->replaceSrc((uint32_t)addr);
pIcode->ll()->setFlags(I);
// PROG &prog(Project::get()->prog);
// long off = (short)getWord(); /* Signed displacement */
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
}
static void convertUsedFlags(x86_insn_t &from,ICODE &to) static void convertUsedFlags(x86_insn_t &from,ICODE &to)
{ {
@@ -345,11 +362,20 @@ static void convertUsedFlags(x86_insn_t &from,ICODE &to)
if(from.containsFlag(insn_eflag_direction,from.flags_tested)) if(from.containsFlag(insn_eflag_direction,from.flags_tested))
to.ll()->flagDU.u |= Df; to.ll()->flagDU.u |= Df;
} }
static void convertPrefix(x86_insn_prefix prefix,ICODE &to)
{
if(prefix ==insn_no_prefix)
return;
// insn_lock - no need to handle
RepPrefix = (uint16_t)prefix & ~insn_lock;
}
/**************************************************************************** /****************************************************************************
Checks for int 34 to int 3B - if so, converts to ESC nn instruction Checks for int 34 to int 3B - if so, converts to ESC nn instruction
****************************************************************************/ ****************************************************************************/
static void fixFloatEmulation(x86_insn_t &insn) static void fixFloatEmulation(x86_insn_t &insn)
{ {
if(insn.operand_count==0)
return;
if(insn.group!=x86_insn_t::insn_interrupt) if(insn.group!=x86_insn_t::insn_interrupt)
return; return;
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
@@ -357,11 +383,10 @@ static void fixFloatEmulation(x86_insn_t &insn)
if ((wOp < 0x34) || (wOp > 0x3B)) if ((wOp < 0x34) || (wOp > 0x3B))
return; return;
uint8_t buf[16]; uint8_t buf[16];
/* This is a Borland/Microsoft floating point emulation instruction. /* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
Treat as if it is an ESC opcode */
int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset); int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
memcpy(buf,prog.Image+insn.offset,actual_valid_bytes); memcpy(buf,prog.image()+insn.offset,actual_valid_bytes);
X86_Disasm ds(opt_16_bit); X86_Disasm ds(opt_16_bit);
x86_insn_t patched_insn; x86_insn_t patched_insn;
//patch actual instruction into buffer; //patch actual instruction into buffer;
@@ -377,7 +402,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
X86_Disasm ds(opt_16_bit); X86_Disasm ds(opt_16_bit);
int cnt=ds.x86_disasm(prog.Image,prog.cbImage,0,ip,&l); int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l);
if(cnt && l.is_valid()) if(cnt && l.is_valid())
{ {
fixFloatEmulation(l); //can change 'l' fixFloatEmulation(l); //can change 'l'
@@ -388,28 +413,122 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
} }
eReg convertRegister(const x86_reg_t &reg) eReg convertRegister(const x86_reg_t &reg)
{ {
if( (reg_pc==reg.type) || (0==reg.id))
return rUNDEF;
eReg regmap[]={ rUNDEF, eReg regmap[]={ rUNDEF,
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //esp ebp esi edi rSP,rUNDEF,rUNDEF,rDI, //esp ebp esi edi
rAX,rCX,rDX,rBX, rAX,rCX,rDX,rBX,
rSP,rBP,rSI,rDI, rSP,rBP,rSI,rDI,
rAL,rCL,rDL,rBL, rAL,rCL,rDL,rBL,
rAH,rCH,rDH,rBH rAH,rCH,rDH,rBH
}; };
std::map<std::string,eReg> nameToEnum = {{"es",rES},{"ds",rDS},{"cs",rCS},{"ss",rSS}};
if(nameToEnum.find(reg.name)!=nameToEnum.end())
return nameToEnum[reg.name];
assert(reg.id<sizeof(regmap)/sizeof(eReg)); assert(reg.id<sizeof(regmap)/sizeof(eReg));
assert(regmap[reg.id]!=rUNDEF);
return regmap[reg.id]; return regmap[reg.id];
} }
LLOperand convertExpression(const x86_ea_t &from)
{
// BASE + Scale*Index + Disp
LLOperand res;
res.seg = rDS;
/*
INDEX_BX_SI = 22, // "bx+si"
INDEX_BX_DI, // "bx+di"
INDEX_BP_SI, // "bp+si"
INDEX_BP_DI, // "bp+di"
INDEX_SI, // "si"
INDEX_DI, // "di"
INDEX_BP, // "bp"
INDEX_BX, // "bx"
*/
if(from.base.id)
{
eReg base_reg = convertRegister(from.base);
eReg index_reg = convertRegister(from.index);
// if(base_reg==rBX)
switch(base_reg)
{
case rDI:
res.regi = INDEX_DI; break;
case rBP:
res.seg=rSS;
switch(index_reg)
{
case rDI:
res.regi = INDEX_BP_DI; break;
case rSI:
res.regi = INDEX_BP_SI; break;
case rUNDEF:
res.regi = INDEX_BP; break;
default:
assert(false);
}
break;
case rBX:
switch(index_reg)
{
case rDI:
res.regi = INDEX_BX_DI; break;
case rSI:
res.regi = INDEX_BX_SI; break;
case rUNDEF:
res.regi = INDEX_BX; break;
default:
assert(false);
}
break;
default:
assert(false);
}
assert(index_reg==rUNDEF);
}
assert(from.scale==0);
if(from.index.id)
{
assert(false);
}
res.off = from.disp;
return res;
}
LLOperand convertOperand(const x86_op_t &from) LLOperand convertOperand(const x86_op_t &from)
{ {
LLOperand res;
switch(from.type) switch(from.type)
{ {
case op_unused: case op_unused:
break; break;
case op_register: case op_register:
return LLOperand::CreateReg2(convertRegister(from.data.reg)); res.regi = convertRegister(from.data.reg); break;
case op_immediate:
res.opz = from.data.sdword;
case op_expression:
res = convertExpression(from.data.expression); break;
case op_offset:
{
LLOperand res;
res.seg = rDS;
res.off = from.data.offset;
break;
} }
default:
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
} }
if(res.isSet() && (res.seg == rUNDEF))
{
res.seg = rDS;
}
return res;
}
/*****************************************************************************
Scans one machine instruction at offset ip in prog.Image and returns error.
At the same time, fill in low-level icode details for the scanned inst.
****************************************************************************/
eErrorId scan(uint32_t ip, ICODE &p) eErrorId scan(uint32_t ip, ICODE &p)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
@@ -425,10 +544,12 @@ eErrorId scan(uint32_t ip, ICODE &p)
if(cnt) if(cnt)
{ {
convertUsedFlags(p.insn,p); convertUsedFlags(p.insn,p);
convertPrefix(p.insn.prefix,p);
} }
SegPrefix = RepPrefix = 0; SegPrefix = RepPrefix = 0;
pInst = prog.Image + ip; pInst = prog.image() + ip;
pIcode = &p; pIcode = &p;
do do
@@ -440,12 +561,20 @@ eErrorId scan(uint32_t ip, ICODE &p)
(*stateTable[op].state2)(op); /* Third state */ (*stateTable[op].state2)(op); /* Third state */
} while (stateTable[op].state1 == prefix); /* Loop if prefix */ } while (stateTable[op].state1 == prefix); /* Loop if prefix */
if(p.insn.group == x86_insn_t::insn_controlflow)
{
if(p.insn.x86_get_branch_target())
decodeBranchTgt(p.insn);
}
// LLOperand conv = convertOperand(*p.insn.get_dest());
// assert(conv==p.ll()->dst);
if (p.ll()->getOpcode()) if (p.ll()->getOpcode())
{ {
/* Save bytes of image used */ /* Save bytes of image used */
p.ll()->numBytes = (uint8_t)((pInst - prog.Image) - ip); p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
if(p.insn.is_valid()) if(p.insn.is_valid())
assert(p.ll()->numBytes == p.insn.size); assert(p.ll()->numBytes == p.insn.size);
p.ll()->numBytes = p.insn.size;
return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */ return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */
(RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */ (RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
} }
@@ -456,11 +585,11 @@ eErrorId scan(uint32_t ip, ICODE &p)
/*************************************************************************** /***************************************************************************
relocItem - returns true if uint16_t pointed at is in relocation table relocItem - returns true if uint16_t pointed at is in relocation table
**************************************************************************/ **************************************************************************/
static bool relocItem(uint8_t *p) static bool relocItem(const uint8_t *p)
{ {
PROG &prog(Project::get()->prog); PROG &prog(Project::get()->prog);
int i; int i;
uint32_t off = p - prog.Image; uint32_t off = p - prog.image();
for (i = 0; i < prog.cReloc; i++) for (i = 0; i < prog.cReloc; i++)
if (prog.relocTable[i] == off) if (prog.relocTable[i] == off)
@@ -495,16 +624,14 @@ static int signex(uint8_t b)
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG) * Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
* fdst == false is for reg part of the field * fdst == false is for reg part of the field
***************************************************************************/ ***************************************************************************/
static void setAddress(int i, boolT fdst, uint16_t seg, int16_t reg, uint16_t off) static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
{ {
LLOperand *pm;
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */ /* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
pm = (!(stateTable[i].flg & TO_REG) == fdst) ? LLOperand *pm = (!(stateTable[i].flg & TO_REG) == fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src();
&pIcode->ll()->dst : &pIcode->ll()->src();
/* Set segment. A later procedure (lookupAddr in proclist.c) will /* Set segment. A later procedure (lookupAddr in proclist.c) will
* provide the value of this segment in the field segValue. */ * provide the value of this segment in the field segValue.
*/
if (seg) /* segment override */ if (seg) /* segment override */
{ {
pm->seg = pm->segOver = (eReg)seg; pm->seg = pm->segOver = (eReg)seg;
@@ -566,9 +693,9 @@ static void rm(int i)
setAddress(i, true, 0, rm + rAX, 0); setAddress(i, true, 0, rm + rAX, 0);
break; break;
} }
//pIcode->insn.get_dest()->
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP || if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
pIcode->ll()->dst.getReg2()==rSP)) pIcode->ll()->m_dst.getReg2()==rSP))
pIcode->ll()->setFlags(NOT_HLL); pIcode->ll()->setFlags(NOT_HLL);
} }
@@ -604,17 +731,19 @@ static void segrm(int i)
***************************************************************************/ ***************************************************************************/
static void regop(int i) static void regop(int i)
{ {
setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0); setAddress(i, false, 0, ((int16_t)i & 0x7) + rAX, 0);
pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2())); pIcode->ll()->replaceDst(pIcode->ll()->src());
// pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
}
}
/***************************************************************************** /*****************************************************************************
segop - seg encoded in middle of opcode segop - seg encoded in middle of opcode
*****************************************************************************/ *****************************************************************************/
static void segop(int i) static void segop(int i)
{ {
if(i==0x1E) {
printf("es");
}
setAddress(i, true, 0, (((int16_t)i & 0x18) >> 3) + rES, 0); setAddress(i, true, 0, (((int16_t)i & 0x18) >> 3) + rES, 0);
} }
@@ -709,14 +838,17 @@ static void trans(int i)
{ {
static llIcode transTable[8] = static llIcode transTable[8] =
{ {
(llIcode)iINC, (llIcode)iDEC, (llIcode)iCALL, (llIcode)iCALLF, (llIcode)iINC, iDEC, (llIcode)iCALL, (llIcode)iCALLF,
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0 (llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
}; };
LLInst *ll = pIcode->ll(); LLInst *ll = pIcode->ll();
// if(transTable[REG(*pInst)]==iPUSH) {
// printf("es");
// }
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */ if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */ ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
rm(i); rm(i);
ll->replaceSrc( pIcode->ll()->dst ); ll->replaceSrc( pIcode->ll()->m_dst );
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF)) if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
ll->setFlags(NO_OPS); ll->setFlags(NO_OPS);
else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC)) else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
@@ -748,7 +880,7 @@ static void arith(int i)
} }
else if (!(opcode == iNOT || opcode == iNEG)) else if (!(opcode == iNOT || opcode == iNEG))
{ {
pIcode->ll()->replaceSrc( pIcode->ll()->dst ); pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
setAddress(i, true, 0, rAX, 0); /* dst = AX */ setAddress(i, true, 0, rAX, 0); /* dst = AX */
} }
else if (opcode == iNEG || opcode == iNOT) else if (opcode == iNEG || opcode == iNOT)
@@ -767,7 +899,7 @@ static void arith(int i)
*****************************************************************************/ *****************************************************************************/
static void data1(int i) static void data1(int i)
{ {
pIcode->ll()->replaceSrc(LLOperand::CreateImm2((stateTable[i].flg & S_EXT)? signex(*pInst++): *pInst++)); pIcode->ll()->replaceSrc(LLOperand::CreateImm2((stateTable[i].flg & S_EXT)? signex(*pInst++): *pInst++,1));
pIcode->ll()->setFlags(I); pIcode->ll()->setFlags(I);
} }
@@ -787,7 +919,7 @@ static void data2(int )
* set to NO_OPS. */ * set to NO_OPS. */
if (pIcode->ll()->getOpcode() == iENTER) if (pIcode->ll()->getOpcode() == iENTER)
{ {
pIcode->ll()->dst.off = getWord(); pIcode->ll()->m_dst.off = getWord();
pIcode->ll()->setFlags(NO_OPS); pIcode->ll()->setFlags(NO_OPS);
} }
else else
@@ -804,47 +936,42 @@ static void dispM(int i)
{ {
setAddress(i, false, SegPrefix, 0, getWord()); setAddress(i, false, SegPrefix, 0, getWord());
} }
/**************************************************************************** /****************************************************************************
dispN - 2 uint8_t disp as immed relative to ip dispN - 2 uint8_t disp as immed relative to ip
****************************************************************************/ ****************************************************************************/
static void dispN(int ) static void dispN(int )
{ {
PROG &prog(Project::get()->prog);
long off = (short)getWord(); /* Signed displacement */ //PROG &prog(Project::get()->prog);
/*long off = (short)*/getWord(); /* Signed displacement */
/* Note: the result of the subtraction could be between 32k and 64k, and /* Note: the result of the subtraction could be between 32k and 64k, and
still be positive; it is an offset from prog.Image. So this must be still be positive; it is an offset from prog.Image. So this must be
treated as unsigned */ treated as unsigned */
pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image))); // decodeBranchTgt();
pIcode->ll()->setFlags(I);
} }
/*************************************************************************** /***************************************************************************
dispS - 1 uint8_t disp as immed relative to ip dispS - 1 byte disp as immed relative to ip
***************************************************************************/ ***************************************************************************/
static void dispS(int ) static void dispS(int )
{ {
PROG &prog(Project::get()->prog); /*long off =*/ signex(*pInst++); /* Signed displacement */
long off = signex(*pInst++); /* Signed displacement */
pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image))); // decodeBranchTgt();
pIcode->ll()->setFlags(I);
} }
/**************************************************************************** /****************************************************************************
dispF - 4 uint8_t disp as immed 20-bit target address dispF - 4 byte disp as immed 20-bit target address
***************************************************************************/ ***************************************************************************/
static void dispF(int ) static void dispF(int i)
{ {
uint32_t off = (unsigned)getWord(); uint16_t off = (unsigned)getWord();
uint32_t seg = (unsigned)getWord(); uint16_t seg = (unsigned)getWord();
setAddress(i, true, seg, 0, off);
pIcode->ll()->replaceSrc(off + ((uint32_t)(unsigned)seg << 4)); // decodeBranchTgt();
pIcode->ll()->setFlags(I);
} }
@@ -874,12 +1001,19 @@ static void strop(int )
{ {
if (RepPrefix) if (RepPrefix)
{ {
// pIcode->ll()->getOpcode() += ((pIcode->ll()->getOpcode() == iCMPS || if ( pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) )
// pIcode->ll()->getOpcode() == iSCAS) {
// && RepPrefix == iREPE)? 2: 1; if(pIcode->insn.prefix & insn_rep_zero)
if ((pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) ) && RepPrefix == iREPE) {
BumpOpcode(*pIcode->ll()); // += 2 BumpOpcode(*pIcode->ll()); // iCMPS -> iREPE_CMPS
BumpOpcode(*pIcode->ll()); // else += 1 BumpOpcode(*pIcode->ll());
}
else if(pIcode->insn.prefix & insn_rep_notzero)
BumpOpcode(*pIcode->ll()); // iX -> iREPNE_X
}
else
if(pIcode->insn.prefix & insn_rep_zero)
BumpOpcode(*pIcode->ll()); // iX -> iREPE_X
if (pIcode->ll()->match(iREP_LODS) ) if (pIcode->ll()->match(iREP_LODS) )
pIcode->ll()->setFlags(NOT_HLL); pIcode->ll()->setFlags(NOT_HLL);
RepPrefix = 0; RepPrefix = 0;

View File

@@ -30,7 +30,7 @@
#define TABLESIZE 16 /* Number of entries added each expansion */ #define TABLESIZE 16 /* Number of entries added each expansion */
/* Probably has to be a power of 2 */ /* Probably has to be a power of 2 */
#define STRTABSIZE 256 /* Size string table is inc'd by */ #define STRTABSIZE 256 /* Size string table is inc'd by */
#define NIL ((uint16_t)-1)
using namespace std; using namespace std;
static char *pStrTab; /* Pointer to the current string table */ static char *pStrTab; /* Pointer to the current string table */
static int strTabNext; /* Next free index into pStrTab */ static int strTabNext; /* Next free index into pStrTab */
@@ -53,7 +53,7 @@ struct TABLEINFO_TYPE
{ {
TABLEINFO_TYPE() TABLEINFO_TYPE()
{ {
symTab=valTab=0; symTab=valTab=nullptr;
} }
//void deleteVal(uint32_t symOff, Function *symProc, boolT bSymToo); //void deleteVal(uint32_t symOff, Function *symProc, boolT bSymToo);
void create(tableType type); void create(tableType type);
@@ -80,7 +80,7 @@ void TABLEINFO_TYPE::create(tableType type)
numEntry = 0; numEntry = 0;
tableSize = TABLESIZE; tableSize = TABLESIZE;
valTab = new SYMTABLE [TABLESIZE]; valTab = new SYMTABLE [TABLESIZE];
symTab = 0; symTab = nullptr;
break; break;
case Label: case Label:
currentTabInfo.numEntry = 0; currentTabInfo.numEntry = 0;
@@ -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) bool 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;

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
@@ -31,6 +31,7 @@ void Function::buildCFG(Disassembler &ds)
if (option.asm2) if (option.asm2)
{ {
ds.disassem(this); // Print 2nd pass assembler listing ds.disassem(this); // Print 2nd pass assembler listing
return;
} }
/* Idiom analysis and propagation of long type */ /* Idiom analysis and propagation of long type */
@@ -43,7 +44,7 @@ void Function::controlFlowAnalysis()
{ {
if (flg & PROC_ISLIB) if (flg & PROC_ISLIB)
return; /* Ignore library functions */ return; /* Ignore library functions */
derSeq *derivedG=0; derSeq *derivedG=nullptr;
/* Make cfg reducible and build derived sequences */ /* Make cfg reducible and build derived sequences */
derivedG=checkReducibility(); derivedG=checkReducibility();
@@ -60,7 +61,8 @@ void Function::controlFlowAnalysis()
if (option.verbose) if (option.verbose)
{ {
printf("\nDepth first traversal - Proc %s\n", name.c_str()); printf("\nDepth first traversal - Proc %s\n", name.c_str());
m_cfg.front()->displayDfs(); (*m_actual_cfg.begin())->displayDfs();
//m_cfg.front()->displayDfs();
} }
/* Free storage occupied by this procedure */ /* Free storage occupied by this procedure */
@@ -73,20 +75,22 @@ 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);
} }
if (option.asm2)
return;
/* Data flow analysis - eliminate condition codes, extraneous registers /* Data flow analysis - eliminate condition codes, extraneous registers
* and intermediate instructions. Find expressions by forward * and intermediate instructions. Find expressions by forward
* substitution algorithm */ * substitution algorithm */
std::bitset<32> live_regs; LivenessSet 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();
} }
@@ -98,7 +102,7 @@ void udm(void)
void Function::displayCFG() void Function::displayCFG()
{ {
printf("\nBasic Block List - Proc %s", name.c_str()); printf("\nBasic Block List - Proc %s", name.c_str());
for (BB *pBB : m_cfg) for (BB *pBB : /*m_cfg*/m_actual_cfg)
{ {
pBB->display(); pBB->display();
} }

View File

@@ -13,16 +13,15 @@ int proc_2 (long arg0, long arg1)
*/ */
{ {
char loc1; /* al */ char loc1; /* al */
int loc2; /* al */ int loc2; /* bx */
int loc3; /* bx */
do { do {
arg0 = (arg0 + 1); arg0 = (arg0 + 1);
loc1 = es[bx]; loc1 = es[bx];
arg1 = (arg1 + 1); arg1 = (arg1 + 1);
es[bx] = loc1; es[bx] = loc1;
} while ((loc2 != 0)); } while ((loc1 != 0));
return (loc3); return (loc2);
} }
@@ -35,7 +34,6 @@ int proc_3 (long arg0, long arg1)
int loc1; /* ax */ int loc1; /* ax */
while ((es[bx] == es[bx])) { while ((es[bx] == es[bx])) {
if (es[bx] == 0) { if (es[bx] == 0) {
loc1 = 0; loc1 = 0;
return (loc1); return (loc1);
@@ -57,9 +55,9 @@ int proc_1 (int arg0, int arg1, int arg2, int arg3)
{ {
int loc1; /* si */ int loc1; /* si */
int loc2; /* di */ int loc2; /* di */
loc1 = 0; loc1 = 0;
loc2 = 0; loc2 = 0;
while ((loc1 < 0x2328)) { while ((loc1 < 0x2328)) {
proc_2 (arg1, arg0, 311); proc_2 (arg1, arg0, 311);
proc_2 (arg3, arg2, 328); proc_2 (arg3, arg2, 328);
@@ -79,13 +77,12 @@ int loc1;
int loc2; int loc2;
int loc3; int loc3;
int loc4; int loc4;
loc3 = 0;
loc3 = 0;
while ((loc3 < 0x3e8)) { while ((loc3 < 0x3e8)) {
loc1 = 0; loc1 = 0;
loc4 = 0; loc4 = 0;
loc2 = 1; loc2 = 1;
while ((loc4 < 179)) { while ((loc4 < 179)) {
loc1 = (loc1 + loc2); loc1 = (loc1 + loc2);
loc2 = (loc2 + 2); loc2 = (loc2 + 2);
@@ -105,8 +102,8 @@ int proc_5 (int arg0)
{ {
int loc1; /* si */ int loc1; /* si */
int loc2; /* ax */ int loc2; /* ax */
loc1 = arg0;
loc1 = arg0;
if (loc1 > 2) { if (loc1 > 2) {
loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe))); loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe)));
} }
@@ -179,7 +176,7 @@ void proc_8 (int arg0)
} }
proc_7 (int arg0, int arg1, int arg2, int arg3) void proc_7 (int arg0, int arg1, int arg2, int arg3)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* High-level language prologue code. * High-level language prologue code.
* Untranslatable routine. Assembler provided. * Untranslatable routine. Assembler provided.
@@ -245,7 +242,7 @@ void proc_8 (int arg0)
} }
proc_9 (int arg0) void proc_9 (int arg0)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* High-level language prologue code. * High-level language prologue code.
* C calling convention. * C calling convention.
@@ -256,106 +253,62 @@ void proc_8 (int arg0)
int loc1; int loc1;
int loc2; int loc2;
int loc3; /* ax */ int loc3; /* ax */
loc2 = 100; loc2 = 100;
loc3 = loc2; loc3 = loc2;
loc2 = (loc2 - 1); loc2 = (loc2 - 1);
while (((loc3 | loc3) != 0)) { while (((loc3 | loc3) != 0)) {
loc3 = loc2; loc3 = loc2;
loc2 = (loc2 - 1); loc2 = (loc2 - 1);
} /* end of while */ } /* end of while */
return (var06278);
} }
int proc_10 () int proc_10 ()
/* Takes no parameters. /* Takes no parameters.
* High-level language prologue code. * High-level language prologue code.
* Untranslatable routine. Assembler provided.
* Return value in register ax.
* Contains instructions not normally used by compilers. * Contains instructions not normally used by compilers.
*/ */
{ {
PUSH bp int loc1;
MOV bp, sp int loc2;
SUB sp, 68h int loc3;
PUSH si int loc4;
PUSH di int loc5;
PUSH ds int loc6; /* bx */
MOV ax, 159h int loc7; /* dx */
PUSH ax int loc8; /* ax */
PUSH ss loc6 = proc_2 (&loc1, 345, , );
LEA ax, [bp-64h] fopen ("zyxw.vut", 368);
PUSH ax loc2 = loc7;
PUSH cs loc3 = loc8;
CALL near ptr proc_2
ADD sp, 8
PUSH ds
MOV ax, 170h
PUSH ax
PUSH ds
MOV ax, 167h
PUSH ax
CALL far ptr fopen
ADD sp, 8
MOV [bp-66h], dx
MOV [bp-68h], ax
OR dx, ax
JNE L1
PUSH ds
MOV ax, 172h
PUSH ax
CALL far ptr printf
POP cx
POP cx
MOV ax, 0FFFFh
PUSH ax
CALL far ptr exit
POP cx
L1: XOR di, 0 if ((loc7 | loc8) == 0) {
printf ("Cannot open file");
exit (0xffff);
}
l1:
if (++loc5 >= 0x3e8) {
fclose (loc3, loc2);
return (loc5);
}
else {
loc4 = 0;
L2: INC di while ((ss[bp+si-0x64] != 0)) {
MOV ax, di
CMP ax, 3E8h
JL L3
PUSH word ptr [bp-66h]
PUSH word ptr [bp-68h]
CALL far ptr fclose
POP cx
POP cx
MOV ax, di
POP di
POP si
MOV sp, bp
POP bp
RETF
L3: XOR si, 0 if (++es[bx] < 0) {
es[bx+0xc] = (es[bx+0xc] + 1);
L4: CMP byte ptr ss:[bp+si-64h], 0 loc6 = (loc6 - 1);
JNE L5 es[bx] = ss[bp+si-0x64];
}
L5: LES bx, dword ptr[bp-68h] else {
INC word ptr es:[bx] _fputc (ss[bp+si-0x64], loc3, loc2);
JGE L6 }
MOV al, ss:[bp+si-64h] loc4 = (loc4 + 1);
LES bx, dword ptr[bp-68h] } /* end of while */
INC word ptr es:[bx+0Ch] goto L1;
LES bx, dword ptres:[bx+0Ch] }
DEC bx
MOV es:[bx], al
MOV ah, 0
L7: INC si
JMP L4 ;Synthetic inst
L6: PUSH word ptr [bp-66h]
PUSH word ptr [bp-68h]
PUSH word ptr ss:[bp+si-64h]
CALL far ptr _fputc
ADD sp, 6
JMP L7 ;Synthetic inst
} }
@@ -379,11 +332,11 @@ int loc10;
int loc11; int loc11;
int loc12; /* ax */ int loc12; /* ax */
int loc13; /* bx */ int loc13; /* bx */
printf ("Start...%c\n\n", 7);
loc11 = 0;
printf ("Start...%c\n\n", 7);
while ((loc11 < 6)) { while ((loc11 < 6)) {
loc12 = loc11; loc12 = loc11;
if (loc12 <= 5) { if (loc12 <= 5) {
loc13 = (loc12 << 1); loc13 = (loc12 << 1);
var06278 = proc_1 (&loc2, &loc1, , ); var06278 = proc_1 (&loc2, &loc1, , );

View File

@@ -15,30 +15,32 @@ long LXMUL@ (long arg0, long arg1)
{ {
int loc1; int loc1;
int loc2; /* tmp */ int loc2; /* tmp */
loc2 = LO(arg0); loc2 = LO(arg0);
LO(arg0) = loc1; LO(arg0) = loc1;
loc1 = loc2; loc1 = loc2;
loc2 = LO(arg0); loc2 = LO(arg0);
LO(arg0) = HI(arg0); LO(arg0) = HI(arg0);
if ((LO(arg0) & LO(arg0)) != 0) { if ((LO(arg0) & LO(arg0)) != 0) {
LO(arg0) = (LO(arg0) * LO(arg1));
} }
loc2 = LO(arg0); loc2 = LO(arg0);
LO(arg0) = HI(arg1); LO(arg0) = HI(arg1);
HI(arg1) = loc2; HI(arg1) = loc2;
if ((LO(arg0) & LO(arg0)) != 0) { if ((LO(arg0) & LO(arg0)) != 0) {
LO(arg0) = (LO(arg0) * loc1); LO(arg0) = (LO(arg0) * loc1);
HI(arg1) = (HI(arg1) + LO(arg0)); HI(arg1) = (HI(arg1) + LO(arg0));
} }
loc2 = LO(arg0); loc2 = LO(arg0);
arg0 = (loc1 * LO(arg1)); LO(arg0) = loc1;
loc1 = loc2;
arg0 = (LO(arg0) * LO(arg1));
HI(arg0) = (HI(arg0) + HI(arg1)); HI(arg0) = (HI(arg0) + HI(arg1));
return (arg0); return (arg0);
} }
long LDIV@ (long arg0, int arg3) long LDIV@ (long arg0, long arg2)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* Runtime support routine of the compiler. * Runtime support routine of the compiler.
* High-level language prologue code. * High-level language prologue code.
@@ -131,7 +133,7 @@ long LDIV@ (long arg0, int arg3)
} }
long LMOD@ (long arg0, int arg3) long LMOD@ (long arg0, long arg2)
/* Takes 8 bytes of parameters. /* Takes 8 bytes of parameters.
* Runtime support routine of the compiler. * Runtime support routine of the compiler.
* High-level language prologue code. * High-level language prologue code.
@@ -280,6 +282,7 @@ void main ()
{ {
long loc1; long loc1;
long loc2; long loc2;
loc2 = 255; loc2 = 255;
loc1 = 143; loc1 = 143;
loc1 = (loc2 + loc1); loc1 = (loc2 + loc1);

View File

@@ -15,16 +15,14 @@ void proc_1 (int arg0, int arg1, int arg2)
int loc1; int loc1;
int loc2; int loc2;
int loc3; int loc3;
loc2 = 0;
loc2 = 0;
while ((loc2 < 5)) { while ((loc2 < 5)) {
loc3 = 0; loc3 = 0;
while ((loc3 < 4)) { while ((loc3 < 4)) {
loc1 = 0; loc1 = 0;
while ((loc1 < 4)) { while ((loc1 < 4)) {
*((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*(((((loc2 << 3) << 1) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1)))); *((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*((((loc2 << 3) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
loc1 = (loc1 + 1); loc1 = (loc1 + 1);
} /* end of while */ } /* end of while */
loc3 = (loc3 + 1); loc3 = (loc3 + 1);
@@ -42,6 +40,7 @@ void main ()
int loc1; int loc1;
int loc2; int loc2;
int loc3; int loc3;
proc_1 (&loc3, &loc2, &loc1); proc_1 (&loc3, &loc2, &loc1);
} }

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 ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/