X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=2c52f782d704f0443ea22db10e0d11458fdc8ac8;hb=054f95b2d6d035e4ea49601072f5b3d3d162a491;hp=3bf8d75238005283cae424ad5cdd8e0491f3c709;hpb=1cd4a6637bcc91c6daadfac995e9ed9fba6680cf;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index 3bf8d75..2c52f78 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -26,6 +26,8 @@ static FILE *g_fhdr; exit(1); \ } while (0) +#include "masm_tools.h" + enum op_flags { OPF_RMD = (1 << 0), /* removed or optimized out */ OPF_DATA = (1 << 1), /* data processing - writes to dst opr */ @@ -281,36 +283,6 @@ static int parse_reg(enum opr_lenmod *reg_lmod, const char *s) return -1; } -static unsigned long parse_number(const char *number) -{ - int len = strlen(number); - const char *p = number; - char *endp = NULL; - unsigned long ret; - int neg = 0; - int bad; - - if (*p == '-') { - neg = 1; - p++; - } - if (len > 1 && *p == '0') - p++; - if (number[len - 1] == 'h') { - ret = strtoul(p, &endp, 16); - bad = (*endp != 'h'); - } - else { - ret = strtoul(p, &endp, 10); - bad = (*endp != 0); - } - if (bad) - aerr("number parsing failed\n"); - if (neg) - ret = -ret; - return ret; -} - static int parse_indmode(char *name, int *regmask, int need_c_cvt) { enum opr_lenmod lmod; @@ -1403,6 +1375,8 @@ static void stack_frame_access(struct parsed_op *po, ferr(po, "bp_arg arg%d/w offset %d and type '%s' is too small\n", i + 1, offset, g_func_pp->arg[i].type.name); } + if (popr->is_ptr && popr->lmod != OPLM_DWORD) + ferr(po, "bp_arg arg%d: non-dword ptr access\n", i + 1); } else { @@ -2202,7 +2176,7 @@ static int scan_for_reg_clear(int i, int reg) static int scan_for_esp_adjust(int i, int opcnt, int *adj) { struct parsed_op *po; - int i_first = i; + int first_pop = -1; *adj = 0; for (; i < opcnt; i++) { @@ -2219,10 +2193,16 @@ static int scan_for_esp_adjust(int i, int opcnt, int *adj) ferr(&ops[i], "unaligned esp adjust: %x\n", *adj); return i; } - else if (po->op == OP_PUSH) + else if (po->op == OP_PUSH) { + if (first_pop == -1) + first_pop = -2; // none *adj -= lmod_bytes(po, po->operand[0].lmod); - else if (po->op == OP_POP) + } + else if (po->op == OP_POP) { + if (first_pop == -1) + first_pop = i; *adj += lmod_bytes(po, po->operand[0].lmod); + } else if (po->flags & (OPF_JMP|OPF_TAIL)) { if (po->op != OP_CALL) break; @@ -2232,12 +2212,12 @@ static int scan_for_esp_adjust(int i, int opcnt, int *adj) } } - if (*adj == 4 && ops[i_first].op == OP_POP - && ops[i_first].operand[0].type == OPT_REG - && ops[i_first].operand[0].reg == xCX) + if (*adj == 4 && first_pop >= 0 && ops[first_pop].op == OP_POP + && ops[first_pop].operand[0].type == OPT_REG + && ops[first_pop].operand[0].reg == xCX) { // probably 'pop ecx' was used.. - return i_first; + return first_pop; } return -1; @@ -2308,9 +2288,9 @@ static const struct parsed_proto *try_recover_pp( pp = g_func_pp->arg[arg].fptr; if (pp == NULL) - ferr(po, "icall: arg%d is not a fptr?\n", arg + 1); + ferr(po, "icall sa: arg%d is not a fptr?\n", arg + 1); if (pp->argc_reg != 0) - ferr(po, "icall: reg arg in arg-call unhandled yet\n"); + ferr(po, "icall sa: reg arg in arg-call unhandled yet\n"); } else if (opr->type == OPT_OFFSET || opr->type == OPT_LABEL) { pp = proto_parse(g_fhdr, opr->name); @@ -2339,12 +2319,8 @@ static void scan_for_call_type(int i, struct parsed_opr *opr, lr = &g_label_refs[i]; for (; lr != NULL; lr = lr->next) scan_for_call_type(lr->i, opr, magic, pp_found); - if (i > 0) { - if (LAST_OP(i - 1)) - return; - scan_for_call_type(i - 1, opr, magic, pp_found); - } - return; + if (i > 0 && LAST_OP(i - 1)) + return; } i--; @@ -2380,7 +2356,8 @@ static void scan_for_call_type(int i, struct parsed_opr *opr, return; pp = g_func_pp->arg[i].fptr; if (pp == NULL) - ferr(po, "icall: arg%d is not a fptr?\n", i + 1); + ferr(po, "icall: arg%d (%s) is not a fptr?\n", + i + 1, g_func_pp->arg[i].reg); if (pp->argc_reg != 0) ferr(po, "icall: reg arg in arg-call unhandled yet\n"); } @@ -2776,6 +2753,8 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) if (po->op == OP_CALL) { if (po->operand[0].type == OPT_LABEL) { tmpname = opr_name(po, 0); + if (IS_START(tmpname, "loc_")) + ferr(po, "call to loc_*\n"); pp_c = proto_parse(fhdr, tmpname); if (pp_c == NULL) ferr(po, "proto_parse failed for call '%s'\n", tmpname);