diff options
Diffstat (limited to 'xexamine.c')
-rw-r--r-- | xexamine.c | 59 |
1 files changed, 39 insertions, 20 deletions
@@ -42,8 +42,7 @@ void crc32(const void *data, size_t n_bytes, uint32_t* crc) { } void usage(int status) { - printf("Usage: " SELF " [-v] [-s segment] file.xex\n"); - if(status) fprintf(stderr, "Try '%s -h' for help\n", SELF); + printf("Usage: " SELF " [-h] [-d] [-v] [-s segment] file.xex\n"); exit(status); } @@ -310,11 +309,14 @@ int main(int argc, char **argv) { xex_segment seg; unsigned char buffer[65536]; char *filename; - int opt, segcount = 0, only_segment = 0, header_printed = 0; + int opt, offset, segcount = 0, only_segment = 0, header_printed = 0, decimal = 0; uint32_t crc; - while((opt = getopt(argc, argv, "vhs:")) != -1) { + while((opt = getopt(argc, argv, "vhs:d")) != -1) { switch(opt) { + case 'd': + decimal = 1; + break; case 's': if( (only_segment = get_address(SELF, optarg)) < 0 ) exit(1); @@ -335,7 +337,13 @@ int main(int argc, char **argv) { } } - if(optind >= argc || argv[optind + 1]) { + if(argv[optind + 1]) { + fprintf(stderr, SELF ": don't know what to do with excess argument '%s'.\n", argv[optind + 1]); + usage(1); + } + + if(optind >= argc) { + fprintf(stderr, SELF ": no xex file argument.\n"); usage(1); } @@ -348,25 +356,36 @@ int main(int argc, char **argv) { seg.object = buffer; + offset = 0; while(xex_fread_seg(&seg, f)) { segcount++; - if(only_segment && (only_segment != segcount)) - continue; - if(!header_printed) { - printf("Seg | Start | End | Bytes | CRC32 | Type\n"); - header_printed++; - } + crc = 0; crc32(seg.object, seg.len, &crc); - printf("%3d | $%04x | $%04x | %5d | %08x | ", - segcount, seg.start_addr, seg.end_addr, seg.len, crc); - if(seg.start_addr == XEX_RUNAD && seg.len > 1) - printf("Run $%04x", (seg.object[0] | (seg.object[1] << 8))); - else if(seg.start_addr == XEX_INITAD && seg.len > 1) - printf("Init $%04x", (seg.object[0] | (seg.object[1] << 8))); - else printf("%d%% code", classify_seg(seg)); - - putchar('\n'); + + if(!only_segment || (only_segment == segcount)) { + if(!header_printed) { + printf("Seg | Offset | Start | End | Bytes | CRC32 | Type\n"); + header_printed++; + } + + printf((decimal ? + "%3d | %6d | %5d | %5d | %5d | %08x | " : + "%3d | %6d | $%04x | $%04x | %5d | %08x | "), + segcount, offset, seg.start_addr, seg.end_addr, seg.len, crc); + + /* TODO: what if there's a >=4 byte segment that loads at RUNAD? + the next 2 bytes are INITAD, we would silently ignore that fact. */ + if(seg.start_addr == XEX_RUNAD && seg.len > 1) + printf((decimal ? "Run %5d" : "Run $%04x"), (seg.object[0] | (seg.object[1] << 8))); + else if(seg.start_addr == XEX_INITAD && seg.len > 1) + printf((decimal ? "Init %5d" : "Run $%04x"), (seg.object[0] | (seg.object[1] << 8))); + else printf("%d%% code", classify_seg(seg)); + + putchar('\n'); + } + + offset = ftell(f); } if(only_segment && (segcount < only_segment)) { |