translate: log unresolved calls, change error logging
[ia32rtools.git] / tools / translate.c
index 7becbdd..db601eb 100644 (file)
@@ -128,9 +128,10 @@ struct parsed_opr {
   unsigned int size_mismatch:1; // type override differs from C
   unsigned int size_lt:1;  // type override is larger than C
   unsigned int had_ds:1;   // had ds: prefix
+  const struct parsed_proto *pp; // for OPT_LABEL
   int reg;
   unsigned int val;
-  char name[256];
+  char name[112];
 };
 
 struct parsed_op {
@@ -148,8 +149,9 @@ struct parsed_op {
   int cc_scratch;         // scratch storage during analysis
   int bt_i;               // branch target for branches
   struct parsed_data *btj;// branch targets for jumptables
-  struct parsed_proto *pp;
+  struct parsed_proto *pp;// parsed_proto for OP_CALL
   void *datap;
+  int asmln;
 };
 
 // datap:
@@ -211,13 +213,13 @@ static int g_stack_fsz;
 static int g_ida_func_attr;
 static int g_allow_regfunc;
 #define ferr(op_, fmt, ...) do { \
-  printf("error:%s:#%zd: '%s': " fmt, g_func, (op_) - ops, \
+  printf("%s:%d: error: [%s] '%s': " fmt, asmfn, (op_)->asmln, g_func, \
     dump_op(op_), ##__VA_ARGS__); \
   fcloseall(); \
   exit(1); \
 } while (0)
 #define fnote(op_, fmt, ...) \
-  printf("error:%s:#%zd: '%s': " fmt, g_func, (op_) - ops, \
+  printf("%s:%d: note: [%s] '%s': " fmt, asmfn, (op_)->asmln, g_func, \
     dump_op(op_), ##__VA_ARGS__)
 
 #define MAX_REGS 8
@@ -507,6 +509,24 @@ static int guess_lmod_from_c_type(enum opr_lenmod *lmod,
   return 0;
 }
 
+static char *default_cast_to(char *buf, size_t buf_size,
+  struct parsed_opr *opr)
+{
+  buf[0] = 0;
+
+  if (!opr->is_ptr)
+    return buf;
+  if (opr->pp == NULL || opr->pp->type.name == NULL
+    || opr->pp->is_fptr)
+  {
+    snprintf(buf, buf_size, "%s", "(void *)");
+    return buf;
+  }
+
+  snprintf(buf, buf_size, "(%s)", opr->pp->type.name);
+  return buf;
+}
+
 static enum opr_type lmod_from_directive(const char *d)
 {
   if (IS(d, "dd"))
@@ -699,6 +719,7 @@ do_label:
     }
     opr->is_array = pp->type.is_array;
   }
+  opr->pp = pp;
 
   if (opr->lmod == OPLM_UNSPEC)
     guess_lmod_from_name(opr);
@@ -884,6 +905,7 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc)
   op->pfo = op_table[i].pfo;
   op->pfo_inv = op_table[i].pfo_inv;
   op->regmask_src = op->regmask_dst = 0;
+  op->asmln = asmln;
 
   for (opr = 0; opr < op_table[i].minopr; opr++) {
     regmask = regmask_ind = 0;
@@ -3807,9 +3829,10 @@ tailcall:
         assert_operand_cnt(2);
         propagate_lmod(po, &po->operand[0], &po->operand[1]);
         out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
+        default_cast_to(buf3, sizeof(buf3), &po->operand[0]);
         fprintf(fout, "  %s = %s;", buf1,
             out_src_opr(buf2, sizeof(buf2), po, &po->operand[1],
-              po->operand[0].is_ptr ? "(void *)" : "", 0));
+              buf3, 0));
         break;
 
       case OP_LEA:
@@ -3853,9 +3876,11 @@ tailcall:
           out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], "", 0));
         fprintf(fout, " %s = %s;",
           out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
-          out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], "", 0));
-        fprintf(fout, " %s = tmp;",
-          out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1]));
+          out_src_opr(buf2, sizeof(buf2), po, &po->operand[1],
+            default_cast_to(buf3, sizeof(buf3), &po->operand[0]), 0));
+        fprintf(fout, " %s = %stmp;",
+          out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1]),
+          default_cast_to(buf3, sizeof(buf3), &po->operand[1]));
         snprintf(g_comment, sizeof(g_comment), "xchg");
         break;
 
