xref: /csrg-svn/old/symorder/symorder.c (revision 16667)
112674Ssam #ifndef lint
2*16667Sralph static char *sccsid = "@(#)symorder.c	4.5 (Berkeley) 07/05/84";
312674Ssam #endif
4*16667Sralph 
5623Sbill /*
6623Sbill  * symorder - reorder symbol table
7623Sbill  */
8*16667Sralph 
9623Sbill #include <stdio.h>
10623Sbill #include <sys/types.h>
1113621Ssam #include <sys/stat.h>
12934Sbill #include <a.out.h>
13623Sbill 
14623Sbill #define SPACE 100
15623Sbill 
16623Sbill struct	nlist order[SPACE];
17623Sbill 
18*16667Sralph char	*savestr(), *index(), *malloc();
19623Sbill struct	exec exec;
20*16667Sralph off_t	sa;
21623Sbill struct	stat stb;
22623Sbill int	nsym = 0;
23623Sbill int	symfound = 0;
24*16667Sralph char	*strings;
25*16667Sralph char	*newstrings;
26*16667Sralph struct	nlist *symtab;
27*16667Sralph struct	nlist *newtab;
28*16667Sralph int	symsize;
29623Sbill char	asym[BUFSIZ];
30623Sbill 
31623Sbill main(argc, argv)
32623Sbill 	char **argv;
33623Sbill {
34*16667Sralph 	register char *ns;
35*16667Sralph 	register struct nlist *symp;
36*16667Sralph 	register struct nlist *p;
37623Sbill 	register FILE *f;
38*16667Sralph 	register int i;
39623Sbill 	int n, o;
40623Sbill 
41*16667Sralph 	if (argc != 3) {
42623Sbill 		fprintf(stderr, "Usage: symorder orderlist file\n");
43623Sbill 		exit(1);
44623Sbill 	}
45*16667Sralph 	if ((f = fopen(argv[1], "r")) == NULL) {
46623Sbill 		perror(argv[1]);
47623Sbill 		exit(1);
48623Sbill 	}
49*16667Sralph 	for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
50*16667Sralph 		for (i = 0; asym[i] && asym[i] != '\n'; i++)
51623Sbill 			continue;
52623Sbill 		if (asym[i] == '\n')
53623Sbill 			asym[i] = 0;
54623Sbill 		p->n_un.n_name = savestr(asym);
55623Sbill 	}
56623Sbill 	fclose(f);
57*16667Sralph 	if ((f = fopen(argv[2], "r")) == NULL)
58623Sbill 		perror(argv[2]), exit(1);
59*16667Sralph 	if ((o = open(argv[2], 1)) < 0)
60623Sbill 		perror(argv[2]), exit(1);
61*16667Sralph 	if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
62623Sbill 		fprintf(stderr, "symorder: %s: bad format\n", argv[2]);
63623Sbill 		exit(1);
64623Sbill 	}
65623Sbill 	if (exec.a_syms == 0) {
66623Sbill 		fprintf(stderr, "symorder: %s is stripped\n", argv[2]);
67623Sbill 		exit(1);
68623Sbill 	}
69623Sbill 	fstat(fileno(f), &stb);
70623Sbill 	if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) {
71*16667Sralph 		fprintf(stderr, "symorder: %s is in old format or truncated\n",
72*16667Sralph 		    argv[2]);
73623Sbill 		exit(1);
74623Sbill 	}
75623Sbill 	sa = N_SYMOFF(exec);
76623Sbill 	fseek(f, sa, 0);
77623Sbill 	n = exec.a_syms;
78*16667Sralph 	symtab = (struct nlist *)malloc(n);
79*16667Sralph 	if (symtab == (struct nlist *)0) {
80*16667Sralph 		fprintf(stderr, "symorder: Out of core, no space for symtab\n");
81*16667Sralph 		exit(1);
82*16667Sralph 	}
83*16667Sralph 	if (fread((char *)symtab, 1, n, f) != n) {
84*16667Sralph 		fprintf(stderr, "symorder: Short file "); perror(argv[2]);
85*16667Sralph 		exit(1);
86*16667Sralph 	}
87*16667Sralph 	if (fread((char *)&symsize, sizeof (int), 1, f) != 1 ||
88*16667Sralph 	    symsize <= 0) {
89*16667Sralph 		fprintf(stderr, "symorder: No strings "); perror(argv[2]);
90*16667Sralph 		exit(1);
91*16667Sralph 	}
92*16667Sralph 	strings = malloc(symsize);
93*16667Sralph 	if (strings == (char *)0) {
94*16667Sralph 		fprintf(stderr,"symorder: Out of core, no space for strings\n");
95*16667Sralph 		exit(1);
96*16667Sralph 	}
97*16667Sralph 	if (fread(strings, 1, symsize, f) != symsize) {
98*16667Sralph 		fprintf(stderr, "symorder: Truncated strings ");
99*16667Sralph 		perror(argv[2]);
100*16667Sralph 		exit(1);
101*16667Sralph 	}
102*16667Sralph 
103*16667Sralph 	newtab = (struct nlist *)malloc(n);
104*16667Sralph 	if (newtab == (struct nlist *)0) {
105*16667Sralph 		fprintf(stderr,
106*16667Sralph 		    "symorder: Out of core, no space for new symtab\n");
107*16667Sralph 		exit(1);
108*16667Sralph 	}
109*16667Sralph 	i = n / sizeof (struct nlist);
110*16667Sralph 	reorder(symtab, newtab, i);
111*16667Sralph 	free((char *)symtab);
112*16667Sralph 	symtab = newtab;
113*16667Sralph 
114*16667Sralph 	newstrings = malloc(symsize);
115*16667Sralph 	if (newstrings == (char *)0) {
116*16667Sralph 		fprintf(stderr,
117*16667Sralph 		    "symorder: Out of core, no space for newstrings\n");
118*16667Sralph 		exit(1);
119*16667Sralph 	}
120*16667Sralph 	ns = newstrings;
121*16667Sralph 	for (symp = symtab; --i >= 0; symp++) {
122*16667Sralph 		if (symp->n_un.n_strx == 0)
123*16667Sralph 			continue;
124*16667Sralph 		symp->n_un.n_strx -= sizeof (int);
125*16667Sralph 		if ((unsigned)symp->n_un.n_strx >= symsize) {
126*16667Sralph 			fprintf(stderr,"symorder: Corrupted string pointers\n");
127623Sbill 			exit(1);
128623Sbill 		}
129*16667Sralph 		strcpy(ns, &strings[symp->n_un.n_strx]);
130*16667Sralph 		symp->n_un.n_strx = (ns - newstrings) + sizeof (int);
131*16667Sralph 		ns = index(ns, 0) + 1;
132*16667Sralph 		if (ns > &newstrings[symsize]) {
133*16667Sralph 			fprintf(stderr, "symorder: Strings grew longer!\n");
134*16667Sralph 			exit(1);
135623Sbill 		}
136623Sbill 	}
137*16667Sralph 
138*16667Sralph 	lseek(o, sa, 0);
139*16667Sralph 	if (write(o, (char *)symtab, n) != n) {
140*16667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
141*16667Sralph 		exit(1);
142*16667Sralph 	}
143*16667Sralph 	if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) {
144*16667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
145*16667Sralph 		exit(1);
146*16667Sralph 	}
147*16667Sralph 	if (write(o, newstrings, symsize) != symsize) {
148*16667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
149*16667Sralph 		exit(1);
150*16667Sralph 	}
151*16667Sralph 	if ((i = nsym - symfound) > 0) {
152*16667Sralph 		fprintf(stderr, "symorder: %d symbol%s not found:\n",
153*16667Sralph 		    i, i == 1 ? "" : "s");
154623Sbill 		for (i = 0; i < nsym; i++) {
155623Sbill 			if (order[i].n_value == 0)
156623Sbill 				printf("%s\n", order[i].n_un.n_name);
157623Sbill 		}
158623Sbill 	}
159*16667Sralph 	exit(0);
160623Sbill }
161623Sbill 
162*16667Sralph reorder(st1, st2, n)
163*16667Sralph 	register struct nlist *st1, *st2;
164*16667Sralph 	register n;
165*16667Sralph {
166*16667Sralph 	register struct nlist *stp = st2 + nsym;
167*16667Sralph 	register i;
168*16667Sralph 
169*16667Sralph 	while (--n >= 0) {
170*16667Sralph 		i = inlist(st1);
171*16667Sralph 		if (i == -1)
172*16667Sralph 			*stp++ = *st1++;
173*16667Sralph 		else
174*16667Sralph 			st2[i] = *st1++;
175*16667Sralph 	}
176*16667Sralph }
177*16667Sralph 
178*16667Sralph inlist(p)
179*16667Sralph 	register struct nlist *p;
180*16667Sralph {
181*16667Sralph 	register char *nam;
182*16667Sralph 	register struct nlist *op;
183*16667Sralph 
184*16667Sralph 	if (p->n_type & N_STAB)
185*16667Sralph 		return (-1);
186*16667Sralph 	if (p->n_un.n_strx == 0)
187*16667Sralph 		return (-1);
188*16667Sralph 
189*16667Sralph 	nam = &strings[p->n_un.n_strx - sizeof(int)];
190*16667Sralph 	if (nam >= &strings[symsize]) {
191*16667Sralph 		fprintf(stderr, "symorder: corrupt symtab\n");
192*16667Sralph 		exit(1);
193*16667Sralph 	}
194*16667Sralph 
195*16667Sralph 	for (op = &order[nsym]; --op >= order; ) {
196*16667Sralph 		if (strcmp(op->n_un.n_name, nam) != 0)
197*16667Sralph 			continue;
198*16667Sralph 		if (op->n_value == 0) {
199*16667Sralph 			op->n_value++;
200*16667Sralph 			symfound++;
201*16667Sralph 		}
202*16667Sralph 		return (op - order);
203*16667Sralph 	}
204*16667Sralph 	return (-1);
205*16667Sralph }
206*16667Sralph 
207623Sbill #define	NSAVETAB	4096
208623Sbill char	*savetab;
209623Sbill int	saveleft;
210623Sbill 
211623Sbill char *
212623Sbill savestr(cp)
213623Sbill 	register char *cp;
214623Sbill {
215623Sbill 	register int len;
216623Sbill 
217623Sbill 	len = strlen(cp) + 1;
218623Sbill 	if (len > saveleft) {
219623Sbill 		saveleft = NSAVETAB;
220623Sbill 		if (len > saveleft)
221623Sbill 			saveleft = len;
222623Sbill 		savetab = (char *)malloc(saveleft);
223623Sbill 		if (savetab == 0) {
224623Sbill 			fprintf(stderr,
225623Sbill 			    "symorder: ran out of memory (savestr)\n");
226623Sbill 			exit(1);
227623Sbill 		}
228623Sbill 	}
229623Sbill 	strncpy(savetab, cp, len);
230623Sbill 	cp = savetab;
231623Sbill 	savetab += len;
232623Sbill 	saveleft -= len;
233623Sbill 	return (cp);
234623Sbill }
235