From: notaz Date: Sun, 28 Jun 2015 23:33:04 +0000 (+0300) Subject: translate: fix an issue with ebp arg X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e627c4d0268fe9237839e68463382c2919ed59fd;p=ia32rtools.git translate: fix an issue with ebp arg --- diff --git a/tests/Makefile b/tests/Makefile index 83def3c..9f0639c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,6 @@ -TESTS = reg_call1 reg_call2 reg_call3 reg_call_tail reg_save \ +TESTS = reg_call1 reg_call2 reg_call3 reg_call4 reg_call5 \ + reg_call_tail reg_save \ varargs ops x87 x87_f x87_s deref all: $(addsuffix .ok,$(TESTS)) diff --git a/tests/reg_call4.asm b/tests/reg_call4.asm new file mode 100644 index 0000000..b409416 --- /dev/null +++ b/tests/reg_call4.asm @@ -0,0 +1,12 @@ +; call a func with ebp reg-arg + +_text segment para public 'CODE' use32 + +call_test proc near + mov ebp, 1 + jmp ebpcall_func +call_test endp + +_text ends + +; vim:expandtab diff --git a/tests/reg_call4.expect.c b/tests/reg_call4.expect.c new file mode 100644 index 0000000..ca8d14b --- /dev/null +++ b/tests/reg_call4.expect.c @@ -0,0 +1,8 @@ +void call_test() +{ + u32 ebp; + + ebp = 1; + ebpcall_func(ebp); // tailcall +} + diff --git a/tests/reg_call4.seed.h b/tests/reg_call4.seed.h new file mode 100644 index 0000000..b4a82f2 --- /dev/null +++ b/tests/reg_call4.seed.h @@ -0,0 +1 @@ +void __usercall ebpcall_func(int a1/**/); diff --git a/tests/reg_call5.asm b/tests/reg_call5.asm new file mode 100644 index 0000000..d325b24 --- /dev/null +++ b/tests/reg_call5.asm @@ -0,0 +1,21 @@ +; special case of callee sharing the stack frame + +_text segment para public 'CODE' use32 + +sub_test proc near + +var_8 = dword ptr -8 + + push ebp + mov ebp, esp + sub esp, 8 + mov [ebp+var_8], 1 + call ebpcall_func + and eax, 0 + leave + retn +sub_test endp + +_text ends + +; vim:expandtab diff --git a/tests/reg_call5.expect.c b/tests/reg_call5.expect.c new file mode 100644 index 0000000..d3571e1 --- /dev/null +++ b/tests/reg_call5.expect.c @@ -0,0 +1,11 @@ +int sub_test() +{ + union { u32 d[2]; u8 b[8]; } sf; + u32 eax; + + sf.d[0] = 1; // var_8 + ebpcall_func((u32)&sf.b[sizeof(sf)]); // bp_ref + eax = 0; + return eax; +} + diff --git a/tests/reg_call5.seed.h b/tests/reg_call5.seed.h new file mode 100644 index 0000000..b4a82f2 --- /dev/null +++ b/tests/reg_call5.seed.h @@ -0,0 +1 @@ +void __usercall ebpcall_func(int a1/**/); diff --git a/tools/translate.c b/tools/translate.c index 5e810a9..de2da47 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -6955,7 +6955,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) if (pp->arg[arg].type.is_retreg) fprintf(fout, "&%s", pp->arg[arg].reg); else if (IS(pp->arg[arg].reg, "ebp") - && !(po->flags & OPF_EBP_S)) + && g_bp_frame && !(po->flags & OPF_EBP_S)) { // rare special case fprintf(fout, "%s(u32)&sf.b[sizeof(sf)]", cast); @@ -7747,8 +7747,11 @@ static void gen_hdr_dep_pass(int i, int opcnt, unsigned char *cbits, po->regmask_dst |= 1 << xAX; dep = hg_fp_find_dep(fp, po->operand[0].name); - if (dep != NULL) + if (dep != NULL) { dep->regmask_live = regmask_save | regmask_dst; + if (g_bp_frame && !(po->flags & OPF_EBP_S)) + dep->regmask_live |= 1 << xBP; + } } else if (po->op == OP_RET) { if (po->operand_cnt > 0) {