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