X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=e8b1ba9a91bc97be2da42f47a48d711f068fcf8d;hb=0ea6430ca5707ae1e6ddd43d5e01dbc0f6979bf4;hp=cc1de70642fd27b8f8f9cc0e120674d4ba831c25;hpb=11437ea1ca9b117227bb3f417796582be70116e7;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index cc1de70..e8b1ba9 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -4,6 +4,15 @@ * * This work is licensed under the terms of 3-clause BSD license. * See COPYING file in the top-level directory. + * + * recognized asm hint comments: + * sctattr - function attributes (see code) + * sctend - force end of function/chunk + * sctpatch:

- replace current asm line with

+ * sctproto:

- prototype of ref'd function or struct + * sctref - variable is referenced, make global + * sctskip_start - start of skipped code chunk (inclusive) + * sctskip_end - end of skipped code chunk (inclusive) */ #define _GNU_SOURCE @@ -1735,14 +1744,12 @@ static struct parsed_equ *equ_find(struct parsed_op *po, const char *name, *extra_offs = 0; namelen = strlen(name); - p = strchr(name, '+'); + p = strpbrk(name, "+-"); if (p != NULL) { namelen = p - name; if (namelen <= 0) ferr(po, "equ parse failed for '%s'\n", name); - if (IS_START(p, "0x")) - p += 2; *extra_offs = strtol(p, &endp, 16); if (*endp != 0) ferr(po, "equ parse failed for '%s'\n", name); @@ -1867,7 +1874,6 @@ static int stack_frame_access(struct parsed_op *po, int offset = 0; int retval = -1; int sf_ofs; - int lim; if (po->flags & OPF_EBP_S) ferr(po, "stack_frame_access while ebp is scratch\n"); @@ -1998,8 +2004,7 @@ static int stack_frame_access(struct parsed_op *po, g_stack_frame_used = 1; sf_ofs = g_stack_fsz + offset; - lim = (ofs_reg[0] != 0) ? -4 : 0; - if (offset > 0 || sf_ofs < lim) + if (ofs_reg[0] == 0 && (offset > 0 || sf_ofs < 0)) ferr(po, "bp_stack offset %d/%d\n", offset, g_stack_fsz); if (is_lea) @@ -2578,10 +2583,10 @@ static int scan_for_pop(int i, int opcnt, int magic, int reg, if (po->pp != NULL && po->pp->is_noreturn) seen_noreturn = 1; else - return -1; + goto out; } else - return -1; // deadend + goto out; } if (po->flags & (OPF_RMD|OPF_DONE|OPF_FARG)) @@ -2632,6 +2637,7 @@ static int scan_for_pop(int i, int opcnt, int magic, int reg, } } +out: // for noreturn, assume msvc skipped stack cleanup return seen_noreturn ? 1 : -1; } @@ -6699,10 +6705,11 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) lmod_cast_s(po, po->operand[0].lmod), buf2); last_arith_dst = &po->operand[0]; delayed_flag_op = NULL; - if (pfomask & (1 << PFO_C)) { + if (pfomask & PFOB_C) { fprintf(fout, "\n cond_c = (%s != 0);", buf1); - pfomask &= ~(1 << PFO_C); + pfomask &= ~PFOB_C; } + output_std_flags(fout, po, &pfomask, buf1); break; case OP_IMUL: @@ -6950,7 +6957,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) if (pp->arg[arg].type.is_retreg) fprintf(fout, "&%s", pp->arg[arg].reg); else if (IS(pp->arg[arg].reg, "ebp") - && !(po->flags & OPF_EBP_S)) + && g_bp_frame && !(po->flags & OPF_EBP_S)) { // rare special case fprintf(fout, "%s(u32)&sf.b[sizeof(sf)]", cast); @@ -7742,8 +7749,11 @@ static void gen_hdr_dep_pass(int i, int opcnt, unsigned char *cbits, po->regmask_dst |= 1 << xAX; dep = hg_fp_find_dep(fp, po->operand[0].name); - if (dep != NULL) + if (dep != NULL) { dep->regmask_live = regmask_save | regmask_dst; + if (g_bp_frame && !(po->flags & OPF_EBP_S)) + dep->regmask_live |= 1 << xBP; + } } else if (po->op == OP_RET) { if (po->operand_cnt > 0) { @@ -7962,7 +7972,7 @@ static void gen_hdr(const char *funcn, int opcnt) // noreturn OS functions break; } - if (ops[i].op != OP_NOP) + if (ops[i].op != OP_NOP && ops[i].op != OPP_ABORT) ferr(&ops[i], "unreachable code\n"); } @@ -8290,10 +8300,14 @@ static int ida_xrefs_show_need(FILE *fasm, char *p, long pos; p = strrchr(p, ';'); - if (p != NULL && *p == ';' && IS_START(p + 2, "DATA XREF: ")) { - p += 13; - if (is_xref_needed(p, rlist, rlist_len)) + if (p != NULL && *p == ';') { + if (IS_START(p + 2, "sctref")) return 1; + if (IS_START(p + 2, "DATA XREF: ")) { + p += 13; + if (is_xref_needed(p, rlist, rlist_len)) + return 1; + } } pos = ftell(fasm); @@ -8312,6 +8326,12 @@ static int ida_xrefs_show_need(FILE *fasm, char *p, p = strrchr(p, ';'); p += 2; + + if (IS_START(p, "sctref")) { + found_need = 1; + break; + } + // it's printed once, but no harm to check again if (IS_START(p, "DATA XREF: ")) p += 11; @@ -8505,7 +8525,7 @@ static int cmp_chunks(const void *p1, const void *p2) return strcmp(c1->name, c2->name); } -static void scan_ahead(FILE *fasm) +static void scan_ahead_for_chunks(FILE *fasm) { char words[2][256]; char line[256]; @@ -8846,7 +8866,7 @@ int main(int argc, char *argv[]) if (addr > f_addr && !scanned_ahead) { //anote("scan_ahead caused by '%s', addr %lx\n", // g_func, addr); - scan_ahead(fasm); + scan_ahead_for_chunks(fasm); scanned_ahead = 1; func_chunks_sorted = 0; }