xref: /csrg-svn/old/symorder/symorder.c (revision 42693)
1 /*
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 char copyright[] =
10 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
11  All rights reserved.\n";
12 #endif /* not lint */
13 
14 #ifndef lint
15 static char sccsid[] = "@(#)symorder.c	5.4 (Berkeley) 06/01/90";
16 #endif /* not lint */
17 
18 /*
19  * symorder - reorder symbol table
20  */
21 
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <a.out.h>
26 
27 #define SPACE 100
28 
29 struct	nlist order[SPACE];
30 
31 char	*savestr(), *index(), *malloc();
32 struct	exec exec;
33 off_t	sa;
34 struct	stat stb;
35 int	nsym = 0;
36 int	symfound = 0;
37 char	*strings;
38 char	*newstrings;
39 struct	nlist *symtab;
40 struct	nlist *newtab;
41 int	symsize;
42 char	asym[BUFSIZ];
43 
44 main(argc, argv)
45 	char **argv;
46 {
47 	register char *ns;
48 	register struct nlist *symp;
49 	register struct nlist *p;
50 	register FILE *f;
51 	register int i;
52 	int n, o;
53 
54 	if (argc != 3) {
55 		fprintf(stderr, "Usage: symorder orderlist file\n");
56 		exit(1);
57 	}
58 	if ((f = fopen(argv[1], "r")) == NULL) {
59 		perror(argv[1]);
60 		exit(1);
61 	}
62 	for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
63 		for (i = 0; asym[i] && asym[i] != '\n'; i++)
64 			continue;
65 		if (asym[i] == '\n')
66 			asym[i] = 0;
67 		p->n_un.n_name = savestr(asym);
68 	}
69 	fclose(f);
70 	if ((f = fopen(argv[2], "r")) == NULL)
71 		perror(argv[2]), exit(1);
72 	if ((o = open(argv[2], 1)) < 0)
73 		perror(argv[2]), exit(1);
74 	if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
75 		fprintf(stderr, "symorder: %s: bad format\n", argv[2]);
76 		exit(1);
77 	}
78 	if (exec.a_syms == 0) {
79 		fprintf(stderr, "symorder: %s is stripped\n", argv[2]);
80 		exit(1);
81 	}
82 	fstat(fileno(f), &stb);
83 	if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) {
84 		fprintf(stderr, "symorder: %s is in old format or truncated\n",
85 		    argv[2]);
86 		exit(1);
87 	}
88 	sa = N_SYMOFF(exec);
89 	fseek(f, sa, 0);
90 	n = exec.a_syms;
91 	symtab = (struct nlist *)malloc(n);
92 	if (symtab == (struct nlist *)0) {
93 		fprintf(stderr, "symorder: Out of core, no space for symtab\n");
94 		exit(1);
95 	}
96 	if (fread((char *)symtab, 1, n, f) != n) {
97 		fprintf(stderr, "symorder: Short file "); perror(argv[2]);
98 		exit(1);
99 	}
100 	if (fread((char *)&symsize, sizeof (int), 1, f) != 1 ||
101 	    symsize <= 0) {
102 		fprintf(stderr, "symorder: No strings "); perror(argv[2]);
103 		exit(1);
104 	}
105 	strings = malloc(symsize);
106 	if (strings == (char *)0) {
107 		fprintf(stderr,"symorder: Out of core, no space for strings\n");
108 		exit(1);
109 	}
110 	/*
111 	 * Need to subtract four from symsize here since
112 	 * symsize includes itself, and we've already read
113 	 * it.  (6/30/85 chris@maryland)
114 	 */
115 	if (fread(strings, 1, symsize - 4, f) != symsize - 4) {
116 		fprintf(stderr, "symorder: Truncated strings ");
117 		perror(argv[2]);
118 		exit(1);
119 	}
120 
121 	newtab = (struct nlist *)malloc(n);
122 	if (newtab == (struct nlist *)0) {
123 		fprintf(stderr,
124 		    "symorder: Out of core, no space for new symtab\n");
125 		exit(1);
126 	}
127 	i = n / sizeof (struct nlist);
128 	reorder(symtab, newtab, i);
129 	free((char *)symtab);
130 	symtab = newtab;
131 
132 	newstrings = malloc(symsize);
133 	if (newstrings == (char *)0) {
134 		fprintf(stderr,
135 		    "symorder: Out of core, no space for newstrings\n");
136 		exit(1);
137 	}
138 	ns = newstrings;
139 	for (symp = symtab; --i >= 0; symp++) {
140 		if (symp->n_un.n_strx == 0)
141 			continue;
142 		symp->n_un.n_strx -= sizeof (int);
143 		if ((unsigned)symp->n_un.n_strx >= symsize) {
144 			fprintf(stderr,"symorder: Corrupted string pointers\n");
145 			exit(1);
146 		}
147 		strcpy(ns, &strings[symp->n_un.n_strx]);
148 		symp->n_un.n_strx = (ns - newstrings) + sizeof (int);
149 		ns = index(ns, 0) + 1;
150 		if (ns > &newstrings[symsize]) {
151 			fprintf(stderr, "symorder: Strings grew longer!\n");
152 			exit(1);
153 		}
154 	}
155 
156 	lseek(o, sa, 0);
157 	if (write(o, (char *)symtab, n) != n) {
158 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
159 		exit(1);
160 	}
161 	if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) {
162 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
163 		exit(1);
164 	}
165 	if (write(o, newstrings, symsize - 4) != symsize - 4) {
166 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
167 		exit(1);
168 	}
169 	if ((i = nsym - symfound) > 0) {
170 		fprintf(stderr, "symorder: %d symbol%s not found:\n",
171 		    i, i == 1 ? "" : "s");
172 		for (i = 0; i < nsym; i++) {
173 			if (order[i].n_value == 0)
174 				printf("%s\n", order[i].n_un.n_name);
175 		}
176 	}
177 	exit(0);
178 }
179 
180 reorder(st1, st2, n)
181 	register struct nlist *st1, *st2;
182 	register n;
183 {
184 	register struct nlist *stp = st2 + nsym;
185 	register i;
186 
187 	while (--n >= 0) {
188 		i = inlist(st1);
189 		if (i == -1)
190 			*stp++ = *st1++;
191 		else
192 			st2[i] = *st1++;
193 	}
194 }
195 
196 inlist(p)
197 	register struct nlist *p;
198 {
199 	register char *nam;
200 	register struct nlist *op;
201 
202 	if (p->n_type & N_STAB)
203 		return (-1);
204 	if (p->n_un.n_strx == 0)
205 		return (-1);
206 
207 	nam = &strings[p->n_un.n_strx - sizeof(int)];
208 	if (nam >= &strings[symsize]) {
209 		fprintf(stderr, "symorder: corrupt symtab\n");
210 		exit(1);
211 	}
212 
213 	for (op = &order[nsym]; --op >= order; ) {
214 		if (strcmp(op->n_un.n_name, nam) != 0)
215 			continue;
216 		if (op->n_value == 0) {
217 			op->n_value++;
218 			symfound++;
219 		}
220 		return (op - order);
221 	}
222 	return (-1);
223 }
224 
225 #define	NSAVETAB	4096
226 char	*savetab;
227 int	saveleft;
228 
229 char *
230 savestr(cp)
231 	register char *cp;
232 {
233 	register int len;
234 
235 	len = strlen(cp) + 1;
236 	if (len > saveleft) {
237 		saveleft = NSAVETAB;
238 		if (len > saveleft)
239 			saveleft = len;
240 		savetab = (char *)malloc(saveleft);
241 		if (savetab == 0) {
242 			fprintf(stderr,
243 			    "symorder: ran out of memory (savestr)\n");
244 			exit(1);
245 		}
246 	}
247 	strncpy(savetab, cp, len);
248 	cp = savetab;
249 	savetab += len;
250 	saveleft -= len;
251 	return (cp);
252 }
253