unsigned int size_mismatch:1; // type override differs from C
unsigned int size_lt:1; // type override is larger than C
unsigned int had_ds:1; // had ds: prefix
+ const struct parsed_proto *pp; // for OPT_LABEL
int reg;
unsigned int val;
- char name[256];
+ char name[112];
};
struct parsed_op {
int cc_scratch; // scratch storage during analysis
int bt_i; // branch target for branches
struct parsed_data *btj;// branch targets for jumptables
- struct parsed_proto *pp;
+ struct parsed_proto *pp;// parsed_proto for OP_CALL
void *datap;
+ int asmln;
};
// datap:
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
return 0;
}
+static char *default_cast_to(char *buf, size_t buf_size,
+ struct parsed_opr *opr)
+{
+ buf[0] = 0;
+
+ if (!opr->is_ptr)
+ return buf;
+ if (opr->pp == NULL || opr->pp->type.name == NULL
+ || opr->pp->is_fptr)
+ {
+ snprintf(buf, buf_size, "%s", "(void *)");
+ return buf;
+ }
+
+ snprintf(buf, buf_size, "(%s)", opr->pp->type.name);
+ return buf;
+}
+
static enum opr_type lmod_from_directive(const char *d)
{
if (IS(d, "dd"))
}
opr->is_array = pp->type.is_array;
}
+ opr->pp = pp;
if (opr->lmod == OPLM_UNSPEC)
guess_lmod_from_name(opr);
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;
assert_operand_cnt(2);
propagate_lmod(po, &po->operand[0], &po->operand[1]);
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
+ default_cast_to(buf3, sizeof(buf3), &po->operand[0]);
fprintf(fout, " %s = %s;", buf1,
out_src_opr(buf2, sizeof(buf2), po, &po->operand[1],
- po->operand[0].is_ptr ? "(void *)" : "", 0));
+ buf3, 0));
break;
case OP_LEA:
out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], "", 0));
fprintf(fout, " %s = %s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], "", 0));
- fprintf(fout, " %s = tmp;",
- out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1]));
+ out_src_opr(buf2, sizeof(buf2), po, &po->operand[1],
+ default_cast_to(buf3, sizeof(buf3), &po->operand[0]), 0));
+ fprintf(fout, " %s = %stmp;",
+ out_dst_opr(buf1, sizeof(buf1), po, &po->operand[1]),
+ default_cast_to(buf3, sizeof(buf3), &po->operand[1]));
snprintf(g_comment, sizeof(g_comment), "xchg");
break;
ferr(po, "TODO\n");
}
else {
- fprintf(fout, " eax = %sedi; esi %c= %d;",
+ fprintf(fout, " eax = %sesi; esi %c= %d;",
lmod_cast_u_ptr(po, po->operand[0].lmod),
(po->flags & OPF_DF) ? '-' : '+',
lmod_bytes(po, po->operand[0].lmod));
if (pfomask & (1 << PFO_C)) {
// ugh..
fprintf(fout,
- " cond_c = %sedi < %sesi;\n", buf1, buf1);
+ " cond_c = %sesi < %sedi;\n", buf1, buf1);
pfomask &= ~(1 << PFO_C);
}
fprintf(fout,
- " cond_z = (%sedi == %sesi); edi %c= %d, esi %c= %d;\n",
+ " cond_z = (%sesi == %sedi); esi %c= %d, edi %c= %d;\n",
buf1, buf1, l, j, l, j);
fprintf(fout,
" if (cond_z %s 0) break;\n",
}
else {
fprintf(fout,
- " cond_z = (%sedi = %sesi); edi %c= %d; esi %c= %d;",
+ " cond_z = (%sesi == %sedi); esi %c= %d; edi %c= %d;",
buf1, buf1, l, j, l, j);
strcpy(g_comment, "cmps");
}
(po->flags & OPF_REPZ) ? "e" : "ne");
}
else {
- fprintf(fout, " cond_z = (%seax = %sedi); edi %c= %d;",
+ fprintf(fout, " cond_z = (%seax == %sedi); edi %c= %d;",
lmod_cast_u(po, po->operand[0].lmod),
lmod_cast_u_ptr(po, po->operand[0].lmod), l, j);
strcpy(g_comment, "scas");
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")) {
}
if (pp->is_unresolved) {
- snprintf(buf2, sizeof(buf2), " unresoved %dreg",
+ snprintf(buf2, sizeof(buf2), " unresolved %dreg",
pp->argc_reg);
strcat(g_comment, buf2);
}
fprintf(fout, " %s = %s;", buf1,
out_src_opr(buf2, sizeof(buf2),
tmp_op, &tmp_op->operand[0],
- po->operand[0].is_ptr ? "(void *)" : "", 0));
+ default_cast_to(buf3, sizeof(buf3), &po->operand[0]), 0));
break;
}
else if (g_func_pp->is_userstack) {
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;
}