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