X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=f9ac8a8d2a98372bdee4323b54c292ae495c410f;hb=36595fd27d06b03f1abf320bd511aec325845ed5;hp=3bf8d75238005283cae424ad5cdd8e0491f3c709;hpb=1cd4a6637bcc91c6daadfac995e9ed9fba6680cf;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index 3bf8d75..f9ac8a8 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; @@ -678,7 +650,7 @@ static int parse_operand(struct parsed_opr *opr, // most likely var in data segment opr->type = OPT_LABEL; - pp = proto_parse(g_fhdr, opr->name); + pp = proto_parse(g_fhdr, opr->name, 0); if (pp != NULL) { if (pp->is_fptr || pp->is_func) { opr->lmod = OPLM_DWORD; @@ -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 { @@ -1463,7 +1437,7 @@ static void check_label_read_ref(struct parsed_op *po, const char *name) { const struct parsed_proto *pp; - pp = proto_parse(g_fhdr, name); + pp = proto_parse(g_fhdr, name, 0); if (pp == NULL) ferr(po, "proto_parse failed for ref '%s'\n", name); @@ -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,12 +2288,12 @@ 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); + pp = proto_parse(g_fhdr, opr->name, 0); if (pp == NULL) ferr(po, "proto_parse failed for icall from '%s'\n", opr->name); if (pp->argc_reg != 0) @@ -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"); } @@ -2609,7 +2586,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) g_bp_frame = g_sp_frame = g_stack_fsz = 0; g_stack_frame_used = 0; - g_func_pp = proto_parse(fhdr, funcn); + g_func_pp = proto_parse(fhdr, funcn, 0); if (g_func_pp == NULL) ferr(ops, "proto_parse failed for '%s'\n", funcn); @@ -2776,7 +2753,9 @@ 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); - pp_c = proto_parse(fhdr, tmpname); + if (IS_START(tmpname, "loc_")) + ferr(po, "call to loc_*\n"); + pp_c = proto_parse(fhdr, tmpname, 0); if (pp_c == NULL) ferr(po, "proto_parse failed for call '%s'\n", tmpname); if (pp_c->is_fptr && pp_c->argc_reg != 0)