2 * Copyright (c) 1980 The Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 char const copyright[] =
36 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
37 All rights reserved.\n";
42 static char sccsid[] = "@(#)symorder.c 5.8 (Berkeley) 4/1/91";
44 static const char rcsid[] =
49 * symorder - reorder symbol table
52 #include <sys/types.h>
67 #define NOTFOUNDEXIT 1
71 struct nlist order[SPACE];
75 struct nlist *newtab, *symtab;
77 int nexclude, nsym, strtabsize, symfound, symkept, small, missing, clean;
78 char *kfile, *newstrings, *strings, asym[BUFSIZ];
80 void badfmt __P((char *));
81 int excluded __P((struct nlist *));
82 int inlist __P((struct nlist *));
83 void reorder __P((struct nlist *, struct nlist *, int));
84 int savesymb __P((struct nlist *));
85 static void usage __P((void));
92 register struct nlist *p, *symp;
93 register FILE *f, *xfile;
95 register char *start, *t, *xfilename;
99 while ((ch = getopt(argc, argv, "cmtx:")) != -1)
111 if (xfilename != NULL)
125 if ((f = fopen(argv[0], "r")) == NULL)
126 err(ERREXIT, "%s", argv[0]);
128 for (p = order; fgets(asym, sizeof(asym), f) != NULL;) {
129 for (t = asym; isspace(*t); ++t);
135 p->n_un.n_name = strdup(start);
137 if (++nsym >= sizeof order / sizeof order[0])
142 if (xfilename != NULL) {
143 if ((xfile = fopen(xfilename, "r")) == NULL)
144 err(ERREXIT, "%s", xfilename);
145 for (; fgets(asym, sizeof(asym), xfile) != NULL;) {
146 for (t = asym; isspace(*t); ++t);
152 exclude[nexclude] = strdup(start);
153 if (++nexclude >= sizeof exclude / sizeof exclude[0])
160 if ((f = fopen(kfile, "r")) == NULL)
161 err(ERREXIT, "%s", kfile);
162 if ((o = open(kfile, O_WRONLY)) < 0)
163 err(ERREXIT, "%s", kfile);
165 /* read exec header */
166 if ((fread(&exec, sizeof(exec), 1, f)) != 1)
167 badfmt("no exec header");
169 badfmt("bad magic number");
170 if (exec.a_syms == 0)
172 (void)fstat(fileno(f), &stb);
173 if (stb.st_size < N_STROFF(exec) + sizeof(off_t))
174 badfmt("no string table");
176 /* seek to and read the symbol table */
178 (void)fseek(f, sa, SEEK_SET);
180 if (!(symtab = (struct nlist *)malloc(n)))
182 if (fread((void *)symtab, 1, n, f) != n)
183 badfmt("corrupted symbol table");
185 /* read string table size and string table */
186 if (fread((void *)&strtabsize, sizeof(int), 1, f) != 1 ||
188 badfmt("corrupted string table");
189 strings = malloc(strtabsize);
193 * Subtract four from strtabsize since strtabsize includes itself,
194 * and we've already read it.
196 if (fread(strings, 1, strtabsize - sizeof(int), f) !=
197 strtabsize - sizeof(int))
198 badfmt("corrupted string table");
200 i = n / sizeof(struct nlist);
202 newtab = (struct nlist *)malloc(n);
203 if (newtab == (struct nlist *)NULL)
205 memset(newtab, 0, n);
207 reorder(symtab, newtab, i);
208 free((void *)symtab);
214 newstrings = malloc(strtabsize);
215 if (newstrings == NULL)
218 for (symp = symtab; --i >= 0; symp++) {
219 if (symp->n_un.n_strx == 0)
221 if (inlist(symp) < 0) {
224 if (clean && !savesymb(symp))
225 symp->n_type &= ~N_EXT;
228 symp->n_un.n_strx -= sizeof(int);
229 (void)strcpy(t, &strings[symp->n_un.n_strx]);
230 symp->n_un.n_strx = (t - newstrings) + sizeof(int);
234 /* update shrunk sizes */
235 strtabsize = t - newstrings + sizeof(int);
236 n = symkept * sizeof(struct nlist);
238 /* fix exec sym size */
239 (void)lseek(o, (off_t)0, SEEK_SET);
241 if (write(o, (void *)&exec, sizeof(exec)) != sizeof(exec))
242 err(ERREXIT, "%s", kfile);
244 (void)lseek(o, sa, SEEK_SET);
245 if (write(o, (void *)symtab, n) != n)
246 err(ERREXIT, "%s", kfile);
247 if (write(o, (void *)&strtabsize, sizeof(int)) != sizeof(int))
248 err(ERREXIT, "%s", kfile);
249 if (write(o, newstrings, strtabsize - sizeof(int)) !=
250 strtabsize - sizeof(int))
251 err(ERREXIT, "%s", kfile);
253 ftruncate(o, lseek(o, (off_t)0, SEEK_CUR));
255 if ((i = nsym - symfound) > 0) {
256 (void)printf("symorder: %d symbol%s not found:\n",
257 i, i == 1 ? "" : "s");
258 for (i = 0; i < nsym; i++)
259 if (order[i].n_value == 0)
260 printf("%s\n", order[i].n_un.n_name);
269 register struct nlist *s;
271 if ((s->n_type & N_EXT) != N_EXT)
273 switch (s->n_type & N_TYPE) {
283 reorder(st1, st2, entries)
284 register struct nlist *st1, *st2;
287 register struct nlist *p;
290 for (p = st1, n = entries; --n >= 0; ++p)
293 for (p = st2 + symfound, n = entries; --n >= 0; ++st1) {
307 register struct nlist *p;
310 register struct nlist *op;
312 if (p->n_type & N_STAB || p->n_un.n_strx == 0)
314 if (p->n_un.n_strx < sizeof(int) || p->n_un.n_strx >= strtabsize)
315 badfmt("corrupted symbol table");
316 nam = &strings[p->n_un.n_strx - sizeof(int)];
317 for (op = &order[nsym]; --op >= order; ) {
318 if (strcmp(op->n_un.n_name, nam) != 0)
328 register struct nlist *p;
333 if (p->n_type & N_STAB || p->n_un.n_strx == 0)
335 if (p->n_un.n_strx < sizeof(int) || p->n_un.n_strx >= strtabsize)
336 badfmt("corrupted symbol table");
337 nam = &strings[p->n_un.n_strx - sizeof(int)];
338 for (x = nexclude; --x >= 0; )
339 if (strcmp(nam, exclude[x]) == 0)
348 errx(ERREXIT, "%s: %s: %s", kfile, why, strerror(EFTYPE));
354 (void)fprintf(stderr,
355 "usage: symorder [-c] [-m] [-t] [-x excludelist] symlist file\n");