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

##### Functions

    cleanup           X
    copyfile          X
    fatal             X
    main              X

##### Variables

    Pgm               X
    Sort              X
    Symdump           X

       1: /*
       2:  *	Program Name:   strcompact.c
       3:  *	Date: February 12, 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:  *	2.0	12Feb94		2. Rewrite.  Use new utility program 'symdump'
      10:  *				   and a multi-key sort to not only create
      11:  *				   shared symbol strings but remove identical
      12:  *				   symbols (identical absolute local symbols
      13:  *				   are quite common).  Execution speed was
      14:  *				   speed up by about a factor of 4.
      15: */
      16:
      17: /*
      18:  * This program compacts the string table of an executable image by
      19:  * preserving only a single string definition of a symbol and updating
      20:  * the symbol table string offsets.  Multiple symbols having the same
      21:  * string are very common - local symbols in a function often have the
      22:  * same name ('int error' inside a function for example).  This program
      23:  * reduced the string table size of the kernel at least 25%!
      24:  *
      25:  * In addition, local symbols with the same value (frame offset within
      26:  * a function) are very common.  By retaining only a single '~error=2'
      27:  * for example the symbol table is reduced even further (about 500 symbols
      28:  * are removed from a typical kernel).
      29: */
      30:
      31: #include <stdio.h>
      32: #include <a.out.h>
      33: #include <signal.h>
      34: #include <string.h>
      35: #include <sysexits.h>
      36: #include <sys/file.h>
      37:
      38:     char    *Pgm;
      39:     char    *Sort = "/usr/bin/sort";
      40:     char    *Symdump = "/usr/ucb/symdump";
      41: static  char    strfn[32], symfn[32];
      42:
      43: main(argc, argv)
      44:     int argc;
      45:     char    **argv;
      46:     {
      47:     struct  nlist   sym;
      48:     char    buf1[128], symname[64], savedname[64];
      49:     struct  xexec   xhdr;
      50:     int nsyms, len;
      51:     FILE    *symfp, *strfp, *sortfp;
      52: register FILE   *fpin;
      53:     long    stroff;
      54:     unsigned short  type, value, ovly;
      55:     void    cleanup();
      56:
      57:     Pgm = argv[0];
      58:     signal(SIGQUIT, cleanup);
      59:     signal(SIGINT, cleanup);
      60:     signal(SIGHUP, cleanup);
      61:
      62:     if  (argc != 2)
      63:         {
      64:         fprintf(stderr, "%s: missing filename argument\n", Pgm);
      65:         exit(EX_USAGE);
      66:         }
      67:     fpin = fopen(argv[1], "r+");
      68:     if  (!fpin)
      69:         {
      70:         fprintf(stderr, "%s: can not open '%s' for update\n",
      71:             Pgm, argv[1]);
      72:         exit(EX_NOINPUT);
      73:         }
      74:     if  (fread(&xhdr, 1, sizeof (xhdr), fpin) < sizeof (xhdr.e))
      75:         {
      76:         fprintf(stderr, "%s: premature EOF\n", Pgm);
      77:         exit(EX_DATAERR);
      78:         }
      79:     if  (N_BADMAG(xhdr.e))
      80:         {
      81:         fprintf(stderr, "%s: Bad magic number\n", Pgm);
      82:         exit(EX_DATAERR);
      83:         }
      84:     nsyms = xhdr.e.a_syms / sizeof (struct nlist);
      85:     if  (!nsyms)
      86:         {
      87:         fprintf(stderr, "%s: '%s' stripped\n", Pgm, argv[1]);
      88:         exit(EX_OK);
      89:         }
      90:
      91:     strcpy(strfn, "/tmp/strXXXXXX");
      92:     mktemp(strfn);
      93:     strcpy(symfn, "/tmp/symXXXXXX");
      94:     mktemp(symfn);
      95:
      96:     sprintf(buf1, "%s %s | %s +0 -1 +1n -2 +2n -3 +3n -4 -u", Symdump,
      97:         argv[1], Sort);
      98:     sortfp = popen(buf1, "r");
      99:     if  (!sortfp)
     100:         {
     101:         fprintf(stderr, "%s: symdump | sort failed\n", Pgm);
     102:         exit(EX_SOFTWARE);
     103:         }
     104:     symfp = fopen(symfn, "w+");
     105:     strfp = fopen(strfn, "w+");
     106:     if  (!symfp || !strfp)
     107:         {
     108:         fprintf(stderr, "%s: can't create %s or %s\n", symfn, strfn);
     109:         exit(EX_CANTCREAT);
     110:         }
     111:
     112:     stroff = sizeof (long);
     113:     len = 0;
     114:     nsyms = 0;
     115:     while   (fscanf(sortfp, "%s %u %u %u\n", symname, &type, &ovly,
     116:             &value) == 4)
     117:         {
     118:         if  (strcmp(symname, savedname))
     119:             {
     120:             stroff += len;
     121:             len = strlen(symname) + 1;
     122:             fwrite(symname, len, 1, strfp);
     123:             strcpy(savedname, symname);
     124:             }
     125:         sym.n_un.n_strx = stroff;
     126:         sym.n_type = type;
     127:         sym.n_ovly = ovly;
     128:         sym.n_value = value;
     129:         fwrite(&sym, sizeof (sym), 1, symfp);
     130:         nsyms++;
     131:         }
     132:     stroff += len;
     133:
     134:     pclose(sortfp);
     135:     rewind(symfp);
     136:     rewind(strfp);
     137:
     138:     if  (nsyms == 0)
     139:         {
     140:         fprintf(stderr, "%s: No symbols - %s not modified\n", argv[1]);
     141:         cleanup();
     142:         }
     143:
     144:     fseek(fpin, N_SYMOFF(xhdr), L_SET);
     145:
     146: /*
     147:  * Now append the new symbol table.  Then write the string table length
     148:  * followed by the string table.  Finally truncate the file to the new
     149:  * length, reflecting the smaller string table.
     150: */
     151:     copyfile(symfp, fpin);
     152:     fwrite(&stroff, sizeof (long), 1, fpin);
     153:     copyfile(strfp, fpin);
     154:     ftruncate(fileno(fpin), ftell(fpin));
     155:
     156: /*
     157:  * Update the header with the correct symbol table size.
     158: */
     159:     rewind(fpin);
     160:     xhdr.e.a_syms = nsyms * sizeof (sym);
     161:     fwrite(&xhdr, sizeof (xhdr.e), 1, fpin);
     162:
     163:     fclose(fpin);
     164:     fclose(symfp);
     165:     fclose(strfp);
     166:     cleanup();
     167:     }
     168:
     169: copyfile(in, out)
     170:     register FILE *in, *out;
     171:     {
     172:     register int c;
     173:
     174:     while   ((c = getc(in)) != EOF)
     175:         putc(c, out);
     176:     }
     177:
     178: fatal(str)
     179:     char    *str;
     180:     {
     181:
     182:     if  (strfn[0])
     183:         unlink(strfn);
     184:     if  (symfn[0])
     185:         unlink(symfn);
     186:     if  (!str)
     187:         exit(EX_OK);
     188:     fprintf(stderr, "%s: %s\n", str);
     189:     exit(EX_SOFTWARE);
     190:     }
     191:
     192: void
     193: cleanup()
     194:     {
     195:     fatal((char *)NULL);
     196:     }

#### Defined functions

cleanup defined in line 192; used 6 times

- in line 55-60(4), 141, 166

copyfile defined in line 169; used 2 times

- in line 151-153(2)

fatal defined in line 178; used 1 times

- in line 195

main defined in line 43; never used

#### Defined variables

Pgm defined in line 38; used 7 times

- in line 57, 64, 71-81(3), 87, 101

Sort defined in line 39; used 1 times

- in line 97

Symdump defined in line 40; used 1 times

- in line 96

strfn defined in line 41; used 6 times

- in line 91-92(2), 105-108(2), 182-183(2)

symfn defined in line 41; used 6 times

- in line 93-94(2), 104-108(2), 184-185(2)

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