static int g_stack_fsz;
static int g_ida_func_attr;
#define ferr(op_, fmt, ...) do { \
static int g_stack_fsz;
static int g_ida_func_attr;
#define ferr(op_, fmt, ...) do { \
- printf("error:%s:#%ld: '%s': " fmt, g_func, (op_) - ops, \
+ printf("error:%s:#%zd: '%s': " fmt, g_func, (op_) - ops, \
{
// output in C-friendly form
snprintf(buf, buf_size, number < 10 ? "%lu" : "0x%02lx", number);
{
// output in C-friendly form
snprintf(buf, buf_size, number < 10 ? "%lu" : "0x%02lx", number);
static const char *dword_types[] = {
"int", "_DWORD", "DWORD", "HANDLE", "HWND", "HMODULE",
};
static const char *dword_types[] = {
"int", "_DWORD", "DWORD", "HANDLE", "HWND", "HMODULE",
};
static const char *byte_types[] = {
"char", "__int8", "unsigned __int8", "BYTE",
};
static const char *byte_types[] = {
"char", "__int8", "unsigned __int8", "BYTE",
};
- for (i = 0; i < ARRAY_SIZE(dword_types); i++) {
- if (IS(c_type, dword_types[i])) {
- opr->lmod = OPLM_DWORD;
- return 1;
- }
- }
+ n = skip_type_mod(c_type->name);
- for (i = 0; i < ARRAY_SIZE(ptr_types); i++) {
- if (IS(c_type, ptr_types[i])) {
- opr->lmod = OPLM_DWORD;
- opr->is_ptr = 1;
+ for (i = 0; i < ARRAY_SIZE(dword_types); i++) {
+ if (IS(n, dword_types[i])) {
+ *lmod = OPLM_DWORD;
- else if (opr->lmod == OPLM_UNSPEC)
- guess_lmod_from_c_type(opr, pp.ret_type);
- opr->is_array = pp.is_array;
+ else if (opr->lmod == OPLM_UNSPEC) {
+ if (!guess_lmod_from_c_type(&opr->lmod, &pp.type))
+ anote("unhandled C type '%s' for '%s'\n", pp.type.name, opr->name);
+ }
+ opr->is_ptr = pp.type.is_ptr;
+ opr->is_array = pp.type.is_array;
static void stack_frame_access(struct parsed_op *po,
enum opr_lenmod lmod, char *buf, size_t buf_size,
static void stack_frame_access(struct parsed_op *po,
enum opr_lenmod lmod, char *buf, size_t buf_size,
- const char *name, int is_src, int is_lea)
+ const char *name, const char *cast, int is_src, int is_lea)
- snprintf(buf, buf_size, "%sa%d", is_src ? "(u32)" : "", i + 1);
+ if (cast[0])
+ prefix = cast;
+ else if (is_src)
+ prefix = "(u32)";
+ snprintf(buf, buf_size, "%sa%d", prefix, i + 1);
- if ((offset & 3)
- && (strstr(g_func_pp.arg[i].type, "int8")
- || strstr(g_func_pp.arg[i].type, "int16")))
- {
+ guess_lmod_from_c_type(&tmp_lmod, &g_func_pp.arg[i].type);
+ if ((offset & 3) && tmp_lmod != OPLM_DWORD)
+static void check_label_read_ref(struct parsed_op *po, const char *name)
+{
+ if (IS_START(name, "sub_"))
+ ferr(po, "func reference?\n");
+}
+
- struct parsed_op *po, struct parsed_opr *popr, int is_lea)
+ struct parsed_op *po, struct parsed_opr *popr, const char *cast,
+ int is_lea)
- snprintf(buf, buf_size, "%s", opr_reg_p(po, popr));
+ snprintf(buf, buf_size, "%s%s", cast, opr_reg_p(po, popr));
break;
case OPLM_WORD:
snprintf(buf, buf_size, "(u16)%s", opr_reg_p(po, popr));
break;
case OPLM_WORD:
snprintf(buf, buf_size, "(u16)%s", opr_reg_p(po, popr));
case OPT_REGMEM:
if (parse_stack_el(popr->name, NULL)) {
stack_frame_access(po, popr->lmod, buf, buf_size,
case OPT_REGMEM:
if (parse_stack_el(popr->name, NULL)) {
stack_frame_access(po, popr->lmod, buf, buf_size,
- snprintf(buf, buf_size, "%s(%s)",
- lmod_cast_u_ptr(po, popr->lmod), expr);
+ if (cast[0] == 0)
+ cast = lmod_cast_u_ptr(po, popr->lmod);
+ snprintf(buf, buf_size, "%s(%s)", cast, expr);
if (is_lea)
snprintf(buf, buf_size, "(u32)&%s", popr->name);
else
if (is_lea)
snprintf(buf, buf_size, "(u32)&%s", popr->name);
else
- snprintf(buf, buf_size, "%s%s%s",
- popr->is_ptr ? "(u32)" : "",
- popr->name,
+ snprintf(buf, buf_size, "%s%s%s", cast, popr->name,
- snprintf(buf, buf_size, "(u32)&%s", popr->name);
+ snprintf(buf, buf_size, "%s&%s", cast, popr->name);
- printf_number(buf, buf_size, popr->val);
+ snprintf(buf, buf_size, "%s", cast);
+ ret = strlen(buf);
+ printf_number(buf + ret, buf_size - ret, popr->val);
case OPT_REGMEM:
if (parse_stack_el(popr->name, NULL)) {
stack_frame_access(po, popr->lmod, buf, buf_size,
case OPT_REGMEM:
if (parse_stack_el(popr->name, NULL)) {
stack_frame_access(po, popr->lmod, buf, buf_size,
- return out_src_opr(buf, buf_size, po, popr, 0);
+ return out_src_opr(buf, buf_size, po, popr, NULL, 0);
case OPT_LABEL:
snprintf(buf, buf_size, "%s%s", popr->name,
case OPT_LABEL:
snprintf(buf, buf_size, "%s%s", popr->name,
+static char *out_src_opr_u32(char *buf, size_t buf_size,
+ struct parsed_op *po, struct parsed_opr *popr)
+{
+ return out_src_opr(buf, buf_size, po, popr, NULL, 0);
+}
+
static enum parsed_flag_op split_cond(struct parsed_op *po,
enum op_op op, int *is_inv)
{
static enum parsed_flag_op split_cond(struct parsed_op *po,
enum op_op op, int *is_inv)
{
if (po->op == OP_TEST) {
if (IS(opr_name(po, 0), opr_name(po, 1))) {
if (po->op == OP_TEST) {
if (IS(opr_name(po, 0), opr_name(po, 1))) {
- out_src_opr(buf3, sizeof(buf3), po, &po->operand[0], 0);
+ out_src_opr_u32(buf3, sizeof(buf3), po, &po->operand[0]);
- out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], 0);
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0);
+ out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]);
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]);
snprintf(buf3, sizeof(buf3), "(%s & %s)", buf1, buf2);
}
out_test_for_cc(buf, buf_size, po, pfo, is_inv,
po->operand[0].lmod, buf3);
}
else if (po->op == OP_CMP) {
snprintf(buf3, sizeof(buf3), "(%s & %s)", buf1, buf2);
}
out_test_for_cc(buf, buf_size, po, pfo, is_inv,
po->operand[0].lmod, buf3);
}
else if (po->op == OP_CMP) {
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[0], 0);
- out_src_opr(buf3, sizeof(buf3), po, &po->operand[1], 0);
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[0]);
+ out_src_opr_u32(buf3, sizeof(buf3), po, &po->operand[1]);
out_cmp_for_cc(buf, buf_size, po, pfo, is_inv,
po->operand[0].lmod, buf2, buf3);
}
out_cmp_for_cc(buf, buf_size, po, pfo, is_inv,
po->operand[0].lmod, buf2, buf3);
}
{
struct parsed_op *po, *delayed_flag_op = NULL, *tmp_op;
struct parsed_opr *last_arith_dst = NULL;
{
struct parsed_op *po, *delayed_flag_op = NULL, *tmp_op;
struct parsed_opr *last_arith_dst = NULL;
- fprintf(fout, "%s %s(", g_func_pp.ret_type, funcn);
+ fprintf(fout, "%s %s(", g_func_pp.ret_type.name, funcn);
- fprintf(fout, "%s a%d", g_func_pp.arg[i].type, i + 1);
+ fprintf(fout, "%s a%d", g_func_pp.arg[i].type.name, i + 1);
j /= 4;
if (j > ARRAY_SIZE(pp->arg))
ferr(po, "esp adjust too large?\n");
j /= 4;
if (j > ARRAY_SIZE(pp->arg))
ferr(po, "esp adjust too large?\n");
- fprintf(fout, " %s (*icall%d)(", pp->ret_type, i);
+ fprintf(fout, " %s (*icall%d)(", pp->ret_type.name, i);
- fprintf(fout, "%s a%d", pp->arg[j].type, j + 1);
+ fprintf(fout, "%s a%d", pp->arg[j].type.name, j + 1);
- out_src_opr(buf3, sizeof(buf3), po, last_arith_dst, 0);
+ out_src_opr_u32(buf3, sizeof(buf3), po, last_arith_dst);
out_test_for_cc(buf1, sizeof(buf1), po, pfo, is_inv,
last_arith_dst->lmod, buf3);
is_delayed = 1;
out_test_for_cc(buf1, sizeof(buf1), po, pfo, is_inv,
last_arith_dst->lmod, buf3);
is_delayed = 1;
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
- po->operand[0].is_ptr ? "(void *)" : "",
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0));
+ out_src_opr(buf2, sizeof(buf2), po, &po->operand[1],
+ po->operand[0].is_ptr ? "(void *)" : "", 0));
po->operand[1].lmod = OPLM_DWORD; // always
fprintf(fout, " %s = %s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
po->operand[1].lmod = OPLM_DWORD; // always
fprintf(fout, " %s = %s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 1));
+ out_src_opr(buf2, sizeof(buf2), po, &po->operand[1],
+ NULL, 1));
break;
case OP_MOVZX:
assert_operand_cnt(2);
fprintf(fout, " %s = %s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
break;
case OP_MOVZX:
assert_operand_cnt(2);
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));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]));
fprintf(fout, " %s = %s%s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
buf3,
fprintf(fout, " %s = %s%s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
buf3,
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]));
assert_operand_cnt(2);
fprintf(fout, " %s = (s32)%s >> 31;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
assert_operand_cnt(2);
fprintf(fout, " %s = (s32)%s >> 31;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]));
fprintf(fout, " %s %s= %s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
op_to_c(po),
fprintf(fout, " %s %s= %s;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
op_to_c(po),
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]));
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
fprintf(fout, " %s = %s%s >> %s;", buf1,
lmod_cast_s(po, po->operand[0].lmod), buf1,
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
fprintf(fout, " %s = %s%s >> %s;", buf1,
lmod_cast_s(po, po->operand[0].lmod), buf1,
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]));
fprintf(fout, " %s %s= %s + cond_c;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
op_to_c(po),
fprintf(fout, " %s %s= %s + cond_c;",
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]),
op_to_c(po),
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[1], 0));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[1]));
case OP_NEG:
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
case OP_NEG:
out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[0], 0);
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[0]);
fprintf(fout, " %s = -%s%s;", buf1,
lmod_cast_s(po, po->operand[0].lmod), buf2);
last_arith_dst = &po->operand[0];
fprintf(fout, " %s = -%s%s;", buf1,
lmod_cast_s(po, po->operand[0].lmod), buf2);
last_arith_dst = &po->operand[0];
assert_operand_cnt(1);
strcpy(buf1, po->op == OP_IMUL ? "(s64)(s32)" : "(u64)");
fprintf(fout, " mul_tmp = %seax * %s%s;\n", buf1, buf1,
assert_operand_cnt(1);
strcpy(buf1, po->op == OP_IMUL ? "(s64)(s32)" : "(u64)");
fprintf(fout, " mul_tmp = %seax * %s%s;\n", buf1, buf1,
- out_src_opr(buf2, sizeof(buf2), po, &po->operand[0], 0));
+ out_src_opr_u32(buf2, sizeof(buf2), po, &po->operand[0]));
fprintf(fout, " edx = mul_tmp >> 32;\n");
fprintf(fout, " eax = mul_tmp;");
last_arith_dst = NULL;
fprintf(fout, " edx = mul_tmp >> 32;\n");
fprintf(fout, " eax = mul_tmp;");
last_arith_dst = NULL;
- out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], 0);
+ out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]);
strcpy(buf2, lmod_cast(po, po->operand[0].lmod,
po->op == OP_IDIV));
fprintf(fout, " edx = %seax %% %s%s;\n", buf2, buf2, buf1);
strcpy(buf2, lmod_cast(po, po->operand[0].lmod,
po->op == OP_IDIV));
fprintf(fout, " edx = %seax %% %s%s;\n", buf2, buf2, buf1);
if (po->operand[0].type != OPT_LABEL)
fprintf(fout, " icall%d = (void *)%s;\n", i,
if (po->operand[0].type != OPT_LABEL)
fprintf(fout, " icall%d = (void *)%s;\n", i,
- out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], 0));
+ out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]));
if (po->flags & OPF_TAIL)
fprintf(fout, "return ");
else
fprintf(fout, "eax = ");
if (po->flags & OPF_TAIL)
fprintf(fout, "return ");
else
fprintf(fout, "eax = ");
- if (strchr(pp->arg[arg].type, '*'))
- fprintf(fout, "(%s)", pp->arg[arg].type);
+ cast[0] = 0;
+ if (pp->arg[arg].type.is_ptr)
+ snprintf(cast, sizeof(cast), "(%s)", pp->arg[arg].type.name);
}
}
fprintf(fout, ");");
if (po->flags & OPF_TAIL) {
strcpy(g_comment, "tailcall");
}
}
fprintf(fout, ");");
if (po->flags & OPF_TAIL) {
strcpy(g_comment, "tailcall");
- if (IS(g_func_pp.ret_type, "void"))
- fprintf(fout, " return;");
- else if (strchr(g_func_pp.ret_type, '*'))
+ if (IS(g_func_pp.ret_type.name, "void")) {
+ if (i != opcnt - 1 || label_pending)
+ fprintf(fout, " return;");
+ }
+ else if (g_func_pp.ret_type.is_ptr) {
- out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], 0);
+ out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]);
for (j = 0; j < 32; j++) {
if (po->argmask & (1 << j))
fprintf(fout, " s_a%d = %s;", j + 1, buf1);
for (j = 0; j < 32; j++) {
if (po->argmask & (1 << j))
fprintf(fout, " s_a%d = %s;", j + 1, buf1);
- out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], 0);
+ out_src_opr_u32(buf1, sizeof(buf1), po, &po->operand[0]);
fprintf(fout, " s_%s = %s;", buf1, buf1);
break;
}
fprintf(fout, " s_%s = %s;", buf1, buf1);
break;
}
- out_src_opr(buf1, sizeof(buf1), po, &po->operand[0], 0);
+ out_dst_opr(buf1, sizeof(buf1), po, &po->operand[0]);
fprintf(fout, " %s = s_%s;", buf1, buf1);
break;
}
fprintf(fout, " %s = s_%s;", buf1, buf1);
break;
}