|
|
1.1 ! root 1: /* ! 2: * cdmp.c ! 3: * 8/12/92 ! 4: * Requires libmisc functions: cc cdmp.c -lmisc ! 5: * Read and print COFF files. ! 6: * Usage: cdmp [ -adlrsx ] filename ... ! 7: * Options: ! 8: * -a supress symbol aux entries ! 9: * -d supress data dumps ! 10: * -i dump .text in instr mode ! 11: * -l supress line numbers ! 12: * -r supress relocation entries ! 13: * -s supress symbol entries ! 14: * -x dump aux entries in hex ! 15: * Does not know all there is to know about aux entry structure yet. ! 16: */ ! 17: ! 18: #include <misc.h> /* misc useful stuff */ ! 19: #include <coff.h> ! 20: #include <errno.h> ! 21: ! 22: #define VERSION "V2.0" ! 23: #define VHSZ 48 /* line size in vertical hex dump */ ! 24: typedef char SECNAME[9]; /* NUL-terminated 8 character section name */ ! 25: ! 26: /* Some shortcut display stuff. */ ! 27: #define show(flag, msg) if (fh.f_flags & flag) printf("\t" msg "\n"); ! 28: #define cs(x) case x: printf(#x); break; ! 29: #define cd(x) case x: printf(#x "\tvalue=%ld ", se->n_value); break; ! 30: #define cx(x) case x: printf(#x "\tvalue=0x%lx ", se->n_value); break; ! 31: ! 32: /* Externals. */ ! 33: extern long ftell(); ! 34: extern char *optarg; ! 35: ! 36: /* Forward. */ ! 37: void fatal(); ! 38: char *checkStr(); ! 39: void optHeader(); ! 40: void readHeaders(); ! 41: void shrLib(); ! 42: void readSection(); ! 43: void readStrings(); ! 44: void readSymbols(); ! 45: void print_aux(); ! 46: void print_sym(); ! 47: void dump(); ! 48: int clean(); ! 49: void outc(); ! 50: int hex(); ! 51: ! 52: /* Globals. */ ! 53: char aswitch; /* Suppress aux entry dumps */ ! 54: char buf[VHSZ]; /* Buffer for hex dump */ ! 55: char dswitch; /* Suppress data dumps */ ! 56: char iswitch; /* Dump text in instr mode */ ! 57: FILE *fp; /* COFF file pointer */ ! 58: char lswitch; /* Suppress line number dumps */ ! 59: long num_sections; /* Number of sections */ ! 60: long num_symbols; /* Number of symbols */ ! 61: char rswitch; /* Suppress reloc dumps */ ! 62: SECNAME *sec_name; /* Section names */ ! 63: long section_seek; /* Seek to seek start of section */ ! 64: char sswitch; /* Suppress symbol dumps */ ! 65: char *str_tab; /* String char array */ ! 66: long symptr; /* File pointer to symbol table entries */ ! 67: char xswitch; /* Dump aux entries in hex */ ! 68: ! 69: /* ! 70: * Print fatal error message and die. ! 71: */ ! 72: /* VARARGS */ ! 73: void ! 74: fatal(s) char *s; ! 75: { ! 76: register int save; ! 77: ! 78: save = errno; ! 79: fprintf(stderr, "cdmp: %r\n", &s); ! 80: if (0 != (errno = save)) ! 81: perror("errno reports"); ! 82: exit(1); ! 83: } ! 84: ! 85: /* ! 86: * Return a printable version of string s, ! 87: * massaging nonprintable characters if necessary. ! 88: */ ! 89: char * ! 90: checkStr(s) unsigned char *s; ! 91: { ! 92: register unsigned char *p, c; ! 93: register int ct, badct; ! 94: static char *work = NULL; ! 95: ! 96: for (badct = 0, ct = 1, p = s; c = *p++; ct++) ! 97: if ((c <= ' ') || (c > '~')) ! 98: badct += 2; /* not printable as is */ ! 99: ! 100: if (!badct) ! 101: return s; /* ok as is */ ! 102: ! 103: if (NULL != work) ! 104: free(work); /* free previous */ ! 105: ! 106: work = alloc(badct + ct); ! 107: for (p = work; c = *s++;) { ! 108: if (c > '~') { ! 109: *p++ = '~'; ! 110: c &= 0x7f; ! 111: } ! 112: if (c <= ' ') { ! 113: *p++ = '^'; ! 114: c |= '@'; ! 115: } ! 116: *p++ = c; ! 117: } ! 118: return work; ! 119: } ! 120: ! 121: /* ! 122: * Process optional file header. ! 123: */ ! 124: void ! 125: optHeader() ! 126: { ! 127: AOUTHDR oh; ! 128: ! 129: if (1 != fread(&oh, sizeof(oh), 1, fp)) ! 130: fatal("error reading optional header"); ! 131: ! 132: printf("\nOPTIONAL HEADER VALUES\n"); ! 133: printf("magic = 0x%x\n", oh.magic); ! 134: printf("version stamp = %d\n", oh.vstamp); ! 135: printf("text size = 0x%lx\n", oh.tsize); ! 136: printf("init data size = 0x%lx\n", oh.dsize); ! 137: printf("uninit data size = 0x%lx\n", oh.bsize); ! 138: printf("entry point = 0x%lx\n", oh.entry); ! 139: printf("text start = 0x%lx\n", oh.text_start); ! 140: printf("data start = 0x%lx\n", oh.data_start); ! 141: } ! 142: ! 143: /* ! 144: * Process file header. ! 145: */ ! 146: void ! 147: readHeaders(fn) char *fn; ! 148: { ! 149: FILEHDR fh; ! 150: ! 151: fp = xopen(fn, "rb"); ! 152: ! 153: if (1 != fread(&fh, sizeof(fh), 1, fp)) ! 154: fatal("error reading COFF header"); ! 155: ! 156: printf("FILE %s HEADER VALUES\n", fn); ! 157: printf("magic number = 0x%x\n", fh.f_magic); ! 158: printf("sections = %ld\n", num_sections = fh.f_nscns); ! 159: printf("file date = %s", ctime(&fh.f_timdat)); ! 160: printf("symbol ptr = 0x%lx\n", symptr = fh.f_symptr); ! 161: printf("symbols = %ld\n", num_symbols = fh.f_nsyms); ! 162: printf("sizeof(opthdr) = %d\n", fh.f_opthdr); ! 163: printf("flags = 0x%x\n", fh.f_flags); ! 164: show(F_RELFLG, "Relocation info stripped from file"); ! 165: show(F_EXEC, "File is executable"); ! 166: show(F_LNNO, "Line numbers stripped from file"); ! 167: show(F_LSYMS, "Local symbols stripped from file"); ! 168: show(F_MINMAL, "Minimal object file"); ! 169: ! 170: /* ! 171: * Allocate section name array. ! 172: */ ! 173: if (num_sections != 0) ! 174: sec_name = (SECNAME *)alloc(((int)num_sections) * (sizeof(SECNAME))); ! 175: ! 176: if (fh.f_opthdr) ! 177: optHeader(); /* optional header */ ! 178: section_seek = sizeof(FILEHDR) + fh.f_opthdr; ! 179: } ! 180: ! 181: /* ! 182: * Process shared library. ! 183: */ ! 184: void ! 185: shrLib() ! 186: { ! 187: SHRLIB shr; ! 188: register long i; ! 189: register char *pathn; ! 190: ! 191: if (1 != fread(&shr, sizeof(shr), 1, fp)) ! 192: fatal("error reading library section"); ! 193: ! 194: if (shr.pathndx -= 2) { ! 195: long j; ! 196: printf("\nExtra Library info:\n"); ! 197: ! 198: for (j = shr.pathndx * 4; ! 199: j && (i = fread(buf, 1, ((j > VHSZ) ? VHSZ : (int)j), fp)); ! 200: j -= i) { ! 201: if (!i) ! 202: fatal("unexpected EOF in .lib data"); ! 203: dump(buf, (int)i); ! 204: } ! 205: } ! 206: ! 207: pathn = alloc(i = (shr.entsz - 2) * 4); ! 208: if (1 != fread(pathn, i, 1, fp)) ! 209: fatal("error reading library name"); ! 210: printf("\nReferences %s\n", pathn); ! 211: free(pathn); ! 212: } ! 213: ! 214: /* ! 215: * Process sections. ! 216: */ ! 217: void ! 218: readSection(n) register int n; ! 219: { ! 220: SCNHDR sh; ! 221: register long i; ! 222: ! 223: fseek(fp, section_seek, 0); ! 224: if (1 != fread(&sh, sizeof(SCNHDR), 1, fp)) ! 225: fatal("error reading section header"); ! 226: ! 227: section_seek += sizeof(SCNHDR); ! 228: fseek(fp, sh.s_scnptr, 0); ! 229: ! 230: strncpy(sec_name[n], checkStr(sh.s_name), sizeof(SECNAME) - 1); ! 231: printf("\n%s - SECTION HEADER -\n", sec_name[n]); ! 232: printf("physical address = 0x%lx\n", sh.s_paddr); ! 233: printf("virtual address = 0x%lx\n", sh.s_vaddr); ! 234: printf("section size = 0x%lx\n", sh.s_size); ! 235: printf("file ptr to data = 0x%lx\n", sh.s_scnptr); ! 236: printf("file ptr to relocs = 0x%lx\n", sh.s_relptr); ! 237: printf("file ptr to lines = 0x%lx\n", sh.s_lnnoptr); ! 238: printf("relocation entries = %u\n", sh.s_nreloc); ! 239: printf("line number entries = %u\n", sh.s_nlnno); ! 240: printf("flags = 0x%lx\t", sh.s_flags); ! 241: switch((int)sh.s_flags) { ! 242: ! 243: case STYP_GROUP: ! 244: printf("grouped section"); break; ! 245: ! 246: case STYP_PAD: ! 247: printf("padding section"); break; ! 248: ! 249: case STYP_COPY: ! 250: printf("copy section"); break; ! 251: ! 252: case STYP_INFO: ! 253: printf("comment section"); break; ! 254: ! 255: case STYP_OVER: ! 256: printf("overlay section"); break; ! 257: ! 258: case STYP_LIB: ! 259: printf(".lib section\n"); ! 260: shrLib(); ! 261: return; ! 262: ! 263: case STYP_TEXT: ! 264: printf("text only"); break; ! 265: ! 266: case STYP_DATA: ! 267: printf("data only"); break; ! 268: ! 269: case STYP_BSS: ! 270: printf("bss only"); break; ! 271: ! 272: default: ! 273: printf("unrecognized section"); ! 274: break; ! 275: } ! 276: putchar('\n'); ! 277: ! 278: /* print instructions */ ! 279: if (iswitch && !strcmp(sh.s_name, ".text")) { ! 280: char *code; ! 281: ! 282: code = alloc(sh.s_size); ! 283: fseek(fp, sh.s_scnptr, 0); ! 284: if (1 != fread(code, sh.s_size, 1, fp)) ! 285: fatal("Error reading .text segment"); ! 286: dumpInst(code, sh.s_size); ! 287: } ! 288: /* Print raw data. */ ! 289: else if (!dswitch && strcmp(sh.s_name, ".bss")) { /* don't output bss */ ! 290: register long j; ! 291: ! 292: fseek(fp, sh.s_scnptr, 0); ! 293: printf("\nRAW DATA\n"); ! 294: ! 295: for (j = sh.s_size; ! 296: j && (i = fread(buf, 1, ((j > VHSZ) ? VHSZ : (int)j), fp)); ! 297: j -= i) { ! 298: if (!i) ! 299: fatal("unexpected EOF in %.8s data", ! 300: checkStr(sh.s_name)); ! 301: dump(buf, (int)i); ! 302: } ! 303: } ! 304: ! 305: /* Print relocs. */ ! 306: if (!rswitch && sh.s_nreloc) { ! 307: fseek(fp, sh.s_relptr, 0); ! 308: printf("\nRELOCATION ENTRIES\n"); ! 309: for (i = 0; i < sh.s_nreloc; i++) { ! 310: RELOC re; /* Relocation entry structure */ ! 311: ! 312: if (1 != fread(&re, RELSZ, 1, fp)) ! 313: fatal("error reading relocation entry"); ! 314: ! 315: printf("address=0x%lx\tindex=%ld \ttype=", ! 316: re.r_vaddr, re.r_symndx); ! 317: switch(re.r_type) { ! 318: cs(R_DIR8) ! 319: cs(R_DIR16) ! 320: cs(R_DIR32) ! 321: cs(R_RELBYTE) ! 322: cs(R_RELWORD) ! 323: cs(R_RELLONG) ! 324: cs(R_PCRBYTE) ! 325: cs(R_PCRWORD) ! 326: cs(R_PCRLONG) ! 327: cs(R_NONREL) ! 328: default: ! 329: fatal("unexpected relocation type 0x%x", ! 330: re.r_type); ! 331: break; ! 332: } ! 333: putchar('\n'); ! 334: } ! 335: } ! 336: ! 337: /* Print line numbers. */ ! 338: if (!lswitch && sh.s_nlnno) { ! 339: fseek(fp, sh.s_lnnoptr, 0); ! 340: printf("\nLINE NUMBER ENTRIES\n"); ! 341: ! 342: for (i = 0; i < sh.s_nlnno; i++) { ! 343: LINENO le; /* Line number entry structure */ ! 344: ! 345: if (1 != fread(&le, LINESZ, 1, fp)) ! 346: fatal("error reading line number entry"); ! 347: ! 348: if (le.l_lnno) ! 349: printf("address=0x%lx\tline=%d\n", ! 350: le.l_addr.l_paddr, le.l_lnno); ! 351: else ! 352: printf("function=%d\n", le.l_addr.l_symndx); ! 353: } ! 354: } ! 355: } ! 356: ! 357: /* ! 358: * Read the string table into memory. ! 359: * This allows readSymbols() to work. ! 360: */ ! 361: void ! 362: readStrings() ! 363: { ! 364: register unsigned char *str_ptr, c; ! 365: long str_seek; ! 366: unsigned long str_length; ! 367: unsigned len; ! 368: ! 369: str_seek = symptr + (SYMESZ * num_symbols); ! 370: fseek(fp, str_seek, 0); ! 371: ! 372: if (1 != fread(&str_length, sizeof(str_length), 1, fp)) ! 373: str_length = 0; ! 374: ! 375: if (str_length == 0) { ! 376: printf("\nNO STRING TABLE\n"); ! 377: return; ! 378: } ! 379: printf("\nSTRING TABLE DUMP\n"); ! 380: len = str_length -= 4; ! 381: if (len != str_length) ! 382: fatal("bad string table length %ld", str_length); ! 383: str_tab = alloc(len); ! 384: if (1 != fread(str_tab, len, 1, fp)) ! 385: fatal("error reading string table %lx %d", ftell(fp), len); ! 386: ! 387: for (str_ptr = str_tab; str_ptr < str_tab + str_length; ) { ! 388: putchar('\t'); ! 389: while (c = *str_ptr++) { ! 390: if (c > '~') { ! 391: c &= 0x7f; ! 392: putchar('~'); ! 393: } ! 394: if (c < ' ') { ! 395: c |= '@'; ! 396: putchar('^'); ! 397: } ! 398: putchar(c); ! 399: } ! 400: putchar('\n'); ! 401: } ! 402: } ! 403: ! 404: /* ! 405: * Process symbol table. ! 406: */ ! 407: void ! 408: readSymbols() ! 409: { ! 410: SYMENT se; ! 411: register long i, j, naux; ! 412: ! 413: if (sswitch) ! 414: return; ! 415: fseek(fp, symptr, 0); ! 416: printf("\nSYMBOL TABLE ENTRIES\n"); ! 417: for (i = 0; i < num_symbols; i++) { ! 418: if (1 != fread(&se, SYMESZ, 1, fp)) ! 419: fatal("error reading symbol entry"); ! 420: print_sym(&se, i); ! 421: naux = se.n_numaux; ! 422: for (j = 0; j < naux; j++) ! 423: print_aux(i+j+1, &se); ! 424: i += naux; ! 425: if (i >= num_symbols) ! 426: fatal("inconsistant sym table"); ! 427: } ! 428: } ! 429: ! 430: /* ! 431: * Process a symbol aux entry. ! 432: * This is still pretty ad hoc, it may not do all entries correctly yet. ! 433: * Does not print 0-valued fields. ! 434: */ ! 435: void ! 436: print_aux(n, sep) int n; register SYMENT *sep; ! 437: { ! 438: AUXENT ae; ! 439: register int type, class, i; ! 440: register long l; ! 441: int has_fsize, has_fcn; ! 442: unsigned short *sp; ! 443: char fname[FILNMLEN + 1]; ! 444: ! 445: if (1 != fread(&ae, AUXESZ, 1, fp)) ! 446: fatal("error reading symbol aux entry"); ! 447: if (aswitch) ! 448: return; /* suppressed */ ! 449: printf("%4ld\t", n); /* symbol number */ ! 450: if (xswitch) { /* dump in hex */ ! 451: printf("\tAUX ENTRY DUMP\n"); ! 452: dump(&ae, sizeof(ae)); ! 453: return; ! 454: } ! 455: ! 456: class = sep->n_sclass; ! 457: type = sep->n_type; ! 458: ! 459: if (class == C_FILE) { /* .file */ ! 460: strncpy(fname, ae.ae_fname, FILNMLEN); ! 461: fname[FILNMLEN] = '\0'; ! 462: printf("\tfilename=%s\n", checkStr(fname)); ! 463: return; ! 464: } else if (class == C_STAT && type == T_NULL) { /* section name */ ! 465: printf("\tlength=%lx\trelocs=%d\tlinenos=%d\n", ! 466: ae.ae_scnlen, ! 467: ae.ae_nreloc, ! 468: ae.ae_nlinno); ! 469: return; ! 470: } ! 471: ! 472: /* ! 473: * In cases not handled above, ! 474: * the AUXENT is an x_sym which must be decyphered. ! 475: * Flags tell which members of unions to dump. ! 476: * The flag setting might not be quite right yet. ! 477: */ ! 478: has_fsize = has_fcn = 0; ! 479: if (class == C_STRTAG || class == C_UNTAG || class == C_ENTAG ! 480: || class == C_BLOCK) /* tag definitions or .bb or .eb */ ! 481: ++has_fcn; ! 482: if (ISFCN(type)) { ! 483: ++has_fsize; ! 484: ++has_fcn; ! 485: } ! 486: ! 487: /* Print tag index. */ ! 488: if (l = ae.ae_tagndx) ! 489: printf("\ttag=%ld", l); ! 490: ! 491: /* Print fsize or lnsz info. */ ! 492: if (has_fsize) { ! 493: if (l = ae.ae_fsize) ! 494: printf("\tfsize=%ld", l); ! 495: } else { ! 496: if (i = ae.ae_lnno) ! 497: printf("\tlnno=%d", i); ! 498: if (i = ae.ae_size) ! 499: printf("\tsize=%d", i); ! 500: } ! 501: ! 502: /* Print fcn or ary info. */ ! 503: if (has_fcn) { ! 504: if (l = ae.ae_lnnoptr) ! 505: printf("\tlnnoptr=0x%lx", l); ! 506: if (l = ae.ae_endndx) ! 507: printf("\tend=%ld", l); ! 508: } else { ! 509: sp = ae.ae_dimen; ! 510: if (*sp != 0) { ! 511: printf("\tdims=< "); ! 512: while (sp < &ae.ae_dimen[DIMNUM] && *sp) ! 513: printf("%d ", *sp++); ! 514: putchar('>'); ! 515: } ! 516: } ! 517: ! 518: /* Print tv index. */ ! 519: if (l = ae.ae_tvndx) ! 520: printf("\ttv=%ld", l); ! 521: ! 522: putchar('\n'); ! 523: } ! 524: ! 525: /* ! 526: * Process symbol table entry. ! 527: */ ! 528: void ! 529: print_sym(se, n) register SYMENT *se; long n; ! 530: { ! 531: register int i, c; ! 532: int eflag, derived; ! 533: ! 534: if (se->n_sclass == C_FILE && n > 0) ! 535: putchar('\n'); /* for readability */ ! 536: printf("%4ld ", n); /* index number */ ! 537: ! 538: eflag = 0; /* no errors */ ! 539: if (se->n_zeroes != 0) { /* name in place */ ! 540: for (i = 0; i < SYMNMLEN; i++) { ! 541: if ((' ' < (c = se->n_name[i])) && ('~' >= c)) ! 542: putchar(c); ! 543: else { ! 544: eflag = c; ! 545: break; ! 546: } ! 547: } ! 548: putchar('\t'); ! 549: } else /* name in string table */ ! 550: printf("%s ", checkStr(str_tab + se->n_offset - 4)); ! 551: ! 552: /* Print section. */ ! 553: i = se->n_scnum; ! 554: printf("section="); ! 555: if (i >= 1 && i <= num_sections) ! 556: printf("%s", sec_name[i-1]); ! 557: else ! 558: switch(i) { ! 559: cs(N_UNDEF) ! 560: cs(N_ABS) ! 561: cs(N_DEBUG) ! 562: default: ! 563: printf("%d?", i); ! 564: break; ! 565: } ! 566: ! 567: /* Print the type. */ ! 568: printf("\ttype="); ! 569: i = se->n_type; ! 570: derived = 0; ! 571: while (i & N_TMASK) { /* derived type */ ! 572: if (derived == 0) { ! 573: derived = 1; ! 574: putchar('<'); ! 575: } ! 576: switch(i & N_TMASK) { ! 577: cs(DT_PTR) ! 578: cs(DT_FCN) ! 579: cs(DT_ARY) ! 580: case DT_NON: ! 581: default: ! 582: fatal("unexpected derived type 0x%x", i & N_TMASK); ! 583: } ! 584: putchar(' '); ! 585: i >>= N_TSHIFT; ! 586: } ! 587: switch (c = (se->n_type & N_BTMASK)) { /* base type */ ! 588: ! 589: case T_NULL: ! 590: printf("none"); ! 591: break; ! 592: ! 593: cs(T_CHAR) ! 594: cs(T_SHORT) ! 595: cs(T_INT) ! 596: cs(T_LONG) ! 597: cs(T_FLOAT) ! 598: cs(T_DOUBLE) ! 599: cs(T_STRUCT) ! 600: cs(T_UNION) ! 601: cs(T_ENUM) ! 602: cs(T_MOE) ! 603: cs(T_UCHAR) ! 604: cs(T_USHORT) ! 605: cs(T_UINT) ! 606: cs(T_ULONG) ! 607: ! 608: case T_ARG: /* What has base type (not storage class) ARG? */ ! 609: default: ! 610: fatal("unexpected base type 0x%x", c); ! 611: ! 612: } ! 613: if (derived) ! 614: putchar('>'); ! 615: ! 616: /* Print the storage class. */ ! 617: printf("\tclass="); ! 618: switch (i = se->n_sclass) { ! 619: ! 620: cd(C_EFCN) ! 621: cd(C_NULL) ! 622: cd(C_AUTO) ! 623: cx(C_STAT) ! 624: cd(C_REG) ! 625: cd(C_EXTDEF) ! 626: cd(C_LABEL) ! 627: cd(C_ULABEL) ! 628: cd(C_MOS) ! 629: cd(C_ARG) ! 630: cd(C_STRTAG) ! 631: cd(C_MOU) ! 632: cd(C_UNTAG) ! 633: cd(C_TPDEF) ! 634: cd(C_ENTAG) ! 635: cd(C_MOE) ! 636: cd(C_REGPARM) ! 637: cd(C_FIELD) ! 638: cd(C_BLOCK) ! 639: cd(C_FCN) ! 640: cd(C_EOS) ! 641: cd(C_FILE) ! 642: ! 643: case C_EXT: ! 644: if (se->n_scnum != N_UNDEF) ! 645: printf("C_EXT\tvalue=0x%lx", se->n_value); ! 646: else if (se->n_value != 0) ! 647: printf("Common\tlength=%ld", se->n_value); ! 648: else ! 649: printf("External"); ! 650: break; ! 651: ! 652: case C_USTATIC: /* What is an undefined static? */ ! 653: fatal("unexpected storage class 0x%x", i); ! 654: ! 655: default: ! 656: printf("0x%x", i); ! 657: ! 658: } ! 659: ! 660: #if 0 ! 661: if (se->n_numaux) ! 662: printf("\tnaux=%d", se->n_numaux); ! 663: #endif ! 664: putchar('\n'); ! 665: ! 666: if (eflag) { ! 667: printf("*** Bad data in name **\n"); ! 668: dump(se, SYMESZ); ! 669: } ! 670: } ! 671: ! 672: /* ! 673: * Vertical hex dump of p bytes from buffer buf. ! 674: */ ! 675: void ! 676: dump(buf, p) register char *buf; register int p; ! 677: { ! 678: register int i; ! 679: ! 680: /* Offset. */ ! 681: printf ("\n%6lx\t", ftell(fp) - p); ! 682: ! 683: /* Printable version of character. */ ! 684: for (i = 0; i < p; i++ ) ! 685: outc(clean(buf[i]), i, ' '); ! 686: printf("\n\t"); ! 687: ! 688: /* High hex digit. */ ! 689: for (i = 0; i < p; i++) ! 690: outc(hex((buf[i] >> 4) & 0x0f), i, '.'); ! 691: printf("\n\t"); ! 692: ! 693: /* Low hex digit. */ ! 694: for (i = 0; i < p; i++) ! 695: outc(hex(buf[i]& 0x0f), i, '.'); ! 696: putchar('\n'); ! 697: } ! 698: ! 699: /* ! 700: * Return c if printable, '.' if not. ! 701: */ ! 702: int ! 703: clean(c) register int c; ! 704: { ! 705: return (c >= ' ' && c <= '~' ) ? c : '.'; ! 706: } ! 707: ! 708: /* ! 709: * Print c, preceded by s every 4 times. ! 710: */ ! 711: void ! 712: outc(c, i, s) register int i, c, s; ! 713: { ! 714: if ((i&3) == 0 && i != 0 ) ! 715: putchar(s); ! 716: putchar(c); ! 717: } ! 718: ! 719: /* ! 720: * Convert hex digit c to corresponding ASCII character. ! 721: */ ! 722: int ! 723: hex(c) register int c; ! 724: { ! 725: return ( c <= 9 ) ? c + '0' : c + 'A' - 10; ! 726: } ! 727: ! 728: /* ! 729: * Mainline. ! 730: */ ! 731: main(argc, argv) int argc; char *argv[]; ! 732: { ! 733: register int i, c; ! 734: ! 735: while (EOF != (c = getargs(argc, argv, "adlrsxV?"))) { ! 736: switch (c) { ! 737: ! 738: case 0: ! 739: /* Process a COFF file. */ ! 740: readHeaders(optarg); ! 741: for (i = 0; i < num_sections; i++) ! 742: readSection(i); ! 743: if (num_symbols) { ! 744: readStrings(); ! 745: readSymbols(); ! 746: } ! 747: /* Cleanup. */ ! 748: if (sec_name != NULL) { ! 749: free(sec_name); ! 750: sec_name = NULL; ! 751: } ! 752: if (str_tab != NULL) { ! 753: free(str_tab); ! 754: str_tab = NULL; ! 755: } ! 756: fclose(fp); ! 757: break; ! 758: ! 759: case 'a': aswitch++; break; ! 760: case 'd': dswitch++; break; ! 761: case 'i': iswitch++; break; ! 762: case 'l': lswitch++; break; ! 763: case 'r': rswitch++; break; ! 764: case 's': sswitch++; break; ! 765: case 'x': xswitch++; break; ! 766: ! 767: case 'V': ! 768: fprintf(stderr, "cdmp: %s\n", VERSION); ! 769: break; ! 770: ! 771: case '?': ! 772: default: ! 773: fprintf(stderr, ! 774: "Usage: cdmp [ -adlrsx ] filename ...\n" ! 775: "Options:\n" ! 776: "\t-a\tsupress symbol aux entries\n" ! 777: "\t-d\tsupress data dumps\n" ! 778: "\t-l\tsupress line numbers\n" ! 779: "\t-r\tsupress relocation entries\n" ! 780: "\t-s\tsupress symbol entries\n" ! 781: "\t-x\tdump aux entries in hex\n"); ! 782: exit(1); ! 783: break; ! 784: } ! 785: } ! 786: exit(0); ! 787: } ! 788: ! 789: /* end of cdmp.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.