first working version.
[unix-history] / usr / src / old / symorder / symorder.c
CommitLineData
34aa0635 1#ifndef lint
45991748 2static char *sccsid = "@(#)symorder.c 4.5 (Berkeley) %G%";
34aa0635 3#endif
45991748 4
faa0bd68
BJ
5/*
6 * symorder - reorder symbol table
7 */
45991748 8
faa0bd68 9#include <stdio.h>
faa0bd68 10#include <sys/types.h>
840fc587 11#include <sys/stat.h>
13257757 12#include <a.out.h>
faa0bd68
BJ
13
14#define SPACE 100
15
16struct nlist order[SPACE];
17
45991748 18char *savestr(), *index(), *malloc();
faa0bd68 19struct exec exec;
45991748 20off_t sa;
faa0bd68
BJ
21struct stat stb;
22int nsym = 0;
23int symfound = 0;
45991748
RC
24char *strings;
25char *newstrings;
26struct nlist *symtab;
27struct nlist *newtab;
28int symsize;
faa0bd68
BJ
29char asym[BUFSIZ];
30
31main(argc, argv)
32 char **argv;
33{
45991748
RC
34 register char *ns;
35 register struct nlist *symp;
36 register struct nlist *p;
faa0bd68 37 register FILE *f;
45991748 38 register int i;
faa0bd68
BJ
39 int n, o;
40
45991748 41 if (argc != 3) {
faa0bd68
BJ
42 fprintf(stderr, "Usage: symorder orderlist file\n");
43 exit(1);
44 }
45991748 45 if ((f = fopen(argv[1], "r")) == NULL) {
faa0bd68
BJ
46 perror(argv[1]);
47 exit(1);
48 }
45991748
RC
49 for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
50 for (i = 0; asym[i] && asym[i] != '\n'; i++)
faa0bd68
BJ
51 continue;
52 if (asym[i] == '\n')
53 asym[i] = 0;
54 p->n_un.n_name = savestr(asym);
faa0bd68
BJ
55 }
56 fclose(f);
45991748 57 if ((f = fopen(argv[2], "r")) == NULL)
faa0bd68 58 perror(argv[2]), exit(1);
45991748 59 if ((o = open(argv[2], 1)) < 0)
faa0bd68 60 perror(argv[2]), exit(1);
45991748 61 if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
faa0bd68
BJ
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)) {
45991748
RC
71 fprintf(stderr, "symorder: %s is in old format or truncated\n",
72 argv[2]);
faa0bd68
BJ
73 exit(1);
74 }
75 sa = N_SYMOFF(exec);
faa0bd68
BJ
76 fseek(f, sa, 0);
77 n = exec.a_syms;
45991748
RC
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");
faa0bd68
BJ
127 exit(1);
128 }
45991748
RC
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);
faa0bd68
BJ
135 }
136 }
45991748
RC
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");
faa0bd68
BJ
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 }
45991748
RC
159 exit(0);
160}
161
162reorder(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
178inlist(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);
faa0bd68
BJ
205}
206
207#define NSAVETAB 4096
208char *savetab;
209int saveleft;
210
211char *
212savestr(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}