X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=disassembler%2Fmain.c;h=8ae804077b7055552788cac7fffd80a346a0b958;hb=2e928c1b94243e38477f113b92d78876a15439be;hp=64e997533f6bc7222dab837dfc77fbf961698602;hpb=b9e19faa25ad9e1b24f08dc77267760df1b98504;p=b43-tools.git diff --git a/disassembler/main.c b/disassembler/main.c index 64e9975..8ae8040 100644 --- a/disassembler/main.c +++ b/disassembler/main.c @@ -13,6 +13,7 @@ #include "list.h" #include "util.h" +#include "args.h" #include #include @@ -64,6 +65,9 @@ struct statement { }; struct disassembler_context { + /* The architecture of the input file. */ + unsigned int arch; + struct bin_instruction *code; size_t nr_insns; @@ -71,7 +75,9 @@ struct disassembler_context { }; -static FILE *infile; +FILE *infile; +FILE *outfile; +const char *infile_name; const char *outfile_name; @@ -635,47 +641,46 @@ static void resolve_labels(struct disassembler_context *ctx) static void emit_asm(struct disassembler_context *ctx) { struct statement *stmt; - FILE *fd; int first, i; + int err; - fd = fopen(outfile_name, "w+"); - if (!fd) { - fprintf(stderr, "Could not open output file \"%s\"\n", - outfile_name); + err = open_output_file(); + if (err) exit(1); - } - fprintf(fd, "%%arch bcm43xx_newworld\n\n"); + + fprintf(outfile, "%%arch %u\n\n", ctx->arch); list_for_each_entry(stmt, &ctx->stmt_list, list) { switch (stmt->type) { case STMT_INSN: - fprintf(fd, "\t%s", stmt->u.insn.name); + fprintf(outfile, "\t%s", stmt->u.insn.name); first = 1; for (i = 0; i < ARRAY_SIZE(stmt->u.insn.operands); i++) { if (stmt->u.insn.is_labelref == i) { - fprintf(fd, ",%s", + fprintf(outfile, ",%s", stmt->u.insn.labelref->u.label.name); } if (!stmt->u.insn.operands[i]) continue; if (first) - fprintf(fd, "\t"); + fprintf(outfile, "\t"); if (!first) - fprintf(fd, ","); + fprintf(outfile, ","); first = 0; - fprintf(fd, "%s", + fprintf(outfile, "%s", stmt->u.insn.operands[i]); } - fprintf(fd, "\n"); + fprintf(outfile, "\n"); break; case STMT_LABEL: - fprintf(fd, "%s:\n", stmt->u.label.name); + fprintf(outfile, "%s:\n", stmt->u.label.name); break; } } - fclose(fd); + + close_output_file(); } -static void read_input(struct disassembler_context *ctx) +static int read_input(struct disassembler_context *ctx) { size_t size = 0, pos = 0; size_t ret; @@ -683,21 +688,24 @@ static void read_input(struct disassembler_context *ctx) unsigned char tmp[sizeof(uint64_t)]; uint64_t codeword; struct fw_header hdr; + int err; + + err = open_input_file(); + if (err) + goto error; ret = fread(&hdr, 1, sizeof(hdr), infile); - if (!ret || ret != sizeof(hdr)) { + if (ret != sizeof(hdr)) { fprintf(stderr, "Corrupt input file (not fwcutter output)\n"); - exit(1); - } - - if (hdr.ver != 1) { - fprintf(stderr, "Invalid fwcutter header version\n"); - exit(1); + goto err_close; } - if (hdr.type != 'u') { - fprintf(stderr, "Not a microcode image\n"); - exit(1); + fprintf(stderr, "Corrupt input file. Not a microcode image.\n"); + goto err_close; + } + if (hdr.ver != 1) { + fprintf(stderr, "Invalid input file header version.\n"); + goto err_close; } while (1) { @@ -710,7 +718,7 @@ static void read_input(struct disassembler_context *ctx) break; if (ret != sizeof(uint64_t)) { fprintf(stderr, "Corrupt input file (not 8 byte aligned)\n"); - exit(1); + goto err_free_code; } codeword = 0; @@ -734,41 +742,50 @@ static void read_input(struct disassembler_context *ctx) ctx->code = code; ctx->nr_insns = pos; + + close_input_file(); + + return 0; + +err_free_code: + free(code); +err_close: + close_input_file(); +error: + return -1; } static void disassemble(void) { struct disassembler_context ctx; + int err; memset(&ctx, 0, sizeof(ctx)); INIT_LIST_HEAD(&ctx.stmt_list); + ctx.arch = cmdargs.arch; - read_input(&ctx); + err = read_input(&ctx); + if (err) + exit(1); disasm_opcodes(&ctx); resolve_labels(&ctx); emit_asm(&ctx); } -static void usage(int argc, char **argv) -{ - fprintf(stderr, "Usage: %s output_file\n", argv[0]); -} - -static void parse_args(int argc, char **argv) -{ - if (argc != 2) { - usage(argc, argv); - exit(1); - } - outfile_name = argv[1]; -} - int main(int argc, char **argv) { - infile = stdin; - parse_args(argc, argv); + int err, res = 1; + + err = parse_args(argc, argv); + if (err < 0) + goto out; + if (err > 0) { + res = 0; + goto out; + } disassemble(); - + res = 0; +out: /* Lazyman simply leaks all allocated memory. */ - return 0; + return res; }