fixes, standalone works?
authornotaz <notasas@gmail.com>
Tue, 21 Jan 2014 01:31:50 +0000 (03:31 +0200)
committernotaz <notasas@gmail.com>
Tue, 21 Jan 2014 02:01:16 +0000 (04:01 +0200)
c_auto.h
tools/cvt_data.c
tools/protoparse.h
tools/translate.c

index 6451290..b316cac 100644 (file)
--- a/c_auto.h
+++ b/c_auto.h
@@ -32,3 +32,7 @@
 
 #define noreturn __attribute__((noreturn))
 
+#ifdef __WINE__
+#define PCVOID LPCVOID
+#define __VALIST __ms_va_list
+#endif
index e21ff96..bddd6ef 100644 (file)
@@ -205,28 +205,6 @@ static char *escape_string(char *s)
   return strcpy(s, buf);
 }
 
-static void sprint_pp(const struct parsed_proto *pp, char *buf,
-  size_t buf_size)
-{
-  size_t l;
-  int i;
-
-  snprintf(buf, buf_size, "%s %s(", pp->ret_type.name, pp->name);
-  l = strlen(buf);
-
-  for (i = 0; i < pp->argc_reg; i++) {
-    snprintf(buf + l, buf_size - l, "%s%s",
-      i == 0 ? "" : ", ", pp->arg[i].reg);
-    l = strlen(buf);
-  }
-  if (pp->argc_stack > 0) {
-    snprintf(buf + l, buf_size - l, "%s{%d stack}",
-      i == 0 ? "" : ", ", pp->argc_stack);
-    l = strlen(buf);
-  }
-  snprintf(buf + l, buf_size - l, ")");
-}
-
 static void sprint_pp_short(const struct parsed_proto *pp, char *buf,
   size_t buf_size)
 {
@@ -272,7 +250,7 @@ static const struct parsed_proto *check_var(FILE *fhdr,
   if (!pp->is_func && !pp->is_fptr)
     return NULL;
 
-  sprint_pp(pp, fp_var, sizeof(fp_var));
+  pp_print(fp_var, sizeof(fp_var), pp);
 
   if (pp->argc_reg == 0)
     goto check_sym;
@@ -324,7 +302,7 @@ check_sym:
   }
 
   if (bad) {
-    sprint_pp(pp_sym, fp_sym, sizeof(fp_sym));
+    pp_print(fp_sym, sizeof(fp_sym), pp_sym);
     anote("var: %s\n", fp_var);
     anote("sym: %s\n", fp_sym);
     awarn("^ mismatch\n");
index be1dca9..0aa8ed8 100644 (file)
@@ -698,6 +698,28 @@ struct parsed_proto *proto_clone(const struct parsed_proto *pp_c)
        return pp;
 }
 
+static inline void pp_print(char *buf, size_t buf_size,
+  const struct parsed_proto *pp)
+{
+  size_t l;
+  int i;
+
+  snprintf(buf, buf_size, "%s %s(", pp->ret_type.name, pp->name);
+  l = strlen(buf);
+
+  for (i = 0; i < pp->argc_reg; i++) {
+    snprintf(buf + l, buf_size - l, "%s%s",
+      i == 0 ? "" : ", ", pp->arg[i].reg);
+    l = strlen(buf);
+  }
+  if (pp->argc_stack > 0) {
+    snprintf(buf + l, buf_size - l, "%s{%d stack}",
+      i == 0 ? "" : ", ", pp->argc_stack);
+    l = strlen(buf);
+  }
+  snprintf(buf + l, buf_size - l, ")");
+}
+
 static inline void proto_release(struct parsed_proto *pp)
 {
        int i;
index e2b6d20..eeea0ac 100644 (file)
@@ -1450,9 +1450,13 @@ static void stack_frame_access(struct parsed_op *po,
 static void check_func_pp(struct parsed_op *po,
   const struct parsed_proto *pp, const char *pfx)
 {
+  char buf[256];
+
   if (pp->argc_reg != 0) {
-    if (!g_allow_regfunc && !pp->is_fastcall)
-      ferr(po, "%s: reg arg in arg-call unhandled yet\n", pfx);
+    if (/*!g_allow_regfunc &&*/ !pp->is_fastcall) {
+      pp_print(buf, sizeof(buf), pp);
+      ferr(po, "%s: unexpected reg arg in icall: %s\n", pfx, buf);
+    }
     if (pp->argc_stack > 0 && pp->argc_reg != 2)
       ferr(po, "%s: %d reg arg(s) with %d stack arg(s)\n",
         pfx, pp->argc_reg, pp->argc_stack);
@@ -3213,9 +3217,22 @@ tailcall:
 
       if (pp->is_unresolved) {
         int regmask_stack = 0;
-        collect_call_args(po, i, pp, &regmask_stack, &save_arg_vars,
+        collect_call_args(po, i, pp, &regmask, &save_arg_vars,
           i + opcnt * 2);
 
+        // this is pretty rough guess:
+        // see ecx and edx were pushed (and not their saved versions)
+        for (arg = 0; arg < pp->argc; arg++) {
+          if (pp->arg[arg].reg != NULL)
+            continue;
+
+          tmp_op = pp->arg[arg].datap;
+          if (tmp_op == NULL)
+            ferr(po, "parsed_op missing for arg%d\n", arg);
+          if (tmp_op->argnum == 0 && tmp_op->operand[0].type == OPT_REG)
+            regmask_stack |= 1 << tmp_op->operand[0].reg;
+        }
+
         if (!((regmask_stack & (1 << xCX))
           && (regmask_stack & (1 << xDX))))
         {
@@ -3235,7 +3252,6 @@ tailcall:
             regmask |= 1 << xDX;
           }
         }
-        regmask |= regmask_stack;
 
         // note: __cdecl doesn't fall into is_unresolved category
         if (pp->argc_stack > 0)