xref: /inferno-os/utils/6l/pass.c (revision b370703f35244a5152bf72daf6a871fba74ed373)
1*b370703fSCharles.Forsyth #include	"l.h"
2*b370703fSCharles.Forsyth 
3*b370703fSCharles.Forsyth void
dodata(void)4*b370703fSCharles.Forsyth dodata(void)
5*b370703fSCharles.Forsyth {
6*b370703fSCharles.Forsyth 	int i;
7*b370703fSCharles.Forsyth 	Sym *s;
8*b370703fSCharles.Forsyth 	Prog *p;
9*b370703fSCharles.Forsyth 	long t, u;
10*b370703fSCharles.Forsyth 
11*b370703fSCharles.Forsyth 	if(debug['v'])
12*b370703fSCharles.Forsyth 		Bprint(&bso, "%5.2f dodata\n", cputime());
13*b370703fSCharles.Forsyth 	Bflush(&bso);
14*b370703fSCharles.Forsyth 	for(p = datap; p != P; p = p->link) {
15*b370703fSCharles.Forsyth 		s = p->from.sym;
16*b370703fSCharles.Forsyth 		if(p->as == ADYNT || p->as == AINIT)
17*b370703fSCharles.Forsyth 			s->value = dtype;
18*b370703fSCharles.Forsyth 		if(s->type == SBSS)
19*b370703fSCharles.Forsyth 			s->type = SDATA;
20*b370703fSCharles.Forsyth 		if(s->type != SDATA)
21*b370703fSCharles.Forsyth 			diag("initialize non-data (%d): %s\n%P",
22*b370703fSCharles.Forsyth 				s->type, s->name, p);
23*b370703fSCharles.Forsyth 		t = p->from.offset + p->width;
24*b370703fSCharles.Forsyth 		if(t > s->value)
25*b370703fSCharles.Forsyth 			diag("initialize bounds (%lld): %s\n%P",
26*b370703fSCharles.Forsyth 				s->value, s->name, p);
27*b370703fSCharles.Forsyth 	}
28*b370703fSCharles.Forsyth 	/* allocate small guys */
29*b370703fSCharles.Forsyth 	datsize = 0;
30*b370703fSCharles.Forsyth 	for(i=0; i<NHASH; i++)
31*b370703fSCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link) {
32*b370703fSCharles.Forsyth 		if(s->type != SDATA)
33*b370703fSCharles.Forsyth 		if(s->type != SBSS)
34*b370703fSCharles.Forsyth 			continue;
35*b370703fSCharles.Forsyth 		t = s->value;
36*b370703fSCharles.Forsyth 		if(t == 0) {
37*b370703fSCharles.Forsyth 			diag("%s: no size", s->name);
38*b370703fSCharles.Forsyth 			t = 1;
39*b370703fSCharles.Forsyth 		}
40*b370703fSCharles.Forsyth 		t = rnd(t, 4);
41*b370703fSCharles.Forsyth 		s->value = t;
42*b370703fSCharles.Forsyth 		if(t > MINSIZ)
43*b370703fSCharles.Forsyth 			continue;
44*b370703fSCharles.Forsyth 		if(t >= 8)
45*b370703fSCharles.Forsyth 			datsize = rnd(datsize, 8);
46*b370703fSCharles.Forsyth 		s->value = datsize;
47*b370703fSCharles.Forsyth 		datsize += t;
48*b370703fSCharles.Forsyth 		s->type = SDATA1;
49*b370703fSCharles.Forsyth 	}
50*b370703fSCharles.Forsyth 
51*b370703fSCharles.Forsyth 	/* allocate the rest of the data */
52*b370703fSCharles.Forsyth 	for(i=0; i<NHASH; i++)
53*b370703fSCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link) {
54*b370703fSCharles.Forsyth 		if(s->type != SDATA) {
55*b370703fSCharles.Forsyth 			if(s->type == SDATA1)
56*b370703fSCharles.Forsyth 				s->type = SDATA;
57*b370703fSCharles.Forsyth 			continue;
58*b370703fSCharles.Forsyth 		}
59*b370703fSCharles.Forsyth 		t = s->value;
60*b370703fSCharles.Forsyth 		if(t >= 8)
61*b370703fSCharles.Forsyth 			datsize = rnd(datsize, 8);
62*b370703fSCharles.Forsyth 		s->value = datsize;
63*b370703fSCharles.Forsyth 		datsize += t;
64*b370703fSCharles.Forsyth 	}
65*b370703fSCharles.Forsyth 	if(datsize)
66*b370703fSCharles.Forsyth 		datsize = rnd(datsize, 8);
67*b370703fSCharles.Forsyth 
68*b370703fSCharles.Forsyth 	if(debug['j']) {
69*b370703fSCharles.Forsyth 		/*
70*b370703fSCharles.Forsyth 		 * pad data with bss that fits up to next
71*b370703fSCharles.Forsyth 		 * 8k boundary, then push data to 8k
72*b370703fSCharles.Forsyth 		 */
73*b370703fSCharles.Forsyth 		u = rnd(datsize, 8192);
74*b370703fSCharles.Forsyth 		u -= datsize;
75*b370703fSCharles.Forsyth 		for(i=0; i<NHASH; i++)
76*b370703fSCharles.Forsyth 		for(s = hash[i]; s != S; s = s->link) {
77*b370703fSCharles.Forsyth 			if(s->type != SBSS)
78*b370703fSCharles.Forsyth 				continue;
79*b370703fSCharles.Forsyth 			t = s->value;
80*b370703fSCharles.Forsyth 			if(t > u)
81*b370703fSCharles.Forsyth 				continue;
82*b370703fSCharles.Forsyth 			u -= t;
83*b370703fSCharles.Forsyth 			s->value = datsize;
84*b370703fSCharles.Forsyth 			s->type = SDATA;
85*b370703fSCharles.Forsyth 			datsize += t;
86*b370703fSCharles.Forsyth 		}
87*b370703fSCharles.Forsyth 		datsize += u;
88*b370703fSCharles.Forsyth 	}
89*b370703fSCharles.Forsyth 
90*b370703fSCharles.Forsyth 	/* now the bss */
91*b370703fSCharles.Forsyth 	bsssize = 0;
92*b370703fSCharles.Forsyth 	for(i=0; i<NHASH; i++)
93*b370703fSCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link) {
94*b370703fSCharles.Forsyth 		if(s->type != SBSS)
95*b370703fSCharles.Forsyth 			continue;
96*b370703fSCharles.Forsyth 		t = s->value;
97*b370703fSCharles.Forsyth 		if(t >= 8)
98*b370703fSCharles.Forsyth 			bsssize = rnd(bsssize, 8);
99*b370703fSCharles.Forsyth 		s->value = bsssize + datsize;
100*b370703fSCharles.Forsyth 		bsssize += t;
101*b370703fSCharles.Forsyth 	}
102*b370703fSCharles.Forsyth 	xdefine("edata", SBSS, datsize);
103*b370703fSCharles.Forsyth 	xdefine("end", SBSS, bsssize + datsize);
104*b370703fSCharles.Forsyth }
105*b370703fSCharles.Forsyth 
106*b370703fSCharles.Forsyth Prog*
brchain(Prog * p)107*b370703fSCharles.Forsyth brchain(Prog *p)
108*b370703fSCharles.Forsyth {
109*b370703fSCharles.Forsyth 	int i;
110*b370703fSCharles.Forsyth 
111*b370703fSCharles.Forsyth 	for(i=0; i<20; i++) {
112*b370703fSCharles.Forsyth 		if(p == P || p->as != AJMP)
113*b370703fSCharles.Forsyth 			return p;
114*b370703fSCharles.Forsyth 		p = p->pcond;
115*b370703fSCharles.Forsyth 	}
116*b370703fSCharles.Forsyth 	return P;
117*b370703fSCharles.Forsyth }
118*b370703fSCharles.Forsyth 
119*b370703fSCharles.Forsyth void
follow(void)120*b370703fSCharles.Forsyth follow(void)
121*b370703fSCharles.Forsyth {
122*b370703fSCharles.Forsyth 
123*b370703fSCharles.Forsyth 	if(debug['v'])
124*b370703fSCharles.Forsyth 		Bprint(&bso, "%5.2f follow\n", cputime());
125*b370703fSCharles.Forsyth 	Bflush(&bso);
126*b370703fSCharles.Forsyth 	firstp = prg();
127*b370703fSCharles.Forsyth 	lastp = firstp;
128*b370703fSCharles.Forsyth 	xfol(textp);
129*b370703fSCharles.Forsyth 	lastp->link = P;
130*b370703fSCharles.Forsyth 	firstp = firstp->link;
131*b370703fSCharles.Forsyth }
132*b370703fSCharles.Forsyth 
133*b370703fSCharles.Forsyth void
xfol(Prog * p)134*b370703fSCharles.Forsyth xfol(Prog *p)
135*b370703fSCharles.Forsyth {
136*b370703fSCharles.Forsyth 	Prog *q;
137*b370703fSCharles.Forsyth 	int i;
138*b370703fSCharles.Forsyth 	enum as a;
139*b370703fSCharles.Forsyth 
140*b370703fSCharles.Forsyth loop:
141*b370703fSCharles.Forsyth 	if(p == P)
142*b370703fSCharles.Forsyth 		return;
143*b370703fSCharles.Forsyth 	if(p->as == ATEXT)
144*b370703fSCharles.Forsyth 		curtext = p;
145*b370703fSCharles.Forsyth 	if(p->as == AJMP)
146*b370703fSCharles.Forsyth 	if((q = p->pcond) != P) {
147*b370703fSCharles.Forsyth 		p->mark = 1;
148*b370703fSCharles.Forsyth 		p = q;
149*b370703fSCharles.Forsyth 		if(p->mark == 0)
150*b370703fSCharles.Forsyth 			goto loop;
151*b370703fSCharles.Forsyth 	}
152*b370703fSCharles.Forsyth 	if(p->mark) {
153*b370703fSCharles.Forsyth 		/* copy up to 4 instructions to avoid branch */
154*b370703fSCharles.Forsyth 		for(i=0,q=p; i<4; i++,q=q->link) {
155*b370703fSCharles.Forsyth 			if(q == P)
156*b370703fSCharles.Forsyth 				break;
157*b370703fSCharles.Forsyth 			if(q == lastp)
158*b370703fSCharles.Forsyth 				break;
159*b370703fSCharles.Forsyth 			a = q->as;
160*b370703fSCharles.Forsyth 			if(a == ANOP) {
161*b370703fSCharles.Forsyth 				i--;
162*b370703fSCharles.Forsyth 				continue;
163*b370703fSCharles.Forsyth 			}
164*b370703fSCharles.Forsyth 			switch(a) {
165*b370703fSCharles.Forsyth 			case AJMP:
166*b370703fSCharles.Forsyth 			case ARET:
167*b370703fSCharles.Forsyth 			case AIRETL:
168*b370703fSCharles.Forsyth 			case AIRETQ:
169*b370703fSCharles.Forsyth 			case AIRETW:
170*b370703fSCharles.Forsyth 			case ARETFL:
171*b370703fSCharles.Forsyth 			case ARETFQ:
172*b370703fSCharles.Forsyth 			case ARETFW:
173*b370703fSCharles.Forsyth 
174*b370703fSCharles.Forsyth 			case APUSHL:
175*b370703fSCharles.Forsyth 			case APUSHFL:
176*b370703fSCharles.Forsyth 			case APUSHQ:
177*b370703fSCharles.Forsyth 			case APUSHFQ:
178*b370703fSCharles.Forsyth 			case APUSHW:
179*b370703fSCharles.Forsyth 			case APUSHFW:
180*b370703fSCharles.Forsyth 			case APOPL:
181*b370703fSCharles.Forsyth 			case APOPFL:
182*b370703fSCharles.Forsyth 			case APOPQ:
183*b370703fSCharles.Forsyth 			case APOPFQ:
184*b370703fSCharles.Forsyth 			case APOPW:
185*b370703fSCharles.Forsyth 			case APOPFW:
186*b370703fSCharles.Forsyth 				goto brk;
187*b370703fSCharles.Forsyth 			}
188*b370703fSCharles.Forsyth 			if(q->pcond == P || q->pcond->mark)
189*b370703fSCharles.Forsyth 				continue;
190*b370703fSCharles.Forsyth 			if(a == ACALL || a == ALOOP)
191*b370703fSCharles.Forsyth 				continue;
192*b370703fSCharles.Forsyth 			for(;;) {
193*b370703fSCharles.Forsyth 				if(p->as == ANOP) {
194*b370703fSCharles.Forsyth 					p = p->link;
195*b370703fSCharles.Forsyth 					continue;
196*b370703fSCharles.Forsyth 				}
197*b370703fSCharles.Forsyth 				q = copyp(p);
198*b370703fSCharles.Forsyth 				p = p->link;
199*b370703fSCharles.Forsyth 				q->mark = 1;
200*b370703fSCharles.Forsyth 				lastp->link = q;
201*b370703fSCharles.Forsyth 				lastp = q;
202*b370703fSCharles.Forsyth 				if(q->as != a || q->pcond == P || q->pcond->mark)
203*b370703fSCharles.Forsyth 					continue;
204*b370703fSCharles.Forsyth 
205*b370703fSCharles.Forsyth 				q->as = relinv(q->as);
206*b370703fSCharles.Forsyth 				p = q->pcond;
207*b370703fSCharles.Forsyth 				q->pcond = q->link;
208*b370703fSCharles.Forsyth 				q->link = p;
209*b370703fSCharles.Forsyth 				xfol(q->link);
210*b370703fSCharles.Forsyth 				p = q->link;
211*b370703fSCharles.Forsyth 				if(p->mark)
212*b370703fSCharles.Forsyth 					return;
213*b370703fSCharles.Forsyth 				goto loop;
214*b370703fSCharles.Forsyth 			}
215*b370703fSCharles.Forsyth 		} /* */
216*b370703fSCharles.Forsyth 	brk:;
217*b370703fSCharles.Forsyth 		q = prg();
218*b370703fSCharles.Forsyth 		q->as = AJMP;
219*b370703fSCharles.Forsyth 		q->line = p->line;
220*b370703fSCharles.Forsyth 		q->to.type = D_BRANCH;
221*b370703fSCharles.Forsyth 		q->to.offset = p->pc;
222*b370703fSCharles.Forsyth 		q->pcond = p;
223*b370703fSCharles.Forsyth 		p = q;
224*b370703fSCharles.Forsyth 	}
225*b370703fSCharles.Forsyth 	p->mark = 1;
226*b370703fSCharles.Forsyth 	lastp->link = p;
227*b370703fSCharles.Forsyth 	lastp = p;
228*b370703fSCharles.Forsyth 	a = p->as;
229*b370703fSCharles.Forsyth 	if(a == AJMP || a == ARET || a == AIRETL || a == AIRETQ || a == AIRETW ||
230*b370703fSCharles.Forsyth 	   a == ARETFL || a == ARETFQ || a == ARETFW)
231*b370703fSCharles.Forsyth 		return;
232*b370703fSCharles.Forsyth 	if(p->pcond != P)
233*b370703fSCharles.Forsyth 	if(a != ACALL) {
234*b370703fSCharles.Forsyth 		q = brchain(p->link);
235*b370703fSCharles.Forsyth 		if(q != P && q->mark)
236*b370703fSCharles.Forsyth 		if(a != ALOOP) {
237*b370703fSCharles.Forsyth 			p->as = relinv(a);
238*b370703fSCharles.Forsyth 			p->link = p->pcond;
239*b370703fSCharles.Forsyth 			p->pcond = q;
240*b370703fSCharles.Forsyth 		}
241*b370703fSCharles.Forsyth 		xfol(p->link);
242*b370703fSCharles.Forsyth 		q = brchain(p->pcond);
243*b370703fSCharles.Forsyth 		if(q->mark) {
244*b370703fSCharles.Forsyth 			p->pcond = q;
245*b370703fSCharles.Forsyth 			return;
246*b370703fSCharles.Forsyth 		}
247*b370703fSCharles.Forsyth 		p = q;
248*b370703fSCharles.Forsyth 		goto loop;
249*b370703fSCharles.Forsyth 	}
250*b370703fSCharles.Forsyth 	p = p->link;
251*b370703fSCharles.Forsyth 	goto loop;
252*b370703fSCharles.Forsyth }
253*b370703fSCharles.Forsyth 
254*b370703fSCharles.Forsyth int
relinv(int a)255*b370703fSCharles.Forsyth relinv(int a)
256*b370703fSCharles.Forsyth {
257*b370703fSCharles.Forsyth 
258*b370703fSCharles.Forsyth 	switch(a) {
259*b370703fSCharles.Forsyth 	case AJEQ:	return AJNE;
260*b370703fSCharles.Forsyth 	case AJNE:	return AJEQ;
261*b370703fSCharles.Forsyth 	case AJLE:	return AJGT;
262*b370703fSCharles.Forsyth 	case AJLS:	return AJHI;
263*b370703fSCharles.Forsyth 	case AJLT:	return AJGE;
264*b370703fSCharles.Forsyth 	case AJMI:	return AJPL;
265*b370703fSCharles.Forsyth 	case AJGE:	return AJLT;
266*b370703fSCharles.Forsyth 	case AJPL:	return AJMI;
267*b370703fSCharles.Forsyth 	case AJGT:	return AJLE;
268*b370703fSCharles.Forsyth 	case AJHI:	return AJLS;
269*b370703fSCharles.Forsyth 	case AJCS:	return AJCC;
270*b370703fSCharles.Forsyth 	case AJCC:	return AJCS;
271*b370703fSCharles.Forsyth 	case AJPS:	return AJPC;
272*b370703fSCharles.Forsyth 	case AJPC:	return AJPS;
273*b370703fSCharles.Forsyth 	case AJOS:	return AJOC;
274*b370703fSCharles.Forsyth 	case AJOC:	return AJOS;
275*b370703fSCharles.Forsyth 	}
276*b370703fSCharles.Forsyth 	diag("unknown relation: %s in %s", anames[a], TNAME);
277*b370703fSCharles.Forsyth 	return a;
278*b370703fSCharles.Forsyth }
279*b370703fSCharles.Forsyth 
280*b370703fSCharles.Forsyth void
doinit(void)281*b370703fSCharles.Forsyth doinit(void)
282*b370703fSCharles.Forsyth {
283*b370703fSCharles.Forsyth 	Sym *s;
284*b370703fSCharles.Forsyth 	Prog *p;
285*b370703fSCharles.Forsyth 	int x;
286*b370703fSCharles.Forsyth 
287*b370703fSCharles.Forsyth 	for(p = datap; p != P; p = p->link) {
288*b370703fSCharles.Forsyth 		x = p->to.type;
289*b370703fSCharles.Forsyth 		if(x != D_EXTERN && x != D_STATIC)
290*b370703fSCharles.Forsyth 			continue;
291*b370703fSCharles.Forsyth 		s = p->to.sym;
292*b370703fSCharles.Forsyth 		if(s->type == 0 || s->type == SXREF)
293*b370703fSCharles.Forsyth 			diag("undefined %s initializer of %s",
294*b370703fSCharles.Forsyth 				s->name, p->from.sym->name);
295*b370703fSCharles.Forsyth 		p->to.offset += s->value;
296*b370703fSCharles.Forsyth 		p->to.type = D_CONST;
297*b370703fSCharles.Forsyth 		if(s->type == SDATA || s->type == SBSS)
298*b370703fSCharles.Forsyth 			p->to.offset += INITDAT;
299*b370703fSCharles.Forsyth 	}
300*b370703fSCharles.Forsyth }
301*b370703fSCharles.Forsyth 
302*b370703fSCharles.Forsyth void
patch(void)303*b370703fSCharles.Forsyth patch(void)
304*b370703fSCharles.Forsyth {
305*b370703fSCharles.Forsyth 	long c;
306*b370703fSCharles.Forsyth 	Prog *p, *q;
307*b370703fSCharles.Forsyth 	Sym *s;
308*b370703fSCharles.Forsyth 	long vexit;
309*b370703fSCharles.Forsyth 
310*b370703fSCharles.Forsyth 	if(debug['v'])
311*b370703fSCharles.Forsyth 		Bprint(&bso, "%5.2f mkfwd\n", cputime());
312*b370703fSCharles.Forsyth 	Bflush(&bso);
313*b370703fSCharles.Forsyth 	mkfwd();
314*b370703fSCharles.Forsyth 	if(debug['v'])
315*b370703fSCharles.Forsyth 		Bprint(&bso, "%5.2f patch\n", cputime());
316*b370703fSCharles.Forsyth 	Bflush(&bso);
317*b370703fSCharles.Forsyth 	s = lookup("exit", 0);
318*b370703fSCharles.Forsyth 	vexit = s->value;
319*b370703fSCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
320*b370703fSCharles.Forsyth 		if(p->as == ATEXT)
321*b370703fSCharles.Forsyth 			curtext = p;
322*b370703fSCharles.Forsyth 		if(p->as == ACALL || p->as == ARET) {
323*b370703fSCharles.Forsyth 			s = p->to.sym;
324*b370703fSCharles.Forsyth 			if(s) {
325*b370703fSCharles.Forsyth 				if(debug['c'])
326*b370703fSCharles.Forsyth 					Bprint(&bso, "%s calls %s\n", TNAME, s->name);
327*b370703fSCharles.Forsyth 				switch(s->type) {
328*b370703fSCharles.Forsyth 				default:
329*b370703fSCharles.Forsyth 					diag("undefined: %s in %s", s->name, TNAME);
330*b370703fSCharles.Forsyth 					s->type = STEXT;
331*b370703fSCharles.Forsyth 					s->value = vexit;
332*b370703fSCharles.Forsyth 					break;	/* or fall through to set offset? */
333*b370703fSCharles.Forsyth 				case STEXT:
334*b370703fSCharles.Forsyth 					p->to.offset = s->value;
335*b370703fSCharles.Forsyth 					break;
336*b370703fSCharles.Forsyth 				case SUNDEF:
337*b370703fSCharles.Forsyth 					p->pcond = UP;
338*b370703fSCharles.Forsyth 					p->to.offset = 0;
339*b370703fSCharles.Forsyth 					break;
340*b370703fSCharles.Forsyth 				}
341*b370703fSCharles.Forsyth 				p->to.type = D_BRANCH;
342*b370703fSCharles.Forsyth 			}
343*b370703fSCharles.Forsyth 		}
344*b370703fSCharles.Forsyth 		if(p->to.type != D_BRANCH || p->pcond == UP)
345*b370703fSCharles.Forsyth 			continue;
346*b370703fSCharles.Forsyth 		c = p->to.offset;
347*b370703fSCharles.Forsyth 		for(q = firstp; q != P;) {
348*b370703fSCharles.Forsyth 			if(q->forwd != P)
349*b370703fSCharles.Forsyth 			if(c >= q->forwd->pc) {
350*b370703fSCharles.Forsyth 				q = q->forwd;
351*b370703fSCharles.Forsyth 				continue;
352*b370703fSCharles.Forsyth 			}
353*b370703fSCharles.Forsyth 			if(c == q->pc)
354*b370703fSCharles.Forsyth 				break;
355*b370703fSCharles.Forsyth 			q = q->link;
356*b370703fSCharles.Forsyth 		}
357*b370703fSCharles.Forsyth 		if(q == P) {
358*b370703fSCharles.Forsyth 			diag("branch out of range in %s\n%P", TNAME, p);
359*b370703fSCharles.Forsyth 			p->to.type = D_NONE;
360*b370703fSCharles.Forsyth 		}
361*b370703fSCharles.Forsyth 		p->pcond = q;
362*b370703fSCharles.Forsyth 	}
363*b370703fSCharles.Forsyth 
364*b370703fSCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
365*b370703fSCharles.Forsyth 		if(p->as == ATEXT)
366*b370703fSCharles.Forsyth 			curtext = p;
367*b370703fSCharles.Forsyth 		p->mark = 0;	/* initialization for follow */
368*b370703fSCharles.Forsyth 		if(p->pcond != P && p->pcond != UP) {
369*b370703fSCharles.Forsyth 			p->pcond = brloop(p->pcond);
370*b370703fSCharles.Forsyth 			if(p->pcond != P)
371*b370703fSCharles.Forsyth 			if(p->to.type == D_BRANCH)
372*b370703fSCharles.Forsyth 				p->to.offset = p->pcond->pc;
373*b370703fSCharles.Forsyth 		}
374*b370703fSCharles.Forsyth 	}
375*b370703fSCharles.Forsyth }
376*b370703fSCharles.Forsyth 
377*b370703fSCharles.Forsyth #define	LOG	5
378*b370703fSCharles.Forsyth void
mkfwd(void)379*b370703fSCharles.Forsyth mkfwd(void)
380*b370703fSCharles.Forsyth {
381*b370703fSCharles.Forsyth 	Prog *p;
382*b370703fSCharles.Forsyth 	int i;
383*b370703fSCharles.Forsyth 	long dwn[LOG], cnt[LOG];
384*b370703fSCharles.Forsyth 	Prog *lst[LOG];
385*b370703fSCharles.Forsyth 
386*b370703fSCharles.Forsyth 	for(i=0; i<LOG; i++) {
387*b370703fSCharles.Forsyth 		if(i == 0)
388*b370703fSCharles.Forsyth 			cnt[i] = 1; else
389*b370703fSCharles.Forsyth 			cnt[i] = LOG * cnt[i-1];
390*b370703fSCharles.Forsyth 		dwn[i] = 1;
391*b370703fSCharles.Forsyth 		lst[i] = P;
392*b370703fSCharles.Forsyth 	}
393*b370703fSCharles.Forsyth 	i = 0;
394*b370703fSCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
395*b370703fSCharles.Forsyth 		if(p->as == ATEXT)
396*b370703fSCharles.Forsyth 			curtext = p;
397*b370703fSCharles.Forsyth 		i--;
398*b370703fSCharles.Forsyth 		if(i < 0)
399*b370703fSCharles.Forsyth 			i = LOG-1;
400*b370703fSCharles.Forsyth 		p->forwd = P;
401*b370703fSCharles.Forsyth 		dwn[i]--;
402*b370703fSCharles.Forsyth 		if(dwn[i] <= 0) {
403*b370703fSCharles.Forsyth 			dwn[i] = cnt[i];
404*b370703fSCharles.Forsyth 			if(lst[i] != P)
405*b370703fSCharles.Forsyth 				lst[i]->forwd = p;
406*b370703fSCharles.Forsyth 			lst[i] = p;
407*b370703fSCharles.Forsyth 		}
408*b370703fSCharles.Forsyth 	}
409*b370703fSCharles.Forsyth }
410*b370703fSCharles.Forsyth 
411*b370703fSCharles.Forsyth Prog*
brloop(Prog * p)412*b370703fSCharles.Forsyth brloop(Prog *p)
413*b370703fSCharles.Forsyth {
414*b370703fSCharles.Forsyth 	int c;
415*b370703fSCharles.Forsyth 	Prog *q;
416*b370703fSCharles.Forsyth 
417*b370703fSCharles.Forsyth 	c = 0;
418*b370703fSCharles.Forsyth 	for(q = p; q != P; q = q->pcond) {
419*b370703fSCharles.Forsyth 		if(q->as != AJMP)
420*b370703fSCharles.Forsyth 			break;
421*b370703fSCharles.Forsyth 		c++;
422*b370703fSCharles.Forsyth 		if(c >= 5000)
423*b370703fSCharles.Forsyth 			return P;
424*b370703fSCharles.Forsyth 	}
425*b370703fSCharles.Forsyth 	return q;
426*b370703fSCharles.Forsyth }
427*b370703fSCharles.Forsyth 
428*b370703fSCharles.Forsyth void
dostkoff(void)429*b370703fSCharles.Forsyth dostkoff(void)
430*b370703fSCharles.Forsyth {
431*b370703fSCharles.Forsyth 	Prog *p, *q;
432*b370703fSCharles.Forsyth 	long autoffset, deltasp;
433*b370703fSCharles.Forsyth 	int a, f, curframe, curbecome, maxbecome, pcsize;
434*b370703fSCharles.Forsyth 
435*b370703fSCharles.Forsyth 	curframe = 0;
436*b370703fSCharles.Forsyth 	curbecome = 0;
437*b370703fSCharles.Forsyth 	maxbecome = 0;
438*b370703fSCharles.Forsyth 	curtext = 0;
439*b370703fSCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
440*b370703fSCharles.Forsyth 
441*b370703fSCharles.Forsyth 		/* find out how much arg space is used in this TEXT */
442*b370703fSCharles.Forsyth 		if(p->to.type == (D_INDIR+D_SP))
443*b370703fSCharles.Forsyth 			if(p->to.offset > curframe)
444*b370703fSCharles.Forsyth 				curframe = p->to.offset;
445*b370703fSCharles.Forsyth 
446*b370703fSCharles.Forsyth 		switch(p->as) {
447*b370703fSCharles.Forsyth 		case ATEXT:
448*b370703fSCharles.Forsyth 			if(curtext && curtext->from.sym) {
449*b370703fSCharles.Forsyth 				curtext->from.sym->frame = curframe;
450*b370703fSCharles.Forsyth 				curtext->from.sym->become = curbecome;
451*b370703fSCharles.Forsyth 				if(curbecome > maxbecome)
452*b370703fSCharles.Forsyth 					maxbecome = curbecome;
453*b370703fSCharles.Forsyth 			}
454*b370703fSCharles.Forsyth 			curframe = 0;
455*b370703fSCharles.Forsyth 			curbecome = 0;
456*b370703fSCharles.Forsyth 
457*b370703fSCharles.Forsyth 			curtext = p;
458*b370703fSCharles.Forsyth 			break;
459*b370703fSCharles.Forsyth 
460*b370703fSCharles.Forsyth 		case ARET:
461*b370703fSCharles.Forsyth 			/* special form of RET is BECOME */
462*b370703fSCharles.Forsyth 			if(p->from.type == D_CONST)
463*b370703fSCharles.Forsyth 				if(p->from.offset > curbecome)
464*b370703fSCharles.Forsyth 					curbecome = p->from.offset;
465*b370703fSCharles.Forsyth 			break;
466*b370703fSCharles.Forsyth 		}
467*b370703fSCharles.Forsyth 	}
468*b370703fSCharles.Forsyth 	if(curtext && curtext->from.sym) {
469*b370703fSCharles.Forsyth 		curtext->from.sym->frame = curframe;
470*b370703fSCharles.Forsyth 		curtext->from.sym->become = curbecome;
471*b370703fSCharles.Forsyth 		if(curbecome > maxbecome)
472*b370703fSCharles.Forsyth 			maxbecome = curbecome;
473*b370703fSCharles.Forsyth 	}
474*b370703fSCharles.Forsyth 
475*b370703fSCharles.Forsyth 	if(debug['b'])
476*b370703fSCharles.Forsyth 		print("max become = %d\n", maxbecome);
477*b370703fSCharles.Forsyth 	xdefine("ALEFbecome", STEXT, maxbecome);
478*b370703fSCharles.Forsyth 
479*b370703fSCharles.Forsyth 	curtext = 0;
480*b370703fSCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
481*b370703fSCharles.Forsyth 		switch(p->as) {
482*b370703fSCharles.Forsyth 		case ATEXT:
483*b370703fSCharles.Forsyth 			curtext = p;
484*b370703fSCharles.Forsyth 			break;
485*b370703fSCharles.Forsyth 		case ACALL:
486*b370703fSCharles.Forsyth 			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
487*b370703fSCharles.Forsyth 				f = maxbecome - curtext->from.sym->frame;
488*b370703fSCharles.Forsyth 				if(f <= 0)
489*b370703fSCharles.Forsyth 					break;
490*b370703fSCharles.Forsyth 				/* calling a become or calling a variable */
491*b370703fSCharles.Forsyth 				if(p->to.sym == S || p->to.sym->become) {
492*b370703fSCharles.Forsyth 					curtext->to.offset += f;
493*b370703fSCharles.Forsyth 					if(debug['b']) {
494*b370703fSCharles.Forsyth 						curp = p;
495*b370703fSCharles.Forsyth 						print("%D calling %D increase %d\n",
496*b370703fSCharles.Forsyth 							&curtext->from, &p->to, f);
497*b370703fSCharles.Forsyth 					}
498*b370703fSCharles.Forsyth 				}
499*b370703fSCharles.Forsyth 			}
500*b370703fSCharles.Forsyth 			break;
501*b370703fSCharles.Forsyth 		}
502*b370703fSCharles.Forsyth 	}
503*b370703fSCharles.Forsyth 
504*b370703fSCharles.Forsyth 	autoffset = 0;
505*b370703fSCharles.Forsyth 	deltasp = 0;
506*b370703fSCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
507*b370703fSCharles.Forsyth 		if(p->as == ATEXT) {
508*b370703fSCharles.Forsyth 			curtext = p;
509*b370703fSCharles.Forsyth 			autoffset = p->to.offset;
510*b370703fSCharles.Forsyth 			if(autoffset < 0)
511*b370703fSCharles.Forsyth 				autoffset = 0;
512*b370703fSCharles.Forsyth 			if(autoffset) {
513*b370703fSCharles.Forsyth 				p = appendp(p);
514*b370703fSCharles.Forsyth 				p->as = AADJSP;
515*b370703fSCharles.Forsyth 				p->from.type = D_CONST;
516*b370703fSCharles.Forsyth 				p->from.offset = autoffset;
517*b370703fSCharles.Forsyth 			}
518*b370703fSCharles.Forsyth 			deltasp = autoffset;
519*b370703fSCharles.Forsyth 		}
520*b370703fSCharles.Forsyth 		pcsize = p->mode/8;
521*b370703fSCharles.Forsyth 		a = p->from.type;
522*b370703fSCharles.Forsyth 		if(a == D_AUTO)
523*b370703fSCharles.Forsyth 			p->from.offset += deltasp;
524*b370703fSCharles.Forsyth 		if(a == D_PARAM)
525*b370703fSCharles.Forsyth 			p->from.offset += deltasp + pcsize;
526*b370703fSCharles.Forsyth 		a = p->to.type;
527*b370703fSCharles.Forsyth 		if(a == D_AUTO)
528*b370703fSCharles.Forsyth 			p->to.offset += deltasp;
529*b370703fSCharles.Forsyth 		if(a == D_PARAM)
530*b370703fSCharles.Forsyth 			p->to.offset += deltasp + pcsize;
531*b370703fSCharles.Forsyth 
532*b370703fSCharles.Forsyth 		switch(p->as) {
533*b370703fSCharles.Forsyth 		default:
534*b370703fSCharles.Forsyth 			continue;
535*b370703fSCharles.Forsyth 		case APUSHL:
536*b370703fSCharles.Forsyth 		case APUSHFL:
537*b370703fSCharles.Forsyth 			deltasp += 4;
538*b370703fSCharles.Forsyth 			continue;
539*b370703fSCharles.Forsyth 		case APUSHQ:
540*b370703fSCharles.Forsyth 		case APUSHFQ:
541*b370703fSCharles.Forsyth 			deltasp += 8;
542*b370703fSCharles.Forsyth 			continue;
543*b370703fSCharles.Forsyth 		case APUSHW:
544*b370703fSCharles.Forsyth 		case APUSHFW:
545*b370703fSCharles.Forsyth 			deltasp += 2;
546*b370703fSCharles.Forsyth 			continue;
547*b370703fSCharles.Forsyth 		case APOPL:
548*b370703fSCharles.Forsyth 		case APOPFL:
549*b370703fSCharles.Forsyth 			deltasp -= 4;
550*b370703fSCharles.Forsyth 			continue;
551*b370703fSCharles.Forsyth 		case APOPQ:
552*b370703fSCharles.Forsyth 		case APOPFQ:
553*b370703fSCharles.Forsyth 			deltasp -= 8;
554*b370703fSCharles.Forsyth 			continue;
555*b370703fSCharles.Forsyth 		case APOPW:
556*b370703fSCharles.Forsyth 		case APOPFW:
557*b370703fSCharles.Forsyth 			deltasp -= 2;
558*b370703fSCharles.Forsyth 			continue;
559*b370703fSCharles.Forsyth 		case ARET:
560*b370703fSCharles.Forsyth 			break;
561*b370703fSCharles.Forsyth 		}
562*b370703fSCharles.Forsyth 
563*b370703fSCharles.Forsyth 		if(autoffset != deltasp)
564*b370703fSCharles.Forsyth 			diag("unbalanced PUSH/POP");
565*b370703fSCharles.Forsyth 		if(p->from.type == D_CONST)
566*b370703fSCharles.Forsyth 			goto become;
567*b370703fSCharles.Forsyth 
568*b370703fSCharles.Forsyth 		if(autoffset) {
569*b370703fSCharles.Forsyth 			q = p;
570*b370703fSCharles.Forsyth 			p = appendp(p);
571*b370703fSCharles.Forsyth 			p->as = ARET;
572*b370703fSCharles.Forsyth 
573*b370703fSCharles.Forsyth 			q->as = AADJSP;
574*b370703fSCharles.Forsyth 			q->from.type = D_CONST;
575*b370703fSCharles.Forsyth 			q->from.offset = -autoffset;
576*b370703fSCharles.Forsyth 		}
577*b370703fSCharles.Forsyth 		continue;
578*b370703fSCharles.Forsyth 
579*b370703fSCharles.Forsyth 	become:
580*b370703fSCharles.Forsyth 		q = p;
581*b370703fSCharles.Forsyth 		p = appendp(p);
582*b370703fSCharles.Forsyth 		p->as = AJMP;
583*b370703fSCharles.Forsyth 		p->to = q->to;
584*b370703fSCharles.Forsyth 		p->pcond = q->pcond;
585*b370703fSCharles.Forsyth 
586*b370703fSCharles.Forsyth 		q->as = AADJSP;
587*b370703fSCharles.Forsyth 		q->from = zprg.from;
588*b370703fSCharles.Forsyth 		q->from.type = D_CONST;
589*b370703fSCharles.Forsyth 		q->from.offset = -autoffset;
590*b370703fSCharles.Forsyth 		q->to = zprg.to;
591*b370703fSCharles.Forsyth 		continue;
592*b370703fSCharles.Forsyth 	}
593*b370703fSCharles.Forsyth }
594*b370703fSCharles.Forsyth 
595*b370703fSCharles.Forsyth vlong
atolwhex(char * s)596*b370703fSCharles.Forsyth atolwhex(char *s)
597*b370703fSCharles.Forsyth {
598*b370703fSCharles.Forsyth 	vlong n;
599*b370703fSCharles.Forsyth 	int f;
600*b370703fSCharles.Forsyth 
601*b370703fSCharles.Forsyth 	n = 0;
602*b370703fSCharles.Forsyth 	f = 0;
603*b370703fSCharles.Forsyth 	while(*s == ' ' || *s == '\t')
604*b370703fSCharles.Forsyth 		s++;
605*b370703fSCharles.Forsyth 	if(*s == '-' || *s == '+') {
606*b370703fSCharles.Forsyth 		if(*s++ == '-')
607*b370703fSCharles.Forsyth 			f = 1;
608*b370703fSCharles.Forsyth 		while(*s == ' ' || *s == '\t')
609*b370703fSCharles.Forsyth 			s++;
610*b370703fSCharles.Forsyth 	}
611*b370703fSCharles.Forsyth 	if(s[0]=='0' && s[1]){
612*b370703fSCharles.Forsyth 		if(s[1]=='x' || s[1]=='X'){
613*b370703fSCharles.Forsyth 			s += 2;
614*b370703fSCharles.Forsyth 			for(;;){
615*b370703fSCharles.Forsyth 				if(*s >= '0' && *s <= '9')
616*b370703fSCharles.Forsyth 					n = n*16 + *s++ - '0';
617*b370703fSCharles.Forsyth 				else if(*s >= 'a' && *s <= 'f')
618*b370703fSCharles.Forsyth 					n = n*16 + *s++ - 'a' + 10;
619*b370703fSCharles.Forsyth 				else if(*s >= 'A' && *s <= 'F')
620*b370703fSCharles.Forsyth 					n = n*16 + *s++ - 'A' + 10;
621*b370703fSCharles.Forsyth 				else
622*b370703fSCharles.Forsyth 					break;
623*b370703fSCharles.Forsyth 			}
624*b370703fSCharles.Forsyth 		} else
625*b370703fSCharles.Forsyth 			while(*s >= '0' && *s <= '7')
626*b370703fSCharles.Forsyth 				n = n*8 + *s++ - '0';
627*b370703fSCharles.Forsyth 	} else
628*b370703fSCharles.Forsyth 		while(*s >= '0' && *s <= '9')
629*b370703fSCharles.Forsyth 			n = n*10 + *s++ - '0';
630*b370703fSCharles.Forsyth 	if(f)
631*b370703fSCharles.Forsyth 		n = -n;
632*b370703fSCharles.Forsyth 	return n;
633*b370703fSCharles.Forsyth }
634*b370703fSCharles.Forsyth 
635*b370703fSCharles.Forsyth void
undef(void)636*b370703fSCharles.Forsyth undef(void)
637*b370703fSCharles.Forsyth {
638*b370703fSCharles.Forsyth 	int i;
639*b370703fSCharles.Forsyth 	Sym *s;
640*b370703fSCharles.Forsyth 
641*b370703fSCharles.Forsyth 	for(i=0; i<NHASH; i++)
642*b370703fSCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link)
643*b370703fSCharles.Forsyth 		if(s->type == SXREF)
644*b370703fSCharles.Forsyth 			diag("%s: not defined", s->name);
645*b370703fSCharles.Forsyth }
646*b370703fSCharles.Forsyth 
647*b370703fSCharles.Forsyth void
import(void)648*b370703fSCharles.Forsyth import(void)
649*b370703fSCharles.Forsyth {
650*b370703fSCharles.Forsyth 	int i;
651*b370703fSCharles.Forsyth 	Sym *s;
652*b370703fSCharles.Forsyth 
653*b370703fSCharles.Forsyth 	for(i = 0; i < NHASH; i++)
654*b370703fSCharles.Forsyth 		for(s = hash[i]; s != S; s = s->link)
655*b370703fSCharles.Forsyth 			if(s->sig != 0 && s->type == SXREF && (nimports == 0 || s->subtype == SIMPORT)){
656*b370703fSCharles.Forsyth 				if(s->value != 0)
657*b370703fSCharles.Forsyth 					diag("value != 0 on SXREF");
658*b370703fSCharles.Forsyth 				undefsym(s);
659*b370703fSCharles.Forsyth 				Bprint(&bso, "IMPORT: %s sig=%lux v=%lld\n", s->name, s->sig, s->value);
660*b370703fSCharles.Forsyth 				if(debug['S'])
661*b370703fSCharles.Forsyth 					s->sig = 0;
662*b370703fSCharles.Forsyth 			}
663*b370703fSCharles.Forsyth }
664*b370703fSCharles.Forsyth 
665*b370703fSCharles.Forsyth void
ckoff(Sym * s,long v)666*b370703fSCharles.Forsyth ckoff(Sym *s, long v)
667*b370703fSCharles.Forsyth {
668*b370703fSCharles.Forsyth 	if(v < 0 || v >= 1<<Roffset)
669*b370703fSCharles.Forsyth 		diag("relocation offset %ld for %s out of range", v, s->name);
670*b370703fSCharles.Forsyth }
671*b370703fSCharles.Forsyth 
672*b370703fSCharles.Forsyth static Prog*
newdata(Sym * s,int o,int w,int t)673*b370703fSCharles.Forsyth newdata(Sym *s, int o, int w, int t)
674*b370703fSCharles.Forsyth {
675*b370703fSCharles.Forsyth 	Prog *p;
676*b370703fSCharles.Forsyth 
677*b370703fSCharles.Forsyth 	p = prg();
678*b370703fSCharles.Forsyth 	if(edatap == P)
679*b370703fSCharles.Forsyth 		datap = p;
680*b370703fSCharles.Forsyth 	else
681*b370703fSCharles.Forsyth 		edatap->link = p;
682*b370703fSCharles.Forsyth 	edatap = p;
683*b370703fSCharles.Forsyth 	p->as = ADATA;
684*b370703fSCharles.Forsyth 	p->width = w;
685*b370703fSCharles.Forsyth 	p->from.scale = w;
686*b370703fSCharles.Forsyth 	p->from.type = t;
687*b370703fSCharles.Forsyth 	p->from.sym = s;
688*b370703fSCharles.Forsyth 	p->from.offset = o;
689*b370703fSCharles.Forsyth 	p->to.type = D_CONST;
690*b370703fSCharles.Forsyth 	return p;
691*b370703fSCharles.Forsyth }
692*b370703fSCharles.Forsyth 
693*b370703fSCharles.Forsyth void
export(void)694*b370703fSCharles.Forsyth export(void)
695*b370703fSCharles.Forsyth {
696*b370703fSCharles.Forsyth 	int i, j, n, off, nb, sv, ne;
697*b370703fSCharles.Forsyth 	Sym *s, *et, *str, **esyms;
698*b370703fSCharles.Forsyth 	Prog *p;
699*b370703fSCharles.Forsyth 	char buf[NSNAME], *t;
700*b370703fSCharles.Forsyth 
701*b370703fSCharles.Forsyth 	n = 0;
702*b370703fSCharles.Forsyth 	for(i = 0; i < NHASH; i++)
703*b370703fSCharles.Forsyth 		for(s = hash[i]; s != S; s = s->link)
704*b370703fSCharles.Forsyth 			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
705*b370703fSCharles.Forsyth 				n++;
706*b370703fSCharles.Forsyth 	esyms = malloc(n*sizeof(Sym*));
707*b370703fSCharles.Forsyth 	ne = n;
708*b370703fSCharles.Forsyth 	n = 0;
709*b370703fSCharles.Forsyth 	for(i = 0; i < NHASH; i++)
710*b370703fSCharles.Forsyth 		for(s = hash[i]; s != S; s = s->link)
711*b370703fSCharles.Forsyth 			if(s->sig != 0 && s->type != SXREF && s->type != SUNDEF && (nexports == 0 || s->subtype == SEXPORT))
712*b370703fSCharles.Forsyth 				esyms[n++] = s;
713*b370703fSCharles.Forsyth 	for(i = 0; i < ne-1; i++)
714*b370703fSCharles.Forsyth 		for(j = i+1; j < ne; j++)
715*b370703fSCharles.Forsyth 			if(strcmp(esyms[i]->name, esyms[j]->name) > 0){
716*b370703fSCharles.Forsyth 				s = esyms[i];
717*b370703fSCharles.Forsyth 				esyms[i] = esyms[j];
718*b370703fSCharles.Forsyth 				esyms[j] = s;
719*b370703fSCharles.Forsyth 			}
720*b370703fSCharles.Forsyth 
721*b370703fSCharles.Forsyth 	nb = 0;
722*b370703fSCharles.Forsyth 	off = 0;
723*b370703fSCharles.Forsyth 	et = lookup(EXPTAB, 0);
724*b370703fSCharles.Forsyth 	if(et->type != 0 && et->type != SXREF)
725*b370703fSCharles.Forsyth 		diag("%s already defined", EXPTAB);
726*b370703fSCharles.Forsyth 	et->type = SDATA;
727*b370703fSCharles.Forsyth 	str = lookup(".string", 0);
728*b370703fSCharles.Forsyth 	if(str->type == 0)
729*b370703fSCharles.Forsyth 		str->type = SDATA;
730*b370703fSCharles.Forsyth 	sv = str->value;
731*b370703fSCharles.Forsyth 	for(i = 0; i < ne; i++){
732*b370703fSCharles.Forsyth 		s = esyms[i];
733*b370703fSCharles.Forsyth 		if(debug['S'])
734*b370703fSCharles.Forsyth 			s->sig = 0;
735*b370703fSCharles.Forsyth 		/* Bprint(&bso, "EXPORT: %s sig=%lux t=%d\n", s->name, s->sig, s->type); */
736*b370703fSCharles.Forsyth 
737*b370703fSCharles.Forsyth 		/* signature */
738*b370703fSCharles.Forsyth 		p = newdata(et, off, sizeof(long), D_EXTERN);
739*b370703fSCharles.Forsyth 		off += sizeof(long);
740*b370703fSCharles.Forsyth 		p->to.offset = s->sig;
741*b370703fSCharles.Forsyth 
742*b370703fSCharles.Forsyth 		/* address */
743*b370703fSCharles.Forsyth 		p = newdata(et, off, sizeof(long), D_EXTERN);
744*b370703fSCharles.Forsyth 		off += sizeof(long);
745*b370703fSCharles.Forsyth 		p->to.type = D_ADDR;
746*b370703fSCharles.Forsyth 		p->to.index = D_EXTERN;
747*b370703fSCharles.Forsyth 		p->to.sym = s;
748*b370703fSCharles.Forsyth 
749*b370703fSCharles.Forsyth 		/* string */
750*b370703fSCharles.Forsyth 		t = s->name;
751*b370703fSCharles.Forsyth 		n = strlen(t)+1;
752*b370703fSCharles.Forsyth 		for(;;){
753*b370703fSCharles.Forsyth 			buf[nb++] = *t;
754*b370703fSCharles.Forsyth 			sv++;
755*b370703fSCharles.Forsyth 			if(nb >= NSNAME){
756*b370703fSCharles.Forsyth 				p = newdata(str, sv-NSNAME, NSNAME, D_STATIC);
757*b370703fSCharles.Forsyth 				p->to.type = D_SCONST;
758*b370703fSCharles.Forsyth 				memmove(p->to.scon, buf, NSNAME);
759*b370703fSCharles.Forsyth 				nb = 0;
760*b370703fSCharles.Forsyth 			}
761*b370703fSCharles.Forsyth 			if(*t++ == 0)
762*b370703fSCharles.Forsyth 				break;
763*b370703fSCharles.Forsyth 		}
764*b370703fSCharles.Forsyth 
765*b370703fSCharles.Forsyth 		/* name */
766*b370703fSCharles.Forsyth 		p = newdata(et, off, sizeof(long), D_EXTERN);
767*b370703fSCharles.Forsyth 		off += sizeof(long);
768*b370703fSCharles.Forsyth 		p->to.type = D_ADDR;
769*b370703fSCharles.Forsyth 		p->to.index = D_STATIC;
770*b370703fSCharles.Forsyth 		p->to.sym = str;
771*b370703fSCharles.Forsyth 		p->to.offset = sv-n;
772*b370703fSCharles.Forsyth 	}
773*b370703fSCharles.Forsyth 
774*b370703fSCharles.Forsyth 	if(nb > 0){
775*b370703fSCharles.Forsyth 		p = newdata(str, sv-nb, nb, D_STATIC);
776*b370703fSCharles.Forsyth 		p->to.type = D_SCONST;
777*b370703fSCharles.Forsyth 		memmove(p->to.scon, buf, nb);
778*b370703fSCharles.Forsyth 	}
779*b370703fSCharles.Forsyth 
780*b370703fSCharles.Forsyth 	for(i = 0; i < 3; i++){
781*b370703fSCharles.Forsyth 		newdata(et, off, sizeof(long), D_EXTERN);
782*b370703fSCharles.Forsyth 		off += sizeof(long);
783*b370703fSCharles.Forsyth 	}
784*b370703fSCharles.Forsyth 	et->value = off;
785*b370703fSCharles.Forsyth 	if(sv == 0)
786*b370703fSCharles.Forsyth 		sv = 1;
787*b370703fSCharles.Forsyth 	str->value = sv;
788*b370703fSCharles.Forsyth 	exports = ne;
789*b370703fSCharles.Forsyth 	free(esyms);
790*b370703fSCharles.Forsyth }
791