X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tools%2Ftranslate.c;h=ecd972f075b7138dbbde1dc52574352188d7fd6c;hb=b4878d2b4f7e08514f204b6a0dc228cf1382db40;hp=381f1749c2f451e71aec971299fd9520d0ba5bc5;hpb=05381e4abadfd03a26243938a106101c804f5d9f;p=ia32rtools.git diff --git a/tools/translate.c b/tools/translate.c index 381f174..ecd972f 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -151,6 +151,7 @@ struct parsed_op { struct parsed_data *btj;// branch targets for jumptables struct parsed_proto *pp;// parsed_proto for OP_CALL void *datap; + int asmln; }; // datap: @@ -212,13 +213,13 @@ static int g_stack_fsz; static int g_ida_func_attr; static int g_allow_regfunc; #define ferr(op_, fmt, ...) do { \ - printf("error:%s:#%zd: '%s': " fmt, g_func, (op_) - ops, \ + printf("%s:%d: error: [%s] '%s': " fmt, asmfn, (op_)->asmln, g_func, \ dump_op(op_), ##__VA_ARGS__); \ fcloseall(); \ exit(1); \ } while (0) #define fnote(op_, fmt, ...) \ - printf("error:%s:#%zd: '%s': " fmt, g_func, (op_) - ops, \ + printf("%s:%d: note: [%s] '%s': " fmt, asmfn, (op_)->asmln, g_func, \ dump_op(op_), ##__VA_ARGS__) #define MAX_REGS 8 @@ -473,6 +474,8 @@ static int guess_lmod_from_c_type(enum opr_lenmod *lmod, "uint8_t", "int8_t", "char", "unsigned __int8", "__int8", "BYTE", "_BYTE", "CHAR", "_UNKNOWN", + // structures.. deal the same as with _UNKNOWN for now + "CRITICAL_SECTION", }; const char *n; int i; @@ -624,8 +627,10 @@ static int parse_operand(struct parsed_opr *opr, if (wordc_in == 2) { if (IS(words[w], "offset")) { opr->type = OPT_OFFSET; + opr->lmod = OPLM_DWORD; strcpy(opr->name, words[w + 1]); - return wordc; + pp = proto_parse(g_fhdr, opr->name, 1); + goto do_label; } if (IS(words[w], "(offset")) { p = strchr(words[w + 1], ')'); @@ -904,6 +909,7 @@ static void parse_op(struct parsed_op *op, char words[16][256], int wordc) op->pfo = op_table[i].pfo; op->pfo_inv = op_table[i].pfo_inv; op->regmask_src = op->regmask_dst = 0; + op->asmln = asmln; for (opr = 0; opr < op_table[i].minopr; opr++) { regmask = regmask_ind = 0; @@ -2891,39 +2897,7 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) if (g_func_pp == NULL) ferr(ops, "proto_parse failed for '%s'\n", funcn); - fprintf(fout, "%s ", g_func_pp->ret_type.name); - output_pp_attrs(fout, g_func_pp, g_ida_func_attr & IDAFA_NORETURN); - fprintf(fout, "%s(", g_func_pp->name); - for (i = 0; i < g_func_pp->argc; i++) { - if (i > 0) - fprintf(fout, ", "); - if (g_func_pp->arg[i].fptr != NULL) { - // func pointer.. - pp = g_func_pp->arg[i].fptr; - fprintf(fout, "%s (", pp->ret_type.name); - output_pp_attrs(fout, pp, 0); - fprintf(fout, "*a%d)(", i + 1); - for (j = 0; j < pp->argc; j++) { - if (j > 0) - fprintf(fout, ", "); - if (pp->arg[j].fptr) - ferr(ops, "nested fptr\n"); - fprintf(fout, "%s", pp->arg[j].type.name); - } - if (pp->is_vararg) { - if (j > 0) - fprintf(fout, ", "); - fprintf(fout, "..."); - } - fprintf(fout, ")"); - } - else if (g_func_pp->arg[i].type.is_retreg) { - fprintf(fout, "u32 *r_%s", g_func_pp->arg[i].reg); - } - else { - fprintf(fout, "%s a%d", g_func_pp->arg[i].type.name, i + 1); - } if (g_func_pp->arg[i].reg != NULL) { reg = char_array_i(regs_r32, ARRAY_SIZE(regs_r32), g_func_pp->arg[i].reg); @@ -2932,13 +2906,6 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) regmask_arg |= 1 << reg; } } - if (g_func_pp->is_vararg) { - if (i > 0) - fprintf(fout, ", "); - fprintf(fout, "..."); - } - - fprintf(fout, ")\n{\n"); // pass1: // - handle ebp/esp frame, remove ops related to it @@ -3512,38 +3479,24 @@ tailcall: } } } - - // declare indirect funcs - if (pp->is_fptr && !(pp->name[0] != 0 && pp->is_arg)) { - if (pp->name[0] != 0) { - memmove(pp->name + 2, pp->name, strlen(pp->name) + 1); - memcpy(pp->name, "i_", 2); - - // might be declared already - found = 0; - for (j = 0; j < i; j++) { - if (ops[j].op == OP_CALL && (pp_tmp = ops[j].pp)) { - if (pp_tmp->is_fptr && IS(pp->name, pp_tmp->name)) { - found = 1; - break; - } - } - } - if (found) - continue; - } - else - snprintf(pp->name, sizeof(pp->name), "icall%d", i); - - fprintf(fout, " %s (", pp->ret_type.name); - output_pp_attrs(fout, pp, 0); - fprintf(fout, "*%s)(", pp->name); - for (j = 0; j < pp->argc; j++) { - if (j > 0) - fprintf(fout, ", "); - fprintf(fout, "%s a%d", pp->arg[j].type.name, j + 1); + } + else if (po->op == OP_MOV && po->operand[0].pp != NULL + && po->operand[1].pp != NULL) + { + // = offset + if ((po->operand[1].pp->is_func || po->operand[1].pp->is_fptr) + && !IS_START(po->operand[1].name, "off_")) + { + if (!po->operand[0].pp->is_fptr) + ferr(po, "%s not declared as fptr when it should be\n", + po->operand[0].name); + if (pp_cmp_func(po->operand[0].pp, po->operand[1].pp)) { + pp_print(buf1, sizeof(buf1), po->operand[0].pp); + pp_print(buf2, sizeof(buf2), po->operand[1].pp); + fnote(po, "var: %s\n", buf1); + fnote(po, "func: %s\n", buf2); + ferr(po, "^ mismatch\n"); } - fprintf(fout, ");\n"); } } else if (po->op == OP_RET && !IS(g_func_pp->ret_type.name, "void")) @@ -3582,6 +3535,102 @@ tailcall: } } + // output starts here + + // define userstack size + if (g_func_pp->is_userstack) { + fprintf(fout, "#ifndef US_SZ_%s\n", g_func_pp->name); + fprintf(fout, "#define US_SZ_%s USERSTACK_SIZE\n", g_func_pp->name); + fprintf(fout, "#endif\n"); + } + + // the function itself + fprintf(fout, "%s ", g_func_pp->ret_type.name); + output_pp_attrs(fout, g_func_pp, g_ida_func_attr & IDAFA_NORETURN); + fprintf(fout, "%s(", g_func_pp->name); + + for (i = 0; i < g_func_pp->argc; i++) { + if (i > 0) + fprintf(fout, ", "); + if (g_func_pp->arg[i].fptr != NULL) { + // func pointer.. + pp = g_func_pp->arg[i].fptr; + fprintf(fout, "%s (", pp->ret_type.name); + output_pp_attrs(fout, pp, 0); + fprintf(fout, "*a%d)(", i + 1); + for (j = 0; j < pp->argc; j++) { + if (j > 0) + fprintf(fout, ", "); + if (pp->arg[j].fptr) + ferr(ops, "nested fptr\n"); + fprintf(fout, "%s", pp->arg[j].type.name); + } + if (pp->is_vararg) { + if (j > 0) + fprintf(fout, ", "); + fprintf(fout, "..."); + } + fprintf(fout, ")"); + } + else if (g_func_pp->arg[i].type.is_retreg) { + fprintf(fout, "u32 *r_%s", g_func_pp->arg[i].reg); + } + else { + fprintf(fout, "%s a%d", g_func_pp->arg[i].type.name, i + 1); + } + } + if (g_func_pp->is_vararg) { + if (i > 0) + fprintf(fout, ", "); + fprintf(fout, "..."); + } + + fprintf(fout, ")\n{\n"); + + // declare indirect functions + for (i = 0; i < opcnt; i++) { + po = &ops[i]; + if (po->flags & OPF_RMD) + continue; + + if (po->op == OP_CALL) { + pp = po->pp; + if (pp == NULL) + ferr(po, "NULL pp\n"); + + if (pp->is_fptr && !(pp->name[0] != 0 && pp->is_arg)) { + if (pp->name[0] != 0) { + memmove(pp->name + 2, pp->name, strlen(pp->name) + 1); + memcpy(pp->name, "i_", 2); + + // might be declared already + found = 0; + for (j = 0; j < i; j++) { + if (ops[j].op == OP_CALL && (pp_tmp = ops[j].pp)) { + if (pp_tmp->is_fptr && IS(pp->name, pp_tmp->name)) { + found = 1; + break; + } + } + } + if (found) + continue; + } + else + snprintf(pp->name, sizeof(pp->name), "icall%d", i); + + fprintf(fout, " %s (", pp->ret_type.name); + output_pp_attrs(fout, pp, 0); + fprintf(fout, "*%s)(", pp->name); + for (j = 0; j < pp->argc; j++) { + if (j > 0) + fprintf(fout, ", "); + fprintf(fout, "%s a%d", pp->arg[j].type.name, j + 1); + } + fprintf(fout, ");\n"); + } + } + } // output LUTs/jumptables for (i = 0; i < g_func_pd_cnt; i++) { @@ -3618,8 +3667,8 @@ tailcall: } if (g_func_pp->is_userstack) { - fprintf(fout, " u32 fake_sf[1024];\n"); - fprintf(fout, " u32 *esp = &fake_sf[1024];\n"); + fprintf(fout, " u32 fake_sf[US_SZ_%s / 4];\n", g_func_pp->name); + fprintf(fout, " u32 *esp = &fake_sf[sizeof(fake_sf) / 4];\n"); had_decl = 1; } @@ -4365,10 +4414,14 @@ tailcall: fprintf(fout, " {\n"); } - if (pp->is_fptr && !pp->is_arg) + if (pp->is_fptr && !pp->is_arg) { fprintf(fout, "%s%s = %s;\n", buf3, pp->name, out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], "(void *)", 0)); + if (pp->is_unresolved) + fprintf(fout, "%sunresolved_call(\"%s:%d\", %s);\n", + buf3, asmfn, po->asmln, pp->name); + } fprintf(fout, "%s", buf3); if (strstr(pp->ret_type.name, "int64")) { @@ -4466,7 +4519,7 @@ tailcall: } if (pp->is_unresolved) { - snprintf(buf2, sizeof(buf2), " unresoved %dreg", + snprintf(buf2, sizeof(buf2), " unresolved %dreg", pp->argc_reg); strcat(g_comment, buf2); } @@ -5296,7 +5349,7 @@ do_pending_endp: parse_op(&ops[pi], words, wordc); if (sctproto != NULL) { - if (ops[pi].op == OP_CALL) + if (ops[pi].op == OP_CALL || ops[pi].op == OP_JMP) ops[pi].datap = sctproto; sctproto = NULL; }