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