xref: /csrg-svn/old/symorder/symorder.c (revision 934)
1*934Sbill static char *sccsid = "@(#)symorder.c	3.2 (Berkeley) 10/01/80;
2623Sbill /*
3623Sbill  * symorder - reorder symbol table
4623Sbill  */
5623Sbill #include <stdio.h>
6623Sbill #include <pagsiz.h>
7623Sbill #include <sys/types.h>
8623Sbill #include <stat.h>
9*934Sbill #include <a.out.h>
10623Sbill 
11623Sbill #define SPACE 100
12623Sbill 
13623Sbill struct	nlist order[SPACE];
14623Sbill 
15623Sbill char	*savestr();
16623Sbill struct	nlist nl1, nl2;
17623Sbill struct	exec exec;
18623Sbill FILE	*strf;
19623Sbill off_t	sa, ss;
20623Sbill struct	stat stb;
21623Sbill int	nsym = 0;
22623Sbill int	symfound = 0;
23623Sbill char	asym[BUFSIZ];
24623Sbill 
25623Sbill main(argc, argv)
26623Sbill 	char **argv;
27623Sbill {
28623Sbill 	register struct nlist *p, *q;
29623Sbill 	register FILE *f;
30623Sbill 	register int na, i, j;
31623Sbill 	int maxlen;
32623Sbill 	int n, o;
33623Sbill 
34623Sbill 	if(argc != 3) {
35623Sbill 		fprintf(stderr, "Usage: symorder orderlist file\n");
36623Sbill 		exit(1);
37623Sbill 	}
38623Sbill 	if((f = fopen(argv[1], "r")) == NULL) {
39623Sbill 		perror(argv[1]);
40623Sbill 		exit(1);
41623Sbill 	}
42623Sbill 	maxlen = 0;
43623Sbill 	for(p = order; fgets(asym, sizeof asym, f) != NULL; p++, nsym++) {
44623Sbill 		for(i = 0; asym[i] && asym[i] != '\n'; i++)
45623Sbill 			continue;
46623Sbill 		if (asym[i] == '\n')
47623Sbill 			asym[i] = 0;
48623Sbill 		p->n_un.n_name = savestr(asym);
49623Sbill 		if (maxlen < strlen(p->n_un.n_name))
50623Sbill 			maxlen = strlen(p->n_un.n_name);
51623Sbill 	}
52623Sbill 	fclose(f);
53623Sbill 	if((f = fopen(argv[2], "r")) == NULL)
54623Sbill 		perror(argv[2]), exit(1);
55623Sbill 	if((strf = fopen(argv[2], "r")) == NULL)
56623Sbill 		perror(argv[2]), exit(1);
57623Sbill 	if((o = open(argv[2], 1)) < 0)
58623Sbill 		perror(argv[2]), exit(1);
59623Sbill 	if((fread(&exec, sizeof exec, 1, f)) != 1 || N_BADMAG(exec)) {
60623Sbill 		fprintf(stderr, "symorder: %s: bad format\n", argv[2]);
61623Sbill 		exit(1);
62623Sbill 	}
63623Sbill 	if (exec.a_syms == 0) {
64623Sbill 		fprintf(stderr, "symorder: %s is stripped\n", argv[2]);
65623Sbill 		exit(1);
66623Sbill 	}
67623Sbill 	fstat(fileno(f), &stb);
68623Sbill 	if (stb.st_size < N_STROFF(exec)+sizeof(off_t)) {
69623Sbill 		fprintf(stderr, "symorder: %s is in old format or truncated\n", argv[2]);
70623Sbill 		exit(1);
71623Sbill 	}
72623Sbill 	sa = N_SYMOFF(exec);
73623Sbill 	na = sa;
74623Sbill 	ss = sa + exec.a_syms;
75623Sbill 	fseek(f, sa, 0);
76623Sbill 	n = exec.a_syms;
77623Sbill 	while(n && symfound < nsym) {
78623Sbill 		if(fread(&nl1, sizeof nl1, 1, f) != 1) {
79623Sbill 			fprintf(stderr, "Short file "); perror(argv[2]);
80623Sbill 			exit(1);
81623Sbill 		}
82623Sbill 		na += sizeof nl1;
83623Sbill 		n -= sizeof nl1;
84623Sbill 		if (nl1.n_un.n_strx == 0 || nl1.n_type & N_STAB)
85623Sbill 			continue;
86623Sbill 		fseek(strf, ss+nl1.n_un.n_strx, 0);
87623Sbill 		fread(asym, maxlen+1, 1, strf);
88623Sbill 		for(j = 0; j < nsym; j++) {
89623Sbill 			for(i = 0; asym[i]; i++)
90623Sbill 				if(asym[i] != order[j].n_un.n_name[i])
91623Sbill 					goto cont;
92623Sbill 			if (order[j].n_un.n_name[i])
93623Sbill 				goto cont;
94623Sbill 			if (order[j].n_value)
95623Sbill 				goto cont;
96623Sbill 			order[j].n_value = 1;
97623Sbill 			fseek(f, (i = (sa+(j * sizeof nl1))), 0);
98623Sbill 			if(fread(&nl2, sizeof nl2, 1, f) != 1)
99623Sbill 				printf("Read err on 2nd asym\n");
100623Sbill 			lseek(o, i, 0);
101623Sbill 			if(write(o, &nl1, sizeof nl1) == -1)
102623Sbill 				perror("write1");
103623Sbill 			lseek(o, na-sizeof nl1, 0);
104623Sbill 			if(write(o, &nl2, sizeof nl2) == -1)
105623Sbill 				perror("write2");
106623Sbill 			fseek(f, 0, 0);
107623Sbill 			fseek(f, na, 0);
108623Sbill 			symfound++;
109623Sbill 			break;
110623Sbill 	cont:           ;
111623Sbill 
112623Sbill 		}
113623Sbill 	}
114623Sbill 	if(symfound < nsym) {
115623Sbill 		fprintf(stderr, "%d symbol(s) not found:\n", nsym - symfound);
116623Sbill 		for (i = 0; i < nsym; i++) {
117623Sbill 			if (order[i].n_value == 0)
118623Sbill 				printf("%s\n", order[i].n_un.n_name);
119623Sbill 		}
120623Sbill 	}
121623Sbill }
122623Sbill 
123623Sbill #define	NSAVETAB	4096
124623Sbill char	*savetab;
125623Sbill int	saveleft;
126623Sbill 
127623Sbill char *
128623Sbill savestr(cp)
129623Sbill 	register char *cp;
130623Sbill {
131623Sbill 	register int len;
132623Sbill 
133623Sbill 	len = strlen(cp) + 1;
134623Sbill 	if (len > saveleft) {
135623Sbill 		saveleft = NSAVETAB;
136623Sbill 		if (len > saveleft)
137623Sbill 			saveleft = len;
138623Sbill 		savetab = (char *)malloc(saveleft);
139623Sbill 		if (savetab == 0) {
140623Sbill 			fprintf(stderr,
141623Sbill 			    "symorder: ran out of memory (savestr)\n");
142623Sbill 			exit(1);
143623Sbill 		}
144623Sbill 	}
145623Sbill 	strncpy(savetab, cp, len);
146623Sbill 	cp = savetab;
147623Sbill 	savetab += len;
148623Sbill 	saveleft -= len;
149623Sbill 	return (cp);
150623Sbill }
151