xref: /csrg-svn/old/symorder/symorder.c (revision 47690)
121578Sdist /*
236196Sbostic  * Copyright (c) 1980 The Regents of the University of California.
336196Sbostic  * All rights reserved.
436196Sbostic  *
542693Sbostic  * %sccs.include.redist.c%
621578Sdist  */
721578Sdist 
812674Ssam #ifndef lint
921578Sdist char copyright[] =
1036196Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
1121578Sdist  All rights reserved.\n";
1236196Sbostic #endif /* not lint */
1316667Sralph 
1421578Sdist #ifndef lint
15*47690Sbostic static char sccsid[] = "@(#)symorder.c	5.8 (Berkeley) 04/01/91";
1636196Sbostic #endif /* not lint */
1721578Sdist 
18623Sbill /*
19623Sbill  * symorder - reorder symbol table
20623Sbill  */
2116667Sralph 
22623Sbill #include <sys/types.h>
2313621Ssam #include <sys/stat.h>
2446222Sbostic #include <fcntl.h>
2546222Sbostic #include <errno.h>
26934Sbill #include <a.out.h>
2746222Sbostic #include <unistd.h>
2846222Sbostic #include <stdio.h>
2946222Sbostic #include <stdlib.h>
3046222Sbostic #include <string.h>
31623Sbill 
3246254Sbostic #define SPACE		500
33623Sbill 
3446254Sbostic #define	OKEXIT		0
3546254Sbostic #define	NOTFOUNDEXIT	1
3646254Sbostic #define	ERREXIT		2
3746254Sbostic 
38623Sbill struct	nlist order[SPACE];
39623Sbill 
40623Sbill struct	exec exec;
4146222Sbostic struct	stat stb;
4246222Sbostic struct	nlist *newtab, *symtab;
4316667Sralph off_t	sa;
4447684Swilliam int	nsym, strtabsize, symfound, small;
4546222Sbostic char	*kfile, *newstrings, *strings, asym[BUFSIZ];
46623Sbill 
main(argc,argv)47623Sbill main(argc, argv)
4846222Sbostic 	int argc;
49623Sbill 	char **argv;
50623Sbill {
51*47690Sbostic 	extern char *optarg;
52*47690Sbostic 	extern int optind;
5346222Sbostic 	register struct nlist *p, *symp;
54623Sbill 	register FILE *f;
5516667Sralph 	register int i;
5646222Sbostic 	register char *start, *t;
57*47690Sbostic 	int ch, n, o;
58623Sbill 
59*47690Sbostic 	while ((ch = getopt(argc, argv, "t")) != EOF)
60*47690Sbostic 		switch(ch) {
61*47690Sbostic 		case 't':
62*47690Sbostic 			small = 1;
63*47690Sbostic 			break;
64*47690Sbostic 		case '?':
65*47690Sbostic 		default:
66*47690Sbostic 			usage();
67*47690Sbostic 		}
68*47690Sbostic 	argc -= optind;
69*47690Sbostic 	argv += optind;
7046222Sbostic 
71*47690Sbostic 	if (argc != 2)
72*47690Sbostic 		usage();
73*47690Sbostic 
74*47690Sbostic 	if ((f = fopen(argv[0], "r")) == NULL)
75*47690Sbostic 		error(argv[0]);
76*47690Sbostic 
7746222Sbostic 	for (p = order; fgets(asym, sizeof(asym), f) != NULL;) {
7846222Sbostic 		for (t = asym; isspace(*t); ++t);
7946222Sbostic 		if (!*(start = t))
80623Sbill 			continue;
8146222Sbostic 		while (*++t);
8246222Sbostic 		if (*--t == '\n')
8346222Sbostic 			*t = '\0';
8446222Sbostic 		p->n_un.n_name = strdup(start);
8546222Sbostic 		++p;
8646222Sbostic 		++nsym;
87623Sbill 	}
8846222Sbostic 	(void)fclose(f);
8946222Sbostic 
90*47690Sbostic 	kfile = argv[1];
9146222Sbostic 	if ((f = fopen(kfile, "r")) == NULL)
9246222Sbostic 		error(kfile);
9346222Sbostic 	if ((o = open(kfile, O_WRONLY)) < 0)
9446222Sbostic 		error(kfile);
9546222Sbostic 
9646222Sbostic 	/* read exec header */
9746222Sbostic 	if ((fread(&exec, sizeof(exec), 1, f)) != 1)
9846222Sbostic 		badfmt("no exec header");
9946222Sbostic 	if (N_BADMAG(exec))
10046222Sbostic 		badfmt("bad magic number");
10146222Sbostic 	if (exec.a_syms == 0)
10246222Sbostic 		badfmt("stripped");
10346222Sbostic 	(void)fstat(fileno(f), &stb);
10446222Sbostic 	if (stb.st_size < N_STROFF(exec) + sizeof(off_t))
10546222Sbostic 		badfmt("no string table");
10646222Sbostic 
10746222Sbostic 	/* seek to and read the symbol table */
108623Sbill 	sa = N_SYMOFF(exec);
10946222Sbostic 	(void)fseek(f, sa, SEEK_SET);
110623Sbill 	n = exec.a_syms;
11146222Sbostic 	if (!(symtab = (struct nlist *)malloc(n)))
112*47690Sbostic 		error(NULL);
113*47690Sbostic 	if (fread((void *)symtab, 1, n, f) != n)
11446222Sbostic 		badfmt("corrupted symbol table");
11546222Sbostic 
11646222Sbostic 	/* read string table size and string table */
117*47690Sbostic 	if (fread((void *)&strtabsize, sizeof(int), 1, f) != 1 ||
11846222Sbostic 	    strtabsize <= 0)
11946222Sbostic 		badfmt("corrupted string table");
12046222Sbostic 	strings = malloc(strtabsize);
121*47690Sbostic 	if (strings == NULL)
122*47690Sbostic 		error(NULL);
12323838Smckusick 	/*
12446222Sbostic 	 * Subtract four from strtabsize since strtabsize includes itself,
12546222Sbostic 	 * and we've already read it.
12623838Smckusick 	 */
12746222Sbostic 	if (fread(strings, 1, strtabsize - sizeof(int), f) !=
12846222Sbostic 	    strtabsize - sizeof(int))
12946222Sbostic 		badfmt("corrupted string table");
13016667Sralph 
13116667Sralph 	newtab = (struct nlist *)malloc(n);
13246222Sbostic 	if (newtab == (struct nlist *)NULL)
133*47690Sbostic 		error(NULL);
13446222Sbostic 
13546222Sbostic 	i = n / sizeof(struct nlist);
13616667Sralph 	reorder(symtab, newtab, i);
137*47690Sbostic 	free((void *)symtab);
13816667Sralph 	symtab = newtab;
13916667Sralph 
14046222Sbostic 	newstrings = malloc(strtabsize);
141*47690Sbostic 	if (newstrings == NULL)
142*47690Sbostic 		error(NULL);
14346222Sbostic 	t = newstrings;
14416667Sralph 	for (symp = symtab; --i >= 0; symp++) {
14516667Sralph 		if (symp->n_un.n_strx == 0)
14616667Sralph 			continue;
14747684Swilliam 		if (small && inlist(symp) < 0) continue;
14846222Sbostic 		symp->n_un.n_strx -= sizeof(int);
14946222Sbostic 		(void)strcpy(t, &strings[symp->n_un.n_strx]);
15046222Sbostic 		symp->n_un.n_strx = (t - newstrings) + sizeof(int);
15146222Sbostic 		t += strlen(t) + 1;
152623Sbill 	}
15316667Sralph 
15447684Swilliam 	/* update shrunk sizes */
15547684Swilliam 	if(small) {
15647684Swilliam 		strtabsize = t - newstrings + sizeof(int);
15747684Swilliam 		n = symfound * sizeof(struct nlist);
15847684Swilliam 		/* fix exec sym size */
15947684Swilliam 		(void)lseek(o, 0, SEEK_SET);
16047684Swilliam 		exec.a_syms = n;
161*47690Sbostic 		if (write(o, (void *)&exec, sizeof(exec)) != sizeof(exec))
16247684Swilliam 			error(kfile);
16347684Swilliam 	}
16447684Swilliam 
16546222Sbostic 	(void)lseek(o, sa, SEEK_SET);
166*47690Sbostic 	if (write(o, (void *)symtab, n) != n)
16746222Sbostic 		error(kfile);
168*47690Sbostic 	if (write(o, (void *)&strtabsize, sizeof(int)) != sizeof(int))
16946222Sbostic 		error(kfile);
17046222Sbostic 	if (write(o, newstrings, strtabsize - sizeof(int)) !=
17146222Sbostic 	    strtabsize - sizeof(int))
17246222Sbostic 		error(kfile);
17347684Swilliam 
17447684Swilliam 	if (small) ftruncate(o, lseek(o, 0, SEEK_CUR));
17547684Swilliam 
17616667Sralph 	if ((i = nsym - symfound) > 0) {
17746222Sbostic 		(void)printf("symorder: %d symbol%s not found:\n",
17816667Sralph 		    i, i == 1 ? "" : "s");
17946222Sbostic 		for (i = 0; i < nsym; i++)
180623Sbill 			if (order[i].n_value == 0)
181623Sbill 				printf("%s\n", order[i].n_un.n_name);
18246254Sbostic 		exit(NOTFOUNDEXIT);
183623Sbill 	}
18446254Sbostic 	exit(OKEXIT);
185623Sbill }
186623Sbill 
reorder(st1,st2,entries)18746222Sbostic reorder(st1, st2, entries)
18816667Sralph 	register struct nlist *st1, *st2;
18946222Sbostic 	int entries;
19016667Sralph {
19146222Sbostic 	register struct nlist *p;
19246222Sbostic 	register int i, n;
19316667Sralph 
19446222Sbostic 	for (p = st1, n = entries; --n >= 0; ++p)
19546222Sbostic 		if (inlist(p) != -1)
19646222Sbostic 			++symfound;
19746222Sbostic 	for (p = st2 + symfound, n = entries; --n >= 0; ++st1) {
19816667Sralph 		i = inlist(st1);
19916667Sralph 		if (i == -1)
20046222Sbostic 			*p++ = *st1;
20116667Sralph 		else
20246222Sbostic 			st2[i] = *st1;
20316667Sralph 	}
20416667Sralph }
20516667Sralph 
inlist(p)20616667Sralph inlist(p)
20716667Sralph 	register struct nlist *p;
20816667Sralph {
20916667Sralph 	register char *nam;
21016667Sralph 	register struct nlist *op;
21116667Sralph 
21216667Sralph 	if (p->n_type & N_STAB)
21316667Sralph 		return (-1);
21416667Sralph 	if (p->n_un.n_strx == 0)
21516667Sralph 		return (-1);
21616667Sralph 
21746222Sbostic 	if (p->n_un.n_strx >= strtabsize)
21846222Sbostic 		badfmt("corrupted symbol table");
21946222Sbostic 
22016667Sralph 	nam = &strings[p->n_un.n_strx - sizeof(int)];
22116667Sralph 	for (op = &order[nsym]; --op >= order; ) {
22216667Sralph 		if (strcmp(op->n_un.n_name, nam) != 0)
22316667Sralph 			continue;
22446222Sbostic 		op->n_value = 1;
22516667Sralph 		return (op - order);
22616667Sralph 	}
22716667Sralph 	return (-1);
22816667Sralph }
22916667Sralph 
badfmt(why)23046222Sbostic badfmt(why)
23146222Sbostic 	char *why;
23246222Sbostic {
23346222Sbostic 	(void)fprintf(stderr,
23446222Sbostic 	    "symorder: %s: %s: %s\n", kfile, why, strerror(EFTYPE));
23546254Sbostic 	exit(ERREXIT);
23646222Sbostic }
237623Sbill 
error(n)23846222Sbostic error(n)
23946222Sbostic 	char *n;
240623Sbill {
24146222Sbostic 	int sverr;
242623Sbill 
24346222Sbostic 	sverr = errno;
24446222Sbostic 	(void)fprintf(stderr, "symorder: ");
24546222Sbostic 	if (n)
24646222Sbostic 		(void)fprintf(stderr, "%s: ", n);
24746222Sbostic 	(void)fprintf(stderr, "%s\n", strerror(sverr));
24846254Sbostic 	exit(ERREXIT);
249623Sbill }
250*47690Sbostic 
usage()251*47690Sbostic usage()
252*47690Sbostic {
253*47690Sbostic 	(void)fprintf(stderr, "usage: symorder [-t] symlist file\n");
254*47690Sbostic 	exit(ERREXIT);
255*47690Sbostic }
256