|
|
1.1 ! root 1: /* ! 2: ** print symbol tables for ! 3: ** object or archive files ! 4: ** ! 5: ** nm [-goprun] [name ...] ! 6: */ ! 7: ! 8: ! 9: ! 10: #include <ar.h> ! 11: #include <stdio.h> ! 12: #include <ctype.h> ! 13: #include <a.out.h> ! 14: #include <pagsiz.h> ! 15: ! 16: #define MAGIC exp.a_magic ! 17: #define BADMAG MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2 \ ! 18: && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4 && MAGIC != 0412 && MAGIC != 0413 ! 19: #define SELECT arch_flg ? arp.ar_name : *argv ! 20: int numsort_flg; ! 21: int undef_flg; ! 22: int revsort_flg = 1; ! 23: int globl_flg; ! 24: int nosort_flg; ! 25: int arch_flg; ! 26: int prep_flg; ! 27: struct ar_hdr arp; ! 28: struct exec exp; ! 29: FILE *fi; ! 30: long off; ! 31: long ftell(); ! 32: char *malloc(); ! 33: char *realloc(); ! 34: ! 35: main(argc, argv) ! 36: char **argv; ! 37: { ! 38: int narg; ! 39: int compare(); ! 40: ! 41: if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) { ! 42: argv++; ! 43: while (*++*argv) switch (**argv) { ! 44: case 'n': /* sort numerically */ ! 45: numsort_flg++; ! 46: continue; ! 47: ! 48: case 'g': /* globl symbols only */ ! 49: globl_flg++; ! 50: continue; ! 51: ! 52: case 'u': /* undefined symbols only */ ! 53: undef_flg++; ! 54: continue; ! 55: ! 56: case 'r': /* sort in reverse order */ ! 57: revsort_flg = -1; ! 58: continue; ! 59: ! 60: case 'p': /* don't sort -- symbol table order */ ! 61: nosort_flg++; ! 62: continue; ! 63: ! 64: case 'o': /* prepend a name to each line */ ! 65: prep_flg++; ! 66: continue; ! 67: ! 68: default: /* oops */ ! 69: fprintf(stderr, "nm: invalid argument -%c\n", *argv[0]); ! 70: exit(1); ! 71: } ! 72: argc--; ! 73: } ! 74: if (argc == 0) { ! 75: argc = 1; ! 76: argv[1] = "a.out"; ! 77: } ! 78: narg = argc; ! 79: while(argc--) { ! 80: fi = fopen(*++argv,"r"); ! 81: if (fi == NULL) { ! 82: fprintf(stderr, "nm: cannot open %s\n", *argv); ! 83: continue; ! 84: } ! 85: off = sizeof(exp.a_magic); ! 86: fread((char *)&exp, 1, sizeof(MAGIC), fi); /* get magic no. */ ! 87: if (MAGIC == ARMAG) ! 88: arch_flg++; ! 89: else if (BADMAG) { ! 90: fprintf(stderr, "nm: %s-- bad format\n", *argv); ! 91: continue; ! 92: } ! 93: fseek(fi, 0L, 0); ! 94: if (arch_flg) { ! 95: nextel(fi); ! 96: if (narg > 1) ! 97: printf("\n%s:\n", *argv); ! 98: } ! 99: do { ! 100: long o; ! 101: register i, n, c; ! 102: struct nlist *symp = NULL; ! 103: struct nlist sym; ! 104: ! 105: fread((char *)&exp, 1, sizeof(struct exec), fi); ! 106: if (BADMAG) /* archive element not in */ ! 107: continue; /* proper format - skip it */ ! 108: o = (long)exp.a_text + exp.a_data + exp.a_trsize + exp.a_drsize; ! 109: if (MAGIC==0412 || MAGIC==0413) ! 110: o += PAGSIZ - sizeof(struct exec); ! 111: fseek(fi, o, 1); ! 112: n = exp.a_syms / sizeof(struct nlist); ! 113: if (n == 0) { ! 114: fprintf(stderr, "nm: %s-- no name list\n", SELECT); ! 115: continue; ! 116: } ! 117: i = 0; ! 118: while (--n >= 0) { ! 119: fread((char *)&sym, 1, sizeof(sym), fi); ! 120: if (globl_flg && (sym.n_type&N_EXT)==0) ! 121: continue; ! 122: if (symp==NULL) ! 123: symp = (struct nlist *)malloc(sizeof(struct nlist)); ! 124: else { ! 125: symp = (struct nlist *)realloc(symp, (i+1)*sizeof(struct nlist)); ! 126: } ! 127: if (symp == NULL) { ! 128: fprintf(stderr, "nm: out of memory on %s\n", *argv); ! 129: exit(2); ! 130: } ! 131: symp[i++] = sym; ! 132: } ! 133: if (nosort_flg==0) ! 134: qsort(symp, i, sizeof(struct nlist), compare); ! 135: if ((arch_flg || narg>1) && prep_flg==0) ! 136: printf("\n%s:\n", SELECT); ! 137: for (n=0; n<i; n++) { ! 138: if (prep_flg) { ! 139: if (arch_flg) ! 140: printf("%s:", *argv); ! 141: printf("%s:", SELECT); ! 142: } ! 143: c = symp[n].n_type; ! 144: ! 145: if (c & STABTYPE) { ! 146: printf("%08x - %-8.8s %02x %02x %04x\n", ! 147: symp[n].n_value, ! 148: symp[n].n_name, ! 149: symp[n].n_type & 0xff, ! 150: symp[n].n_other & 0xff, ! 151: symp[n].n_desc & 0xffff); ! 152: continue; ! 153: } ! 154: switch (c&(N_TYPE-N_EXT)) { ! 155: ! 156: case N_UNDF: ! 157: c = 'u'; ! 158: if (symp[n].n_value) ! 159: c = 'c'; ! 160: break; ! 161: ! 162: case N_ABS: ! 163: c = 'a'; ! 164: break; ! 165: ! 166: case N_TEXT: ! 167: c = 't'; ! 168: break; ! 169: ! 170: case N_DATA: ! 171: c = 'd'; ! 172: break; ! 173: ! 174: case N_BSS: ! 175: c = 'b'; ! 176: break; ! 177: ! 178: case N_FN: ! 179: c = 'f'; ! 180: break; ! 181: ! 182: /* ! 183: case N_REG: ! 184: c = 'r'; ! 185: break; ! 186: */ ! 187: } ! 188: if (undef_flg && c!='u') ! 189: continue; ! 190: if (symp[n].n_type&N_EXT) ! 191: c = toupper(c); ! 192: if (!undef_flg) { ! 193: if (c=='u' || c=='U') ! 194: printf(" "); ! 195: else ! 196: printf(FORMAT, symp[n].n_value); ! 197: printf(" %c ", c); ! 198: } ! 199: printf("%.8s\n", symp[n].n_name); ! 200: l1:; } ! 201: if (symp) ! 202: free((char *)symp); ! 203: } while(arch_flg && nextel(fi)); ! 204: fclose(fi); ! 205: } ! 206: exit(0); ! 207: } ! 208: ! 209: compare(p1, p2) ! 210: struct nlist *p1, *p2; ! 211: { ! 212: register i; ! 213: ! 214: if (numsort_flg) { ! 215: if (p1->n_value > p2->n_value) ! 216: return(revsort_flg); ! 217: if (p1->n_value < p2->n_value) ! 218: return(-revsort_flg); ! 219: } ! 220: for(i=0; i<sizeof(p1->n_name); i++) ! 221: if (p1->n_name[i] != p2->n_name[i]) { ! 222: if (p1->n_name[i] > p2->n_name[i]) ! 223: return(revsort_flg); ! 224: else ! 225: return(-revsort_flg); ! 226: } ! 227: return(0); ! 228: } ! 229: ! 230: nextel(af) ! 231: FILE *af; ! 232: { ! 233: register r; ! 234: ! 235: fseek(af, off, 0); ! 236: r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af); /* read archive header */ ! 237: if (r <= 0) ! 238: return(0); ! 239: if (arp.ar_size & 1) ! 240: ++arp.ar_size; ! 241: off = ftell(af) + arp.ar_size; /* offset to next element */ ! 242: return(1); ! 243: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.