xref: /csrg-svn/old/symorder/symorder.c (revision 21578)
1*21578Sdist /*
2*21578Sdist  * Copyright (c) 1980 Regents of the University of California.
3*21578Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21578Sdist  * specifies the terms and conditions for redistribution.
5*21578Sdist  */
6*21578Sdist 
712674Ssam #ifndef lint
8*21578Sdist char copyright[] =
9*21578Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*21578Sdist  All rights reserved.\n";
11*21578Sdist #endif not lint
1216667Sralph 
13*21578Sdist #ifndef lint
14*21578Sdist static char sccsid[] = "@(#)symorder.c	5.1 (Berkeley) 05/31/85";
15*21578Sdist #endif not lint
16*21578Sdist 
17623Sbill /*
18623Sbill  * symorder - reorder symbol table
19623Sbill  */
2016667Sralph 
21623Sbill #include <stdio.h>
22623Sbill #include <sys/types.h>
2313621Ssam #include <sys/stat.h>
24934Sbill #include <a.out.h>
25623Sbill 
26623Sbill #define SPACE 100
27623Sbill 
28623Sbill struct	nlist order[SPACE];
29623Sbill 
3016667Sralph char	*savestr(), *index(), *malloc();
31623Sbill struct	exec exec;
3216667Sralph off_t	sa;
33623Sbill struct	stat stb;
34623Sbill int	nsym = 0;
35623Sbill int	symfound = 0;
3616667Sralph char	*strings;
3716667Sralph char	*newstrings;
3816667Sralph struct	nlist *symtab;
3916667Sralph struct	nlist *newtab;
4016667Sralph int	symsize;
41623Sbill char	asym[BUFSIZ];
42623Sbill 
43623Sbill main(argc, argv)
44623Sbill 	char **argv;
45623Sbill {
4616667Sralph 	register char *ns;
4716667Sralph 	register struct nlist *symp;
4816667Sralph 	register struct nlist *p;
49623Sbill 	register FILE *f;
5016667Sralph 	register int i;
51623Sbill 	int n, o;
52623Sbill 
5316667Sralph 	if (argc != 3) {
54623Sbill 		fprintf(stderr, "Usage: symorder orderlist file\n");
55623Sbill 		exit(1);
56623Sbill 	}
5716667Sralph 	if ((f = fopen(argv[1], "r")) == NULL) {
58623Sbill 		perror(argv[1]);
59623Sbill 		exit(1);
60623Sbill 	}
6116667Sralph 	for (p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
6216667Sralph 		for (i = 0; asym[i] && asym[i] != '\n'; i++)
63623Sbill 			continue;
64623Sbill 		if (asym[i] == '\n')
65623Sbill 			asym[i] = 0;
66623Sbill 		p->n_un.n_name = savestr(asym);
67623Sbill 	}
68623Sbill 	fclose(f);
6916667Sralph 	if ((f = fopen(argv[2], "r")) == NULL)
70623Sbill 		perror(argv[2]), exit(1);
7116667Sralph 	if ((o = open(argv[2], 1)) < 0)
72623Sbill 		perror(argv[2]), exit(1);
7316667Sralph 	if ((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
74623Sbill 		fprintf(stderr, "symorder: %s: bad format\n", argv[2]);
75623Sbill 		exit(1);
76623Sbill 	}
77623Sbill 	if (exec.a_syms == 0) {
78623Sbill 		fprintf(stderr, "symorder: %s is stripped\n", argv[2]);
79623Sbill 		exit(1);
80623Sbill 	}
81623Sbill 	fstat(fileno(f), &stb);
82623Sbill 	if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) {
8316667Sralph 		fprintf(stderr, "symorder: %s is in old format or truncated\n",
8416667Sralph 		    argv[2]);
85623Sbill 		exit(1);
86623Sbill 	}
87623Sbill 	sa = N_SYMOFF(exec);
88623Sbill 	fseek(f, sa, 0);
89623Sbill 	n = exec.a_syms;
9016667Sralph 	symtab = (struct nlist *)malloc(n);
9116667Sralph 	if (symtab == (struct nlist *)0) {
9216667Sralph 		fprintf(stderr, "symorder: Out of core, no space for symtab\n");
9316667Sralph 		exit(1);
9416667Sralph 	}
9516667Sralph 	if (fread((char *)symtab, 1, n, f) != n) {
9616667Sralph 		fprintf(stderr, "symorder: Short file "); perror(argv[2]);
9716667Sralph 		exit(1);
9816667Sralph 	}
9916667Sralph 	if (fread((char *)&symsize, sizeof (int), 1, f) != 1 ||
10016667Sralph 	    symsize <= 0) {
10116667Sralph 		fprintf(stderr, "symorder: No strings "); perror(argv[2]);
10216667Sralph 		exit(1);
10316667Sralph 	}
10416667Sralph 	strings = malloc(symsize);
10516667Sralph 	if (strings == (char *)0) {
10616667Sralph 		fprintf(stderr,"symorder: Out of core, no space for strings\n");
10716667Sralph 		exit(1);
10816667Sralph 	}
10916667Sralph 	if (fread(strings, 1, symsize, f) != symsize) {
11016667Sralph 		fprintf(stderr, "symorder: Truncated strings ");
11116667Sralph 		perror(argv[2]);
11216667Sralph 		exit(1);
11316667Sralph 	}
11416667Sralph 
11516667Sralph 	newtab = (struct nlist *)malloc(n);
11616667Sralph 	if (newtab == (struct nlist *)0) {
11716667Sralph 		fprintf(stderr,
11816667Sralph 		    "symorder: Out of core, no space for new symtab\n");
11916667Sralph 		exit(1);
12016667Sralph 	}
12116667Sralph 	i = n / sizeof (struct nlist);
12216667Sralph 	reorder(symtab, newtab, i);
12316667Sralph 	free((char *)symtab);
12416667Sralph 	symtab = newtab;
12516667Sralph 
12616667Sralph 	newstrings = malloc(symsize);
12716667Sralph 	if (newstrings == (char *)0) {
12816667Sralph 		fprintf(stderr,
12916667Sralph 		    "symorder: Out of core, no space for newstrings\n");
13016667Sralph 		exit(1);
13116667Sralph 	}
13216667Sralph 	ns = newstrings;
13316667Sralph 	for (symp = symtab; --i >= 0; symp++) {
13416667Sralph 		if (symp->n_un.n_strx == 0)
13516667Sralph 			continue;
13616667Sralph 		symp->n_un.n_strx -= sizeof (int);
13716667Sralph 		if ((unsigned)symp->n_un.n_strx >= symsize) {
13816667Sralph 			fprintf(stderr,"symorder: Corrupted string pointers\n");
139623Sbill 			exit(1);
140623Sbill 		}
14116667Sralph 		strcpy(ns, &strings[symp->n_un.n_strx]);
14216667Sralph 		symp->n_un.n_strx = (ns - newstrings) + sizeof (int);
14316667Sralph 		ns = index(ns, 0) + 1;
14416667Sralph 		if (ns > &newstrings[symsize]) {
14516667Sralph 			fprintf(stderr, "symorder: Strings grew longer!\n");
14616667Sralph 			exit(1);
147623Sbill 		}
148623Sbill 	}
14916667Sralph 
15016667Sralph 	lseek(o, sa, 0);
15116667Sralph 	if (write(o, (char *)symtab, n) != n) {
15216667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
15316667Sralph 		exit(1);
15416667Sralph 	}
15516667Sralph 	if (write(o, (char *)&symsize, sizeof (int)) != sizeof (int)) {
15616667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
15716667Sralph 		exit(1);
15816667Sralph 	}
15916667Sralph 	if (write(o, newstrings, symsize) != symsize) {
16016667Sralph 		fprintf(stderr, "symorder: Write failed "); perror(argv[2]);
16116667Sralph 		exit(1);
16216667Sralph 	}
16316667Sralph 	if ((i = nsym - symfound) > 0) {
16416667Sralph 		fprintf(stderr, "symorder: %d symbol%s not found:\n",
16516667Sralph 		    i, i == 1 ? "" : "s");
166623Sbill 		for (i = 0; i < nsym; i++) {
167623Sbill 			if (order[i].n_value == 0)
168623Sbill 				printf("%s\n", order[i].n_un.n_name);
169623Sbill 		}
170623Sbill 	}
17116667Sralph 	exit(0);
172623Sbill }
173623Sbill 
17416667Sralph reorder(st1, st2, n)
17516667Sralph 	register struct nlist *st1, *st2;
17616667Sralph 	register n;
17716667Sralph {
17816667Sralph 	register struct nlist *stp = st2 + nsym;
17916667Sralph 	register i;
18016667Sralph 
18116667Sralph 	while (--n >= 0) {
18216667Sralph 		i = inlist(st1);
18316667Sralph 		if (i == -1)
18416667Sralph 			*stp++ = *st1++;
18516667Sralph 		else
18616667Sralph 			st2[i] = *st1++;
18716667Sralph 	}
18816667Sralph }
18916667Sralph 
19016667Sralph inlist(p)
19116667Sralph 	register struct nlist *p;
19216667Sralph {
19316667Sralph 	register char *nam;
19416667Sralph 	register struct nlist *op;
19516667Sralph 
19616667Sralph 	if (p->n_type & N_STAB)
19716667Sralph 		return (-1);
19816667Sralph 	if (p->n_un.n_strx == 0)
19916667Sralph 		return (-1);
20016667Sralph 
20116667Sralph 	nam = &strings[p->n_un.n_strx - sizeof(int)];
20216667Sralph 	if (nam >= &strings[symsize]) {
20316667Sralph 		fprintf(stderr, "symorder: corrupt symtab\n");
20416667Sralph 		exit(1);
20516667Sralph 	}
20616667Sralph 
20716667Sralph 	for (op = &order[nsym]; --op >= order; ) {
20816667Sralph 		if (strcmp(op->n_un.n_name, nam) != 0)
20916667Sralph 			continue;
21016667Sralph 		if (op->n_value == 0) {
21116667Sralph 			op->n_value++;
21216667Sralph 			symfound++;
21316667Sralph 		}
21416667Sralph 		return (op - order);
21516667Sralph 	}
21616667Sralph 	return (-1);
21716667Sralph }
21816667Sralph 
219623Sbill #define	NSAVETAB	4096
220623Sbill char	*savetab;
221623Sbill int	saveleft;
222623Sbill 
223623Sbill char *
224623Sbill savestr(cp)
225623Sbill 	register char *cp;
226623Sbill {
227623Sbill 	register int len;
228623Sbill 
229623Sbill 	len = strlen(cp) + 1;
230623Sbill 	if (len > saveleft) {
231623Sbill 		saveleft = NSAVETAB;
232623Sbill 		if (len > saveleft)
233623Sbill 			saveleft = len;
234623Sbill 		savetab = (char *)malloc(saveleft);
235623Sbill 		if (savetab == 0) {
236623Sbill 			fprintf(stderr,
237623Sbill 			    "symorder: ran out of memory (savestr)\n");
238623Sbill 			exit(1);
239623Sbill 		}
240623Sbill 	}
241623Sbill 	strncpy(savetab, cp, len);
242623Sbill 	cp = savetab;
243623Sbill 	savetab += len;
244623Sbill 	saveleft -= len;
245623Sbill 	return (cp);
246623Sbill }
247