@@ -3880,7 +3905,7 @@ tailcall:
           ferr(po, "TODO\n");
         }
         else {
-          fprintf(fout, "  eax = %sedi; esi %c= %d;",
+          fprintf(fout, "  eax = %sesi; esi %c= %d;",
             lmod_cast_u_ptr(po, po->operand[0].lmod),
             (po->flags & OPF_DF) ? '-' : '+',
             lmod_bytes(po, po->operand[0].lmod));
@@ -3939,11 +3964,11 @@ tailcall:
           if (pfomask & (1 << PFO_C)) {
             // ugh..
             fprintf(fout,
-            "    cond_c = %sedi < %sesi;\n", buf1, buf1);
+            "    cond_c = %sesi < %sedi;\n", buf1, buf1);
             pfomask &= ~(1 << PFO_C);
           }
           fprintf(fout,
-            "    cond_z = (%sedi == %sesi); edi %c= %d, esi %c= %d;\n",
+            "    cond_z = (%sesi == %sedi); esi %c= %d, edi %c= %d;\n",
               buf1, buf1, l, j, l, j);
           fprintf(fout,
             "    if (cond_z %s 0) break;\n",
@@ -3955,7 +3980,7 @@ tailcall:
         }
         else {
           fprintf(fout,
-            "  cond_z = (%sedi = %sesi); edi %c= %d; esi %c= %d;",
+            "  cond_z = (%sesi == %sedi); esi %c= %d; edi %c= %d;",
             buf1, buf1, l, j, l, j);
           strcpy(g_comment, "cmps");
         }
@@ -3986,7 +4011,7 @@ tailcall:
             (po->flags & OPF_REPZ) ? "e" : "ne");
         }
         else {
-          fprintf(fout, "  cond_z = (%seax = %sedi); edi %c= %d;",
+          fprintf(fout, "  cond_z = (%seax == %sedi); edi %c= %d;",
               lmod_cast_u(po, po->operand[0].lmod),
               lmod_cast_u_ptr(po, po->operand[0].lmod), l, j);
           strcpy(g_comment, "scas");
@@ -4342,10 +4367,14 @@ tailcall:
           fprintf(fout, " {\n");
         }
 
-        if (pp->is_fptr && !pp->is_arg)
+        if (pp->is_fptr && !pp->is_arg) {
           fprintf(fout, "%s%s = %s;\n", buf3, pp->name,
             out_src_opr(buf1, sizeof(buf1), po, &po->operand[0],
               "(void *)", 0));
+          if (pp->is_unresolved)
+            fprintf(fout, "%sunresolved_call(\"%s:%d\", %s);\n",
+              buf3, asmfn, po->asmln, pp->name);
+        }
 
         fprintf(fout, "%s", buf3);
         if (strstr(pp->ret_type.name, "int64")) {
@@ -4443,7 +4472,7 @@ tailcall:
         }
 
         if (pp->is_unresolved) {
-          snprintf(buf2, sizeof(buf2), " unresoved %dreg",
+          snprintf(buf2, sizeof(buf2), " unresolved %dreg",
             pp->argc_reg);
           strcat(g_comment, buf2);
         }
@@ -4544,7 +4573,7 @@ tailcall:
           fprintf(fout, "  %s = %s;", buf1,
             out_src_opr(buf2, sizeof(buf2),
               tmp_op, &tmp_op->operand[0],
-              po->operand[0].is_ptr ? "(void *)" : "", 0));
+              default_cast_to(buf3, sizeof(buf3), &po->operand[0]), 0));
           break;
         }
         else if (g_func_pp->is_userstack) {
@@ -5273,7 +5302,7 @@ do_pending_endp:
     parse_op(&ops[pi], words, wordc);
 
     if (sctproto != NULL) {
-      if (ops[pi].op == OP_CALL)
+      if (ops[pi].op == OP_CALL || ops[pi].op == OP_JMP)
         ops[pi].datap = sctproto;
       sctproto = NULL;
     }