1: #if !defined(lint) && !defined(DOSCCS)
   2: static  char sccsid[] = "@(#)nm.c 2.11BSD 1/22/94";
   3: #endif
   4: /*
   5:  * nm - print name list. string table version
   6:  */
   7: #include <sys/types.h>
   8: #include <sys/dir.h>
   9: #include <ar.h>
  10: #include <stdio.h>
  11: #include <ctype.h>
  12: #include <a.out.h>
  13: #include <sys/file.h>
  14: #include "archive.h"
  15: #include <string.h>
  16: 
  17:     CHDR    chdr;
  18: 
  19: #define SELECT  archive ? chdr.name : *xargv
  20: 
  21:     char    aflg, gflg, nflg, oflg, pflg, uflg, rflg = 1, archive;
  22:     char    **xargv;
  23:     char    *strp;
  24:     union {
  25:         char    mag_armag[SARMAG+1];
  26:         struct  xexec mag_exp;
  27:     } mag_un;
  28: 
  29:     off_t   off, skip();
  30: extern  off_t   ftell();
  31: extern  char    *malloc();
  32: extern  long    strtol();
  33:     int compare(), narg, errs;
  34: 
  35: main(argc, argv)
  36:     int argc;
  37:     char    **argv;
  38: {
  39: 
  40:     if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) {
  41:         argv++;
  42:         while (*++*argv) switch (**argv) {
  43: 
  44:         case 'n':
  45:             nflg++;
  46:             continue;
  47:         case 'g':
  48:             gflg++;
  49:             continue;
  50:         case 'u':
  51:             uflg++;
  52:             continue;
  53:         case 'r':
  54:             rflg = -1;
  55:             continue;
  56:         case 'p':
  57:             pflg++;
  58:             continue;
  59:         case 'o':
  60:             oflg++;
  61:             continue;
  62:         case 'a':
  63:             aflg++;
  64:             continue;
  65:         default:
  66:             fprintf(stderr, "nm: invalid argument -%c\n",
  67:                 *argv[0]);
  68:             exit(2);
  69:         }
  70:         argc--;
  71:     }
  72:     if (argc == 0) {
  73:         argc = 1;
  74:         argv[1] = "a.out";
  75:     }
  76:     narg = argc;
  77:     xargv = argv;
  78:     while (argc--) {
  79:         ++xargv;
  80:         namelist();
  81:     }
  82:     exit(errs);
  83: }
  84: 
  85: namelist()
  86: {
  87:     char    ibuf[BUFSIZ];
  88:     register FILE   *fi;
  89: 
  90:     archive = 0;
  91:     fi = fopen(*xargv, "r");
  92:     if (fi == NULL) {
  93:         error(0, "cannot open");
  94:         return;
  95:     }
  96:     setbuf(fi, ibuf);
  97: 
  98:     off = 0;
  99:     fread((char *)&mag_un, 1, sizeof(mag_un), fi);
 100:     if (strncmp(mag_un.mag_armag, ARMAG, SARMAG)==0) {
 101:         archive++;
 102:         off = SARMAG;
 103:     }
 104:     else if (N_BADMAG(mag_un.mag_exp.e)) {
 105:         error(0, "bad format");
 106:         goto out;
 107:     }
 108:     rewind(fi);
 109: 
 110:     if (archive) {
 111:         nextel(fi);
 112:         if (narg > 1)
 113:             printf("\n%s:\n", *xargv);
 114:     }
 115:     do {
 116:         off_t   o, curpos, stroff;
 117:         long    strsiz;
 118:         register i, n;
 119:         struct nlist *symp = NULL;
 120:         struct  nlist sym;
 121: 
 122:         curpos = ftell(fi);
 123:         fread((char *)&mag_un.mag_exp, 1, sizeof(struct xexec), fi);
 124:         if (N_BADMAG(mag_un.mag_exp.e))
 125:             continue;
 126: 
 127:         o = N_SYMOFF(mag_un.mag_exp);
 128:         fseek(fi, curpos + o, L_SET);
 129:         n = mag_un.mag_exp.e.a_syms / sizeof(struct nlist);
 130:         if (n == 0) {
 131:             error(0, "no name list");
 132:             continue;
 133:         }
 134: 
 135:         i = 0;
 136:         if (strp)
 137:             free(strp), strp = 0;
 138:         while (--n >= 0) {
 139:             fread((char *)&sym, 1, sizeof(sym), fi);
 140:             if (sym.n_un.n_strx == 0)
 141:                 continue;
 142:             if (gflg && (sym.n_type & N_EXT) == 0)
 143:                 continue;
 144:             if (uflg && (sym.n_type & N_TYPE) == N_UNDF && sym.n_value)
 145:                 continue;
 146:             i++;
 147:         }
 148: 
 149:         fseek(fi, curpos + o, L_SET);
 150:         symp = (struct nlist *)malloc(i * sizeof (struct nlist));
 151:         if (symp == 0)
 152:             error(1, "out of memory");
 153:         i = 0;
 154:         n = mag_un.mag_exp.e.a_syms / sizeof(struct nlist);
 155:         while (--n >= 0) {
 156:             fread((char *)&sym, 1, sizeof(sym), fi);
 157:             if (sym.n_un.n_strx == 0)
 158:                 continue;
 159:             if (gflg && (sym.n_type & N_EXT) == 0)
 160:                 continue;
 161:             if (uflg && (sym.n_type & N_TYPE) == N_UNDF && sym.n_value)
 162:                 continue;
 163:             symp[i++] = sym;
 164:         }
 165:         stroff = curpos + N_STROFF(mag_un.mag_exp);
 166:         fseek(fi, stroff, L_SET);
 167:         if (fread(&strsiz, sizeof (long), 1, fi) != 1)
 168:             error(1, "no string table");
 169:         strp = (char *)malloc((int)strsiz);
 170:         if (strp == NULL || strsiz > 48 * 1024L)
 171:             error(1, "ran out of memory");
 172:         if (fread(strp+sizeof(strsiz),(int)strsiz-sizeof(strsiz),1,fi) != 1)
 173:             error(1, "error reading strings");
 174:         for (n = 0; n < i; n++)
 175:             symp[n].n_un.n_name = strp + (int)symp[n].n_un.n_strx;
 176: 
 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 = NULL;
 184:         if (strp)
 185:             free((char *)strp), strp = NULL;
 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_FN)
 200:             c = 'f';
 201:         else switch (c&N_TYPE) {
 202: 
 203:         case N_UNDF:
 204:             c = 'u';
 205:             if (symp[n].n_value)
 206:                 c = 'c';
 207:             break;
 208:         case N_ABS:
 209:             c = 'a';
 210:             break;
 211:         case N_TEXT:
 212:             c = 't';
 213:             break;
 214:         case N_DATA:
 215:             c = 'd';
 216:             break;
 217:         case N_BSS:
 218:             c = 'b';
 219:             break;
 220:         case N_REG:
 221:             c = 'r';
 222:             break;
 223:         default:
 224:             c = '?';
 225:             break;
 226:         }
 227:         if (uflg && c!='u')
 228:             continue;
 229:         if (oflg) {
 230:             if (archive)
 231:                 printf("%s:", *xargv);
 232:             printf("%s:", SELECT);
 233:         }
 234:         if (symp[n].n_type&N_EXT)
 235:             c = toupper(c);
 236:         if (!uflg) {
 237:             if (c=='u' || c=='U')
 238:                 printf("      ");
 239:             else
 240:                 printf(N_FORMAT, symp[n].n_value);
 241:             printf(" %c ", c);
 242:         }
 243:         if (symp[n].n_ovly)
 244:             printf("%s %d\n", symp[n].n_un.n_name,
 245:                 symp[n].n_ovly & 0xff);
 246:         else
 247:             printf("%s\n", symp[n].n_un.n_name);
 248:     }
 249: }
 250: 
 251: compare(p1, p2)
 252: register struct nlist *p1, *p2;
 253: {
 254: 
 255:     if (nflg) {
 256:         if (p1->n_value > p2->n_value)
 257:             return(rflg);
 258:         if (p1->n_value < p2->n_value)
 259:             return(-rflg);
 260:     }
 261:     return (rflg * strcmp(p1->n_un.n_name, p2->n_un.n_name));
 262: }
 263: 
 264: nextel(af)
 265: FILE *af;
 266: {
 267: 
 268:     fseek(af, off, L_SET);
 269:     if (get_arobj(af) < 0)
 270:         return(0);
 271:     off += (sizeof (struct ar_hdr) + chdr.size +
 272:         (chdr.size + chdr.lname & 1));
 273:     return(1);
 274: }
 275: 
 276: error(n, s)
 277: char *s;
 278: {
 279:     fprintf(stderr, "nm: %s:", *xargv);
 280:     if (archive) {
 281:         fprintf(stderr, "(%s)", chdr.name);
 282:         fprintf(stderr, ": ");
 283:     } else
 284:         fprintf(stderr, " ");
 285:     fprintf(stderr, "%s\n", s);
 286:     if (n)
 287:         exit(2);
 288:     errs = 1;
 289: }
 290: 
 291: /*
 292:  * "borrowed" from 'ar' because we didn't want to drag in everything else
 293:  * from 'ar'.  The error checking was also ripped out, basically if any
 294:  * of the criteria for being an archive are not met then a -1 is returned
 295:  * and the rest of 'ld' figures out what to do.
 296: */
 297: 
 298: typedef struct ar_hdr HDR;
 299: static char hb[sizeof(HDR) + 1];    /* real header */
 300: 
 301: /* Convert ar header field to an integer. */
 302: #define AR_ATOI(from, to, len, base) { \
 303:     bcopy(from, buf, len); \
 304:     buf[len] = '\0'; \
 305:     to = strtol(buf, (char **)NULL, base); \
 306: }
 307: 
 308: /*
 309:  *	read the archive header for this member.  Use a file pointer
 310:  *	rather than a file descriptor.
 311:  */
 312: get_arobj(fp)
 313:     FILE *fp;
 314: {
 315:     HDR *hdr;
 316:     register int len, nr;
 317:     register char *p;
 318:     char buf[20];
 319: 
 320:     nr = fread(hb, 1, sizeof(HDR), fp);
 321:     if (nr != sizeof(HDR))
 322:         return(-1);
 323: 
 324:     hdr = (HDR *)hb;
 325:     if (strncmp(hdr->ar_fmag, ARFMAG, sizeof(ARFMAG) - 1))
 326:         return(-1);
 327: 
 328:     /* Convert the header into the internal format. */
 329: #define DECIMAL 10
 330: #define OCTAL    8
 331: 
 332:     AR_ATOI(hdr->ar_date, chdr.date, sizeof(hdr->ar_date), DECIMAL);
 333:     AR_ATOI(hdr->ar_uid, chdr.uid, sizeof(hdr->ar_uid), DECIMAL);
 334:     AR_ATOI(hdr->ar_gid, chdr.gid, sizeof(hdr->ar_gid), DECIMAL);
 335:     AR_ATOI(hdr->ar_mode, chdr.mode, sizeof(hdr->ar_mode), OCTAL);
 336:     AR_ATOI(hdr->ar_size, chdr.size, sizeof(hdr->ar_size), DECIMAL);
 337: 
 338:     /* Leading spaces should never happen. */
 339:     if (hdr->ar_name[0] == ' ')
 340:         return(-1);
 341: 
 342:     /*
 343: 	 * Long name support.  Set the "real" size of the file, and the
 344: 	 * long name flag/size.
 345: 	 */
 346:     if (!bcmp(hdr->ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1)) {
 347:         chdr.lname = len = atoi(hdr->ar_name + sizeof(AR_EFMT1) - 1);
 348:         if (len <= 0 || len > MAXNAMLEN)
 349:             return(-1);
 350:         nr = fread(chdr.name, 1, (size_t)len, fp);
 351:         if (nr != len)
 352:             return(-1);
 353:         chdr.name[len] = 0;
 354:         chdr.size -= len;
 355:     } else {
 356:         chdr.lname = 0;
 357:         bcopy(hdr->ar_name, chdr.name, sizeof(hdr->ar_name));
 358: 
 359:         /* Strip trailing spaces, null terminate. */
 360:         for (p = chdr.name + sizeof(hdr->ar_name) - 1; *p == ' '; --p);
 361:         *++p = '\0';
 362:     }
 363:     return(1);
 364: }

Defined functions

compare defined in line 251; used 2 times
error defined in line 276; used 7 times
get_arobj defined in line 312; used 1 times
main defined in line 35; never used
namelist defined in line 85; used 1 times
  • in line 80
nextel defined in line 264; used 2 times
psyms defined in line 191; used 1 times

Defined variables

aflg defined in line 21; used 1 times
  • in line 63
errs defined in line 33; used 2 times
gflg defined in line 21; used 3 times
hb defined in line 299; used 2 times
narg defined in line 33; used 3 times
nflg defined in line 21; used 2 times
off defined in line 29; used 4 times
oflg defined in line 21; used 3 times
pflg defined in line 21; used 2 times
rflg defined in line 21; used 4 times
sccsid defined in line 2; never used
strp defined in line 23; used 10 times
uflg defined in line 21; used 5 times
xargv defined in line 22; used 7 times

Defined typedef's

HDR defined in line 298; used 5 times

Defined macros

AR_ATOI defined in line 302; used 5 times
DECIMAL defined in line 329; used 4 times
OCTAL defined in line 330; used 1 times
SELECT defined in line 19; used 2 times
Last modified: 1994-02-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4881
Valid CSS Valid XHTML 1.0 Strict