From: notaz Date: Tue, 21 Jan 2014 01:31:50 +0000 (+0200) Subject: fixes, standalone works? X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b74c31e30301a2e5c03e2947a5017af28bf94e65;p=ia32rtools.git fixes, standalone works? --- diff --git a/c_auto.h b/c_auto.h index 6451290..b316cac 100644 --- 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 diff --git a/tools/cvt_data.c b/tools/cvt_data.c index e21ff96..bddd6ef 100644 --- a/tools/cvt_data.c +++ b/tools/cvt_data.c @@ -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"); diff --git a/tools/protoparse.h b/tools/protoparse.h index be1dca9..0aa8ed8 100644 --- a/tools/protoparse.h +++ b/tools/protoparse.h @@ -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; diff --git a/tools/translate.c b/tools/translate.c index e2b6d20..eeea0ac 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -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, ®mask_stack, &save_arg_vars, + collect_call_args(po, i, pp, ®mask, &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)