|
|
1.1 ! root 1: /* ! 2: * List a coff symbol table. ! 3: */ ! 4: #include <misc.h> ! 5: #include <canon.h> ! 6: #include <l.out.h> ! 7: #include <ar.h> ! 8: #include <errno.h> ! 9: ! 10: FILE *fd; /* Current input file */ ! 11: ! 12: int asw; /* list all symbols */ ! 13: int dsw; /* list only defined symbols */ ! 14: int gsw; /* print only global symbols */ ! 15: int nsw; /* list numerically not alphabetically */ ! 16: int osw; /* append file name to each line */ ! 17: int psw; /* print symbols in symbol table order */ ! 18: int rsw; /* print in reverse alpha order */ ! 19: int usw; /* print only undefined symbols */ ! 20: int vsw; /* print coff type symbols */ ! 21: ! 22: int namesw; /* one if header is required */ ! 23: char *str_tab; ! 24: char *fname; ! 25: ! 26: /* ! 27: * read or have an error. ! 28: */ ! 29: static void ! 30: xread(to, size, msg) ! 31: char *to; ! 32: unsigned size; ! 33: char *msg; ! 34: { ! 35: if (1 != fread(to, size, 1, fd)) ! 36: fatal("Error reading %s - %s", fname, msg); ! 37: } ! 38: ! 39: /* ! 40: * Old form sort logic. ! 41: */ ! 42: ncomp_old(s1, s2) ! 43: struct nlist *s1, *s2; ! 44: { ! 45: long i; ! 46: ! 47: if (!(i = (s1->n_value - s2->n_value))) ! 48: return (0); ! 49: if (i < 0) ! 50: return (-1); ! 51: return (1); ! 52: } ! 53: ! 54: acomp_old(s1, s2) ! 55: struct nlist *s1, *s2; ! 56: { ! 57: return(strncmp(s1->n_name, s2->n_name, NCPLN)); ! 58: } ! 59: ! 60: rcomp_old(s1, s2) ! 61: struct nlist *s1, *s2; ! 62: { ! 63: return(strncmp(s2->n_name, s1->n_name, NCPLN)); ! 64: } ! 65: ! 66: /* ! 67: * Process old ar files. ! 68: */ ! 69: old_ar(filen, at) ! 70: char *filen; ! 71: long at; ! 72: { ! 73: long arhend; ! 74: struct old_ar_hdr arh; ! 75: ! 76: namesw = 0; ! 77: for (arhend = at + sizeof(short); ; ) { ! 78: fseek(fd, arhend, 0); ! 79: if (1 != fread(&arh, sizeof(arh), 1, fd)) ! 80: break; ! 81: arhend += sizeof(arh); ! 82: arh.ar_date = 0; /* terminate name */ ! 83: cansize(arh.ar_size); ! 84: if (strcmp(arh.ar_name, HDRNAME)) { ! 85: printf("%s(%s)\n", filen, arh.ar_name); ! 86: readHeaders(arhend, arh.ar_size); ! 87: } ! 88: arhend += arh.ar_size; ! 89: } ! 90: namesw = 1; ! 91: } ! 92: ! 93: /* ! 94: * Process old form stuff. ! 95: */ ! 96: old_nout(at) ! 97: long at; ! 98: { ! 99: struct ldheader ldh; ! 100: struct ldsym *sym, *s; ! 101: register unsigned i, syms, ct; ! 102: long toSym; ! 103: short type; ! 104: extern char *realloc(); ! 105: ! 106: fseek(fd, at, 0); ! 107: xread(&ldh, sizeof(ldh), "n.out header"); ! 108: if (!ldh.l_ssize[L_SYM]) { ! 109: printf("No symbols in %s\n", fname); ! 110: return; ! 111: } ! 112: ! 113: if (namesw) ! 114: printf("%s:\n", fname); ! 115: ! 116: canshort(ldh.l_machine); ! 117: toSym = ldh.l_entry + sizeof(ldh); ! 118: ! 119: for (i = 0; i < L_SYM; i++) { ! 120: cansize(ldh.l_ssize[i]); ! 121: if (i != L_BSSI && i != L_BSSD) ! 122: toSym += ldh.l_ssize[i]; ! 123: } ! 124: ! 125: fseek(fd, at + toSym, 0); ! 126: cansize(ldh.l_ssize[L_SYM]); ! 127: i = ldh.l_ssize[L_SYM]; ! 128: if (i != ldh.l_ssize[L_SYM]) ! 129: fatal("Out of space"); ! 130: sym = alloc(i); ! 131: xread(sym, i, "symbol table"); ! 132: ct = i / sizeof(*sym); ! 133: ! 134: /* squeeze out unneeded stuff before sort */ ! 135: for (i = syms = 0; i < ct; i++) { ! 136: canshort(sym[i].ls_type); ! 137: canshort(sym[i].ls_addr); ! 138: type = sym[i].ls_type; ! 139: if (gsw && !(type & L_GLOBAL)) ! 140: continue; ! 141: if ((type & ~L_GLOBAL) == L_REF) { /* a reference */ ! 142: if (dsw) /* list only defined */ ! 143: continue; ! 144: if (usw && sym[i].ls_addr) ! 145: continue; ! 146: } ! 147: else if (usw) ! 148: continue; ! 149: if (!asw && !csymbol(sym + i)) ! 150: continue; ! 151: if (i != syms) ! 152: sym[syms] = sym[i]; ! 153: syms++; ! 154: } ! 155: sym = realloc(sym, syms * sizeof(*sym)); ! 156: ! 157: if (nsw) ! 158: qsort(sym, syms, sizeof(*sym), ncomp_old); ! 159: else if (rsw) ! 160: qsort(sym, syms, sizeof(*sym), rcomp_old); ! 161: else if (!psw) ! 162: qsort(sym, syms, sizeof(*sym), acomp_old); ! 163: ! 164: for (s = sym; s < (sym + syms); s++) { ! 165: static char *gn[] = { ! 166: "SI", "PI", "BI", ! 167: "SD", "PD", "BD", ! 168: " D", " ", " ", ! 169: " A", " C", "??" ! 170: }; ! 171: static char *ln[] = { ! 172: "si", "pi", "bi", ! 173: "sd", "pd", "bd", ! 174: " d", " ", " ", ! 175: " a", " c", "??" ! 176: }; ! 177: if (osw) ! 178: printf("%s ", fname); ! 179: i = s->ls_type & L_GLOBAL; ! 180: type = s->ls_type & ~ L_GLOBAL; ! 181: if (type < L_SHRI || type > L_REF) ! 182: type = L_REF + 1; ! 183: if (type == L_REF && !s->ls_addr) ! 184: printf(" %c", i ? 'U' : 'u'); ! 185: else ! 186: printf("%04x %s", ! 187: s->ls_addr, ! 188: i ? gn[type] : ln[type]); ! 189: printf(" %.*s\n", NCPLN, s->ls_id); ! 190: } ! 191: ! 192: free(sym); ! 193: } ! 194: ! 195: /* ! 196: * This routine gets called if we ! 197: * are not in '-a' mode. It determines if ! 198: * the symbol pointed to by 'sp' is a C ! 199: * style symbol (trailing '_' or longer than ! 200: * (NCPLN-1) characters). If it is it eats the '_' ! 201: * and returns true. ! 202: */ ! 203: csymbol(sp) ! 204: register struct ldsym *sp; ! 205: { ! 206: register char *cp1, *cp2; ! 207: ! 208: cp1 = &sp->ls_id[0]; ! 209: cp2 = &sp->ls_id[NCPLN]; ! 210: while (cp2!=cp1 && *--cp2==0) ! 211: ; ! 212: if (*cp2 != 0) { ! 213: if (*cp2 == '_') { ! 214: *cp2 = 0; ! 215: return (1); ! 216: } ! 217: if (cp2-cp1 >= (NCPLN-1)) ! 218: return (1); ! 219: } ! 220: return (0); ! 221: } ! 222: ! 223: /* ! 224: * Note some #defines in these include files interferes with ! 225: * items in preceeding include files. Hence the strange ! 226: * program order. ! 227: */ ! 228: #include <coff.h> ! 229: #include <arcoff.h> ! 230: ! 231: #define cx(x) case C_ ## x: printf("%6.6s ", #x); break ! 232: #define ct(x) case T_ ## x: printf("%6.6s ", #x); break ! 233: ! 234: static char helpmsg[] = ! 235: "-d list only defined symbols\n" ! 236: "-g print only global symbols\n" ! 237: "-n list numerically not alphabetically\n" ! 238: "-o append file name to each line\n" ! 239: "-p print symbols in symbol table order\n" ! 240: "-r print in reverse alpha order\n" ! 241: "-u print only undefined symbols\n" ! 242: "-v print coff type symbols\n"; ! 243: ! 244: FILEHDR fh; ! 245: SCNHDR *scns; ! 246: ! 247: /* ! 248: * Symbol name. ! 249: */ ! 250: static char * ! 251: symName(sym, work) ! 252: SYMENT *sym; ! 253: char *work; ! 254: { ! 255: if (!sym->n_zeroes) ! 256: return (str_tab + sym->n_offset - 4); ! 257: ! 258: /* make sure it's zero terminated */ ! 259: memcpy(work, sym->n_name, SYMNMLEN); ! 260: work[SYMNMLEN] = '\0'; ! 261: return (work); ! 262: } ! 263: ! 264: main(argc, argv) ! 265: char *argv[]; ! 266: { ! 267: char c; ! 268: extern int optind; ! 269: extern char *optarg; ! 270: ! 271: while (EOF != (c = getopt(argc, argv, "adgnopruv?"))) { ! 272: switch (c) { ! 273: case '?': ! 274: printf(helpmsg); ! 275: break; ! 276: case 'a': ! 277: asw = 1; ! 278: break; ! 279: case 'd': ! 280: dsw = 1; ! 281: break; ! 282: case 'g': ! 283: gsw = 1; ! 284: break; ! 285: case 'n': ! 286: nsw = 1; ! 287: break; ! 288: case 'o': ! 289: osw = 1; ! 290: break; ! 291: case 'p': ! 292: psw = 1; ! 293: break; ! 294: case 'r': ! 295: rsw = 1; ! 296: break; ! 297: case 'u': ! 298: usw = 1; ! 299: break; ! 300: case 'v': ! 301: vsw = 1; ! 302: break; ! 303: default: ! 304: printf("usage: nm [-dgnopruv?] file ...\n"); ! 305: exit(1); ! 306: } ! 307: } ! 308: ! 309: if ((psw + rsw + nsw) > 1) ! 310: fatal("More than one sort order"); ! 311: ! 312: namesw = (argc - optind) > 1; ! 313: for (; optind < argc; optind++) { ! 314: fd = xopen(fname = argv[optind], "rb"); ! 315: ! 316: printf("%s\n", fname); ! 317: readHeaders(0L, 0L); ! 318: fclose(fd); ! 319: } ! 320: ! 321: exit (0); ! 322: } ! 323: ! 324: static ! 325: readHeaders(at, size) ! 326: long at, size; ! 327: { ! 328: unsigned i; ! 329: ! 330: if (1 != fread(&fh, sizeof(fh), 1, fd)) { ! 331: if (ferror(fd)) ! 332: fatal("Error reading %s", fname); ! 333: printf("Inappropriate filetype %s\n", fname); ! 334: return (0); ! 335: } ! 336: if (C_386_MAGIC != fh.f_magic) { ! 337: if (!memcmp(ARMAG, &fh, SARMAG)) ! 338: return(archive(at)); ! 339: ! 340: canshort(fh.f_magic); ! 341: if (fh.f_magic == OLD_ARMAG) ! 342: return (old_ar(fname, at)); ! 343: if (fh.f_magic == L_MAGIC) ! 344: return (old_nout(at)); ! 345: printf("Inappropriate filetype %s\n", fname); ! 346: return (0); ! 347: } ! 348: if (fh.f_opthdr) /* pass opt hdr */ ! 349: fseek(fd, at + sizeof(fh) + fh.f_opthdr, 0); ! 350: scns = alloc(i = (fh.f_nscns * sizeof(SCNHDR))); ! 351: xread(scns, i, "section headers"); ! 352: ! 353: if (fh.f_nsyms) ! 354: readSymbols(at, size); ! 355: else ! 356: printf("No symbols in %s\n", fname); ! 357: ! 358: } ! 359: ! 360: /* ! 361: * Sort by alpha. ! 362: */ ! 363: acomp(s1, s2) ! 364: SYMENT *s1, *s2; ! 365: { ! 366: char w1[SYMNMLEN + 1], w2[SYMNMLEN + 1]; ! 367: ! 368: return (strcmp(symName(s1, w1), symName(s2, w2))); ! 369: } ! 370: ! 371: /* ! 372: * Sort by reverse alpha. ! 373: */ ! 374: rcomp(s1, s2) ! 375: SYMENT *s1, *s2; ! 376: { ! 377: char w1[SYMNMLEN + 1], w2[SYMNMLEN + 1]; ! 378: ! 379: return (- strcmp(symName(s1, w1), symName(s2, w2))); ! 380: } ! 381: ! 382: /* ! 383: * Sort by value; ! 384: */ ! 385: ncomp(s1, s2) ! 386: SYMENT *s1, *s2; ! 387: { ! 388: long i; ! 389: ! 390: if (!(i = (s1->n_value - s2->n_value))) ! 391: return (0); ! 392: if (i < 0) ! 393: return (-1); ! 394: return (1); ! 395: } ! 396: ! 397: static ! 398: readSymbols(at, size) ! 399: long at; ! 400: { ! 401: register SYMENT *s; ! 402: SYMENT *sym; ! 403: long str_len; ! 404: unsigned len; ! 405: int i, aux, syms; ! 406: extern char *realloc(); ! 407: ! 408: /* read whole symbol table */ ! 409: fseek(fd, at + fh.f_symptr, 0); ! 410: len = str_len = SYMESZ * fh.f_nsyms; ! 411: if (str_len != len) ! 412: fatal("Cannot process small model"); ! 413: sym = alloc(len); ! 414: xread(sym, len, "symbol table"); ! 415: ! 416: /* squeeze out unneeded stuff before sort */ ! 417: for (i = aux = syms = 0; i < fh.f_nsyms; i++) { ! 418: if (aux) { ! 419: aux--; ! 420: continue; ! 421: } ! 422: s = sym + i; ! 423: aux = s->n_numaux; ! 424: switch (s->n_sclass) { ! 425: case C_EXT: ! 426: if (s->n_scnum || s->n_value) { /* defined */ ! 427: if (usw) /* print only undefined */ ! 428: continue; ! 429: } else { /* undefined */ ! 430: if (dsw) /* print only defined */ ! 431: continue; ! 432: } ! 433: break; ! 434: case C_EXTDEF: ! 435: if (dsw) ! 436: continue; ! 437: break; ! 438: case C_STAT: ! 439: if (gsw || usw) ! 440: continue; ! 441: switch (s->n_scnum) { ! 442: case 1: ! 443: if (!strcmp(s->n_name, ".text")) ! 444: continue; ! 445: break; ! 446: case 2: ! 447: if (!strcmp(s->n_name, ".data")) ! 448: continue; ! 449: break; ! 450: case 3: ! 451: if (!strcmp(s->n_name, ".bss")) ! 452: continue; ! 453: break; ! 454: } ! 455: break; ! 456: default: ! 457: if (!vsw) ! 458: continue; ! 459: } ! 460: if (i != syms) ! 461: sym[syms] = *s; ! 462: syms++; ! 463: } ! 464: sym = realloc(sym, syms * SYMESZ); ! 465: ! 466: str_len = 0; ! 467: if (!size || ((fh.f_symptr + len + sizeof(long)) < size)) ! 468: if (1 != fread(&str_len, sizeof(str_len), 1, fd)) ! 469: str_len = 0; ! 470: if (str_len) { ! 471: len = str_len -= 4; ! 472: if (len != str_len) ! 473: fatal("Cannot process small model"); ! 474: str_tab = alloc(len); ! 475: xread(str_tab, len, "string table"); ! 476: } ! 477: ! 478: if (nsw) ! 479: qsort(sym, syms, SYMESZ, ncomp); ! 480: else if (rsw) ! 481: qsort(sym, syms, SYMESZ, rcomp); ! 482: else if (!psw) ! 483: qsort(sym, syms, SYMESZ, acomp); ! 484: ! 485: for (s = sym; s < (sym + syms); s++) { ! 486: char w1[SYMNMLEN + 1], *n; ! 487: ! 488: i = strlen(n = symName(s, w1)); ! 489: ! 490: if (osw) ! 491: printf("%s ", fname); ! 492: ! 493: /* display section name */ ! 494: switch (s->n_scnum) { ! 495: case N_DEBUG: ! 496: printf("DEBUG "); ! 497: break; ! 498: case N_ABS: ! 499: printf("ABSOLUTE "); ! 500: break; ! 501: case N_TV: ! 502: printf("TV "); ! 503: break; ! 504: case N_UNDEF: ! 505: if (s->n_value) ! 506: printf(".comm "); ! 507: else ! 508: printf("UNDEF "); ! 509: break; ! 510: default: ! 511: printf("%-8.8s ", scns[s->n_scnum - 1].s_name); ! 512: } ! 513: ! 514: if (vsw) { /* print coff type data */ ! 515: /* display storage class */ ! 516: switch (s->n_sclass) { ! 517: cx(EFCN); ! 518: cx(NULL); ! 519: cx(AUTO); ! 520: cx(EXT); ! 521: cx(STAT); ! 522: cx(REG); ! 523: cx(EXTDEF); ! 524: cx(LABEL); ! 525: cx(ULABEL); ! 526: cx(MOS); ! 527: cx(ARG); ! 528: cx(STRTAG); ! 529: cx(MOU); ! 530: cx(UNTAG); ! 531: cx(TPDEF); ! 532: cx(USTATIC); ! 533: cx(ENTAG); ! 534: cx(MOE); ! 535: cx(REGPARM); ! 536: cx(FIELD); ! 537: cx(BLOCK); ! 538: cx(FCN); ! 539: cx(EOS); ! 540: cx(FILE); ! 541: default: ! 542: printf("unknown "); ! 543: } ! 544: ! 545: if (s->n_type & N_TMASK) { ! 546: if (ISPTR(s->n_type)) ! 547: printf("pointer "); ! 548: else if (ISFCN(s->n_type)) ! 549: printf("function "); ! 550: else if (ISARY(s->n_type)) ! 551: printf("array "); ! 552: else if (ISTAG(s->n_type)) ! 553: printf("struct "); ! 554: else if (INCREF(s->n_type)) ! 555: printf("union "); ! 556: else if (DECREF(s->n_type)) ! 557: printf("enum "); ! 558: } ! 559: else ! 560: printf("- "); ! 561: ! 562: /* display type */ ! 563: switch (BTYPE(s->n_type)) { ! 564: ct(NULL); ! 565: ct(ARG); ! 566: ct(CHAR); ! 567: ct(SHORT); ! 568: ct(INT); ! 569: ct(LONG); ! 570: ct(FLOAT); ! 571: ct(DOUBLE); ! 572: ct(STRUCT); ! 573: ct(UNION); ! 574: ct(ENUM); ! 575: ct(MOE); ! 576: ct(UCHAR); ! 577: ct(USHORT); ! 578: ct(UINT); ! 579: ct(ULONG); ! 580: default: ! 581: printf("unknown "); ! 582: } ! 583: } ! 584: ! 585: printf("%08lX %s\n", s->n_value, n); ! 586: } ! 587: free(sym); ! 588: } ! 589: ! 590: /* ! 591: * Print members of archive. ! 592: */ ! 593: archive(at) ! 594: long at; ! 595: { ! 596: long arhend; ! 597: struct ar_hdr coff_arh; ! 598: struct old_ar_hdr arh; ! 599: char *p; ! 600: extern char *strchr(); ! 601: ! 602: namesw = 0; ! 603: for (arhend = at + SARMAG; ; ) { ! 604: fseek(fd, arhend, 0); ! 605: if (1 != fread(&coff_arh, sizeof(coff_arh), 1, fd)) ! 606: break; ! 607: memset(&arh, '\0', sizeof(arh)); ! 608: memcpy(arh.ar_name, coff_arh.ar_name, DIRSIZ); ! 609: if (NULL != (p = strchr(arh.ar_name, '/'))) ! 610: *p = '\0'; ! 611: ! 612: sscanf(coff_arh.ar_date, "%ld %d %d %o %ld", ! 613: &arh.ar_date, &arh.ar_uid, ! 614: &arh.ar_gid, &arh.ar_mode, &arh.ar_size); ! 615: ! 616: arhend += sizeof(coff_arh); ! 617: if (arh.ar_name[0]) { ! 618: printf("%s(%s)\n", fname, arh.ar_name); ! 619: readHeaders(arhend, arh.ar_size); ! 620: } ! 621: arhend += arh.ar_size; ! 622: if (arhend & 1) ! 623: arhend++; ! 624: } ! 625: namesw = 1; ! 626: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.