Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"l.h"
2
 
3
#define	Dbufslop	100
4
 
5
#define PADDR(a)	((a) & ~0xfffffffff0000000ull)
6
 
7
vlong
8
entryvalue(void)
9
{
10
	char *a;
11
	Sym *s;
12
 
13
	a = INITENTRY;
14
	if(*a >= '0' && *a <= '9')
15
		return atolwhex(a);
16
	s = lookup(a, 0);
17
	if(s->type == 0)
18
		return INITTEXT;
19
	switch(s->type) {
20
	case STEXT:
21
		break;
22
	case SDATA:
23
		if(dlm)
24
			return s->value+INITDAT;
25
	default:
26
		diag("entry not text: %s", s->name);
27
	}
28
	return s->value;
29
}
30
 
31
/* these need to take long arguments to be compatible with elf.c */void
32
wputl(long w)
33
{
34
	cput(w);
35
	cput(w>>8);
36
}
37
 
38
void
39
wput(long w)
40
{
41
	cput(w>>8);
42
	cput(w);
43
}
44
 
45
void
46
lput(long l)
47
{
48
	cput(l>>24);
49
	cput(l>>16);
50
	cput(l>>8);
51
	cput(l);
52
}
53
 
54
void
55
llput(vlong v)
56
{
57
	lput(v>>32);
58
	lput(v);
59
}
60
 
61
void
62
lputl(long l)
63
{
64
	cput(l);
65
	cput(l>>8);
66
	cput(l>>16);
67
	cput(l>>24);
68
}
69
 
70
void
71
llputl(vlong v)
72
{
73
	lputl(v);
74
	lputl(v>>32);
75
}
76
 
77
void
78
strnput(char *s, int n)
79
{
80
	for(; *s && n > 0; s++){
81
		cput(*s);
82
		n--;
83
	}
84
	while(n > 0){
85
		cput(0);
86
		n--;
87
	}
88
}
89
 
90
void
91
asmb(void)
92
{
93
	Prog *p;
94
	long v, magic;
95
	int a;
96
	uchar *op1;
97
	vlong vl;
98
 
99
	if(debug['v'])
100
		Bprint(&bso, "%5.2f asmb\n", cputime());
101
	Bflush(&bso);
102
 
103
	seek(cout, HEADR, 0);
104
	pc = INITTEXT;
105
	curp = firstp;
106
	for(p = firstp; p != P; p = p->link) {
107
		if(p->as == ATEXT)
108
			curtext = p;
109
		if(p->pc != pc) {
110
			if(!debug['a'])
111
				print("%P\n", curp);
112
			diag("phase error %llux sb %llux in %s", p->pc, pc, TNAME);
113
			pc = p->pc;
114
		}
115
		curp = p;
116
		asmins(p);
117
		a = (andptr - and);
118
		if(cbc < a)
119
			cflush();
120
		if(debug['a']) {
121
			Bprint(&bso, pcstr, pc);
122
			for(op1 = and; op1 < andptr; op1++)
123
				Bprint(&bso, "%.2ux", *op1 & 0xff);
124
			Bprint(&bso, "\t%P\n", curp);
125
		}
126
		if(dlm) {
127
			if(p->as == ATEXT)
128
				reloca = nil;
129
			else if(reloca != nil)
130
				diag("reloc failure: %P", curp);
131
		}
132
		memmove(cbp, and, a);
133
		cbp += a;
134
		pc += a;
135
		cbc -= a;
136
	}
137
	cflush();
138
	switch(HEADTYPE) {
139
	default:
140
		diag("unknown header type %ld", HEADTYPE);
141
	case 2:
142
	case 5:
143
	case 6:
144
		seek(cout, HEADR+textsize, 0);
145
		break;
146
	}
147
 
148
	if(debug['v'])
149
		Bprint(&bso, "%5.2f datblk\n", cputime());
150
	Bflush(&bso);
151
 
152
	if(dlm){
153
		char buf[8];
154
 
155
		write(cout, buf, INITDAT-textsize);
156
		textsize = INITDAT;
157
	}
158
 
159
	for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
160
		if(datsize-v > sizeof(buf)-Dbufslop)
161
			datblk(v, sizeof(buf)-Dbufslop);
162
		else
163
			datblk(v, datsize-v);
164
	}
