2 * Copyright (c) 1980 The Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * @(#) Copyright (c) 1980 The Regents of the University of California. All rights reserved.
30 * @(#)symorder.c 5.8 (Berkeley) 4/1/91
31 * $FreeBSD: src/usr.bin/symorder/symorder.c,v 1.15 1999/08/28 01:05:57 peter Exp $
35 * symorder - reorder symbol table
38 #include <sys/types.h>
49 #include <netinet/in.h>
54 #define NOTFOUNDEXIT 1
58 struct nlist order
[SPACE
];
62 struct nlist
*newtab
, *symtab
;
64 int nexclude
, nsym
, strtabsize
, symfound
, symkept
, small
, missing
, clean
;
65 char *kfile
, *newstrings
, *strings
, asym
[BUFSIZ
];
68 int excluded(struct nlist
*);
69 int inlist(struct nlist
*);
70 void reorder(struct nlist
*, struct nlist
*, int);
71 int savesymb(struct nlist
*);
72 static void usage(void);
75 main(int argc
, char **argv
)
77 struct nlist
*p
, *symp
;
80 char *start
, *t
, *xfilename
;
84 while ((ch
= getopt(argc
, argv
, "cmtx:")) != -1)
96 if (xfilename
!= NULL
)
110 if ((f
= fopen(argv
[0], "r")) == NULL
)
111 err(ERREXIT
, "%s", argv
[0]);
113 for (p
= order
; fgets(asym
, sizeof(asym
), f
) != NULL
;) {
114 for (t
= asym
; isspace(*t
); ++t
);
120 p
->n_un
.n_name
= strdup(start
);
122 if (++nsym
>= sizeof order
/ sizeof order
[0])
127 if (xfilename
!= NULL
) {
128 if ((xfile
= fopen(xfilename
, "r")) == NULL
)
129 err(ERREXIT
, "%s", xfilename
);
130 for (; fgets(asym
, sizeof(asym
), xfile
) != NULL
;) {
131 for (t
= asym
; isspace(*t
); ++t
);
137 exclude
[nexclude
] = strdup(start
);
138 if (++nexclude
>= sizeof exclude
/ sizeof exclude
[0])
145 if ((f
= fopen(kfile
, "r")) == NULL
)
146 err(ERREXIT
, "%s", kfile
);
147 if ((o
= open(kfile
, O_WRONLY
)) < 0)
148 err(ERREXIT
, "%s", kfile
);
150 /* read exec header */
151 if ((fread(&exec
, sizeof(exec
), 1, f
)) != 1)
152 badfmt("no exec header");
154 badfmt("bad magic number");
155 if (exec
.a_syms
== 0)
157 (void)fstat(fileno(f
), &stb
);
158 if (stb
.st_size
< N_STROFF(exec
) + sizeof(off_t
))
159 badfmt("no string table");
161 /* seek to and read the symbol table */
163 (void)fseek(f
, sa
, SEEK_SET
);
165 if (!(symtab
= (struct nlist
*)malloc(n
)))
167 if (fread((void *)symtab
, 1, n
, f
) != n
)
168 badfmt("corrupted symbol table");
170 /* read string table size and string table */
171 if (fread((void *)&strtabsize
, sizeof(int), 1, f
) != 1 ||
173 badfmt("corrupted string table");
174 strings
= malloc(strtabsize
);
178 * Subtract four from strtabsize since strtabsize includes itself,
179 * and we've already read it.
181 if (fread(strings
, 1, strtabsize
- sizeof(int), f
) !=
182 strtabsize
- sizeof(int))
183 badfmt("corrupted string table");
185 i
= n
/ sizeof(struct nlist
);
187 newtab
= (struct nlist
*)malloc(n
);
190 memset(newtab
, 0, n
);
192 reorder(symtab
, newtab
, i
);
193 free((void *)symtab
);
199 newstrings
= malloc(strtabsize
);
200 if (newstrings
== NULL
)
203 for (symp
= symtab
; --i
>= 0; symp
++) {
204 if (symp
->n_un
.n_strx
== 0)
206 if (inlist(symp
) < 0) {
209 if (clean
&& !savesymb(symp
))
210 symp
->n_type
&= ~N_EXT
;
213 symp
->n_un
.n_strx
-= sizeof(int);
214 (void)strcpy(t
, &strings
[symp
->n_un
.n_strx
]);
215 symp
->n_un
.n_strx
= (t
- newstrings
) + sizeof(int);
219 /* update shrunk sizes */
220 strtabsize
= t
- newstrings
+ sizeof(int);
221 n
= symkept
* sizeof(struct nlist
);
223 /* fix exec sym size */
224 (void)lseek(o
, (off_t
)0, SEEK_SET
);
226 if (write(o
, (void *)&exec
, sizeof(exec
)) != sizeof(exec
))
227 err(ERREXIT
, "%s", kfile
);
229 (void)lseek(o
, sa
, SEEK_SET
);
230 if (write(o
, (void *)symtab
, n
) != n
)
231 err(ERREXIT
, "%s", kfile
);
232 if (write(o
, (void *)&strtabsize
, sizeof(int)) != sizeof(int))
233 err(ERREXIT
, "%s", kfile
);
234 if (write(o
, newstrings
, strtabsize
- sizeof(int)) !=
235 strtabsize
- sizeof(int))
236 err(ERREXIT
, "%s", kfile
);
238 ftruncate(o
, lseek(o
, (off_t
)0, SEEK_CUR
));
240 if ((i
= nsym
- symfound
) > 0) {
241 (void)printf("symorder: %d symbol%s not found:\n",
242 i
, i
== 1 ? "" : "s");
243 for (i
= 0; i
< nsym
; i
++)
244 if (order
[i
].n_value
== 0)
245 printf("%s\n", order
[i
].n_un
.n_name
);
253 savesymb(struct nlist
*s
)
255 if ((s
->n_type
& N_EXT
) != N_EXT
)
257 switch (s
->n_type
& N_TYPE
) {
267 reorder(struct nlist
*st1
, struct nlist
*st2
, int entries
)
272 for (p
= st1
, n
= entries
; --n
>= 0; ++p
)
275 for (p
= st2
+ symfound
, n
= entries
; --n
>= 0; ++st1
) {
288 inlist(struct nlist
*p
)
293 if (p
->n_type
& N_STAB
|| p
->n_un
.n_strx
== 0)
295 if (p
->n_un
.n_strx
< sizeof(int) || p
->n_un
.n_strx
>= strtabsize
)
296 badfmt("corrupted symbol table");
297 nam
= &strings
[p
->n_un
.n_strx
- sizeof(int)];
298 for (op
= &order
[nsym
]; --op
>= order
; ) {
299 if (strcmp(op
->n_un
.n_name
, nam
) != 0)
308 excluded(struct nlist
*p
)
313 if (p
->n_type
& N_STAB
|| p
->n_un
.n_strx
== 0)
315 if (p
->n_un
.n_strx
< sizeof(int) || p
->n_un
.n_strx
>= strtabsize
)
316 badfmt("corrupted symbol table");
317 nam
= &strings
[p
->n_un
.n_strx
- sizeof(int)];
318 for (x
= nexclude
; --x
>= 0; )
319 if (strcmp(nam
, exclude
[x
]) == 0)
327 errx(ERREXIT
, "%s: %s: %s", kfile
, why
, strerror(EFTYPE
));
333 (void)fprintf(stderr
,
334 "usage: symorder [-c] [-m] [-t] [-x excludelist] symlist file\n");