xref: /inferno-os/utils/kl/obj.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #define	EXTERN
2*74a4d8c2SCharles.Forsyth #include	"l.h"
3*74a4d8c2SCharles.Forsyth #include	<ar.h>
4*74a4d8c2SCharles.Forsyth 
5*74a4d8c2SCharles.Forsyth #ifndef	DEFAULT
6*74a4d8c2SCharles.Forsyth #define	DEFAULT	'9'
7*74a4d8c2SCharles.Forsyth #endif
8*74a4d8c2SCharles.Forsyth 
9*74a4d8c2SCharles.Forsyth char	*noname		= "<none>";
10*74a4d8c2SCharles.Forsyth char	symname[]	= SYMDEF;
11*74a4d8c2SCharles.Forsyth char	thechar		= 'k';
12*74a4d8c2SCharles.Forsyth char	*thestring 	= "sparc";
13*74a4d8c2SCharles.Forsyth 
14*74a4d8c2SCharles.Forsyth /*
15*74a4d8c2SCharles.Forsyth  *	-H0 -T0x200000 -R0		is boot
16*74a4d8c2SCharles.Forsyth  *	-H2 -T4128 -R4096		is plan9 format
17*74a4d8c2SCharles.Forsyth  *	-H3 -T0xE0004000 -R4		is javastation boot format
18*74a4d8c2SCharles.Forsyth  */
19*74a4d8c2SCharles.Forsyth 
20*74a4d8c2SCharles.Forsyth void
main(int argc,char * argv[])21*74a4d8c2SCharles.Forsyth main(int argc, char *argv[])
22*74a4d8c2SCharles.Forsyth {
23*74a4d8c2SCharles.Forsyth 	int c;
24*74a4d8c2SCharles.Forsyth 	char *a;
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth 	Binit(&bso, 1, OWRITE);
27*74a4d8c2SCharles.Forsyth 	cout = -1;
28*74a4d8c2SCharles.Forsyth 	listinit();
29*74a4d8c2SCharles.Forsyth 	outfile = 0;
30*74a4d8c2SCharles.Forsyth 	nerrors = 0;
31*74a4d8c2SCharles.Forsyth 	curtext = P;
32*74a4d8c2SCharles.Forsyth 	HEADTYPE = -1;
33*74a4d8c2SCharles.Forsyth 	INITTEXT = -1;
34*74a4d8c2SCharles.Forsyth 	INITDAT = -1;
35*74a4d8c2SCharles.Forsyth 	INITRND = -1;
36*74a4d8c2SCharles.Forsyth 	INITENTRY = 0;
37*74a4d8c2SCharles.Forsyth 
38*74a4d8c2SCharles.Forsyth 	ARGBEGIN {
39*74a4d8c2SCharles.Forsyth 	default:
40*74a4d8c2SCharles.Forsyth 		c = ARGC();
41*74a4d8c2SCharles.Forsyth 		if(c >= 0 && c < sizeof(debug))
42*74a4d8c2SCharles.Forsyth 			debug[c]++;
43*74a4d8c2SCharles.Forsyth 		break;
44*74a4d8c2SCharles.Forsyth 	case 'o':
45*74a4d8c2SCharles.Forsyth 		outfile = ARGF();
46*74a4d8c2SCharles.Forsyth 		break;
47*74a4d8c2SCharles.Forsyth 	case 'E':
48*74a4d8c2SCharles.Forsyth 		a = ARGF();
49*74a4d8c2SCharles.Forsyth 		if(a)
50*74a4d8c2SCharles.Forsyth 			INITENTRY = a;
51*74a4d8c2SCharles.Forsyth 		break;
52*74a4d8c2SCharles.Forsyth 	case 'T':
53*74a4d8c2SCharles.Forsyth 		a = ARGF();
54*74a4d8c2SCharles.Forsyth 		if(a)
55*74a4d8c2SCharles.Forsyth 			INITTEXT = atolwhex(a);
56*74a4d8c2SCharles.Forsyth 		break;
57*74a4d8c2SCharles.Forsyth 	case 'D':
58*74a4d8c2SCharles.Forsyth 		a = ARGF();
59*74a4d8c2SCharles.Forsyth 		if(a)
60*74a4d8c2SCharles.Forsyth 			INITDAT = atolwhex(a);
61*74a4d8c2SCharles.Forsyth 		break;
62*74a4d8c2SCharles.Forsyth 	case 'R':
63*74a4d8c2SCharles.Forsyth 		a = ARGF();
64*74a4d8c2SCharles.Forsyth 		if(a)
65*74a4d8c2SCharles.Forsyth 			INITRND = atolwhex(a);
66*74a4d8c2SCharles.Forsyth 		break;
67*74a4d8c2SCharles.Forsyth 	case 'H':
68*74a4d8c2SCharles.Forsyth 		a = ARGF();
69*74a4d8c2SCharles.Forsyth 		if(a)
70*74a4d8c2SCharles.Forsyth 			HEADTYPE = atolwhex(a);
71*74a4d8c2SCharles.Forsyth 		break;
72*74a4d8c2SCharles.Forsyth 	} ARGEND
73*74a4d8c2SCharles.Forsyth 	USED(argc);
74*74a4d8c2SCharles.Forsyth 	if(*argv == 0) {
75*74a4d8c2SCharles.Forsyth 		diag("usage: vl [-options] objects");
76*74a4d8c2SCharles.Forsyth 		errorexit();
77*74a4d8c2SCharles.Forsyth 	}
78*74a4d8c2SCharles.Forsyth 	if(!debug['9'] && !debug['U'] && !debug['B'])
79*74a4d8c2SCharles.Forsyth 		debug[DEFAULT] = 1;
80*74a4d8c2SCharles.Forsyth 	if(HEADTYPE == -1) {
81*74a4d8c2SCharles.Forsyth 		if(debug['U'])
82*74a4d8c2SCharles.Forsyth 			HEADTYPE = 0;
83*74a4d8c2SCharles.Forsyth 		if(debug['B'])
84*74a4d8c2SCharles.Forsyth 			HEADTYPE = 1;
85*74a4d8c2SCharles.Forsyth 		if(debug['9'])
86*74a4d8c2SCharles.Forsyth 			HEADTYPE = 2;
87*74a4d8c2SCharles.Forsyth 	}
88*74a4d8c2SCharles.Forsyth 	switch(HEADTYPE) {
89*74a4d8c2SCharles.Forsyth 	default:
90*74a4d8c2SCharles.Forsyth 		diag("unknown -H option");
91*74a4d8c2SCharles.Forsyth 		errorexit();
92*74a4d8c2SCharles.Forsyth 
93*74a4d8c2SCharles.Forsyth 	case 0:	/* boot */
94*74a4d8c2SCharles.Forsyth 		HEADR = 32L;
95*74a4d8c2SCharles.Forsyth 		if(INITTEXT == -1)
96*74a4d8c2SCharles.Forsyth 			INITTEXT = 0x200000L;
97*74a4d8c2SCharles.Forsyth 		if(INITDAT == -1)
98*74a4d8c2SCharles.Forsyth 			INITDAT = 0;
99*74a4d8c2SCharles.Forsyth 		if(INITRND == -1)
100*74a4d8c2SCharles.Forsyth 			INITRND = 4096L;
101*74a4d8c2SCharles.Forsyth 		break;
102*74a4d8c2SCharles.Forsyth 	case 1:	/* garbage */
103*74a4d8c2SCharles.Forsyth 		HEADR = 20L+60L;
104*74a4d8c2SCharles.Forsyth 		if(INITTEXT == -1)
105*74a4d8c2SCharles.Forsyth 			INITTEXT = 0x80020000L;
106*74a4d8c2SCharles.Forsyth 		if(INITDAT == -1)
107*74a4d8c2SCharles.Forsyth 			INITDAT = 0;
108*74a4d8c2SCharles.Forsyth 		if(INITRND == -1)
109*74a4d8c2SCharles.Forsyth 			INITRND = 4;
110*74a4d8c2SCharles.Forsyth 		break;
111*74a4d8c2SCharles.Forsyth 	case 2:	/* plan 9 */
112*74a4d8c2SCharles.Forsyth 		HEADR = 32L;
113*74a4d8c2SCharles.Forsyth 		if(INITTEXT == -1)
114*74a4d8c2SCharles.Forsyth 			INITTEXT = 4128;
115*74a4d8c2SCharles.Forsyth 		if(INITDAT == -1)
116*74a4d8c2SCharles.Forsyth 			INITDAT = 0;
117*74a4d8c2SCharles.Forsyth 		if(INITRND == -1)
118*74a4d8c2SCharles.Forsyth 			INITRND = 4096;
119*74a4d8c2SCharles.Forsyth 		break;
120*74a4d8c2SCharles.Forsyth 	case 3:	/* javastation boot */
121*74a4d8c2SCharles.Forsyth 		HEADR = 32L;
122*74a4d8c2SCharles.Forsyth 		if(INITTEXT == -1)
123*74a4d8c2SCharles.Forsyth 			INITTEXT = 0xE0004020L;
124*74a4d8c2SCharles.Forsyth 		if(INITDAT == -1)
125*74a4d8c2SCharles.Forsyth 			INITDAT = 0;
126*74a4d8c2SCharles.Forsyth 		if(INITRND == -1)
127*74a4d8c2SCharles.Forsyth 			INITRND = 4;
128*74a4d8c2SCharles.Forsyth 		break;
129*74a4d8c2SCharles.Forsyth 	}
130*74a4d8c2SCharles.Forsyth 	if(INITDAT != 0 && INITRND != 0)
131*74a4d8c2SCharles.Forsyth 		print("warning: -D0x%lux is ignored because of -R0x%lux\n",
132*74a4d8c2SCharles.Forsyth 			INITDAT, INITRND);
133*74a4d8c2SCharles.Forsyth 	if(debug['v'])
134*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "HEADER = -H0x%d -T0x%lux -D0x%lux -R0x%lux\n",
135*74a4d8c2SCharles.Forsyth 			HEADTYPE, INITTEXT, INITDAT, INITRND);
136*74a4d8c2SCharles.Forsyth 	Bflush(&bso);
137*74a4d8c2SCharles.Forsyth 	zprg.as = AGOK;
138*74a4d8c2SCharles.Forsyth 	zprg.reg = NREG;
139*74a4d8c2SCharles.Forsyth 	zprg.from.name = D_NONE;
140*74a4d8c2SCharles.Forsyth 	zprg.from.type = D_NONE;
141*74a4d8c2SCharles.Forsyth 	zprg.from.reg = NREG;
142*74a4d8c2SCharles.Forsyth 	zprg.to = zprg.from;
143*74a4d8c2SCharles.Forsyth 	buildop();
144*74a4d8c2SCharles.Forsyth 	histgen = 0;
145*74a4d8c2SCharles.Forsyth 	textp = P;
146*74a4d8c2SCharles.Forsyth 	datap = P;
147*74a4d8c2SCharles.Forsyth 	pc = 0;
148*74a4d8c2SCharles.Forsyth 	dtype = 4;
149*74a4d8c2SCharles.Forsyth 	if(outfile == 0)
150*74a4d8c2SCharles.Forsyth 		outfile = "k.out";
151*74a4d8c2SCharles.Forsyth 	cout = create(outfile, 1, 0775);
152*74a4d8c2SCharles.Forsyth 	if(cout < 0) {
153*74a4d8c2SCharles.Forsyth 		diag("%s: cannot create", outfile);
154*74a4d8c2SCharles.Forsyth 		errorexit();
155*74a4d8c2SCharles.Forsyth 	}
156*74a4d8c2SCharles.Forsyth 	nuxiinit();
157*74a4d8c2SCharles.Forsyth 	version = 0;
158*74a4d8c2SCharles.Forsyth 	cbp = buf.cbuf;
159*74a4d8c2SCharles.Forsyth 	cbc = sizeof(buf.cbuf);
160*74a4d8c2SCharles.Forsyth 	firstp = prg();
161*74a4d8c2SCharles.Forsyth 	lastp = firstp;
162*74a4d8c2SCharles.Forsyth 
163*74a4d8c2SCharles.Forsyth 	if(INITENTRY == 0) {
164*74a4d8c2SCharles.Forsyth 		INITENTRY = "_main";
165*74a4d8c2SCharles.Forsyth 		if(debug['p'])
166*74a4d8c2SCharles.Forsyth 			INITENTRY = "_mainp";
167*74a4d8c2SCharles.Forsyth 		if(!debug['l'])
168*74a4d8c2SCharles.Forsyth 			lookup(INITENTRY, 0)->type = SXREF;
169*74a4d8c2SCharles.Forsyth 	} else
170*74a4d8c2SCharles.Forsyth 		lookup(INITENTRY, 0)->type = SXREF;
171*74a4d8c2SCharles.Forsyth 
172*74a4d8c2SCharles.Forsyth 	while(*argv)
173*74a4d8c2SCharles.Forsyth 		objfile(*argv++);
174*74a4d8c2SCharles.Forsyth 	if(!debug['l'])
175*74a4d8c2SCharles.Forsyth 		loadlib();
176*74a4d8c2SCharles.Forsyth 	firstp = firstp->link;
177*74a4d8c2SCharles.Forsyth 	if(firstp == P)
178*74a4d8c2SCharles.Forsyth 		goto out;
179*74a4d8c2SCharles.Forsyth 	patch();
180*74a4d8c2SCharles.Forsyth 	if(debug['p'])
181*74a4d8c2SCharles.Forsyth 		if(debug['1'])
182*74a4d8c2SCharles.Forsyth 			doprof1();
183*74a4d8c2SCharles.Forsyth 		else
184*74a4d8c2SCharles.Forsyth 			doprof2();
185*74a4d8c2SCharles.Forsyth 	dodata();
186*74a4d8c2SCharles.Forsyth 	follow();
187*74a4d8c2SCharles.Forsyth 	if(firstp == P)
188*74a4d8c2SCharles.Forsyth 		goto out;
189*74a4d8c2SCharles.Forsyth 	noops();
190*74a4d8c2SCharles.Forsyth 	span();
191*74a4d8c2SCharles.Forsyth 	asmb();
192*74a4d8c2SCharles.Forsyth 	undef();
193*74a4d8c2SCharles.Forsyth 
194*74a4d8c2SCharles.Forsyth out:
195*74a4d8c2SCharles.Forsyth 	if(debug['v']) {
196*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f cpu time\n", cputime());
197*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%ld memory used\n", tothunk);
198*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
199*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
200*74a4d8c2SCharles.Forsyth 	}
201*74a4d8c2SCharles.Forsyth 	errorexit();
202*74a4d8c2SCharles.Forsyth }
203*74a4d8c2SCharles.Forsyth 
204*74a4d8c2SCharles.Forsyth void
loadlib(void)205*74a4d8c2SCharles.Forsyth loadlib(void)
206*74a4d8c2SCharles.Forsyth {
207*74a4d8c2SCharles.Forsyth 	int i;
208*74a4d8c2SCharles.Forsyth 	long h;
209*74a4d8c2SCharles.Forsyth 	Sym *s;
210*74a4d8c2SCharles.Forsyth 
211*74a4d8c2SCharles.Forsyth loop:
212*74a4d8c2SCharles.Forsyth 	xrefresolv = 0;
213*74a4d8c2SCharles.Forsyth 	for(i=0; i<libraryp; i++) {
214*74a4d8c2SCharles.Forsyth 		if(debug['v'])
215*74a4d8c2SCharles.Forsyth 			Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);
216*74a4d8c2SCharles.Forsyth 		objfile(library[i]);
217*74a4d8c2SCharles.Forsyth 	}
218*74a4d8c2SCharles.Forsyth 	if(xrefresolv)
219*74a4d8c2SCharles.Forsyth 	for(h=0; h<nelem(hash); h++)
220*74a4d8c2SCharles.Forsyth 	for(s = hash[h]; s != S; s = s->link)
221*74a4d8c2SCharles.Forsyth 		if(s->type == SXREF)
222*74a4d8c2SCharles.Forsyth 			goto loop;
223*74a4d8c2SCharles.Forsyth }
224*74a4d8c2SCharles.Forsyth 
225*74a4d8c2SCharles.Forsyth void
errorexit(void)226*74a4d8c2SCharles.Forsyth errorexit(void)
227*74a4d8c2SCharles.Forsyth {
228*74a4d8c2SCharles.Forsyth 
229*74a4d8c2SCharles.Forsyth 	Bflush(&bso);
230*74a4d8c2SCharles.Forsyth 	if(nerrors) {
231*74a4d8c2SCharles.Forsyth 		if(cout >= 0)
232*74a4d8c2SCharles.Forsyth 			remove(outfile);
233*74a4d8c2SCharles.Forsyth 		exits("error");
234*74a4d8c2SCharles.Forsyth 	}
235*74a4d8c2SCharles.Forsyth 	exits(0);
236*74a4d8c2SCharles.Forsyth }
237*74a4d8c2SCharles.Forsyth 
238*74a4d8c2SCharles.Forsyth void
objfile(char * file)239*74a4d8c2SCharles.Forsyth objfile(char *file)
240*74a4d8c2SCharles.Forsyth {
241*74a4d8c2SCharles.Forsyth 	long off, esym, cnt, l;
242*74a4d8c2SCharles.Forsyth 	int f, work;
243*74a4d8c2SCharles.Forsyth 	Sym *s;
244*74a4d8c2SCharles.Forsyth 	char magbuf[SARMAG];
245*74a4d8c2SCharles.Forsyth 	char name[100], pname[150];
246*74a4d8c2SCharles.Forsyth 	struct ar_hdr arhdr;
247*74a4d8c2SCharles.Forsyth 	char *e, *start, *stop;
248*74a4d8c2SCharles.Forsyth 
249*74a4d8c2SCharles.Forsyth 	if(file[0] == '-' && file[1] == 'l') {
250*74a4d8c2SCharles.Forsyth 		if(debug['9'])
251*74a4d8c2SCharles.Forsyth 			sprint(name, "/%s/lib/lib", thestring);
252*74a4d8c2SCharles.Forsyth 		else
253*74a4d8c2SCharles.Forsyth 			sprint(name, "/usr/%clib/lib", thechar);
254*74a4d8c2SCharles.Forsyth 		strcat(name, file+2);
255*74a4d8c2SCharles.Forsyth 		strcat(name, ".a");
256*74a4d8c2SCharles.Forsyth 		file = name;
257*74a4d8c2SCharles.Forsyth 	}
258*74a4d8c2SCharles.Forsyth 	if(debug['v'])
259*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
260*74a4d8c2SCharles.Forsyth 	Bflush(&bso);
261*74a4d8c2SCharles.Forsyth 	f = open(file, 0);
262*74a4d8c2SCharles.Forsyth 	if(f < 0) {
263*74a4d8c2SCharles.Forsyth 		diag("cannot open file: %s", file);
264*74a4d8c2SCharles.Forsyth 		errorexit();
265*74a4d8c2SCharles.Forsyth 	}
266*74a4d8c2SCharles.Forsyth 	l = read(f, magbuf, SARMAG);
267*74a4d8c2SCharles.Forsyth 	if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
268*74a4d8c2SCharles.Forsyth 		/* load it as a regular file */
269*74a4d8c2SCharles.Forsyth 		l = seek(f, 0L, 2);
270*74a4d8c2SCharles.Forsyth 		seek(f, 0L, 0);
271*74a4d8c2SCharles.Forsyth 		ldobj(f, l, file);
272*74a4d8c2SCharles.Forsyth 		close(f);
273*74a4d8c2SCharles.Forsyth 		return;
274*74a4d8c2SCharles.Forsyth 	}
275*74a4d8c2SCharles.Forsyth 
276*74a4d8c2SCharles.Forsyth 	l = read(f, &arhdr, SAR_HDR);
277*74a4d8c2SCharles.Forsyth 	if(l != SAR_HDR) {
278*74a4d8c2SCharles.Forsyth 		diag("%s: short read on archive file symbol header", file);
279*74a4d8c2SCharles.Forsyth 		goto out;
280*74a4d8c2SCharles.Forsyth 	}
281*74a4d8c2SCharles.Forsyth 	if(strncmp(arhdr.name, symname, strlen(symname))) {
282*74a4d8c2SCharles.Forsyth 		diag("%s: first entry not symbol header", file);
283*74a4d8c2SCharles.Forsyth 		goto out;
284*74a4d8c2SCharles.Forsyth 	}
285*74a4d8c2SCharles.Forsyth 
286*74a4d8c2SCharles.Forsyth 	esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
287*74a4d8c2SCharles.Forsyth 	off = SARMAG + SAR_HDR;
288*74a4d8c2SCharles.Forsyth 
289*74a4d8c2SCharles.Forsyth 	/*
290*74a4d8c2SCharles.Forsyth 	 * just bang the whole symbol file into memory
291*74a4d8c2SCharles.Forsyth 	 */
292*74a4d8c2SCharles.Forsyth 	seek(f, off, 0);
293*74a4d8c2SCharles.Forsyth 	cnt = esym - off;
294*74a4d8c2SCharles.Forsyth 	start = malloc(cnt + 10);
295*74a4d8c2SCharles.Forsyth 	cnt = read(f, start, cnt);
296*74a4d8c2SCharles.Forsyth 	if(cnt <= 0){
297*74a4d8c2SCharles.Forsyth 		close(f);
298*74a4d8c2SCharles.Forsyth 		return;
299*74a4d8c2SCharles.Forsyth 	}
300*74a4d8c2SCharles.Forsyth 	stop = &start[cnt];
301*74a4d8c2SCharles.Forsyth 	memset(stop, 0, 10);
302*74a4d8c2SCharles.Forsyth 
303*74a4d8c2SCharles.Forsyth 	work = 1;
304*74a4d8c2SCharles.Forsyth 	while(work){
305*74a4d8c2SCharles.Forsyth 		if(debug['v'])
306*74a4d8c2SCharles.Forsyth 			Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file);
307*74a4d8c2SCharles.Forsyth 		Bflush(&bso);
308*74a4d8c2SCharles.Forsyth 		work = 0;
309*74a4d8c2SCharles.Forsyth 		for(e = start; e < stop; e = strchr(e+5, 0) + 1) {
310*74a4d8c2SCharles.Forsyth 			s = lookup(e+5, 0);
311*74a4d8c2SCharles.Forsyth 			if(s->type != SXREF)
312*74a4d8c2SCharles.Forsyth 				continue;
313*74a4d8c2SCharles.Forsyth 			sprint(pname, "%s(%s)", file, s->name);
314*74a4d8c2SCharles.Forsyth 			if(debug['v'])
315*74a4d8c2SCharles.Forsyth 				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
316*74a4d8c2SCharles.Forsyth 			Bflush(&bso);
317*74a4d8c2SCharles.Forsyth 			l = e[1] & 0xff;
318*74a4d8c2SCharles.Forsyth 			l |= (e[2] & 0xff) << 8;
319*74a4d8c2SCharles.Forsyth 			l |= (e[3] & 0xff) << 16;
320*74a4d8c2SCharles.Forsyth 			l |= (e[4] & 0xff) << 24;
321*74a4d8c2SCharles.Forsyth 			seek(f, l, 0);
322*74a4d8c2SCharles.Forsyth 			l = read(f, &arhdr, SAR_HDR);
323*74a4d8c2SCharles.Forsyth 			if(l != SAR_HDR)
324*74a4d8c2SCharles.Forsyth 				goto bad;
325*74a4d8c2SCharles.Forsyth 			if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
326*74a4d8c2SCharles.Forsyth 				goto bad;
327*74a4d8c2SCharles.Forsyth 			l = atolwhex(arhdr.size);
328*74a4d8c2SCharles.Forsyth 			ldobj(f, l, pname);
329*74a4d8c2SCharles.Forsyth 			if(s->type == SXREF) {
330*74a4d8c2SCharles.Forsyth 				diag("%s: failed to load: %s", file, s->name);
331*74a4d8c2SCharles.Forsyth 				errorexit();
332*74a4d8c2SCharles.Forsyth 			}
333*74a4d8c2SCharles.Forsyth 			work = 1;
334*74a4d8c2SCharles.Forsyth 			xrefresolv = 1;
335*74a4d8c2SCharles.Forsyth 		}
336*74a4d8c2SCharles.Forsyth 	}
337*74a4d8c2SCharles.Forsyth 	return;
338*74a4d8c2SCharles.Forsyth 
339*74a4d8c2SCharles.Forsyth bad:
340*74a4d8c2SCharles.Forsyth 	diag("%s: bad or out of date archive", file);
341*74a4d8c2SCharles.Forsyth out:
342*74a4d8c2SCharles.Forsyth 	close(f);
343*74a4d8c2SCharles.Forsyth }
344*74a4d8c2SCharles.Forsyth 
345*74a4d8c2SCharles.Forsyth int
zaddr(uchar * p,Adr * a,Sym * h[])346*74a4d8c2SCharles.Forsyth zaddr(uchar *p, Adr *a, Sym *h[])
347*74a4d8c2SCharles.Forsyth {
348*74a4d8c2SCharles.Forsyth 	int i, c;
349*74a4d8c2SCharles.Forsyth 	long l;
350*74a4d8c2SCharles.Forsyth 	Sym *s;
351*74a4d8c2SCharles.Forsyth 	Auto *u;
352*74a4d8c2SCharles.Forsyth 
353*74a4d8c2SCharles.Forsyth 	c = p[2];
354*74a4d8c2SCharles.Forsyth 	if(c < 0 || c > NSYM){
355*74a4d8c2SCharles.Forsyth 		print("sym out of range: %d\n", c);
356*74a4d8c2SCharles.Forsyth 		p[0] = AEND+1;
357*74a4d8c2SCharles.Forsyth 		return 0;
358*74a4d8c2SCharles.Forsyth 	}
359*74a4d8c2SCharles.Forsyth 	a->type = p[0];
360*74a4d8c2SCharles.Forsyth 	a->reg = p[1];
361*74a4d8c2SCharles.Forsyth 	a->sym = h[c];
362*74a4d8c2SCharles.Forsyth 	a->name = p[3];
363*74a4d8c2SCharles.Forsyth 	c = 4;
364*74a4d8c2SCharles.Forsyth 
365*74a4d8c2SCharles.Forsyth 	if(a->reg < 0 || a->reg > NREG) {
366*74a4d8c2SCharles.Forsyth 		print("register out of range %d\n", a->reg);
367*74a4d8c2SCharles.Forsyth 		p[0] = AEND+1;
368*74a4d8c2SCharles.Forsyth 		return 0;	/*  force real diagnostic */
369*74a4d8c2SCharles.Forsyth 	}
370*74a4d8c2SCharles.Forsyth 
371*74a4d8c2SCharles.Forsyth 	switch(a->type) {
372*74a4d8c2SCharles.Forsyth 	default:
373*74a4d8c2SCharles.Forsyth 		print("unknown type %d\n", a->type);
374*74a4d8c2SCharles.Forsyth 		p[0] = AEND+1;
375*74a4d8c2SCharles.Forsyth 		return 0;	/* force real diagnostic */
376*74a4d8c2SCharles.Forsyth 
377*74a4d8c2SCharles.Forsyth 	case D_NONE:
378*74a4d8c2SCharles.Forsyth 	case D_REG:
379*74a4d8c2SCharles.Forsyth 	case D_FREG:
380*74a4d8c2SCharles.Forsyth 	case D_CREG:
381*74a4d8c2SCharles.Forsyth 	case D_PREG:
382*74a4d8c2SCharles.Forsyth 		break;
383*74a4d8c2SCharles.Forsyth 
384*74a4d8c2SCharles.Forsyth 	case D_BRANCH:
385*74a4d8c2SCharles.Forsyth 	case D_OREG:
386*74a4d8c2SCharles.Forsyth 	case D_ASI:
387*74a4d8c2SCharles.Forsyth 	case D_CONST:
388*74a4d8c2SCharles.Forsyth 		a->offset = p[4] | (p[5]<<8) |
389*74a4d8c2SCharles.Forsyth 			(p[6]<<16) | (p[7]<<24);
390*74a4d8c2SCharles.Forsyth 		c += 4;
391*74a4d8c2SCharles.Forsyth 		break;
392*74a4d8c2SCharles.Forsyth 
393*74a4d8c2SCharles.Forsyth 	case D_SCONST:
394*74a4d8c2SCharles.Forsyth 		memmove(a->sval, p+4, NSNAME);
395*74a4d8c2SCharles.Forsyth 		c += NSNAME;
396*74a4d8c2SCharles.Forsyth 		break;
397*74a4d8c2SCharles.Forsyth 
398*74a4d8c2SCharles.Forsyth 	case D_FCONST:
399*74a4d8c2SCharles.Forsyth 		a->ieee.l = p[4] | (p[5]<<8) |
400*74a4d8c2SCharles.Forsyth 			(p[6]<<16) | (p[7]<<24);
401*74a4d8c2SCharles.Forsyth 		a->ieee.h = p[8] | (p[9]<<8) |
402*74a4d8c2SCharles.Forsyth 			(p[10]<<16) | (p[11]<<24);
403*74a4d8c2SCharles.Forsyth 		c += 8;
404*74a4d8c2SCharles.Forsyth 		break;
405*74a4d8c2SCharles.Forsyth 	}
406*74a4d8c2SCharles.Forsyth 	s = a->sym;
407*74a4d8c2SCharles.Forsyth 	if(s == S)
408*74a4d8c2SCharles.Forsyth 		goto out;
409*74a4d8c2SCharles.Forsyth 	i = a->name;
410*74a4d8c2SCharles.Forsyth 	if(i != D_AUTO && i != D_PARAM)
411*74a4d8c2SCharles.Forsyth 		goto out;
412*74a4d8c2SCharles.Forsyth 
413*74a4d8c2SCharles.Forsyth 	l = a->offset;
414*74a4d8c2SCharles.Forsyth 	for(u=curauto; u; u=u->link)
415*74a4d8c2SCharles.Forsyth 		if(u->asym == s)
416*74a4d8c2SCharles.Forsyth 		if(u->type == i) {
417*74a4d8c2SCharles.Forsyth 			if(u->aoffset > l)
418*74a4d8c2SCharles.Forsyth 				u->aoffset = l;
419*74a4d8c2SCharles.Forsyth 			goto out;
420*74a4d8c2SCharles.Forsyth 		}
421*74a4d8c2SCharles.Forsyth 
422*74a4d8c2SCharles.Forsyth 	u = malloc(sizeof(Auto));
423*74a4d8c2SCharles.Forsyth 
424*74a4d8c2SCharles.Forsyth 	u->link = curauto;
425*74a4d8c2SCharles.Forsyth 	curauto = u;
426*74a4d8c2SCharles.Forsyth 	u->asym = s;
427*74a4d8c2SCharles.Forsyth 	u->aoffset = l;
428*74a4d8c2SCharles.Forsyth 	u->type = i;
429*74a4d8c2SCharles.Forsyth out:
430*74a4d8c2SCharles.Forsyth 	return c;
431*74a4d8c2SCharles.Forsyth }
432*74a4d8c2SCharles.Forsyth 
433*74a4d8c2SCharles.Forsyth void
addlib(char * obj)434*74a4d8c2SCharles.Forsyth addlib(char *obj)
435*74a4d8c2SCharles.Forsyth {
436*74a4d8c2SCharles.Forsyth 	char name[1024], comp[256], *p;
437*74a4d8c2SCharles.Forsyth 	int i;
438*74a4d8c2SCharles.Forsyth 
439*74a4d8c2SCharles.Forsyth 	if(histfrogp <= 0)
440*74a4d8c2SCharles.Forsyth 		return;
441*74a4d8c2SCharles.Forsyth 
442*74a4d8c2SCharles.Forsyth 	if(histfrog[0]->name[1] == '/') {
443*74a4d8c2SCharles.Forsyth 		sprint(name, "");
444*74a4d8c2SCharles.Forsyth 		i = 1;
445*74a4d8c2SCharles.Forsyth 	} else
446*74a4d8c2SCharles.Forsyth 	if(histfrog[0]->name[1] == '.') {
447*74a4d8c2SCharles.Forsyth 		sprint(name, ".");
448*74a4d8c2SCharles.Forsyth 		i = 0;
449*74a4d8c2SCharles.Forsyth 	} else {
450*74a4d8c2SCharles.Forsyth 		if(debug['9'])
451*74a4d8c2SCharles.Forsyth 			sprint(name, "/%s/lib", thestring);
452*74a4d8c2SCharles.Forsyth 		else
453*74a4d8c2SCharles.Forsyth 			sprint(name, "/usr/%clib", thechar);
454*74a4d8c2SCharles.Forsyth 		i = 0;
455*74a4d8c2SCharles.Forsyth 	}
456*74a4d8c2SCharles.Forsyth 
457*74a4d8c2SCharles.Forsyth 	for(; i<histfrogp; i++) {
458*74a4d8c2SCharles.Forsyth 		snprint(comp, sizeof comp, histfrog[i]->name+1);
459*74a4d8c2SCharles.Forsyth 		for(;;) {
460*74a4d8c2SCharles.Forsyth 			p = strstr(comp, "$O");
461*74a4d8c2SCharles.Forsyth 			if(p == 0)
462*74a4d8c2SCharles.Forsyth 				break;
463*74a4d8c2SCharles.Forsyth 			memmove(p+1, p+2, strlen(p+2)+1);
464*74a4d8c2SCharles.Forsyth 			p[0] = thechar;
465*74a4d8c2SCharles.Forsyth 		}
466*74a4d8c2SCharles.Forsyth 		for(;;) {
467*74a4d8c2SCharles.Forsyth 			p = strstr(comp, "$M");
468*74a4d8c2SCharles.Forsyth 			if(p == 0)
469*74a4d8c2SCharles.Forsyth 				break;
470*74a4d8c2SCharles.Forsyth 			if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
471*74a4d8c2SCharles.Forsyth 				diag("library component too long");
472*74a4d8c2SCharles.Forsyth 				return;
473*74a4d8c2SCharles.Forsyth 			}
474*74a4d8c2SCharles.Forsyth 			memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
475*74a4d8c2SCharles.Forsyth 			memmove(p, thestring, strlen(thestring));
476*74a4d8c2SCharles.Forsyth 		}
477*74a4d8c2SCharles.Forsyth 		if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
478*74a4d8c2SCharles.Forsyth 			diag("library component too long");
479*74a4d8c2SCharles.Forsyth 			return;
480*74a4d8c2SCharles.Forsyth 		}
481*74a4d8c2SCharles.Forsyth 		strcat(name, "/");
482*74a4d8c2SCharles.Forsyth 		strcat(name, comp);
483*74a4d8c2SCharles.Forsyth 	}
484*74a4d8c2SCharles.Forsyth 	for(i=0; i<libraryp; i++)
485*74a4d8c2SCharles.Forsyth 		if(strcmp(name, library[i]) == 0)
486*74a4d8c2SCharles.Forsyth 			return;
487*74a4d8c2SCharles.Forsyth 	if(libraryp == nelem(library)){
488*74a4d8c2SCharles.Forsyth 		diag("too many autolibs; skipping %s", name);
489*74a4d8c2SCharles.Forsyth 		return;
490*74a4d8c2SCharles.Forsyth 	}
491*74a4d8c2SCharles.Forsyth 
492*74a4d8c2SCharles.Forsyth 	p = malloc(strlen(name) + 1);
493*74a4d8c2SCharles.Forsyth 	strcpy(p, name);
494*74a4d8c2SCharles.Forsyth 	library[libraryp] = p;
495*74a4d8c2SCharles.Forsyth 	p = malloc(strlen(obj) + 1);
496*74a4d8c2SCharles.Forsyth 	strcpy(p, obj);
497*74a4d8c2SCharles.Forsyth 	libraryobj[libraryp] = p;
498*74a4d8c2SCharles.Forsyth 	libraryp++;
499*74a4d8c2SCharles.Forsyth }
500*74a4d8c2SCharles.Forsyth 
501*74a4d8c2SCharles.Forsyth void
addhist(long line,int type)502*74a4d8c2SCharles.Forsyth addhist(long line, int type)
503*74a4d8c2SCharles.Forsyth {
504*74a4d8c2SCharles.Forsyth 	Auto *u;
505*74a4d8c2SCharles.Forsyth 	Sym *s;
506*74a4d8c2SCharles.Forsyth 	int i, j, k;
507*74a4d8c2SCharles.Forsyth 
508*74a4d8c2SCharles.Forsyth 	u = malloc(sizeof(Auto));
509*74a4d8c2SCharles.Forsyth 	s = malloc(sizeof(Sym));
510*74a4d8c2SCharles.Forsyth 	s->name = malloc(2*(histfrogp+1) + 1);
511*74a4d8c2SCharles.Forsyth 
512*74a4d8c2SCharles.Forsyth 	u->asym = s;
513*74a4d8c2SCharles.Forsyth 	u->type = type;
514*74a4d8c2SCharles.Forsyth 	u->aoffset = line;
515*74a4d8c2SCharles.Forsyth 	u->link = curhist;
516*74a4d8c2SCharles.Forsyth 	curhist = u;
517*74a4d8c2SCharles.Forsyth 
518*74a4d8c2SCharles.Forsyth 	j = 1;
519*74a4d8c2SCharles.Forsyth 	for(i=0; i<histfrogp; i++) {
520*74a4d8c2SCharles.Forsyth 		k = histfrog[i]->value;
521*74a4d8c2SCharles.Forsyth 		s->name[j+0] = k>>8;
522*74a4d8c2SCharles.Forsyth 		s->name[j+1] = k;
523*74a4d8c2SCharles.Forsyth 		j += 2;
524*74a4d8c2SCharles.Forsyth 	}
525*74a4d8c2SCharles.Forsyth }
526*74a4d8c2SCharles.Forsyth 
527*74a4d8c2SCharles.Forsyth void
histtoauto(void)528*74a4d8c2SCharles.Forsyth histtoauto(void)
529*74a4d8c2SCharles.Forsyth {
530*74a4d8c2SCharles.Forsyth 	Auto *l;
531*74a4d8c2SCharles.Forsyth 
532*74a4d8c2SCharles.Forsyth 	while(l = curhist) {
533*74a4d8c2SCharles.Forsyth 		curhist = l->link;
534*74a4d8c2SCharles.Forsyth 		l->link = curauto;
535*74a4d8c2SCharles.Forsyth 		curauto = l;
536*74a4d8c2SCharles.Forsyth 	}
537*74a4d8c2SCharles.Forsyth }
538*74a4d8c2SCharles.Forsyth 
539*74a4d8c2SCharles.Forsyth void
collapsefrog(Sym * s)540*74a4d8c2SCharles.Forsyth collapsefrog(Sym *s)
541*74a4d8c2SCharles.Forsyth {
542*74a4d8c2SCharles.Forsyth 	int i;
543*74a4d8c2SCharles.Forsyth 
544*74a4d8c2SCharles.Forsyth 	/*
545*74a4d8c2SCharles.Forsyth 	 * bad encoding of path components only allows
546*74a4d8c2SCharles.Forsyth 	 * MAXHIST components. if there is an overflow,
547*74a4d8c2SCharles.Forsyth 	 * first try to collapse xxx/..
548*74a4d8c2SCharles.Forsyth 	 */
549*74a4d8c2SCharles.Forsyth 	for(i=1; i<histfrogp; i++)
550*74a4d8c2SCharles.Forsyth 		if(strcmp(histfrog[i]->name+1, "..") == 0) {
551*74a4d8c2SCharles.Forsyth 			memmove(histfrog+i-1, histfrog+i+1,
552*74a4d8c2SCharles.Forsyth 				(histfrogp-i-1)*sizeof(histfrog[0]));
553*74a4d8c2SCharles.Forsyth 			histfrogp--;
554*74a4d8c2SCharles.Forsyth 			goto out;
555*74a4d8c2SCharles.Forsyth 		}
556*74a4d8c2SCharles.Forsyth 
557*74a4d8c2SCharles.Forsyth 	/*
558*74a4d8c2SCharles.Forsyth 	 * next try to collapse .
559*74a4d8c2SCharles.Forsyth 	 */
560*74a4d8c2SCharles.Forsyth 	for(i=0; i<histfrogp; i++)
561*74a4d8c2SCharles.Forsyth 		if(strcmp(histfrog[i]->name+1, ".") == 0) {
562*74a4d8c2SCharles.Forsyth 			memmove(histfrog+i, histfrog+i+1,
563*74a4d8c2SCharles.Forsyth 				(histfrogp-i-1)*sizeof(histfrog[0]));
564*74a4d8c2SCharles.Forsyth 			goto out;
565*74a4d8c2SCharles.Forsyth 		}
566*74a4d8c2SCharles.Forsyth 
567*74a4d8c2SCharles.Forsyth 	/*
568*74a4d8c2SCharles.Forsyth 	 * last chance, just truncate from front
569*74a4d8c2SCharles.Forsyth 	 */
570*74a4d8c2SCharles.Forsyth 	memmove(histfrog+0, histfrog+1,
571*74a4d8c2SCharles.Forsyth 		(histfrogp-1)*sizeof(histfrog[0]));
572*74a4d8c2SCharles.Forsyth 
573*74a4d8c2SCharles.Forsyth out:
574*74a4d8c2SCharles.Forsyth 	histfrog[histfrogp-1] = s;
575*74a4d8c2SCharles.Forsyth }
576*74a4d8c2SCharles.Forsyth 
577*74a4d8c2SCharles.Forsyth void
nopout(Prog * p)578*74a4d8c2SCharles.Forsyth nopout(Prog *p)
579*74a4d8c2SCharles.Forsyth {
580*74a4d8c2SCharles.Forsyth 	p->as = ANOP;
581*74a4d8c2SCharles.Forsyth 	p->from.type = D_NONE;
582*74a4d8c2SCharles.Forsyth 	p->to.type = D_NONE;
583*74a4d8c2SCharles.Forsyth }
584*74a4d8c2SCharles.Forsyth 
585*74a4d8c2SCharles.Forsyth uchar*
readsome(int f,uchar * buf,uchar * good,uchar * stop,int max)586*74a4d8c2SCharles.Forsyth readsome(int f, uchar *buf, uchar *good, uchar *stop, int max)
587*74a4d8c2SCharles.Forsyth {
588*74a4d8c2SCharles.Forsyth 	int n;
589*74a4d8c2SCharles.Forsyth 
590*74a4d8c2SCharles.Forsyth 	n = stop - good;
591*74a4d8c2SCharles.Forsyth 	memmove(buf, good, stop - good);
592*74a4d8c2SCharles.Forsyth 	stop = buf + n;
593*74a4d8c2SCharles.Forsyth 	n = MAXIO - n;
594*74a4d8c2SCharles.Forsyth 	if(n > max)
595*74a4d8c2SCharles.Forsyth 		n = max;
596*74a4d8c2SCharles.Forsyth 	n = read(f, stop, n);
597*74a4d8c2SCharles.Forsyth 	if(n <= 0)
598*74a4d8c2SCharles.Forsyth 		return 0;
599*74a4d8c2SCharles.Forsyth 	return stop + n;
600*74a4d8c2SCharles.Forsyth }
601*74a4d8c2SCharles.Forsyth 
602*74a4d8c2SCharles.Forsyth void
ldobj(int f,long c,char * pn)603*74a4d8c2SCharles.Forsyth ldobj(int f, long c, char *pn)
604*74a4d8c2SCharles.Forsyth {
605*74a4d8c2SCharles.Forsyth 	Prog *p, *t;
606*74a4d8c2SCharles.Forsyth 	Sym *h[NSYM], *s, *di;
607*74a4d8c2SCharles.Forsyth 	int v, o, r, skip;
608*74a4d8c2SCharles.Forsyth 	long ipc;
609*74a4d8c2SCharles.Forsyth 	uchar *bloc, *bsize, *stop;
610*74a4d8c2SCharles.Forsyth 
611*74a4d8c2SCharles.Forsyth 	bsize = buf.xbuf;
612*74a4d8c2SCharles.Forsyth 	bloc = buf.xbuf;
613*74a4d8c2SCharles.Forsyth 	di = S;
614*74a4d8c2SCharles.Forsyth 
615*74a4d8c2SCharles.Forsyth newloop:
616*74a4d8c2SCharles.Forsyth 	memset(h, 0, sizeof(h));
617*74a4d8c2SCharles.Forsyth 	histfrogp = 0;
618*74a4d8c2SCharles.Forsyth 	version++;
619*74a4d8c2SCharles.Forsyth 	ipc = pc;
620*74a4d8c2SCharles.Forsyth 	skip = 0;
621*74a4d8c2SCharles.Forsyth 
622*74a4d8c2SCharles.Forsyth loop:
623*74a4d8c2SCharles.Forsyth 	if(c <= 0)
624*74a4d8c2SCharles.Forsyth 		goto eof;
625*74a4d8c2SCharles.Forsyth 	r = bsize - bloc;
626*74a4d8c2SCharles.Forsyth 	if(r < 100 && r < c) {		/* enough for largest prog */
627*74a4d8c2SCharles.Forsyth 		bsize = readsome(f, buf.xbuf, bloc, bsize, c);
628*74a4d8c2SCharles.Forsyth 		if(bsize == 0)
629*74a4d8c2SCharles.Forsyth 			goto eof;
630*74a4d8c2SCharles.Forsyth 		bloc = buf.xbuf;
631*74a4d8c2SCharles.Forsyth 		goto loop;
632*74a4d8c2SCharles.Forsyth 	}
633*74a4d8c2SCharles.Forsyth 	o = bloc[0];		/* as */
634*74a4d8c2SCharles.Forsyth 	if(o <= 0 || o >= ALAST) {
635*74a4d8c2SCharles.Forsyth 		diag("%s: opcode out of range %d", pn, o);
636*74a4d8c2SCharles.Forsyth 		print("	probably not a .k file\n");
637*74a4d8c2SCharles.Forsyth 		errorexit();
638*74a4d8c2SCharles.Forsyth 	}
639*74a4d8c2SCharles.Forsyth 	if(o == ANAME || o == ASIGNAME) {
640*74a4d8c2SCharles.Forsyth 		if(o == ASIGNAME) {
641*74a4d8c2SCharles.Forsyth 			bloc += 4;
642*74a4d8c2SCharles.Forsyth 			c -= 4;
643*74a4d8c2SCharles.Forsyth 		}
644*74a4d8c2SCharles.Forsyth 		stop = memchr(&bloc[3], 0, bsize-&bloc[3]);
645*74a4d8c2SCharles.Forsyth 		if(stop == 0){
646*74a4d8c2SCharles.Forsyth 			bsize = readsome(f, buf.xbuf, bloc, bsize, c);
647*74a4d8c2SCharles.Forsyth 			if(bsize == 0)
648*74a4d8c2SCharles.Forsyth 				goto eof;
649*74a4d8c2SCharles.Forsyth 			bloc = buf.xbuf;
650*74a4d8c2SCharles.Forsyth 			stop = memchr(&bloc[3], 0, bsize-&bloc[3]);
651*74a4d8c2SCharles.Forsyth 			if(stop == 0){
652*74a4d8c2SCharles.Forsyth 				fprint(2, "%s: name too long\n", pn);
653*74a4d8c2SCharles.Forsyth 				errorexit();
654*74a4d8c2SCharles.Forsyth 			}
655*74a4d8c2SCharles.Forsyth 		}
656*74a4d8c2SCharles.Forsyth 		v = bloc[1];	/* type */
657*74a4d8c2SCharles.Forsyth 		o = bloc[2];	/* sym */
658*74a4d8c2SCharles.Forsyth 		bloc += 3;
659*74a4d8c2SCharles.Forsyth 		c -= 3;
660*74a4d8c2SCharles.Forsyth 
661*74a4d8c2SCharles.Forsyth 		r = 0;
662*74a4d8c2SCharles.Forsyth 		if(v == D_STATIC)
663*74a4d8c2SCharles.Forsyth 			r = version;
664*74a4d8c2SCharles.Forsyth 		s = lookup((char*)bloc, r);
665*74a4d8c2SCharles.Forsyth 		c -= &stop[1] - bloc;
666*74a4d8c2SCharles.Forsyth 		bloc = stop + 1;
667*74a4d8c2SCharles.Forsyth 
668*74a4d8c2SCharles.Forsyth 		if(debug['W'])
669*74a4d8c2SCharles.Forsyth 			print("	ANAME	%s\n", s->name);
670*74a4d8c2SCharles.Forsyth 		h[o] = s;
671*74a4d8c2SCharles.Forsyth 		if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
672*74a4d8c2SCharles.Forsyth 			s->type = SXREF;
673*74a4d8c2SCharles.Forsyth 		if(v == D_FILE) {
674*74a4d8c2SCharles.Forsyth 			if(s->type != SFILE) {
675*74a4d8c2SCharles.Forsyth 				histgen++;
676*74a4d8c2SCharles.Forsyth 				s->type = SFILE;
677*74a4d8c2SCharles.Forsyth 				s->value = histgen;
678*74a4d8c2SCharles.Forsyth 			}
679*74a4d8c2SCharles.Forsyth 			if(histfrogp < MAXHIST) {
680*74a4d8c2SCharles.Forsyth 				histfrog[histfrogp] = s;
681*74a4d8c2SCharles.Forsyth 				histfrogp++;
682*74a4d8c2SCharles.Forsyth 			} else
683*74a4d8c2SCharles.Forsyth 				collapsefrog(s);
684*74a4d8c2SCharles.Forsyth 		}
685*74a4d8c2SCharles.Forsyth 		goto loop;
686*74a4d8c2SCharles.Forsyth 	}
687*74a4d8c2SCharles.Forsyth 
688*74a4d8c2SCharles.Forsyth 	if(nhunk < sizeof(Prog))
689*74a4d8c2SCharles.Forsyth 		gethunk();
690*74a4d8c2SCharles.Forsyth 	p = (Prog*)hunk;
691*74a4d8c2SCharles.Forsyth 	nhunk -= sizeof(Prog);
692*74a4d8c2SCharles.Forsyth 	hunk += sizeof(Prog);
693*74a4d8c2SCharles.Forsyth 
694*74a4d8c2SCharles.Forsyth 	p->as = o;
695*74a4d8c2SCharles.Forsyth 	p->reg = bloc[1] & 0x7f;
696*74a4d8c2SCharles.Forsyth 	if(bloc[1] & 0x80)
697*74a4d8c2SCharles.Forsyth 		p->mark = NOSCHED;
698*74a4d8c2SCharles.Forsyth 	p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);
699*74a4d8c2SCharles.Forsyth 	r = zaddr(bloc+6, &p->from, h) + 6;
700*74a4d8c2SCharles.Forsyth 	r += zaddr(bloc+r, &p->to, h);
701*74a4d8c2SCharles.Forsyth 	bloc += r;
702*74a4d8c2SCharles.Forsyth 	c -= r;
703*74a4d8c2SCharles.Forsyth 
704*74a4d8c2SCharles.Forsyth 	if(p->reg < 0 || p->reg > NREG)
705*74a4d8c2SCharles.Forsyth 		diag("register out of range %d", p->reg);
706*74a4d8c2SCharles.Forsyth 
707*74a4d8c2SCharles.Forsyth 	p->link = P;
708*74a4d8c2SCharles.Forsyth 	p->cond = P;
709*74a4d8c2SCharles.Forsyth 
710*74a4d8c2SCharles.Forsyth 	if(debug['W'])
711*74a4d8c2SCharles.Forsyth 		print("%P\n", p);
712*74a4d8c2SCharles.Forsyth 
713*74a4d8c2SCharles.Forsyth 	switch(o) {
714*74a4d8c2SCharles.Forsyth 	case AHISTORY:
715*74a4d8c2SCharles.Forsyth 		if(p->to.offset == -1) {
716*74a4d8c2SCharles.Forsyth 			addlib(pn);
717*74a4d8c2SCharles.Forsyth 			histfrogp = 0;
718*74a4d8c2SCharles.Forsyth 			goto loop;
719*74a4d8c2SCharles.Forsyth 		}
720*74a4d8c2SCharles.Forsyth 		addhist(p->line, D_FILE);		/* 'z' */
721*74a4d8c2SCharles.Forsyth 		if(p->to.offset)
722*74a4d8c2SCharles.Forsyth 			addhist(p->to.offset, D_FILE1);	/* 'Z' */
723*74a4d8c2SCharles.Forsyth 		histfrogp = 0;
724*74a4d8c2SCharles.Forsyth 		goto loop;
725*74a4d8c2SCharles.Forsyth 
726*74a4d8c2SCharles.Forsyth 	case AEND:
727*74a4d8c2SCharles.Forsyth 		histtoauto();
728*74a4d8c2SCharles.Forsyth 		if(curtext != P)
729*74a4d8c2SCharles.Forsyth 			curtext->to.autom = curauto;
730*74a4d8c2SCharles.Forsyth 		curauto = 0;
731*74a4d8c2SCharles.Forsyth 		curtext = P;
732*74a4d8c2SCharles.Forsyth 		if(c)
733*74a4d8c2SCharles.Forsyth 			goto newloop;
734*74a4d8c2SCharles.Forsyth 		return;
735*74a4d8c2SCharles.Forsyth 
736*74a4d8c2SCharles.Forsyth 	case AGLOBL:
737*74a4d8c2SCharles.Forsyth 		s = p->from.sym;
738*74a4d8c2SCharles.Forsyth 		if(s == S) {
739*74a4d8c2SCharles.Forsyth 			diag("GLOBL must have a name\n%P", p);
740*74a4d8c2SCharles.Forsyth 			errorexit();
741*74a4d8c2SCharles.Forsyth 		}
742*74a4d8c2SCharles.Forsyth 		if(s->type == 0 || s->type == SXREF) {
743*74a4d8c2SCharles.Forsyth 			s->type = SBSS;
744*74a4d8c2SCharles.Forsyth 			s->value = 0;
745*74a4d8c2SCharles.Forsyth 		}
746*74a4d8c2SCharles.Forsyth 		if(s->type != SBSS) {
747*74a4d8c2SCharles.Forsyth 			diag("redefinition: %s\n%P", s->name, p);
748*74a4d8c2SCharles.Forsyth 			s->type = SBSS;
749*74a4d8c2SCharles.Forsyth 			s->value = 0;
750*74a4d8c2SCharles.Forsyth 		}
751*74a4d8c2SCharles.Forsyth 		if(p->to.offset > s->value)
752*74a4d8c2SCharles.Forsyth 			s->value = p->to.offset;
753*74a4d8c2SCharles.Forsyth 		break;
754*74a4d8c2SCharles.Forsyth 
755*74a4d8c2SCharles.Forsyth 	case ADYNT:
756*74a4d8c2SCharles.Forsyth 		if(p->to.sym == S) {
757*74a4d8c2SCharles.Forsyth 			diag("DYNT without a sym\n%P", p);
758*74a4d8c2SCharles.Forsyth 			break;
759*74a4d8c2SCharles.Forsyth 		}
760*74a4d8c2SCharles.Forsyth 		di = p->to.sym;
761*74a4d8c2SCharles.Forsyth 		p->reg = 4;
762*74a4d8c2SCharles.Forsyth 		if(di->type == SXREF) {
763*74a4d8c2SCharles.Forsyth 			if(debug['z'])
764*74a4d8c2SCharles.Forsyth 				Bprint(&bso, "%P set to %d\n", p, dtype);
765*74a4d8c2SCharles.Forsyth 			di->type = SCONST;
766*74a4d8c2SCharles.Forsyth 			di->value = dtype;
767*74a4d8c2SCharles.Forsyth 			dtype += 4;
768*74a4d8c2SCharles.Forsyth 		}
769*74a4d8c2SCharles.Forsyth 		if(p->from.sym == S)
770*74a4d8c2SCharles.Forsyth 			break;
771*74a4d8c2SCharles.Forsyth 
772*74a4d8c2SCharles.Forsyth 		p->from.offset = di->value;
773*74a4d8c2SCharles.Forsyth 		p->from.sym->type = SDATA;
774*74a4d8c2SCharles.Forsyth 		if(curtext == P) {
775*74a4d8c2SCharles.Forsyth 			diag("DYNT not in text: %P", p);
776*74a4d8c2SCharles.Forsyth 			break;
777*74a4d8c2SCharles.Forsyth 		}
778*74a4d8c2SCharles.Forsyth 		p->to.sym = curtext->from.sym;
779*74a4d8c2SCharles.Forsyth 		p->to.type = D_CONST;
780*74a4d8c2SCharles.Forsyth 		p->link = datap;
781*74a4d8c2SCharles.Forsyth 		datap = p;
782*74a4d8c2SCharles.Forsyth 		break;
783*74a4d8c2SCharles.Forsyth 
784*74a4d8c2SCharles.Forsyth 	case AINIT:
785*74a4d8c2SCharles.Forsyth 		if(p->from.sym == S) {
786*74a4d8c2SCharles.Forsyth 			diag("INIT without a sym\n%P", p);
787*74a4d8c2SCharles.Forsyth 			break;
788*74a4d8c2SCharles.Forsyth 		}
789*74a4d8c2SCharles.Forsyth 		if(di == S) {
790*74a4d8c2SCharles.Forsyth 			diag("INIT without previous DYNT\n%P", p);
791*74a4d8c2SCharles.Forsyth 			break;
792*74a4d8c2SCharles.Forsyth 		}
793*74a4d8c2SCharles.Forsyth 		p->from.offset = di->value;
794*74a4d8c2SCharles.Forsyth 		p->from.sym->type = SDATA;
795*74a4d8c2SCharles.Forsyth 		p->link = datap;
796*74a4d8c2SCharles.Forsyth 		datap = p;
797*74a4d8c2SCharles.Forsyth 		break;
798*74a4d8c2SCharles.Forsyth 
799*74a4d8c2SCharles.Forsyth 	case ADATA:
800*74a4d8c2SCharles.Forsyth 		p->link = datap;
801*74a4d8c2SCharles.Forsyth 		datap = p;
802*74a4d8c2SCharles.Forsyth 		break;
803*74a4d8c2SCharles.Forsyth 
804*74a4d8c2SCharles.Forsyth 	case AGOK:
805*74a4d8c2SCharles.Forsyth 		diag("unknown opcode\n%P", p);
806*74a4d8c2SCharles.Forsyth 		p->pc = pc;
807*74a4d8c2SCharles.Forsyth 		pc++;
808*74a4d8c2SCharles.Forsyth 		break;
809*74a4d8c2SCharles.Forsyth 
810*74a4d8c2SCharles.Forsyth 	case ATEXT:
811*74a4d8c2SCharles.Forsyth 		if(curtext != P) {
812*74a4d8c2SCharles.Forsyth 			histtoauto();
813*74a4d8c2SCharles.Forsyth 			curtext->to.autom = curauto;
814*74a4d8c2SCharles.Forsyth 			curauto = 0;
815*74a4d8c2SCharles.Forsyth 		}
816*74a4d8c2SCharles.Forsyth 		curtext = p;
817*74a4d8c2SCharles.Forsyth 		autosize = (p->to.offset+3L) & ~3L;
818*74a4d8c2SCharles.Forsyth 		p->to.offset = autosize;
819*74a4d8c2SCharles.Forsyth 		autosize += 4;
820*74a4d8c2SCharles.Forsyth 		s = p->from.sym;
821*74a4d8c2SCharles.Forsyth 		if(s == S) {
822*74a4d8c2SCharles.Forsyth 			diag("TEXT must have a name\n%P", p);
823*74a4d8c2SCharles.Forsyth 			errorexit();
824*74a4d8c2SCharles.Forsyth 		}
825*74a4d8c2SCharles.Forsyth 		if(s->type != 0 && s->type != SXREF) {
826*74a4d8c2SCharles.Forsyth 			if(p->reg & DUPOK) {
827*74a4d8c2SCharles.Forsyth 				skip = 1;
828*74a4d8c2SCharles.Forsyth 				goto casedef;
829*74a4d8c2SCharles.Forsyth 			}
830*74a4d8c2SCharles.Forsyth 			diag("redefinition: %s\n%P", s->name, p);
831*74a4d8c2SCharles.Forsyth 		}
832*74a4d8c2SCharles.Forsyth 		s->type = STEXT;
833*74a4d8c2SCharles.Forsyth 		s->value = pc;
834*74a4d8c2SCharles.Forsyth 		if(textp != P) {
835*74a4d8c2SCharles.Forsyth 			for(t = textp; t->cond != P; t = t->cond)
836*74a4d8c2SCharles.Forsyth 				;
837*74a4d8c2SCharles.Forsyth 			t->cond = p;
838*74a4d8c2SCharles.Forsyth 		} else
839*74a4d8c2SCharles.Forsyth 			textp = p;
840*74a4d8c2SCharles.Forsyth 		lastp->link = p;
841*74a4d8c2SCharles.Forsyth 		lastp = p;
842*74a4d8c2SCharles.Forsyth 		p->pc = pc;
843*74a4d8c2SCharles.Forsyth 		pc++;
844*74a4d8c2SCharles.Forsyth 		break;
845*74a4d8c2SCharles.Forsyth 
846*74a4d8c2SCharles.Forsyth 	case AFMOVF:
847*74a4d8c2SCharles.Forsyth 		if(skip)
848*74a4d8c2SCharles.Forsyth 			goto casedef;
849*74a4d8c2SCharles.Forsyth 
850*74a4d8c2SCharles.Forsyth 		if(p->from.type == D_FCONST) {
851*74a4d8c2SCharles.Forsyth 			/* size sb 9 max */
852*74a4d8c2SCharles.Forsyth 			sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
853*74a4d8c2SCharles.Forsyth 			s = lookup(literal, 0);
854*74a4d8c2SCharles.Forsyth 			if(s->type == 0) {
855*74a4d8c2SCharles.Forsyth 				s->type = SBSS;
856*74a4d8c2SCharles.Forsyth 				s->value = 4;
857*74a4d8c2SCharles.Forsyth 				t = prg();
858*74a4d8c2SCharles.Forsyth 				t->as = ADATA;
859*74a4d8c2SCharles.Forsyth 				t->line = p->line;
860*74a4d8c2SCharles.Forsyth 				t->from.type = D_OREG;
861*74a4d8c2SCharles.Forsyth 				t->from.sym = s;
862*74a4d8c2SCharles.Forsyth 				t->from.name = D_EXTERN;
863*74a4d8c2SCharles.Forsyth 				t->reg = 4;
864*74a4d8c2SCharles.Forsyth 				t->to = p->from;
865*74a4d8c2SCharles.Forsyth 				t->link = datap;
866*74a4d8c2SCharles.Forsyth 				datap = t;
867*74a4d8c2SCharles.Forsyth 			}
868*74a4d8c2SCharles.Forsyth 			p->from.type = D_OREG;
869*74a4d8c2SCharles.Forsyth 			p->from.sym = s;
870*74a4d8c2SCharles.Forsyth 			p->from.name = D_EXTERN;
871*74a4d8c2SCharles.Forsyth 			p->from.offset = 0;
872*74a4d8c2SCharles.Forsyth 		}
873*74a4d8c2SCharles.Forsyth 		goto casedef;
874*74a4d8c2SCharles.Forsyth 
875*74a4d8c2SCharles.Forsyth 	case AFMOVD:
876*74a4d8c2SCharles.Forsyth 		if(skip)
877*74a4d8c2SCharles.Forsyth 			goto casedef;
878*74a4d8c2SCharles.Forsyth 		if(p->from.type == D_FCONST) {
879*74a4d8c2SCharles.Forsyth 			/* size sb 18 max */
880*74a4d8c2SCharles.Forsyth 			sprint(literal, "$%lux.%lux",
881*74a4d8c2SCharles.Forsyth 				p->from.ieee.l, p->from.ieee.h);
882*74a4d8c2SCharles.Forsyth 			s = lookup(literal, 0);
883*74a4d8c2SCharles.Forsyth 			if(s->type == 0) {
884*74a4d8c2SCharles.Forsyth 				s->type = SBSS;
885*74a4d8c2SCharles.Forsyth 				s->value = 8;
886*74a4d8c2SCharles.Forsyth 				t = prg();
887*74a4d8c2SCharles.Forsyth 				t->as = ADATA;
888*74a4d8c2SCharles.Forsyth 				t->line = p->line;
889*74a4d8c2SCharles.Forsyth 				t->from.type = D_OREG;
890*74a4d8c2SCharles.Forsyth 				t->from.sym = s;
891*74a4d8c2SCharles.Forsyth 				t->from.name = D_EXTERN;
892*74a4d8c2SCharles.Forsyth 				t->reg = 8;
893*74a4d8c2SCharles.Forsyth 				t->to = p->from;
894*74a4d8c2SCharles.Forsyth 				t->link = datap;
895*74a4d8c2SCharles.Forsyth 				datap = t;
896*74a4d8c2SCharles.Forsyth 			}
897*74a4d8c2SCharles.Forsyth 			p->from.type = D_OREG;
898*74a4d8c2SCharles.Forsyth 			p->from.sym = s;
899*74a4d8c2SCharles.Forsyth 			p->from.name = D_EXTERN;
900*74a4d8c2SCharles.Forsyth 			p->from.offset = 0;
901*74a4d8c2SCharles.Forsyth 		}
902*74a4d8c2SCharles.Forsyth 		goto casedef;
903*74a4d8c2SCharles.Forsyth 
904*74a4d8c2SCharles.Forsyth 	default:
905*74a4d8c2SCharles.Forsyth 	casedef:
906*74a4d8c2SCharles.Forsyth 		if(skip)
907*74a4d8c2SCharles.Forsyth 			nopout(p);
908*74a4d8c2SCharles.Forsyth 
909*74a4d8c2SCharles.Forsyth 		if(p->to.type == D_BRANCH)
910*74a4d8c2SCharles.Forsyth 			p->to.offset += ipc;
911*74a4d8c2SCharles.Forsyth 		lastp->link = p;
912*74a4d8c2SCharles.Forsyth 		lastp = p;
913*74a4d8c2SCharles.Forsyth 		p->pc = pc;
914*74a4d8c2SCharles.Forsyth 		pc++;
915*74a4d8c2SCharles.Forsyth 		break;
916*74a4d8c2SCharles.Forsyth 	}
917*74a4d8c2SCharles.Forsyth 	goto loop;
918*74a4d8c2SCharles.Forsyth 
919*74a4d8c2SCharles.Forsyth eof:
920*74a4d8c2SCharles.Forsyth 	diag("truncated object file: %s", pn);
921*74a4d8c2SCharles.Forsyth }
922*74a4d8c2SCharles.Forsyth 
923*74a4d8c2SCharles.Forsyth Sym*
lookup(char * symb,int v)924*74a4d8c2SCharles.Forsyth lookup(char *symb, int v)
925*74a4d8c2SCharles.Forsyth {
926*74a4d8c2SCharles.Forsyth 	Sym *s;
927*74a4d8c2SCharles.Forsyth 	char *p;
928*74a4d8c2SCharles.Forsyth 	long h;
929*74a4d8c2SCharles.Forsyth 	int c, l;
930*74a4d8c2SCharles.Forsyth 
931*74a4d8c2SCharles.Forsyth 	h = v;
932*74a4d8c2SCharles.Forsyth 	for(p=symb; c = *p; p++)
933*74a4d8c2SCharles.Forsyth 		h = h+h+h + c;
934*74a4d8c2SCharles.Forsyth 	l = (p - symb) + 1;
935*74a4d8c2SCharles.Forsyth 	if(h < 0)
936*74a4d8c2SCharles.Forsyth 		h = ~h;
937*74a4d8c2SCharles.Forsyth 	h %= NHASH;
938*74a4d8c2SCharles.Forsyth 	for(s = hash[h]; s != S; s = s->link)
939*74a4d8c2SCharles.Forsyth 		if(s->version == v)
940*74a4d8c2SCharles.Forsyth 		if(memcmp(s->name, symb, l) == 0)
941*74a4d8c2SCharles.Forsyth 			return s;
942*74a4d8c2SCharles.Forsyth 
943*74a4d8c2SCharles.Forsyth 	while(nhunk < sizeof(Sym))
944*74a4d8c2SCharles.Forsyth 		gethunk();
945*74a4d8c2SCharles.Forsyth 	s = (Sym*)hunk;
946*74a4d8c2SCharles.Forsyth 	nhunk -= sizeof(Sym);
947*74a4d8c2SCharles.Forsyth 	hunk += sizeof(Sym);
948*74a4d8c2SCharles.Forsyth 
949*74a4d8c2SCharles.Forsyth 	s->name = malloc(l + 1);
950*74a4d8c2SCharles.Forsyth 	memmove(s->name, symb, l);
951*74a4d8c2SCharles.Forsyth 
952*74a4d8c2SCharles.Forsyth 	s->link = hash[h];
953*74a4d8c2SCharles.Forsyth 	s->type = 0;
954*74a4d8c2SCharles.Forsyth 	s->version = v;
955*74a4d8c2SCharles.Forsyth 	s->value = 0;
956*74a4d8c2SCharles.Forsyth 	hash[h] = s;
957*74a4d8c2SCharles.Forsyth 	return s;
958*74a4d8c2SCharles.Forsyth }
959*74a4d8c2SCharles.Forsyth 
960*74a4d8c2SCharles.Forsyth Prog*
prg(void)961*74a4d8c2SCharles.Forsyth prg(void)
962*74a4d8c2SCharles.Forsyth {
963*74a4d8c2SCharles.Forsyth 	Prog *p;
964*74a4d8c2SCharles.Forsyth 	int n;
965*74a4d8c2SCharles.Forsyth 
966*74a4d8c2SCharles.Forsyth 	n = (sizeof(Prog) + 3) & ~3;
967*74a4d8c2SCharles.Forsyth 	while(nhunk < n)
968*74a4d8c2SCharles.Forsyth 		gethunk();
969*74a4d8c2SCharles.Forsyth 
970*74a4d8c2SCharles.Forsyth 	p = (Prog*)hunk;
971*74a4d8c2SCharles.Forsyth 	nhunk -= n;
972*74a4d8c2SCharles.Forsyth 	hunk += n;
973*74a4d8c2SCharles.Forsyth 
974*74a4d8c2SCharles.Forsyth 	*p = zprg;
975*74a4d8c2SCharles.Forsyth 	return p;
976*74a4d8c2SCharles.Forsyth }
977*74a4d8c2SCharles.Forsyth 
978*74a4d8c2SCharles.Forsyth void
gethunk(void)979*74a4d8c2SCharles.Forsyth gethunk(void)
980*74a4d8c2SCharles.Forsyth {
981*74a4d8c2SCharles.Forsyth 	char *h;
982*74a4d8c2SCharles.Forsyth 	long nh;
983*74a4d8c2SCharles.Forsyth 
984*74a4d8c2SCharles.Forsyth 	nh = NHUNK;
985*74a4d8c2SCharles.Forsyth 	if(tothunk >= 5L*NHUNK) {
986*74a4d8c2SCharles.Forsyth 		nh = 5L*NHUNK;
987*74a4d8c2SCharles.Forsyth 		if(tothunk >= 25L*NHUNK)
988*74a4d8c2SCharles.Forsyth 			nh = 25L*NHUNK;
989*74a4d8c2SCharles.Forsyth 	}
990*74a4d8c2SCharles.Forsyth 	h = mysbrk(nh);
991*74a4d8c2SCharles.Forsyth 	if(h == (char *)-1) {
992*74a4d8c2SCharles.Forsyth 		diag("out of memory");
993*74a4d8c2SCharles.Forsyth 		errorexit();
994*74a4d8c2SCharles.Forsyth 	}
995*74a4d8c2SCharles.Forsyth 
996*74a4d8c2SCharles.Forsyth 	hunk = h;
997*74a4d8c2SCharles.Forsyth 	nhunk = nh;
998*74a4d8c2SCharles.Forsyth 	tothunk += nh;
999*74a4d8c2SCharles.Forsyth }
1000*74a4d8c2SCharles.Forsyth 
1001*74a4d8c2SCharles.Forsyth void
doprof1(void)1002*74a4d8c2SCharles.Forsyth doprof1(void)
1003*74a4d8c2SCharles.Forsyth {
1004*74a4d8c2SCharles.Forsyth 	Sym *s;
1005*74a4d8c2SCharles.Forsyth 	long n;
1006*74a4d8c2SCharles.Forsyth 	Prog *p, *q;
1007*74a4d8c2SCharles.Forsyth 
1008*74a4d8c2SCharles.Forsyth 	if(debug['v'])
1009*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f profile 1\n", cputime());
1010*74a4d8c2SCharles.Forsyth 	Bflush(&bso);
1011*74a4d8c2SCharles.Forsyth 	s = lookup("__mcount", 0);
1012*74a4d8c2SCharles.Forsyth 	n = 1;
1013*74a4d8c2SCharles.Forsyth 	for(p = firstp->link; p != P; p = p->link) {
1014*74a4d8c2SCharles.Forsyth 		if(p->as == ATEXT) {
1015*74a4d8c2SCharles.Forsyth 			q = prg();
1016*74a4d8c2SCharles.Forsyth 			q->line = p->line;
1017*74a4d8c2SCharles.Forsyth 			q->link = datap;
1018*74a4d8c2SCharles.Forsyth 			datap = q;
1019*74a4d8c2SCharles.Forsyth 			q->as = ADATA;
1020*74a4d8c2SCharles.Forsyth 			q->from.type = D_OREG;
1021*74a4d8c2SCharles.Forsyth 			q->from.name = D_EXTERN;
1022*74a4d8c2SCharles.Forsyth 			q->from.offset = n*4;
1023*74a4d8c2SCharles.Forsyth 			q->from.sym = s;
1024*74a4d8c2SCharles.Forsyth 			q->reg = 4;
1025*74a4d8c2SCharles.Forsyth 			q->to = p->from;
1026*74a4d8c2SCharles.Forsyth 			q->to.type = D_CONST;
1027*74a4d8c2SCharles.Forsyth 
1028*74a4d8c2SCharles.Forsyth 			q = prg();
1029*74a4d8c2SCharles.Forsyth 			q->line = p->line;
1030*74a4d8c2SCharles.Forsyth 			q->pc = p->pc;
1031*74a4d8c2SCharles.Forsyth 			q->link = p->link;
1032*74a4d8c2SCharles.Forsyth 			p->link = q;
1033*74a4d8c2SCharles.Forsyth 			p = q;
1034*74a4d8c2SCharles.Forsyth 			p->as = AMOVW;
1035*74a4d8c2SCharles.Forsyth 			p->from.type = D_OREG;
1036*74a4d8c2SCharles.Forsyth 			p->from.name = D_EXTERN;
1037*74a4d8c2SCharles.Forsyth 			p->from.sym = s;
1038*74a4d8c2SCharles.Forsyth 			p->from.offset = n*4 + 4;
1039*74a4d8c2SCharles.Forsyth 			p->to.type = D_REG;
1040*74a4d8c2SCharles.Forsyth 			p->to.reg = REGTMP;
1041*74a4d8c2SCharles.Forsyth 
1042*74a4d8c2SCharles.Forsyth 			q = prg();
1043*74a4d8c2SCharles.Forsyth 			q->line = p->line;
1044*74a4d8c2SCharles.Forsyth 			q->pc = p->pc;
1045*74a4d8c2SCharles.Forsyth 			q->link = p->link;
1046*74a4d8c2SCharles.Forsyth 			p->link = q;
1047*74a4d8c2SCharles.Forsyth 			p = q;
1048*74a4d8c2SCharles.Forsyth 			p->as = AADD;
1049*74a4d8c2SCharles.Forsyth 			p->from.type = D_CONST;
1050*74a4d8c2SCharles.Forsyth 			p->from.offset = 1;
1051*74a4d8c2SCharles.Forsyth 			p->to.type = D_REG;
1052*74a4d8c2SCharles.Forsyth 			p->to.reg = REGTMP;
1053*74a4d8c2SCharles.Forsyth 
1054*74a4d8c2SCharles.Forsyth 			q = prg();
1055*74a4d8c2SCharles.Forsyth 			q->line = p->line;
1056*74a4d8c2SCharles.Forsyth 			q->pc = p->pc;
1057*74a4d8c2SCharles.Forsyth 			q->link = p->link;
1058*74a4d8c2SCharles.Forsyth 			p->link = q;
1059*74a4d8c2SCharles.Forsyth 			p = q;
1060*74a4d8c2SCharles.Forsyth 			p->as = AMOVW;
1061*74a4d8c2SCharles.Forsyth 			p->from.type = D_REG;
1062*74a4d8c2SCharles.Forsyth 			p->from.reg = REGTMP;
1063*74a4d8c2SCharles.Forsyth 			p->to.type = D_OREG;
1064*74a4d8c2SCharles.Forsyth 			p->to.name = D_EXTERN;
1065*74a4d8c2SCharles.Forsyth 			p->to.sym = s;
1066*74a4d8c2SCharles.Forsyth 			p->to.offset = n*4 + 4;
1067*74a4d8c2SCharles.Forsyth 
1068*74a4d8c2SCharles.Forsyth 			n += 2;
1069*74a4d8c2SCharles.Forsyth 			continue;
1070*74a4d8c2SCharles.Forsyth 		}
1071*74a4d8c2SCharles.Forsyth 	}
1072*74a4d8c2SCharles.Forsyth 	q = prg();
1073*74a4d8c2SCharles.Forsyth 	q->line = 0;
1074*74a4d8c2SCharles.Forsyth 	q->link = datap;
1075*74a4d8c2SCharles.Forsyth 	datap = q;
1076*74a4d8c2SCharles.Forsyth 
1077*74a4d8c2SCharles.Forsyth 	q->as = ADATA;
1078*74a4d8c2SCharles.Forsyth 	q->from.type = D_OREG;
1079*74a4d8c2SCharles.Forsyth 	q->from.name = D_EXTERN;
1080*74a4d8c2SCharles.Forsyth 	q->from.sym = s;
1081*74a4d8c2SCharles.Forsyth 	q->reg = 4;
1082*74a4d8c2SCharles.Forsyth 	q->to.type = D_CONST;
1083*74a4d8c2SCharles.Forsyth 	q->to.offset = n;
1084*74a4d8c2SCharles.Forsyth 
1085*74a4d8c2SCharles.Forsyth 	s->type = SBSS;
1086*74a4d8c2SCharles.Forsyth 	s->value = n*4;
1087*74a4d8c2SCharles.Forsyth }
1088*74a4d8c2SCharles.Forsyth 
1089*74a4d8c2SCharles.Forsyth void
doprof2(void)1090*74a4d8c2SCharles.Forsyth doprof2(void)
1091*74a4d8c2SCharles.Forsyth {
1092*74a4d8c2SCharles.Forsyth 	Sym *s2, *s4;
1093*74a4d8c2SCharles.Forsyth 	Prog *p, *q, *ps2, *ps4;
1094*74a4d8c2SCharles.Forsyth 
1095*74a4d8c2SCharles.Forsyth 	if(debug['v'])
1096*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f profile 2\n", cputime());
1097*74a4d8c2SCharles.Forsyth 	Bflush(&bso);
1098*74a4d8c2SCharles.Forsyth 
1099*74a4d8c2SCharles.Forsyth 	s2 = lookup("_profin", 0);
1100*74a4d8c2SCharles.Forsyth 	s4 = lookup("_profout", 0);
1101*74a4d8c2SCharles.Forsyth 	if(s2->type != STEXT || s4->type != STEXT) {
1102*74a4d8c2SCharles.Forsyth 		diag("_profin/_profout not defined");
1103*74a4d8c2SCharles.Forsyth 		return;
1104*74a4d8c2SCharles.Forsyth 	}
1105*74a4d8c2SCharles.Forsyth 
1106*74a4d8c2SCharles.Forsyth 	ps2 = P;
1107*74a4d8c2SCharles.Forsyth 	ps4 = P;
1108*74a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
1109*74a4d8c2SCharles.Forsyth 		if(p->as == ATEXT) {
1110*74a4d8c2SCharles.Forsyth 			if(p->from.sym == s2) {
1111*74a4d8c2SCharles.Forsyth 				p->reg = 1;
1112*74a4d8c2SCharles.Forsyth 				ps2 = p;
1113*74a4d8c2SCharles.Forsyth 			}
1114*74a4d8c2SCharles.Forsyth 			if(p->from.sym == s4) {
1115*74a4d8c2SCharles.Forsyth 				p->reg = 1;
1116*74a4d8c2SCharles.Forsyth 				ps4 = p;
1117*74a4d8c2SCharles.Forsyth 			}
1118*74a4d8c2SCharles.Forsyth 		}
1119*74a4d8c2SCharles.Forsyth 	}
1120*74a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
1121*74a4d8c2SCharles.Forsyth 		if(p->as == ATEXT) {
1122*74a4d8c2SCharles.Forsyth 			curtext = p;
1123*74a4d8c2SCharles.Forsyth 
1124*74a4d8c2SCharles.Forsyth 			if(p->reg & NOPROF) {	/* dont profile */
1125*74a4d8c2SCharles.Forsyth 				for(;;) {
1126*74a4d8c2SCharles.Forsyth 					q = p->link;
1127*74a4d8c2SCharles.Forsyth 					if(q == P)
1128*74a4d8c2SCharles.Forsyth 						break;
1129*74a4d8c2SCharles.Forsyth 					if(q->as == ATEXT)
1130*74a4d8c2SCharles.Forsyth 						break;
1131*74a4d8c2SCharles.Forsyth 					p = q;
1132*74a4d8c2SCharles.Forsyth 				}
1133*74a4d8c2SCharles.Forsyth 				continue;
1134*74a4d8c2SCharles.Forsyth 			}
1135*74a4d8c2SCharles.Forsyth 
1136*74a4d8c2SCharles.Forsyth 			/*
1137*74a4d8c2SCharles.Forsyth 			 * JMPL	profin
1138*74a4d8c2SCharles.Forsyth 			 */
1139*74a4d8c2SCharles.Forsyth 			q = prg();
1140*74a4d8c2SCharles.Forsyth 			q->line = p->line;
1141*74a4d8c2SCharles.Forsyth 			q->pc = p->pc;
1142*74a4d8c2SCharles.Forsyth 			q->link = p->link;
1143*74a4d8c2SCharles.Forsyth 			p->link = q;
1144*74a4d8c2SCharles.Forsyth 			p = q;
1145*74a4d8c2SCharles.Forsyth 			p->as = AJMPL;
1146*74a4d8c2SCharles.Forsyth 			p->to.type = D_BRANCH;
1147*74a4d8c2SCharles.Forsyth 			p->cond = ps2;
1148*74a4d8c2SCharles.Forsyth 			p->to.sym = s2;
1149*74a4d8c2SCharles.Forsyth 
1150*74a4d8c2SCharles.Forsyth 			continue;
1151*74a4d8c2SCharles.Forsyth 		}
1152*74a4d8c2SCharles.Forsyth 		if(p->as == ARETURN) {
1153*74a4d8c2SCharles.Forsyth 
1154*74a4d8c2SCharles.Forsyth 			/*
1155*74a4d8c2SCharles.Forsyth 			 * RETURN
1156*74a4d8c2SCharles.Forsyth 			 */
1157*74a4d8c2SCharles.Forsyth 			q = prg();
1158*74a4d8c2SCharles.Forsyth 			q->as = ARETURN;
1159*74a4d8c2SCharles.Forsyth 			q->from = p->from;
1160*74a4d8c2SCharles.Forsyth 			q->to = p->to;
1161*74a4d8c2SCharles.Forsyth 			q->link = p->link;
1162*74a4d8c2SCharles.Forsyth 			p->link = q;
1163*74a4d8c2SCharles.Forsyth 
1164*74a4d8c2SCharles.Forsyth 			/*
1165*74a4d8c2SCharles.Forsyth 			 * JMPL profout
1166*74a4d8c2SCharles.Forsyth 			 */
1167*74a4d8c2SCharles.Forsyth 			p->as = AJMPL;
1168*74a4d8c2SCharles.Forsyth 			p->from = zprg.from;
1169*74a4d8c2SCharles.Forsyth 			p->to = zprg.to;
1170*74a4d8c2SCharles.Forsyth 			p->to.type = D_BRANCH;
1171*74a4d8c2SCharles.Forsyth 			p->cond = ps4;
1172*74a4d8c2SCharles.Forsyth 			p->to.sym = s4;
1173*74a4d8c2SCharles.Forsyth 
1174*74a4d8c2SCharles.Forsyth 			p = q;
1175*74a4d8c2SCharles.Forsyth 
1176*74a4d8c2SCharles.Forsyth 			continue;
1177*74a4d8c2SCharles.Forsyth 		}
1178*74a4d8c2SCharles.Forsyth 	}
1179*74a4d8c2SCharles.Forsyth }
1180*74a4d8c2SCharles.Forsyth 
1181*74a4d8c2SCharles.Forsyth void
nuxiinit(void)1182*74a4d8c2SCharles.Forsyth nuxiinit(void)
1183*74a4d8c2SCharles.Forsyth {
1184*74a4d8c2SCharles.Forsyth 	int i, c;
1185*74a4d8c2SCharles.Forsyth 
1186*74a4d8c2SCharles.Forsyth 	for(i=0; i<4; i++) {
1187*74a4d8c2SCharles.Forsyth 		c = find1(0x01020304L, i+1);
1188*74a4d8c2SCharles.Forsyth 		if(i >= 2)
1189*74a4d8c2SCharles.Forsyth 			inuxi2[i-2] = c;
1190*74a4d8c2SCharles.Forsyth 		if(i >= 3)
1191*74a4d8c2SCharles.Forsyth 			inuxi1[i-3] = c;
1192*74a4d8c2SCharles.Forsyth 		inuxi4[i] = c;
1193*74a4d8c2SCharles.Forsyth 
1194*74a4d8c2SCharles.Forsyth 		fnuxi8[i] = c+4;
1195*74a4d8c2SCharles.Forsyth 		fnuxi8[i+4] = c;
1196*74a4d8c2SCharles.Forsyth 	}
1197*74a4d8c2SCharles.Forsyth 	if(debug['v']) {
1198*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "inuxi = ");
1199*74a4d8c2SCharles.Forsyth 		for(i=0; i<1; i++)
1200*74a4d8c2SCharles.Forsyth 			Bprint(&bso, "%d", inuxi1[i]);
1201*74a4d8c2SCharles.Forsyth 		Bprint(&bso, " ");
1202*74a4d8c2SCharles.Forsyth 		for(i=0; i<2; i++)
1203*74a4d8c2SCharles.Forsyth 			Bprint(&bso, "%d", inuxi2[i]);
1204*74a4d8c2SCharles.Forsyth 		Bprint(&bso, " ");
1205*74a4d8c2SCharles.Forsyth 		for(i=0; i<4; i++)
1206*74a4d8c2SCharles.Forsyth 			Bprint(&bso, "%d", inuxi4[i]);
1207*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "\nfnuxi = ");
1208*74a4d8c2SCharles.Forsyth 		for(i=0; i<8; i++)
1209*74a4d8c2SCharles.Forsyth 			Bprint(&bso, "%d", fnuxi8[i]);
1210*74a4d8c2SCharles.Forsyth 		Bprint(&bso, "\n");
1211*74a4d8c2SCharles.Forsyth 	}
1212*74a4d8c2SCharles.Forsyth 	Bflush(&bso);
1213*74a4d8c2SCharles.Forsyth }
1214*74a4d8c2SCharles.Forsyth 
1215*74a4d8c2SCharles.Forsyth int
find1(long l,int c)1216*74a4d8c2SCharles.Forsyth find1(long l, int c)
1217*74a4d8c2SCharles.Forsyth {
1218*74a4d8c2SCharles.Forsyth 	char *p;
1219*74a4d8c2SCharles.Forsyth 	int i;
1220*74a4d8c2SCharles.Forsyth 
1221*74a4d8c2SCharles.Forsyth 	p = (char*)&l;
1222*74a4d8c2SCharles.Forsyth 	for(i=0; i<4; i++)
1223*74a4d8c2SCharles.Forsyth 		if(*p++ == c)
1224*74a4d8c2SCharles.Forsyth 			return i;
1225*74a4d8c2SCharles.Forsyth 	return 0;
1226*74a4d8c2SCharles.Forsyth }
1227*74a4d8c2SCharles.Forsyth 
1228*74a4d8c2SCharles.Forsyth long
ieeedtof(Ieee * ieeep)1229*74a4d8c2SCharles.Forsyth ieeedtof(Ieee *ieeep)
1230*74a4d8c2SCharles.Forsyth {
1231*74a4d8c2SCharles.Forsyth 	int exp;
1232*74a4d8c2SCharles.Forsyth 	long v;
1233*74a4d8c2SCharles.Forsyth 
1234*74a4d8c2SCharles.Forsyth 	if(ieeep->h == 0)
1235*74a4d8c2SCharles.Forsyth 		return 0;
1236*74a4d8c2SCharles.Forsyth 	exp = (ieeep->h>>20) & ((1L<<11)-1L);
1237*74a4d8c2SCharles.Forsyth 	exp -= (1L<<10) - 2L;
1238*74a4d8c2SCharles.Forsyth 	v = (ieeep->h & 0xfffffL) << 3;
1239*74a4d8c2SCharles.Forsyth 	v |= (ieeep->l >> 29) & 0x7L;
1240*74a4d8c2SCharles.Forsyth 	if((ieeep->l >> 28) & 1) {
1241*74a4d8c2SCharles.Forsyth 		v++;
1242*74a4d8c2SCharles.Forsyth 		if(v & 0x800000L) {
1243*74a4d8c2SCharles.Forsyth 			v = (v & 0x7fffffL) >> 1;
1244*74a4d8c2SCharles.Forsyth 			exp++;
1245*74a4d8c2SCharles.Forsyth 		}
1246*74a4d8c2SCharles.Forsyth 	}
1247*74a4d8c2SCharles.Forsyth 	if(exp <= -126 || exp >= 130)
1248*74a4d8c2SCharles.Forsyth 		diag("double fp to single fp overflow");
1249*74a4d8c2SCharles.Forsyth 	v |= ((exp + 126) & 0xffL) << 23;
1250*74a4d8c2SCharles.Forsyth 	v |= ieeep->h & 0x80000000L;
1251*74a4d8c2SCharles.Forsyth 	return v;
1252*74a4d8c2SCharles.Forsyth }
1253*74a4d8c2SCharles.Forsyth 
1254*74a4d8c2SCharles.Forsyth double
ieeedtod(Ieee * ieeep)1255*74a4d8c2SCharles.Forsyth ieeedtod(Ieee *ieeep)
1256*74a4d8c2SCharles.Forsyth {
1257*74a4d8c2SCharles.Forsyth 	Ieee e;
1258*74a4d8c2SCharles.Forsyth 	double fr;
1259*74a4d8c2SCharles.Forsyth 	int exp;
1260*74a4d8c2SCharles.Forsyth 
1261*74a4d8c2SCharles.Forsyth 	if(ieeep->h & (1L<<31)) {
1262*74a4d8c2SCharles.Forsyth 		e.h = ieeep->h & ~(1L<<31);
1263*74a4d8c2SCharles.Forsyth 		e.l = ieeep->l;
1264*74a4d8c2SCharles.Forsyth 		return -ieeedtod(&e);
1265*74a4d8c2SCharles.Forsyth 	}
1266*74a4d8c2SCharles.Forsyth 	if(ieeep->l == 0 && ieeep->h == 0)
1267*74a4d8c2SCharles.Forsyth 		return 0;
1268*74a4d8c2SCharles.Forsyth 	fr = ieeep->l & ((1L<<16)-1L);
1269*74a4d8c2SCharles.Forsyth 	fr /= 1L<<16;
1270*74a4d8c2SCharles.Forsyth 	fr += (ieeep->l>>16) & ((1L<<16)-1L);
1271*74a4d8c2SCharles.Forsyth 	fr /= 1L<<16;
1272*74a4d8c2SCharles.Forsyth 	fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
1273*74a4d8c2SCharles.Forsyth 	fr /= 1L<<21;
1274*74a4d8c2SCharles.Forsyth 	exp = (ieeep->h>>20) & ((1L<<11)-1L);
1275*74a4d8c2SCharles.Forsyth 	exp -= (1L<<10) - 2L;
1276*74a4d8c2SCharles.Forsyth 	return ldexp(fr, exp);
1277*74a4d8c2SCharles.Forsyth }
1278