xref: /csrg-svn/old/symorder/symorder.c (revision 42693)
121578Sdist /*
236196Sbostic  * Copyright (c) 1980 The Regents of the University of California.
336196Sbostic  * All rights reserved.
436196Sbostic  *
5*42693Sbostic  * %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*42693Sbostic static char sccsid[] = "@(#)symorder.c	5.4 (Berkeley) 06/01/90";
1636196Sbostic #endif /* not lint */
1721578Sdist 
18623Sbill /*
19623Sbill  * symorder - reorder symbol table
20623Sbill  */
2116667Sralph 
22623Sbill #include <stdio.h>
23623Sbill #include <sys/types.h>
2413621Ssam #include <sys/stat.h>
25934Sbill #include <a.out.h>
26623Sbill 
27623Sbill #define SPACE 100
28623Sbill 
29623Sbill struct	nlist order[SPACE];
30623Sbill 
3116667Sralph char	*savestr(), *index(), *malloc();
32623Sbill struct	exec exec;
3316667Sralph off_t	sa;
34623Sbill struct	stat stb;
35623Sbill int	nsym = 0;
36623Sbill int	symfound = 0;
3716667Sralph char	*strings;
3816667Sralph char	*newstrings;
3916667Sralph struct	nlist *symtab;
4016667Sralph struct	nlist *newtab;
4116667Sralph int	symsize;
42623Sbill char	asym[BUFSIZ];
43623Sbill 
44623Sbill main(argc, argv)
45623Sbill 	char **argv;
46623Sbill {
4716667Sralph 	register char *ns;
4816667Sralph 	register struct nlist *symp;
4916667Sralph 	register struct nlist *p;
50623Sbill 	register FILE *f;
5116667Sralph 	register int i;
52623Sbill 	int n, o;
53623Sbill 
5416667Sralph 	if (argc != 3) {
55623Sbill 		fprintf(stderr, "Usage: symorder orderlist file\n");
56623Sbill 		exit(1);
57623Sbill 	}
5816667Sralph 	if ((f = fopen(argv[1], "r")) == NULL) {
59623Sbill 		perror(argv[1]);
60623Sbill 		exit(1);
61623Sbill 	}
6216667Sralph 	for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
6316667Sralph 		for (i = 0; asym[i] && asym[i] != '\n'; i++)
64623Sbill 			continue;
65623Sbill 		if (asym[i] == '\n')
66623Sbill 			asym[i] = 0;
67623Sbill 		p->n_un.n_name = savestr(asym);
68623Sbill 	}
69623Sbill 	fclose(f);
7016667Sralph 	if ((f = fopen(argv[2], "r")) == NULL)
71623Sbill 		perror(argv[2]), exit(1);
7216667Sralph 	if ((o = open(argv[2], 1)) < 0)
73623Sbill 		perror(argv[2]), exit(1);
7416667Sralph 	if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
75623Sbill 		fprintf(stderr, "symorder: %s: bad format\n", argv[2]);
76623Sbill 		exit(1);
77623Sbill 	}
78623Sbill 	if (exec.a_syms == 0) {
79623Sbill 		fprintf(stderr, "symorder: %s is stripped\n", argv[2]);
80623Sbill 		exit(1);
81623Sbill 	}
82623Sbill 	fstat(fileno(f), &stb);
83623Sbill 	if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) {
8416667Sralph 		fprintf(stderr, "symorder: %s is in old format or truncated\n",
8516667Sralph 		    argv[2]);
86623Sbill 		exit(1);
87623Sbill 	}
88623Sbill 	sa = N_SYMOFF(exec);
89623Sbill 	fseek(f, sa, 0);
90623Sbill 	n = exec.a_syms;
9116667Sralph 	symtab = (struct nlist *)malloc(n);
9216667Sralph 	if (symtab == (struct nlist *)0) {
9316667Sralph 		fprintf(stderr, "symorder: Out of core, no space for symtab\n");
9416667Sralph 		exit(1);
9516667Sralph 	}
9616667Sralph 	if (fread((char *)symtab, 1, n, f) != n) {
9716667Sralph 		fprintf(stderr, "symorder: Short file "); perror(argv[2]);
9816667Sralph 		exit(1);
9916667Sralph 	}
10016667Sralph 	if (fread((char *)&symsize, sizeof (int), 1, f) != 1 ||
10116667Sralph 	    symsize <= 0) {
10216667Sralph 		fprintf(stderr, "symorder: No strings "); perror(argv[2]);
10316667Sralph 		exit(1);
10416667Sralph 	}
10516667Sralph 	strings = malloc(symsize);
10616667Sralph 	if (strings == (char *)0) {
10716667Sralph 		fprintf(stderr,"symorder: Out of core, no space for strings\n");
10816667Sralph 		exit(1);
10916667Sralph 	}
11023838Smckusick 	/*
11123838Smckusick 	 * Need to subtract four from symsize here since
11223838Smckusick 	 * symsize includes itself, and we've already read
11323838Smckusick 	 * it.  (6/30/85 chris@maryland)
11423838Smckusick 	 */
11523838Smckusick 	if (fread(strings, 1, symsize - 4, f) != symsize - 4) {
11616667Sralph 		fprintf(stderr, "symorder: Truncated strings ");
11716667Sralph 		perror(argv[2]);
11816667Sralph 		exit(1);
11916667Sralph 	}
12016667Sralph 
12116667Sralph 	newtab = (struct nlist *)malloc(n);
12216667Sralph 	if (newtab == (struct nlist *)0) {
12316667Sralph 		fprintf(stderr,
12416667Sralph 		    "symorder: Out of core, no space for new symtab\n");
12516667Sralph 		exit(1);
12616667Sralph 	}
12716667Sralph 	i = n / sizeof (struct nlist);
12816667Sralph 	reorder(symtab, newtab, i);
12916667Sralph 	free((char *)symtab);
13016667Sralph 	symtab = newtab;
13116667Sralph 
13216667Sralph 	newstrings = malloc(symsize);
13316667Sralph 	if (newstrings == (char *)0) {
13416667Sralph 		fprintf(stderr,
13516667Sralph 		    "symorder: Out of core, no space for newstrings\n");
13616667Sralph 		exit(1);
13716667Sralph 	}
13816667Sralph 	ns = newstrings;
13916667Sralph 	for (symp = symtab; --i >= 0; symp++) {
14016667Sralph 		if (symp->n_un.n_strx == 0)
14116667Sralph 			continue;
14216667Sralph 		symp->n_un.n_strx -= sizeof (int);
14316667Sralph 		if ((unsigned)symp->n_un.n_strx >= symsize) {
14416667Sralph 			fprintf(stderr,"symorder: Corrupted string pointers\n");
145623Sbill 			exit(1);
146623Sbill 		}
14716667Sralph 		strcpy(ns, &strings[symp->n_un.n_strx]);
14816667Sralph 		symp->n_un.n_strx = (ns - newstrings) + sizeof (int);
14916667Sralph 		ns = index(ns, 0) + 1;
15016667Sralph 		if (ns > &newstrings[symsize]) {
15116667Sralph 			fprintf(stderr, "symorder: Strings grew longer!\n");
15216667Sralph 			exit(1);
153623Sbill 		}
154623Sbill 	}
15516667Sralph 
15616667Sralph 	lseek(o, sa, 0);
15716667Sralph 	if (write(o, (char *)symtab, n) != n) {
15816667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
15916667Sralph 		exit(1);
16016667Sralph 	}
16116667Sralph 	if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) {
16216667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
16316667Sralph 		exit(1);
16416667Sralph 	}
16523838Smckusick 	if (write(o, newstrings, symsize - 4) != symsize - 4) {
16616667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
16716667Sralph 		exit(1);
16816667Sralph 	}
16916667Sralph 	if ((i = nsym - symfound) > 0) {
17016667Sralph 		fprintf(stderr, "symorder: %d symbol%s not found:\n",
17116667Sralph 		    i, i == 1 ? "" : "s");
172623Sbill 		for (i = 0; i < nsym; i++) {
173623Sbill 			if (order[i].n_value == 0)
174623Sbill 				printf("%s\n", order[i].n_un.n_name);
175623Sbill 		}
176623Sbill 	}
17716667Sralph 	exit(0);
178623Sbill }
179623Sbill 
18016667Sralph reorder(st1, st2, n)
18116667Sralph 	register struct nlist *st1, *st2;
18216667Sralph 	register n;
18316667Sralph {
18416667Sralph 	register struct nlist *stp = st2 + nsym;
18516667Sralph 	register i;
18616667Sralph 
18716667Sralph 	while (--n >= 0) {
18816667Sralph 		i = inlist(st1);
18916667Sralph 		if (i == -1)
19016667Sralph 			*stp++ = *st1++;
19116667Sralph 		else
19216667Sralph 			st2[i] = *st1++;
19316667Sralph 	}
19416667Sralph }
19516667Sralph 
19616667Sralph inlist(p)
19716667Sralph 	register struct nlist *p;
19816667Sralph {
19916667Sralph 	register char *nam;
20016667Sralph 	register struct nlist *op;
20116667Sralph 
20216667Sralph 	if (p->n_type & N_STAB)
20316667Sralph 		return (-1);
20416667Sralph 	if (p->n_un.n_strx == 0)
20516667Sralph 		return (-1);
20616667Sralph 
20716667Sralph 	nam = &strings[p->n_un.n_strx - sizeof(int)];
20816667Sralph 	if (nam >= &strings[symsize]) {
20916667Sralph 		fprintf(stderr, "symorder: corrupt symtab\n");
21016667Sralph 		exit(1);
21116667Sralph 	}
21216667Sralph 
21316667Sralph 	for (op = &order[nsym]; --op >= order; ) {
21416667Sralph 		if (strcmp(op->n_un.n_name, nam) != 0)
21516667Sralph 			continue;
21616667Sralph 		if (op->n_value == 0) {
21716667Sralph 			op->n_value++;
21816667Sralph 			symfound++;
21916667Sralph 		}
22016667Sralph 		return (op - order);
22116667Sralph 	}
22216667Sralph 	return (-1);
22316667Sralph }
22416667Sralph 
225623Sbill #define	NSAVETAB	4096
226623Sbill char	*savetab;
227623Sbill int	saveleft;
228623Sbill 
229623Sbill char *
230623Sbill savestr(cp)
231623Sbill 	register char *cp;
232623Sbill {
233623Sbill 	register int len;
234623Sbill 
235623Sbill 	len = strlen(cp) + 1;
236623Sbill 	if (len > saveleft) {
237623Sbill 		saveleft = NSAVETAB;
238623Sbill 		if (len > saveleft)
239623Sbill 			saveleft = len;
240623Sbill 		savetab = (char *)malloc(saveleft);
241623Sbill 		if (savetab == 0) {
242623Sbill 			fprintf(stderr,
243623Sbill 			    "symorder: ran out of memory (savestr)\n");
244623Sbill 			exit(1);
245623Sbill 		}
246623Sbill 	}
247623Sbill 	strncpy(savetab, cp, len);
248623Sbill 	cp = savetab;
249623Sbill 	savetab += len;
250623Sbill 	saveleft -= len;
251623Sbill 	return (cp);
252623Sbill }
253