From 11437ea1ca9b117227bb3f417796582be70116e7 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 3 May 2015 23:10:51 +0300 Subject: [PATCH] translate: minor fixes --- c_auto.h | 4 +++ ida/saveasm/saveasm.cpp | 24 +++++++++++------ tests/x87.expect.c | 10 ++++---- tests/x87_s.expect.c | 4 +-- tools/cvt_data.c | 2 +- tools/translate.c | 57 ++++++++++++++++++++++++++++++++++++----- 6 files changed, 78 insertions(+), 23 deletions(-) diff --git a/c_auto.h b/c_auto.h index d76e596..31e89e1 100644 --- a/c_auto.h +++ b/c_auto.h @@ -44,3 +44,7 @@ static inline BOOL PtInRect_sa(LPCRECT r, int x, int y) POINT p = { x, y }; return PtInRect(r, p); } + +#define do_skip_code_abort() \ + printf("%s:%d: skip_code_abort\n", __FILE__, __LINE__); \ + *(volatile int *)0 = 1 diff --git a/ida/saveasm/saveasm.cpp b/ida/saveasm/saveasm.cpp index 51f67d2..5a6a2a6 100644 --- a/ida/saveasm/saveasm.cpp +++ b/ida/saveasm/saveasm.cpp @@ -374,14 +374,18 @@ static void idaapi run(int /*arg*/) if (cmd.Operands[o].type == o_mem) { tmp_ea = cmd.Operands[o].addr; - flags_t tmp_ea_flags = get_flags_novalue(tmp_ea); - // ..but base float is ok.. - int is_flt = isDwrd(tmp_ea_flags) || isFloat(tmp_ea_flags); - if (!is_flt && !isUnknown(tmp_ea_flags)) + flags_t tmp_flg = get_flags_novalue(tmp_ea); + buf[0] = 0; + if (isDouble(tmp_flg)) { - buf[0] = 0; get_name(ea, tmp_ea, buf, sizeof(buf)); - msg("%x: undefining %x '%s'\n", ea, tmp_ea, buf); + msg("%x: converting dbl %x '%s'\n", ea, tmp_ea, buf); + doQwrd(tmp_ea, 8); + } + if (isOwrd(tmp_flg) || isYwrd(tmp_flg) || isTbyt(tmp_flg)) + { + get_name(ea, tmp_ea, buf, sizeof(buf)); + msg("%x: undefining lrg %x '%s'\n", ea, tmp_ea, buf); do_unknown(tmp_ea, DOUNK_EXPAND); } } @@ -452,8 +456,12 @@ static void idaapi run(int /*arg*/) } // IDA vs masm float/mmx/xmm type incompatibility - if (isDouble(ea_flags) || isTbyt(ea_flags) - || isPackReal(ea_flags)) + if (isDouble(ea_flags)) + { + msg("%x: converting double\n", ea); + doQwrd(ea, 8); + } + else if (isTbyt(ea_flags) || isPackReal(ea_flags)) { do_undef = 1; } diff --git a/tests/x87.expect.c b/tests/x87.expect.c index f1442b0..ae64239 100644 --- a/tests/x87.expect.c +++ b/tests/x87.expect.c @@ -12,22 +12,22 @@ int sub_test(int a1, int a2) f_st0 = (double)(s32)sf.d[0]; // var_20 fild f_st0 /= (double)(s32)a1; // arg_0 - f_st0 *= *((double *)(u32)&sf.q[1]); // var_18 + f_st0 *= *(double *)((u32)&sf.q[1]); // var_18 f_st1 = f_st0; f_st0 = (double)(s32)sf.d[0]; // var_20 fild f_st1 /= f_st0; f_st0 = f_st1 + f_st0; - f_st1 = f_st0; f_st0 = *((double *)(u32)&sf.q[1]); // var_18 fld + f_st1 = f_st0; f_st0 = *(double *)((u32)&sf.q[1]); // var_18 fld fs_3 = f_st0; f_st0 = f_st1; // fst fs_1 = f_st0; // fst f_st0 = pow(fs_1, fs_3); - f_sw = f_st0 <= *((double *)(u32)&sf.q[1]) ? 0x4100 : 0; // var_18 z_chk_det + f_sw = f_st0 <= *(double *)((u32)&sf.q[1]) ? 0x4100 : 0; // var_18 z_chk_det eax = 0; LOWORD(eax) = f_sw; cond_z = ((u8)((u8)(eax >> 8) & 0x41) == 0); eax = 0; LOBYTE(eax) = (cond_z); f_st1 = f_st0; f_st0 = 1.0; - f_st0 = *((double *)(u32)&sf.q[1]) / f_st0; // var_18 + f_st0 = *(double *)((u32)&sf.q[1]) / f_st0; // var_18 { double t = f_st0; f_st0 = f_st1; f_st1 = t; } // fxch f_st0 = -f_st0; f_st0 = f_st1; @@ -35,7 +35,7 @@ int sub_test(int a1, int a2) f_st0 = f_st1 * log2(f_st0); // fyl2x f_st1 = f_st0; // fld st sf.d[0] = (s32)f_st0; f_st0 = f_st1; // var_20 fist - *((double *)(u32)&sf.q[1]) = f_st0; // var_18 fst + *(double *)((u32)&sf.q[1]) = f_st0; // var_18 fst eax = (s32)f_st0; // ftol return eax; } diff --git a/tests/x87_s.expect.c b/tests/x87_s.expect.c index 3a644b9..b2a6d89 100644 --- a/tests/x87_s.expect.c +++ b/tests/x87_s.expect.c @@ -6,7 +6,7 @@ double sub_test() sf.d[0] = 4; // var_4 f_st[--f_stp & 7] = (float)(s32)sf.d[0]; // var_4 fild - f_st[--f_stp & 7] = *((float *)(u32)&sf.d[0]); // var_4 fld + f_st[--f_stp & 7] = *(float *)((u32)&sf.d[0]); // var_4 fld f_st[--f_stp & 7] = (float)(s32)sf.d[0]; // var_4 fild f_st[--f_stp & 7] = 1.0; f_st[--f_stp & 7] = (float)(s32)sf.d[0]; // var_4 fild @@ -22,7 +22,7 @@ double sub_test() f_st[f_stp & 7] = -f_st[f_stp & 7]; f_st[(f_stp + 1) & 7] = atanf(f_st[(f_stp + 1) & 7] / f_st[f_stp & 7]); f_stp++; sf.d[0] = (s32)f_st[f_stp & 7]; // var_4 fist - *((float *)(u32)&sf.d[0]) = f_st[f_stp & 7]; f_stp++; // var_4 fst + *(float *)((u32)&sf.d[0]) = f_st[f_stp & 7]; f_stp++; // var_4 fst return f_st[f_stp & 7]; } diff --git a/tools/cvt_data.c b/tools/cvt_data.c index bc9b2da..93c5fd0 100644 --- a/tools/cvt_data.c +++ b/tools/cvt_data.c @@ -195,7 +195,7 @@ static char *escape_string(char *s) for (; *s != 0; s++) { if (*s == '"') { - strcpy(t, "\\22"); + strcpy(t, "\\x22"); t += strlen(t); continue; } diff --git a/tools/translate.c b/tools/translate.c index e7fd5c7..cc1de70 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -157,6 +157,7 @@ enum op_op { OPP_ALLSHR, OPP_FTOL, OPP_CIPOW, + OPP_ABORT, // undefined OP_UD2, }; @@ -620,6 +621,9 @@ static int guess_lmod_from_name(struct parsed_opr *opr) static int guess_lmod_from_c_type(enum opr_lenmod *lmod, const struct parsed_type *c_type) { + static const char *qword_types[] = { + "uint64_t", "int64_t", "__int64", + }; static const char *dword_types[] = { "uint32_t", "int", "_DWORD", "UINT_PTR", "DWORD", "WPARAM", "LPARAM", "UINT", "__int32", @@ -668,6 +672,13 @@ static int guess_lmod_from_c_type(enum opr_lenmod *lmod, } } + for (i = 0; i < ARRAY_SIZE(qword_types); i++) { + if (IS(n, qword_types[i])) { + *lmod = OPLM_QWORD; + return 1; + } + } + return 0; } @@ -2310,7 +2321,7 @@ static char *out_src_opr_float(char *buf, size_t buf_size, break; } out_src_opr(tmp, sizeof(tmp), po, popr, "", 1); - snprintf(buf, buf_size, "*((%s *)%s)", cast, tmp); + snprintf(buf, buf_size, "*(%s *)(%s)", cast, tmp); break; default: @@ -5586,6 +5597,8 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) reg_use_pass(0, opcnt, cbits, regmask_init, ®mask, 0, ®mask_save, ®mask_init, regmask_arg); + need_float_stack = !!(regmask & mxST7_2); + // pass7: // - find flag set ops for their users // - do unresolved calls @@ -5793,10 +5806,13 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) // this might need it's own pass... if (po->op != OP_FST && po->p_argnum > 0) save_arg_vars[po->p_arggrp] |= 1 << (po->p_argnum - 1); + + // correct for "full stack" mode late enable + if ((po->flags & (OPF_PPUSH|OPF_FPOP)) && need_float_stack) + po->flags |= OPF_FSHIFT; } float_type = need_double ? "double" : "float"; - need_float_stack = !!(regmask & mxST7_2); float_st0 = need_float_stack ? "f_st[f_stp & 7]" : "f_st0"; float_st1 = need_float_stack ? "f_st[(f_stp + 1) & 7]" : "f_st1"; @@ -7446,9 +7462,13 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) strcat(g_comment, " CIpow"); break; + case OPP_ABORT: + fprintf(fout, " do_skip_code_abort();"); + break; + // mmx case OP_EMMS: - strcpy(g_comment, " (emms)"); + fprintf(fout, " do_emms();"); break; default: @@ -8566,7 +8586,8 @@ int main(int argc, char *argv[]) char *sctproto = NULL; int in_func = 0; int pending_endp = 0; - int skip_func = 0; + int skip_code = 0; + int skip_code_end = 0; int skip_warned = 0; int eq_alloc; int verbose = 0; @@ -8632,6 +8653,8 @@ int main(int argc, char *argv[]) memset(words, 0, sizeof(words)); for (; arg < argc; arg++) { + int skip_func = 0; + frlist = fopen(argv[arg], "r"); my_assert_not(frlist, NULL); @@ -8663,7 +8686,6 @@ int main(int argc, char *argv[]) } rlist[rlist_len++] = strdup(words[0]); } - skip_func = 0; fclose(frlist); frlist = NULL; @@ -8846,7 +8868,12 @@ parse_words: if (*p != 0 && *p != ';') aerr("too many words\n"); - // alow asm patches in comments + if (skip_code_end) { + skip_code_end = 0; + skip_code = 0; + } + + // allow asm patches in comments if (*p == ';') { if (IS_START(p, "; sctpatch:")) { p = sskip(p + 11); @@ -8862,6 +8889,20 @@ parse_words: if (!pending_endp) break; } + else if (IS_START(p, "; sctskip_start")) { + if (in_func && !g_skip_func) { + if (!skip_code) { + ops[pi].op = OPP_ABORT; + ops[pi].asmln = asmln; + pi++; + } + skip_code = 1; + } + } + else if (IS_START(p, "; sctskip_end")) { + if (skip_code) + skip_code_end = 1; + } } if (wordc == 0) { @@ -9001,6 +9042,8 @@ do_pending_endp: if (!IS(g_func, words[0])) aerr("endp '%s' while in_func '%s'?\n", words[0], g_func); + if (skip_code) + aerr("endp '%s' while skipping code\n", words[0]); if ((g_ida_func_attr & IDAFA_THUNK) && pi == 1 && ops[0].op == OP_JMP && ops[0].operand[0].had_ds) @@ -9068,7 +9111,7 @@ do_pending_endp: continue; } - if (!in_func || g_skip_func) { + if (!in_func || g_skip_func || skip_code) { if (!skip_warned && !g_skip_func && g_labels[pi] != NULL) { if (verbose) anote("skipping from '%s'\n", g_labels[pi]); -- 2.39.2