165
 
166
	symsize = 0;
167
	spsize = 0;
168
	lcsize = 0;
169
	if(!debug['s']) {
170
		if(debug['v'])
171
			Bprint(&bso, "%5.2f sym\n", cputime());
172
		Bflush(&bso);
173
		switch(HEADTYPE) {
174
		default:
175
		case 2:
176
		case 5:
177
		case 6:
178
			seek(cout, HEADR+textsize+datsize, 0);
179
			break;
180
		}
181
		if(!debug['s'])
182
			asmsym();
183
		if(debug['v'])
184
			Bprint(&bso, "%5.2f sp\n", cputime());
185
		Bflush(&bso);
186
		if(debug['v'])
187
			Bprint(&bso, "%5.2f pc\n", cputime());
188
		Bflush(&bso);
189
		if(!debug['s'])
190
			asmlc();
191
		if(dlm)
192
			asmdyn();
193
		cflush();
194
	}
195
	else if(dlm){
196
		seek(cout, HEADR+textsize+datsize, 0);
197
		asmdyn();
198
		cflush();
199
	}
200
	if(debug['v'])
201
		Bprint(&bso, "%5.2f headr\n", cputime());
202
	Bflush(&bso);
203
	seek(cout, 0L, 0);
204
	switch(HEADTYPE) {
205
	default:
206
	case 2:	/* plan9 */
207
		magic = 4*26*26+7;
208
		magic |= 0x00008000;		/* fat header */
209
		if(dlm)
210
			magic |= 0x80000000;	/* dlm */
211
		lput(magic);			/* magic */
212
		lput(textsize);			/* sizes */
213
		lput(datsize);
214
		lput(bsssize);
215
		lput(symsize);			/* nsyms */
216
		vl = entryvalue();
217
		lput(PADDR(vl));		/* va of entry */
218
		lput(spsize);			/* sp offsets */
219
		lput(lcsize);			/* line offsets */
220
		llput(vl);			/* va of entry */
221
		break;
222
	case 5:
223
		elf32(debug['8']? I386: AMD64, ELFDATA2LSB, 0, nil);
224
		break;
225
	case 6:
226
		elf64(AMD64, ELFDATA2LSB, 0, nil);
227
		break;
228
	}
229
	cflush();
230
}
231
 
232
void
233
cflush(void)
234
{
235
	int n;
236
 
237
	n = sizeof(buf.cbuf) - cbc;
238
	if(n)
239
		write(cout, buf.cbuf, n);
240
	cbp = buf.cbuf;
241
	cbc = sizeof(buf.cbuf);
242
}
243
 
