diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1993-06-12 14:49:13 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1993-06-12 14:49:13 +0000 |
commit | f078b88a160c467761b3f3641f05dfd0aa3f7753 (patch) | |
tree | 1f058a53dd274694716ec00c288d27223606ee45 /usr.bin/symorder | |
download | FreeBSD-src-f078b88a160c467761b3f3641f05dfd0aa3f7753.zip FreeBSD-src-f078b88a160c467761b3f3641f05dfd0aa3f7753.tar.gz |
Initial import, 0.1 + pk 0.2.4-B1
Diffstat (limited to 'usr.bin/symorder')
-rw-r--r-- | usr.bin/symorder/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/symorder/symorder.1 | 81 | ||||
-rw-r--r-- | usr.bin/symorder/symorder.c | 281 |
3 files changed, 367 insertions, 0 deletions
diff --git a/usr.bin/symorder/Makefile b/usr.bin/symorder/Makefile new file mode 100644 index 0000000..5fe1caf --- /dev/null +++ b/usr.bin/symorder/Makefile @@ -0,0 +1,5 @@ +# @(#)Makefile 5.3 (Berkeley) 5/11/90 + +PROG= symorder + +.include <bsd.prog.mk> diff --git a/usr.bin/symorder/symorder.1 b/usr.bin/symorder/symorder.1 new file mode 100644 index 0000000..f113bca --- /dev/null +++ b/usr.bin/symorder/symorder.1 @@ -0,0 +1,81 @@ +.\" Copyright (c) 1980, 1990 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)symorder.1 6.5 (Berkeley) 4/22/91 +.\" +.Dd April 22, 1991 +.Dt SYMORDER 1 +.Os BSD 3 +.Sh NAME +.Nm symorder +.Nd rearrange name list +.Sh SYNOPSIS +.Nm symorder +.Fl t Ar symlist file +.Sh DESCRIPTION +The file +.Ar symlist +contains a list of symbols to be found in +.Ar file, +one symbol per line. +.Pp +The symbol table of +.Ar file +is updated in place; +symbols read from +.Ar symlist +are relocated to the beginning of the table and in the order given. +.Bl -tag -width flag +.It Fl t +Restrict the symbol table to the symbols listed in +.Ar symlist . +.El +.Pp +This program was specifically designed to cut down on the +overhead of getting symbols from +.Pa /vmunix. +.Sh DIAGNOSTICS +The +.Nm symorder +utility exits 0 on success, 1 if a symbol +listed in the +.Ar symlist +file was not found in the symbol +table, and >1 if an error occurs. +.Sh SEE ALSO +.Xr nm 3 , +.Xr nlist 3 , +.Xr strip 3 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 3.0 . diff --git a/usr.bin/symorder/symorder.c b/usr.bin/symorder/symorder.c new file mode 100644 index 0000000..4c41a14 --- /dev/null +++ b/usr.bin/symorder/symorder.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 1980 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1980 The Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)symorder.c 5.8 (Berkeley) 4/1/91"; +#endif /* not lint */ + +/* + * symorder - reorder symbol table + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <a.out.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define SPACE 500 + +#define OKEXIT 0 +#define NOTFOUNDEXIT 1 +#define ERREXIT 2 + +struct nlist order[SPACE]; + +struct exec exec; +struct stat stb; +struct nlist *newtab, *symtab; +off_t sa; +int nsym, strtabsize, symfound, small; +char *kfile, *newstrings, *strings, asym[BUFSIZ]; + +main(argc, argv) + int argc; + char **argv; +{ + extern char *optarg; + extern int optind; + register struct nlist *p, *symp; + register FILE *f; + register int i; + register char *start, *t; + int ch, n, o; + + while ((ch = getopt(argc, argv, "t")) != EOF) + switch(ch) { + case 't': + small = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + if ((f = fopen(argv[0], "r")) == NULL) + error(argv[0]); + + for (p = order; fgets(asym, sizeof(asym), f) != NULL;) { + for (t = asym; isspace(*t); ++t); + if (!*(start = t)) + continue; + while (*++t); + if (*--t == '\n') + *t = '\0'; + p->n_un.n_name = strdup(start); + ++p; + ++nsym; + } + (void)fclose(f); + + kfile = argv[1]; + if ((f = fopen(kfile, "r")) == NULL) + error(kfile); + if ((o = open(kfile, O_WRONLY)) < 0) + error(kfile); + + /* read exec header */ + if ((fread(&exec, sizeof(exec), 1, f)) != 1) + badfmt("no exec header"); + if (N_BADMAG(exec)) + badfmt("bad magic number"); + if (exec.a_syms == 0) + badfmt("stripped"); + (void)fstat(fileno(f), &stb); + if (stb.st_size < N_STROFF(exec) + sizeof(off_t)) + badfmt("no string table"); + + /* seek to and read the symbol table */ + sa = N_SYMOFF(exec); + (void)fseek(f, sa, SEEK_SET); + n = exec.a_syms; + if (!(symtab = (struct nlist *)malloc(n))) + error(NULL); + if (fread((void *)symtab, 1, n, f) != n) + badfmt("corrupted symbol table"); + + /* read string table size and string table */ + if (fread((void *)&strtabsize, sizeof(int), 1, f) != 1 || + strtabsize <= 0) + badfmt("corrupted string table"); + strings = malloc(strtabsize); + if (strings == NULL) + error(NULL); + /* + * Subtract four from strtabsize since strtabsize includes itself, + * and we've already read it. + */ + if (fread(strings, 1, strtabsize - sizeof(int), f) != + strtabsize - sizeof(int)) + badfmt("corrupted string table"); + + newtab = (struct nlist *)malloc(n); + if (newtab == (struct nlist *)NULL) + error(NULL); + + i = n / sizeof(struct nlist); + reorder(symtab, newtab, i); + free((void *)symtab); + symtab = newtab; + + newstrings = malloc(strtabsize); + if (newstrings == NULL) + error(NULL); + t = newstrings; + for (symp = symtab; --i >= 0; symp++) { + if (symp->n_un.n_strx == 0) + continue; + if (small && inlist(symp) < 0) continue; + symp->n_un.n_strx -= sizeof(int); + (void)strcpy(t, &strings[symp->n_un.n_strx]); + symp->n_un.n_strx = (t - newstrings) + sizeof(int); + t += strlen(t) + 1; + } + + /* update shrunk sizes */ + if(small) { + strtabsize = t - newstrings + sizeof(int); + n = symfound * sizeof(struct nlist); + /* fix exec sym size */ + (void)lseek(o, 0, SEEK_SET); + exec.a_syms = n; + if (write(o, (void *)&exec, sizeof(exec)) != sizeof(exec)) + error(kfile); + } + + (void)lseek(o, sa, SEEK_SET); + if (write(o, (void *)symtab, n) != n) + error(kfile); + if (write(o, (void *)&strtabsize, sizeof(int)) != sizeof(int)) + error(kfile); + if (write(o, newstrings, strtabsize - sizeof(int)) != + strtabsize - sizeof(int)) + error(kfile); + + if (small) ftruncate(o, lseek(o, 0, SEEK_CUR)); + + if ((i = nsym - symfound) > 0) { + (void)printf("symorder: %d symbol%s not found:\n", + i, i == 1 ? "" : "s"); + for (i = 0; i < nsym; i++) + if (order[i].n_value == 0) + printf("%s\n", order[i].n_un.n_name); + exit(NOTFOUNDEXIT); + } + exit(OKEXIT); +} + +reorder(st1, st2, entries) + register struct nlist *st1, *st2; + int entries; +{ + register struct nlist *p; + register int i, n; + + for (p = st1, n = entries; --n >= 0; ++p) + if (inlist(p) != -1) + ++symfound; + for (p = st2 + symfound, n = entries; --n >= 0; ++st1) { + i = inlist(st1); + if (i == -1) + *p++ = *st1; + else + st2[i] = *st1; + } +} + +inlist(p) + register struct nlist *p; +{ + register char *nam; + register struct nlist *op; + + if (p->n_type & N_STAB) + return (-1); + if (p->n_un.n_strx == 0) + return (-1); + + if (p->n_un.n_strx >= strtabsize) + badfmt("corrupted symbol table"); + + nam = &strings[p->n_un.n_strx - sizeof(int)]; + for (op = &order[nsym]; --op >= order; ) { + if (strcmp(op->n_un.n_name, nam) != 0) + continue; + op->n_value = 1; + return (op - order); + } + return (-1); +} + +badfmt(why) + char *why; +{ + (void)fprintf(stderr, + "symorder: %s: %s: %s\n", kfile, why, strerror(EFTYPE)); + exit(ERREXIT); +} + +error(n) + char *n; +{ + int sverr; + + sverr = errno; + (void)fprintf(stderr, "symorder: "); + if (n) + (void)fprintf(stderr, "%s: ", n); + (void)fprintf(stderr, "%s\n", strerror(sverr)); + exit(ERREXIT); +} + +usage() +{ + (void)fprintf(stderr, "usage: symorder [-t] symlist file\n"); + exit(ERREXIT); +} |