1 #ifndef lint 2 static char sccsid[] = "@(#)nm.c 4.2 05/22/83"; 3 #endif 4 /* 5 * nm - print name list; VAX string table version 6 */ 7 #include <sys/types.h> 8 #include <ar.h> 9 #include <stdio.h> 10 #include <ctype.h> 11 #include <a.out.h> 12 #include <stab.h> 13 #include <stat.h> 14 15 #define SELECT archive ? archdr.ar_name : *xargv 16 17 int aflg, gflg, nflg, oflg, pflg, uflg; 18 int rflg = 1; 19 char **xargv; 20 int archive; 21 struct ar_hdr archdr; 22 union { 23 char mag_armag[SARMAG+1]; 24 struct exec mag_exp; 25 } mag_un; 26 #define OARMAG 0177545 27 FILE *fi; 28 off_t off; 29 off_t ftell(); 30 char *malloc(); 31 char *realloc(); 32 char *strp; 33 char *stab(); 34 off_t strsiz; 35 int compare(); 36 int narg; 37 int errs; 38 39 main(argc, argv) 40 char **argv; 41 { 42 43 if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) { 44 argv++; 45 while (*++*argv) switch (**argv) { 46 47 case 'n': 48 nflg++; 49 continue; 50 case 'g': 51 gflg++; 52 continue; 53 case 'u': 54 uflg++; 55 continue; 56 case 'r': 57 rflg = -1; 58 continue; 59 case 'p': 60 pflg++; 61 continue; 62 case 'o': 63 oflg++; 64 continue; 65 case 'a': 66 aflg++; 67 continue; 68 default: 69 fprintf(stderr, "nm: invalid argument -%c\n", 70 *argv[0]); 71 exit(2); 72 } 73 argc--; 74 } 75 if (argc == 0) { 76 argc = 1; 77 argv[1] = "a.out"; 78 } 79 narg = argc; 80 xargv = argv; 81 while (argc--) { 82 ++xargv; 83 namelist(); 84 } 85 exit(errs); 86 } 87 88 namelist() 89 { 90 register int j; 91 92 archive = 0; 93 fi = fopen(*xargv, "r"); 94 if (fi == NULL) { 95 error(0, "cannot open"); 96 return; 97 } 98 off = SARMAG; 99 fread((char *)&mag_un, 1, sizeof(mag_un), fi); 100 if (mag_un.mag_exp.a_magic == OARMAG) { 101 error(0, "old archive"); 102 return; 103 } 104 if (strncmp(mag_un.mag_armag, ARMAG, SARMAG)==0) 105 archive++; 106 else if (N_BADMAG(mag_un.mag_exp)) { 107 error(0, "bad format"); 108 return; 109 } 110 fseek(fi, 0L, 0); 111 if (archive) { 112 nextel(fi); 113 if (narg > 1) 114 printf("\n%s:\n", *xargv); 115 } 116 do { 117 off_t o; 118 register i, n, c; 119 struct nlist *symp = NULL; 120 struct nlist sym; 121 struct stat stb; 122 123 fread((char *)&mag_un.mag_exp, 1, sizeof(struct exec), fi); 124 if (N_BADMAG(mag_un.mag_exp)) 125 continue; 126 if (archive == 0) 127 fstat(fileno(fi), &stb); 128 o = N_SYMOFF(mag_un.mag_exp) - sizeof (struct exec); 129 fseek(fi, o, 1); 130 n = mag_un.mag_exp.a_syms / sizeof(struct nlist); 131 if (n == 0) { 132 error(0, "no name list"); 133 continue; 134 } 135 if (N_STROFF(mag_un.mag_exp) + sizeof (off_t) > 136 (archive ? off : stb.st_size)) 137 error(1, "old format .o (no string table) or truncated file"); 138 i = 0; 139 if (strp) 140 free(strp), strp = 0; 141 while (--n >= 0) { 142 fread((char *)&sym, 1, sizeof(sym), fi); 143 if (gflg && (sym.n_type&N_EXT)==0) 144 continue; 145 if ((sym.n_type&N_STAB) && (!aflg||gflg||uflg)) 146 continue; 147 if (symp==NULL) 148 symp = (struct nlist *) 149 malloc(sizeof(struct nlist)); 150 else 151 symp = (struct nlist *) 152 realloc(symp, 153 (i+1)*sizeof(struct nlist)); 154 if (symp == NULL) 155 error(1, "out of memory"); 156 symp[i++] = sym; 157 } 158 if (archive && ftell(fi)+sizeof(off_t) >= off) { 159 error(0, "no string table (old format .o?)"); 160 continue; 161 } 162 if (fread((char *)&strsiz,sizeof(strsiz),1,fi) != 1) { 163 error(0, "no string table (old format .o?)"); 164 goto out; 165 } 166 strp = (char *)malloc(strsiz); 167 if (strp == NULL) 168 error(1, "ran out of memory"); 169 if (fread(strp+sizeof(strsiz),strsiz-sizeof(strsiz),1,fi) != 1) 170 error(1, "error reading string table"); 171 for (j = 0; j < i; j++) 172 if (symp[j].n_un.n_strx) 173 symp[j].n_un.n_name = 174 symp[j].n_un.n_strx + strp; 175 else 176 symp[j].n_un.n_name = ""; 177 if (pflg==0) 178 qsort(symp, i, sizeof(struct nlist), compare); 179 if ((archive || narg>1) && oflg==0) 180 printf("\n%s:\n", SELECT); 181 psyms(symp, i); 182 if (symp) 183 free((char *)symp), symp = 0; 184 if (strp) 185 free((char *)strp), strp = 0; 186 } while(archive && nextel(fi)); 187 out: 188 fclose(fi); 189 } 190 191 psyms(symp, nsyms) 192 register struct nlist *symp; 193 int nsyms; 194 { 195 register int n, c; 196 197 for (n=0; n<nsyms; n++) { 198 c = symp[n].n_type; 199 if (c & N_STAB) { 200 if (oflg) { 201 if (archive) 202 printf("%s:", *xargv); 203 printf("%s:", SELECT); 204 } 205 printf("%08x - %02x %04x %5.5s %s\n", 206 symp[n].n_value, 207 symp[n].n_other & 0xff, symp[n].n_desc & 0xffff, 208 stab(symp[n].n_type & 0xff), 209 symp[n].n_un.n_name); 210 continue; 211 } 212 switch (c&N_TYPE) { 213 214 case N_UNDF: 215 c = 'u'; 216 if (symp[n].n_value) 217 c = 'c'; 218 break; 219 case N_ABS: 220 c = 'a'; 221 break; 222 case N_TEXT: 223 c = 't'; 224 break; 225 case N_DATA: 226 c = 'd'; 227 break; 228 case N_BSS: 229 c = 'b'; 230 break; 231 case N_FN: 232 c = 'f'; 233 break; 234 } 235 if (uflg && c!='u') 236 continue; 237 if (oflg) { 238 if (archive) 239 printf("%s:", *xargv); 240 printf("%s:", SELECT); 241 } 242 if (symp[n].n_type&N_EXT) 243 c = toupper(c); 244 if (!uflg) { 245 if (c=='u' || c=='U') 246 printf(" "); 247 else 248 printf(N_FORMAT, symp[n].n_value); 249 printf(" %c ", c); 250 } 251 printf("%s\n", symp[n].n_un.n_name); 252 l1: ; 253 } 254 } 255 256 compare(p1, p2) 257 struct nlist *p1, *p2; 258 { 259 register i; 260 261 if (nflg) { 262 if (p1->n_value > p2->n_value) 263 return(rflg); 264 if (p1->n_value < p2->n_value) 265 return(-rflg); 266 } 267 return (rflg * strcmp(p1->n_un.n_name, p2->n_un.n_name)); 268 } 269 270 nextel(af) 271 FILE *af; 272 { 273 register char *cp; 274 register r; 275 long arsize; 276 277 fseek(af, off, 0); 278 r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); 279 if (r != sizeof(struct ar_hdr)) 280 return(0); 281 for (cp = archdr.ar_name; cp < &archdr.ar_name[sizeof(archdr.ar_name)]; cp++) 282 if (*cp == ' ') 283 *cp = '\0'; 284 arsize = atol(archdr.ar_size); 285 if (arsize & 1) 286 ++arsize; 287 off = ftell(af) + arsize; /* beginning of next element */ 288 return(1); 289 } 290 291 error(n, s) 292 char *s; 293 { 294 fprintf(stderr, "nm: %s:", *xargv); 295 if (archive) { 296 fprintf(stderr, "(%s)", archdr.ar_name); 297 fprintf(stderr, ": "); 298 } else 299 fprintf(stderr, " "); 300 fprintf(stderr, "%s\n", s); 301 if (n) 302 exit(2); 303 errs = 1; 304 } 305 306 struct stabnames { 307 int st_value; 308 char *st_name; 309 } stabnames[] ={ 310 N_GSYM, "GSYM", 311 N_FNAME, "FNAME", 312 N_FUN, "FUN", 313 N_STSYM, "STSYM", 314 N_LCSYM, "LCSYM", 315 N_RSYM, "RSYM", 316 N_SLINE, "SLINE", 317 N_SSYM, "SSYM", 318 N_SO, "SO", 319 N_LSYM, "LSYM", 320 N_SOL, "SOL", 321 N_PSYM, "PSYM", 322 N_ENTRY, "ENTRY", 323 N_LBRAC, "LBRAC", 324 N_RBRAC, "RBRAC", 325 N_BCOMM, "BCOMM", 326 N_ECOMM, "ECOMM", 327 N_ECOML, "ECOML", 328 N_LENG, "LENG", 329 N_PC, "PC", 330 0, 0 331 }; 332 333 char * 334 stab(val) 335 { 336 register struct stabnames *sp; 337 static char prbuf[32]; 338 339 for (sp = stabnames; sp->st_name; sp++) 340 if (sp->st_value == val) 341 return (sp->st_name); 342 sprintf(prbuf, "%02x", val); 343 return (prbuf); 344 } 345