244
void
245
datblk(long s, long n)
246
{
247
	Prog *p;
248
	uchar *cast;
249
	long l, fl, j;
250
	vlong o;
251
	int i, c;
252
 
253
	memset(buf.dbuf, 0, n+Dbufslop);
254
	for(p = datap; p != P; p = p->link) {
255
		curp = p;
256
		l = p->from.sym->value + p->from.offset - s;
257
		c = p->from.scale;
258
		i = 0;
259
		if(l < 0) {
260
			if(l+c <= 0)
261
				continue;
262
			while(l < 0) {
263
				l++;
264
				i++;
265
			}
266
		}
267
		if(l >= n)
268
			continue;
269
		if(p->as != AINIT && p->as != ADYNT) {
270
			for(j=l+(c-i)-1; j>=l; j--)
271
				if(buf.dbuf[j]) {
272
					print("%P\n", p);
273
					diag("multiple initialization");
274
					break;
275
				}
276
		}
277
		switch(p->to.type) {
278
		case D_FCONST:
279
			switch(c) {
280
			default:
281
			case 4:
282
				fl = ieeedtof(&p->to.ieee);
283
				cast = (uchar*)&fl;
284
				if(debug['a'] && i == 0) {
285
					Bprint(&bso, pcstr, l+s+INITDAT);
286
					for(j=0; j<c; j++)
287
						Bprint(&bso, "%.2ux", cast[fnuxi4[j]]);
288
					Bprint(&bso, "\t%P\n", curp);
289
				}
290
				for(; i<c; i++) {
291
					buf.dbuf[l] = cast[fnuxi4[i]];
292
					l++;
293
				}
294
				break;
295
			case 8:
296
				cast = (uchar*)&p->to.ieee;
297
				if(debug['a'] && i == 0) {
298
					Bprint(&bso, pcstr, l+s+INITDAT);
299
					for(j=0; j<c; j++)
300
						Bprint(&bso, "%.2ux", cast[fnuxi8[j]]);
301
					Bprint(&bso, "\t%P\n", curp);
302
				}
303
				for(; i<c; i++) {
304
					buf.dbuf[l] = cast[fnuxi8[i]];
305
					l++;
306
				}
307
				break;
308
			}
309
			break;
310
 
311
		case D_SCONST:
312
			if(debug['a'] && i == 0) {
313
				Bprint(&bso, pcstr, l+s+INITDAT);
314
				for(j=0; j<c; j++)
315
					Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
316
				Bprint(&bso, "\t%P\n", curp);
317
			}
318
			for(; i<c; i++) {
319
				buf.dbuf[l] = p->to.scon[i];
320
				l++;
321
			}
322
			break;
323
		default:
324
			o = p->to.offset;
325
			if(p->to.type == D_ADDR) {
326
				if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
327
					diag("DADDR type%P", p);
328
				if(p->to.sym) {
329
					if(p->to.sym->type == SUNDEF)
330
						ckoff(p->to.sym, o);
331
					o += p->to.sym->value;
332
					if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF)
333
						o += INITDAT;
334
					if(dlm)
335
						dynreloc(p->to.sym, l+s+INITDAT, 1);
336
				}
337
			}
338
			fl = o;
339
			cast = (uchar*)&fl;
340
			switch(c) {
341
			default:
342
				diag("bad nuxi %d %d\n%P", c, i, curp);
343
				break;
344
			case 1:
345
				if(debug['a'] && i == 0) {
346
					Bprint(&bso, pcstr, l+s+INITDAT);
347
					for(j=0; j<c; j++)
348
						Bprint(&bso, "%.2ux", cast[inuxi1[j]]);
349
					Bprint(&bso, "\t%P\n", curp);
350
				}
351
				for(; i<c; i++) {
352
					buf.dbuf[l] = cast[inuxi1[i]];
353
					l++;
354
				}
355
				break;
356
			case 2:
357
				if(debug['a'] && i == 0) {
358
					Bprint(&bso, pcstr, l+s+INITDAT);
359
					for(j=0; j<c; j++)
360
						Bprint(&bso, "%.2ux", cast[inuxi2[j]]);
361
					Bprint(&bso, "\t%P\n", curp);
362
				}
363
				for(; i<c; i++) {
364
					buf.dbuf[l] = cast[inuxi2[i]];
365
					l++;
366
				}
367
				break;
368
			case 4:
369
				if(debug['a'] && i == 0) {
370
					Bprint(&bso, pcstr, l+s+INITDAT);
371
					for(j=0; j<c; j++)
372
						Bprint(&bso, "%.2ux", cast[inuxi4[j]]);
373
					Bprint(&bso, "\t%P\n", curp);
374
				}
375
				for(; i<c; i++) {
376
					buf.dbuf[l] = cast[inuxi4[i]];
377
					l++;
378
				}
379
				break;
380
			case 8:
381
				cast = (uchar*)&o;
382
				if(debug['a'] && i == 0) {
383
					Bprint(&bso, pcstr, l+s+INITDAT);
384
					for(j=0; j<c; j++)
385
						Bprint(&bso, "%.2ux", cast[inuxi8[j]]);
386
					Bprint(&bso, "\t%P\n", curp);
387
				}
388
				for(; i<c; i++) {
389
					buf.dbuf[l] = cast[inuxi8[i]];
390
					l++;
391
				}
392
				break;
393
			}
394
			break;
395
		}
396
	}
397
	write(cout, buf.dbuf, n);
398
}
399
 
400
vlong
401
rnd(vlong v, vlong r)
402
{
403
	vlong c;
404
 
405
	if(r <= 0)
406
		return v;
407
	v += r - 1;
408
	c = v % r;
409
	if(c < 0)
410
		c += r;
411
	v -= c;
412
	return v;
413
}