# 2.11BSD#431 - /usr/src/ucb/symorder.c

##### Functions

    cleanup           X
    getsyms           X
    inlist            X
    main              X

##### Variables

    Pgm               X
    nsorted           X
    order             X

##### Macros

    NUMSYMS           X

       1: /*
       2:  *	Program Name:   symorder.c
       3:  *	Date: January 21, 1994
       4:  *	Author: S.M. Schultz
       5:  *
       6:  *	-----------------   Modification History   ---------------
       7:  *      Version Date            Reason For Modification
       8:  *      1.0     21Jan94         1. Initial release into the public domain.
       9: */
      10:
      11: /*
      12:  * This program reorders the symbol table of an executable.  This is
      13:  * done by moving symbols found in the second file argument (one symbol
      14:  * per line) to the front of the symbol table.
      15:  *
      16:  * NOTE: This program needs to hold the string table in memory.
      17:  * For the kernel which has not been 'strcompact'd this is about 21kb.
      18:  * It is highly recommended that 'strcompact' be run first - that program
      19:  * removes redundant strings, significantly reducing the amount of memory
      20:  * needed.  Running 'symcompact' will reduce the run time needed by
      21:  * this program by eliminating redundant non-overlaid text symbols.
      22: */
      23:
      24: #include <stdio.h>
      25: #include <a.out.h>
      26: #include <ctype.h>
      27: #include <signal.h>
      28: #include <string.h>
      29: #include <sysexits.h>
      30: #include <sys/file.h>
      31:
      32: #define NUMSYMS 125
      33:     char    *order[NUMSYMS];
      34:     int nsorted;
      35:     char    *Pgm;
      36:     void    cleanup();
      37: static  char    sym1tmp[20], sym2tmp[20], strtmp[20];
      38: static  char    *strtab, *oldname;
      39:
      40: main(argc, argv)
      41:     int argc;
      42:     char    **argv;
      43:     {
      44:     FILE    *fp, *fp2, *sym1fp, *sym2fp, *strfp;
      45:     int cnt, nsyms, len, c;
      46:     char    fbuf1[BUFSIZ], fbuf2[BUFSIZ];
      47:     off_t   symoff, stroff, ltmp;
      48:     long    strsiz;
      49:     struct  nlist   sym;
      50:     struct  xexec   xhdr;
      51:
      52:     Pgm = argv[0];
      53:
      54:     signal(SIGQUIT, cleanup);
      55:     signal(SIGINT, cleanup);
      56:     signal(SIGHUP, cleanup);
      57:
      58:     if  (argc != 3)
      59:         {
      60:         fprintf(stderr, "usage %s: symlist file\n", Pgm);
      61:         exit(EX_USAGE);
      62:         }
      63:     fp = fopen(argv[2], "r+");
      64:     if  (!fp)
      65:         {
      66:         fprintf(stderr, "%s: can't open '%s' for update\n", Pgm,
      67:             argv[2]);
      68:         exit(EX_NOINPUT);
      69:         }
      70:     setbuf(fp, fbuf1);
      71:     cnt = fread(&xhdr, 1, sizeof (xhdr), fp);
      72:     if  (cnt < sizeof (xhdr.e))
      73:         {
      74:         fprintf(stderr, "%s: Premature EOF reading header\n", Pgm);
      75:         exit(EX_DATAERR);
      76:         }
      77:     if  (N_BADMAG(xhdr.e))
      78:         {
      79:         fprintf(stderr, "%s: Bad magic number\n", Pgm);
      80:         exit(EX_DATAERR);
      81:         }
      82:     nsyms = xhdr.e.a_syms / sizeof (struct nlist);
      83:     if  (!nsyms)
      84:         {
      85:         fprintf(stderr, "%s: '%s' stripped\n", Pgm);
      86:         exit(EX_OK);
      87:         }
      88:     stroff = N_STROFF(xhdr);
      89:     symoff = N_SYMOFF(xhdr);
      90: /*
      91:  * Seek to the string table size longword and read it.  Then attempt to
      92:  * malloc memory to hold the string table.  First make a sanity check on
      93:  * the size.
      94: */
      95:     fseek(fp, stroff, L_SET);
      96:     fread(&strsiz, sizeof (long), 1, fp);
      97:     if  (strsiz > 48 * 1024L)
      98:         {
      99:         fprintf(stderr, "%s: string table > 48kb\n", Pgm);
     100:         exit(EX_DATAERR);
     101:         }
     102:     strtab = (char *)malloc((int)strsiz);
     103:     if  (!strtab)
     104:         {
     105:         fprintf(stderr, "%s: no memory for strings\n", Pgm);
     106:         exit(EX_OSERR);
     107:         }
     108: /*
     109:  * Now read the string table into memory.  Reduce the size read because
     110:  * we've already retrieved the string table size longword.  Adjust the
     111:  * address used so that we don't have to adjust each symbol table entry's
     112:  * string offset.
     113: */
     114:     cnt = fread(strtab + sizeof (long), 1, (int)strsiz - sizeof (long), fp);
     115:     if  (cnt != (int)strsiz - sizeof (long))
     116:         {
     117:         fprintf(stderr, "%s: Premature EOF reading strings\n", Pgm);
     118:         exit(EX_DATAERR);
     119:         }
     120: /*
     121:  * Now open the file containing the list of symbols to
     122:  * relocate to the front of the symbol table.
     123: */
     124:     fp2 = fopen(argv[1], "r");
     125:     if  (!fp2)
     126:         {
     127:         fprintf(stderr, "%s: Can not open '%s'\n", Pgm, argv[1]);
     128:         exit(EX_NOINPUT);
     129:         }
     130:     getsyms(fp2);
     131:
     132: /*
     133:  * Create the temporary files which will hold the new symbol table and the
     134:  * new string table.  One temp file receives symbols _in_ the list,
     135:  * another file receives all other symbols, and the last file receives the
     136:  * new string table.
     137: */
     138:     strcpy(sym1tmp, "/tmp/sym1XXXXXX");
     139:     mktemp(sym1tmp);
     140:     strcpy(sym2tmp, "/tmp/sym2XXXXXX");
     141:     mktemp(sym2tmp);
     142:     strcpy(strtmp, "/tmp/strXXXXXX");
     143:     mktemp(strtmp);
     144:     sym1fp = fopen(sym1tmp, "w+");
     145:     sym2fp = fopen(sym2tmp, "w+");
     146:     strfp = fopen(strtmp, "w+");
     147:     if  (!sym1fp || !sym2fp || !strfp)
     148:         {
     149:         fprintf(stderr, "%s: Can't create %s, %s or %s\n", sym1tmp,
     150:             sym2tmp, strtmp);
     151:         exit(EX_CANTCREAT);
     152:         }
     153:     setbuf(sym1fp, fbuf2);
     154: /*
     155:  * Now position the executable to the start of the symbol table.  For each
     156:  * symbol scan the list for a match on the symbol name.  If the
     157:  * name matches write the symbol table entry to one tmp file, else write it
     158:  * to the second symbol tmp file.
     159:  *
     160:  * NOTE: Since the symbol table is being rearranged the usefulness of
     161:  * "local" symbols, especially 'register' symbols, is greatly diminished
     162:  * Not that they are terribly useful in any event - especially the register
     163:  * symbols, 'adb' claims to do something with them but doesn't.  In any
     164:  * event this suite of programs is targeted at the kernel and the register
     165:  * local symbols are of no use.  For this reason 'register' symbols are
     166:  * removed - this has the side effect of even further reducing the symbol
     167:  * and string tables that must be processed by 'nm', 'ps', 'adb' and so on.
     168:  * This removal probably should have been done earlier - in 'strcompact' or
     169:  * 'symcompact' and it may be in the future, but for now just do it here.
     170: */
     171:     fseek(fp, symoff, L_SET);
     172:     while   (nsyms--)
     173:         {
     174:         fread(&sym, sizeof (sym), 1, fp);
     175:         if  (sym.n_type == N_REG)
     176:             continue;
     177:         if  (inlist(&sym))
     178:             fwrite(&sym, sizeof (sym), 1, sym1fp);
     179:         else
     180:             fwrite(&sym, sizeof (sym), 1, sym2fp);
     181:         }
     182:
     183: /*
     184:  * Position the executable file to where the symbol table starts.  Truncate
     185:  * the file to the current position to remove the old symbols and strings.  Then
     186:  * write the symbol table entries which are to appear at the front, followed
     187:  * by the remainder of the symbols.  As each symbol is processed adjust the
     188:  * string table offset and write the string to the strings tmp file.
     189:  *
     190:  * It was either re-scan the tmp files with the symbols again to retrieve
     191:  * the string offsets or simply write the strings to yet another tmp file.
     192:  * The latter was chosen.
     193: */
     194:     fseek(fp, symoff, L_SET);
     195:     ftruncate(fileno(fp), ftell(fp));
     196:     ltmp = sizeof (long);
     197:     rewind(sym1fp);
     198:     rewind(sym2fp);
     199:     nsyms = 0;
     200:     while   (fread(&sym, sizeof (sym), 1, sym1fp) == 1)
     201:         {
     202:         if  (ferror(sym1fp) || feof(sym1fp))
     203:             break;
     204:         oldname = strtab + (int)sym.n_un.n_strx;
     205:         sym.n_un.n_strx = ltmp;
     206:         len = strlen(oldname) + 1;
     207:         ltmp += len;
     208:         fwrite(&sym, sizeof (sym), 1, fp);
     209:         fwrite(oldname, len, 1, strfp);
     210:         nsyms++;
     211:         }
     212:     fclose(sym1fp);
     213:     while   (fread(&sym, sizeof (sym), 1, sym2fp) == 1)
     214:         {
     215:         if  (ferror(sym2fp) || feof(sym2fp))
     216:             break;
     217:         oldname = strtab + (int)sym.n_un.n_strx;
     218:         sym.n_un.n_strx = ltmp;
     219:         len = strlen(oldname) + 1;
     220:         ltmp += len;
     221:         fwrite(&sym, sizeof (sym), 1, fp);
     222:         fwrite(oldname, len, 1, strfp);
     223:         nsyms++;
     224:         }
     225:     fclose(sym2fp);
     226: /*
     227:  * Next write the symbol table size longword followed by the
     228:  * string table itself.
     229: */
     230:     fwrite(&ltmp, sizeof (long), 1, fp);
     231:     rewind(strfp);
     232:     while   ((c = getc(strfp)) != EOF)
     233:         putc(c, fp);
     234:     fclose(strfp);
     235: /*
     236:  * And last (but not least) we need to update the a.out header with
     237:  * the correct size of the symbol table.
     238: */
     239:     rewind(fp);
     240:     xhdr.e.a_syms = nsyms * sizeof (struct nlist);
     241:     fwrite(&xhdr.e, sizeof (xhdr.e), 1, fp);
     242:     fclose(fp);
     243:     free(strtab);
     244:     cleanup();
     245:     }
     246:
     247: inlist(sp)
     248:     register struct nlist *sp;
     249:     {
     250:     register int i;
     251:
     252:     for (i = 0; i < nsorted; i++)
     253:         {
     254:         if  (strcmp(strtab + (int)sp->n_un.n_strx, order[i]) == 0)
     255:             return(1);
     256:         }
     257:     return(0);
     258:     }
     259:
     260: getsyms(fp)
     261:     FILE    *fp;
     262:     {
     263:     char    asym[128], *start;
     264:     register char *t, **p;
     265:
     266:     for (p = order; fgets(asym, sizeof(asym), fp) != NULL;)
     267:         {
     268:         if  (nsorted >= NUMSYMS)
     269:             {
     270:             fprintf(stderr, "%s: only doing %d symbols\n",
     271:                 Pgm, NUMSYMS);
     272:             break;
     273:             }
     274:         for (t = asym; isspace(*t); ++t)
     275:             ;
     276:         if  (!*(start = t))
     277:             continue;
     278:         while   (*++t)
     279:             ;
     280:         if  (*--t == '\n')
     281:             *t = '\0';
     282:         *p++ = strdup(start);
     283:         ++nsorted;
     284:         }
     285:     fclose(fp);
     286:     }
     287:
     288: void
     289: cleanup()
     290:     {
     291:     if  (strtmp[0])
     292:         unlink(strtmp);
     293:     if  (sym1tmp[0])
     294:         unlink(sym1tmp);
     295:     if  (sym2tmp[0])
     296:         unlink(sym2tmp);
     297:     exit(EX_OK);
     298:     }

#### Defined functions

cleanup defined in line 288; used 5 times

- in line 36, 54-56(3), 244

getsyms defined in line 260; used 1 times

- in line 130

inlist defined in line 247; used 1 times

- in line 177

main defined in line 40; never used

#### Defined variables

Pgm defined in line 35; used 11 times

- in line 52, 60, 66, 74-79(2), 85, 99, 105, 117, 127, 271

nsorted defined in line 34; used 3 times

- in line 252, 268, 283

oldname defined in line 38; used 6 times

- in line 204-209(3), 217-222(3)

order defined in line 33; used 2 times

- in line 254, 266

strtab defined in line 38; used 7 times

- in line 102-103(2), 114, 204, 217, 243, 254

strtmp defined in line 37; used 6 times

- in line 142-150(4), 291-292(2)

sym1tmp defined in line 37; used 6 times

- in line 138-149(4), 293-294(2)

sym2tmp defined in line 37; used 6 times

- in line 140-150(4), 295-296(2)

#### Defined macros

NUMSYMS defined in line 32; used 3 times

- in line 33, 268-271(2)

Last modified: 1994-01-23 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 906 |