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