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