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