# 2.11BSD#431 - /usr/src/bin/nm/nm.c

##### Functions

    compare           X
    error             X
    get_arobj         X
    main              X
    namelist          X
    nextel            X
    psyms             X

##### Variables

    aflg              X
    errs              X
    gflg              X
    narg              X
    nflg              X
    off               X
    oflg              X
    pflg              X
    rflg              X
    strp              X
    uflg              X
    xargv             X

##### Macros

    AR_ATOI           X
    DECIMAL           X
    OCTAL             X
    SELECT            X

##### typedef's

    HDR               X

       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

- in line 33, 178

error defined in line 276; used 7 times

- in line 93, 105, 131, 152, 168-173(3)

get_arobj defined in line 312; used 1 times

- in line 269

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

- in line 111, 186

psyms defined in line 191; used 1 times

- in line 181

#### Defined variables

aflg defined in line 21; used 1 times

- in line 63

errs defined in line 33; used 2 times

- in line 82, 288

gflg defined in line 21; used 3 times

- in line 48, 142, 159

hb defined in line 299; used 2 times

- in line 320-324(2)

narg defined in line 33; used 3 times

- in line 76, 112, 179

nflg defined in line 21; used 2 times

- in line 45, 255

off defined in line 29; used 4 times

- in line 98-102(2), 268-271(2)

oflg defined in line 21; used 3 times

- in line 60, 179, 229

pflg defined in line 21; used 2 times

- in line 57, 177

rflg defined in line 21; used 4 times

- in line 54, 257-261(3)

sccsid defined in line 2; never used
strp defined in line 23; used 10 times

- in line 136-137(3), 169-175(4), 184-185(3)

uflg defined in line 21; used 5 times

- in line 51, 144, 161, 227, 236

xargv defined in line 22; used 7 times

- in line 19, 77-79(2), 91, 113, 231, 279

#### Defined typedef's

HDR defined in line 298; used 5 times

- in line 299, 315-324(4)

#### Defined macros

AR_ATOI defined in line 302; used 5 times

- in line 332-336(5)

DECIMAL defined in line 329; used 4 times

- in line 332-336(4)

OCTAL defined in line 330; used 1 times

- in line 335

SELECT defined in line 19; used 2 times

- in line 180, 232

Last modified: 1994-02-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2202 |