translate: minor fixes
authornotaz <notasas@gmail.com>
Sun, 3 May 2015 20:10:51 +0000 (23:10 +0300)
committernotaz <notasas@gmail.com>
Sun, 3 May 2015 20:12:26 +0000 (23:12 +0300)
c_auto.h
ida/saveasm/saveasm.cpp
tests/x87.expect.c
tests/x87_s.expect.c
tools/cvt_data.c
tools/translate.c

index d76e596..31e89e1 100644 (file)
--- 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
index 51f67d2..5a6a2a6 100644 (file)
@@ -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;
       }
index f1442b0..ae64239 100644 (file)
@@ -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;
 }
index 3a644b9..b2a6d89 100644 (file)
@@ -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];
 }
 
index bc9b2da..93c5fd0 100644 (file)
@@ -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;
     }
index e7fd5c7..cc1de70 100644 (file)
@@ -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, &regmask,
     0, &regmask_save, &regmask_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]);