return !nosave;
}
-static void out_toasm_x86(FILE *f, char *sym, const struct parsed_proto *pp)
+static void out_toasm_x86(FILE *f, const char *sym_in,
+ const char *sym_out, const struct parsed_proto *pp)
{
int must_save = 0;
int sarg_ofs = 1; // stack offset to args, in DWORDs
must_save |= is_x86_reg_saved(pp->arg[i].reg);
}
- fprintf(f, ".global _%s\n", sym);
- fprintf(f, "_%s:\n", sym);
+ fprintf(f, ".global _%s\n", sym_in);
+ fprintf(f, "_%s:\n", sym_in);
- if (pp->argc_reg == 0 && !pp->is_stdcall) {
- fprintf(f, "\tjmp %s\n\n", sym);
+ if (pp->argc_reg == 0) {
+ fprintf(f, "\tjmp %s\n\n", sym_out);
return;
}
fprintf(f, "\tmovl %d(%%esp), %%%s\n",
(i + sarg_ofs) * 4, pp->arg[i].reg);
}
- fprintf(f, "\tjmp %s\n\n", sym);
+ fprintf(f, "\tjmp %s\n\n", sym_out);
return;
}
}
fprintf(f, "\n\t# %s\n", pp->is_stdcall ? "__stdcall" : "__cdecl");
- fprintf(f, "\tcall %s\n\n", sym);
+ fprintf(f, "\tcall %s\n\n", sym_out);
if (args_repushed && !pp->is_stdcall)
fprintf(f, "\tadd $%d,%%esp\n", args_repushed * 4);
fprintf(f, "\tret\n\n");
}
-static void out_fromasm_x86(FILE *f, char *sym, const struct parsed_proto *pp)
+static void out_fromasm_x86(FILE *f, const char *sym,
+ const struct parsed_proto *pp)
{
int sarg_ofs = 1; // stack offset to args, in DWORDs
int argc_repush;
fprintf(f, ".global %s\n", sym);
fprintf(f, "%s:\n", sym);
- if (pp->argc_reg == 0 && !pp->is_stdcall) {
- fprintf(f, "\tjmp _%s\n\n", sym);
+ if (pp->argc_reg == 0) {
+ //fprintf(f, "\tjmp _%s\n\n", sym);
+ fprintf(f, "\tjmp _%s", sym);
+ if (pp->is_stdcall && pp->argc > 0)
+ fprintf(f, "@%d", pp->argc * 4);
+ fprintf(f, "\n\n");
return;
}
FILE *fout, *fsyms_to, *fsyms_from, *fhdr;
const struct parsed_proto *pp;
char line[256];
+ char sym_noat[256];
char sym[256];
- int ret;
+ char *p;
+ int ret = 1;
if (argc != 5) {
printf("usage:\n%s <bridge.s> <toasm_symf> <fromasm_symf> <hdrf>\n",
if (sym[0] == 0 || sym[0] == ';' || sym[0] == '#')
continue;
- pp = proto_parse(fhdr, sym);
+ // IDA asm doesn't do '@' notation..
+ strcpy(sym_noat, sym);
+ p = strchr(sym_noat, '@');
+ if (p != NULL)
+ *p = 0;
+
+ pp = proto_parse(fhdr, sym_noat);
if (pp == NULL)
goto out;
- out_toasm_x86(fout, sym, pp);
+ out_toasm_x86(fout, sym, sym_noat, pp);
}
fprintf(fout, "# from asm\n\n");
ferr(ops, "proto_parse failed for '%s'\n", funcn);
fprintf(fout, "%s ", g_func_pp->ret_type.name);
+ if (g_func_pp->is_stdcall && g_func_pp->argc_reg == 0)
+ fprintf(fout, "__stdcall ");
if (g_ida_func_attr & IDAFA_NORETURN)
fprintf(fout, "noreturn ");
fprintf(fout, "%s(", funcn);
+
for (i = 0; i < g_func_pp->argc; i++) {
if (i > 0)
fprintf(fout, ", ");
- fprintf(fout, "%s a%d", g_func_pp->arg[i].type.name, i + 1);
+ if (g_func_pp->arg[i].fptr != NULL) {
+ // func pointer..
+ pp = g_func_pp->arg[i].fptr;
+ fprintf(fout, "%s (", pp->ret_type.name);
+ if (pp->is_stdcall && pp->argc_reg == 0)
+ fprintf(fout, "__stdcall ");
+ 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);
+ }
+ fprintf(fout, ")");
+ }
+ 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");
// pass1: