Example #1
0
File: span.c Project: 8l/go-learn
void
span(void)
{
	Prog *p, *q;
	int32 v, c, idat;
	int m, n, again;

	xdefine("etext", STEXT, 0L);
	idat = INITDAT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		n = 0;
		if(p->to.type == D_BRANCH)
			if(p->pcond == P)
				p->pcond = p;
		if((q = p->pcond) != P)
			if(q->back != 2)
				n = 1;
		p->back = n;
		if(p->as == AADJSP) {
			p->to.type = D_SP;
			v = -p->from.offset;
			p->from.offset = v;
			p->as = AADDL;
			if(v < 0) {
				p->as = ASUBL;
				v = -v;
				p->from.offset = v;
			}
			if(v == 0)
				p->as = ANOP;
		}
	}

	n = 0;
start:
	do{
		again = 0;
		if(debug['v'])
			Bprint(&bso, "%5.2f span %d\n", cputime(), n);
		Bflush(&bso);
		if(n > 500) {
			// TODO(rsc): figure out why nacl takes so long to converge.
			print("span must be looping - %d\n", textsize);
			errorexit();
		}
		c = INITTEXT;
		for(p = firstp; p != P; p = p->link) {
			if(p->as == ATEXT) {
				curtext = p;
				if(HEADTYPE == 8)
					c = (c+31)&~31;
			}
			if(p->to.type == D_BRANCH)
				if(p->back)
					p->pc = c;
			if(n == 0 || HEADTYPE == 8 || p->to.type == D_BRANCH) {
				if(HEADTYPE == 8)
					p->pc = c;
				asmins(p);
				m = andptr-and;
				if(p->mark != m)
					again = 1;
				p->mark = m;
			}
			if(HEADTYPE == 8) {
				c = p->pc + p->mark;
			} else {
				p->pc = c;
				c += p->mark;
			}
		}
		textsize = c;
		n++;
	}while(again);

	if(INITRND) {
		INITDAT = rnd(c, INITRND);
		if(INITDAT != idat) {
			idat = INITDAT;
			goto start;
		}
	}
	xdefine("etext", STEXT, c);
	if(debug['v'])
		Bprint(&bso, "etext = %lux\n", c);
	Bflush(&bso);
	for(p = textp; p != P; p = p->pcond)
		p->from.sym->value = p->pc;
	textsize = c - INITTEXT;
}
Example #2
0
void
asmb(void)
{
	Prog *p;
	long v;
	int a;
	short *op1;

	if(debug['v'])
		Bprint(&bso, "%5.2f asmb\n", cputime());
	Bflush(&bso);

	seek(cout, HEADR, 0);
	pc = INITTEXT;
	curp = firstp;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		if(p->pc != pc) {
			if(!debug['a'])
				print("%P\n", curp);
			diag("phase error %.4lux sb %.4lux in %s", p->pc, pc, TNAME);
			pc = p->pc;
		}
		curp = p;
		if(debug['a'])
			Bprint(&bso, "%lux:%P\n", pc, curp);
		asmins(p);
		if(cbc < sizeof(opa))
			cflush();
		for(op1 = opa; op1 < op; op1++) {
			a = *op1;
			*cbp++ = a >> 8;
			*cbp++ = a;
		}
		a = 2*(op - opa);
		pc += a;
		cbc -= a;
		if(debug['a']) {
			for(op1 = opa; op1 < op; op1++)
				if(op1 == opa)
					Bprint(&bso, "\t\t%4ux", *op1 & 0xffff);
				else
					Bprint(&bso, " %4ux", *op1 & 0xffff);
			if(op != opa)
				Bprint(&bso, "\n");
		}
	}
	cflush();
	switch(HEADTYPE) {
	case 0:	/* this is garbage */
		seek(cout, rnd(HEADR+textsize, 8192), 0);
		break;
	case 1:	/* plan9 boot data goes into text */
		seek(cout, rnd(HEADR+textsize, INITRND), 0);
		break;
	case 2:	/* plan 9 */
		seek(cout, HEADR+textsize, 0);
		break;
	case 3:	/* next boot */
		seek(cout, HEADR+rnd(textsize, INITRND), 0);
		break;
	case 4:	/* preprocess pilot */
		seek(cout, HEADR+textsize, 0);
		break;
	}

	if(debug['v'])
		Bprint(&bso, "%5.2f datblk\n", cputime());
	Bflush(&bso);

	for(v = 0; v < datsize; v += sizeof(buf)-100) {
		if(datsize-v > sizeof(buf)-100)
			datblk(v, sizeof(buf)-100);
		else
			datblk(v, datsize-v);
	}

	symsize = 0;
	spsize = 0;
	lcsize = 0;
	relocsize = 0;

	Bflush(&bso);

	switch(HEADTYPE) {
	default:
		seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
		break;
	case 1:	/* plan9 boot data goes into text */
		seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
		break;
	case 2:	/* plan 9 */
		seek(cout, HEADR+textsize+datsize, 0);
		break;
	case 3:	/* next boot */
		seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0);
		break;
	case 4:	/* preprocess pilot */
		seek(cout, HEADR+textsize+datsize, 0);
		break;
	}
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sym\n", cputime());
		asmsym();
	}
	Bflush(&bso);
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f sp\n", cputime());
		asmsp();
	}
	Bflush(&bso);
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f pc\n", cputime());
		asmlc();
	}
	Bflush(&bso);
	if(!debug['s']) {
		if(debug['v'])
			Bprint(&bso, "%5.2f reloc\n", cputime());
		asmreloc();
	}
	cflush();

	if(debug['v'])
		Bprint(&bso, "%5.2f headr\n", cputime());
	Bflush(&bso);
	seek(cout, 0L, 0);
	switch(HEADTYPE) {
	default:
		lput(0x160L<<16);		/* magic and sections */
		lput(0L);			/* time and date */
		lput(rnd(HEADR+textsize, 4096)+datsize);
		lput(symsize);			/* nsyms */
		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */
		lput((0413<<16)|0437L);		/* magic and version */
		lput(rnd(HEADR+textsize, 4096));	/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(entryvalue());		/* va of entry */
		lput(INITTEXT-HEADR);		/* va of base of text */
		lput(INITDAT);			/* va of base of data */
		lput(INITDAT+datsize);		/* va of base of bss */
		lput(~0L);			/* gp reg mask */
		lput(0L);
		lput(0L);
		lput(0L);
		lput(0L);
		lput(~0L);			/* gp value ?? */
		break;
	case 1:	/* plan9 boot data goes into text */
		lput(0407);			/* magic */
		lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize);		/* sizes */
		lput(0);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(spsize);			/* sp offsets */
		lput(lcsize);			/* line offsets */
		break;
	case 2:	/* plan 9 */
		lput(0407);			/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(spsize);			/* sp offsets */
		lput(lcsize);			/* line offsets */
		break;
	case 3:	/* next boot */
		/* header */
		lput(0xfeedfaceL);			/* magic */
		lput(6);				/* 68040 */
		lput(1);				/* more 68040 */
		lput(5);				/* file type 'boot' */
		lput(HEADTYPE);				/* number commands */
		lput(HEADR-7*4);			/* sizeof commands */
		lput(1);				/* no undefineds */
		/* command 1 text */
		lput(1);				/* command = 'segment' */
		lput(124);				/* command size */
		s16put("__TEXT");
			/* botch?? entryvalue() */
		lput(INITTEXT);				/* va of start */
		lput(rnd(textsize, 8192));		/* va size */
		lput(HEADR);				/* file offset */
		lput(rnd(textsize, 8192));		/* file size */
		lput(7);				/* max prot */
		lput(7);				/* init prot */
		lput(1);				/* number of sections */
		lput(0);				/* flags */
		/* text section */
		s16put("__text");
		s16put("__TEXT");
			/* botch?? entryvalue() */
		lput(INITTEXT);				/* va of start */
		lput(textsize);				/* va size */
		lput(HEADR);				/* file offset */
		lput(2);				/* align */
		lput(0);				/* reloff */
		lput(0);				/* nreloc */
		lput(0);				/* flags */
		lput(0);				/* reserved1 */
		lput(0);				/* reserved2 */
		/* command 1 data */
		lput(1);				/* command = 'segment' */
		lput(192);				/* command size */
		s16put("__DATA");
		lput(INITDAT);				/* va of start */
		lput(rnd(datsize, 8192));		/* va size */
		lput(HEADR+rnd(textsize, 8192));	/* file offset */
		lput(rnd(datsize, 8192));		/* file size */
		lput(7);				/* max prot */
		lput(7);				/* init prot */
		lput(2);				/* number of sections */
		lput(0);				/* flags */
		/* data section */
		s16put("__data");
		s16put("__DATA");
		lput(INITDAT);				/* va of start */
		lput(datsize);				/* va size */
		lput(HEADR+rnd(textsize, 8192));	/* file offset */
		lput(2);				/* align */
		lput(0);				/* reloff */
		lput(0);				/* nreloc */
		lput(0);				/* flags */
		lput(0);				/* reserved1 */
		lput(0);				/* reserved2 */
		/* bss section */
		s16put("__bss");
		s16put("__DATA");
		lput(INITDAT+datsize);			/* va of start */
		lput(bsssize);				/* va size */
		lput(0);				/* file offset */
		lput(2);				/* align */
		lput(0);				/* reloff */
		lput(0);				/* nreloc */
		lput(1);				/* flags = zero fill */
		lput(0);				/* reserved1 */
		lput(0);				/* reserved2 */
		/* command 2 symbol */
		lput(2);				/* command = 'symbol' */
		lput(24);				/* command size */
		lput(HEADR+rnd(textsize, INITRND)
			+datsize);			/* symoff */
		lput(symsize);				/* nsyms */
		lput(spsize);				/* sp offsets */
		lput(lcsize);				/* line offsets */
		break;
	case 4:	/* preprocess pilot */
		lput(0407);			/* magic */
		lput(textsize);			/* sizes */
		lput(datsize);
		lput(bsssize);
		lput(symsize);			/* nsyms */
		lput(entryvalue());		/* va of entry */
		lput(spsize);			/* sp offsets */
		lput(lcsize);			/* line offsets */
		lput(relocsize);		/* relocation */
		break;
	}
	cflush();
}
Example #3
0
void
span1(Sym *s)
{
	Prog *p, *q;
	int32 c, v, loop;
	uchar *bp;
	int n, m, i;

	cursym = s;
	
	if(s->p != nil)
		return;

	for(p = s->text; p != P; p = p->link) {
		p->back = 2;	// use short branches first time through
		if((q = p->pcond) != P && (q->back & 2))
			p->back |= 1;	// backward jump

		if(p->as == AADJSP) {
			p->to.type = D_SP;
			v = -p->from.offset;
			p->from.offset = v;
			p->as = p->mode != 64? AADDL: AADDQ;
			if(v < 0) {
				p->as = p->mode != 64? ASUBL: ASUBQ;
				v = -v;
				p->from.offset = v;
			}
			if(v == 0)
				p->as = ANOP;
		}
	}
	
	n = 0;
	do {
		loop = 0;
		memset(s->r, 0, s->nr*sizeof s->r[0]);
		s->nr = 0;
		s->np = 0;
		c = 0;
		for(p = s->text; p != P; p = p->link) {
			p->pc = c;

			// process forward jumps to p
			for(q = p->comefrom; q != P; q = q->forwd) {
				v = p->pc - (q->pc + q->mark);
				if(q->back & 2)	{	// short
					if(v > 127) {
						loop++;
						q->back ^= 2;
					}
					if(q->as == AJCXZL)
						s->p[q->pc+2] = v;
					else
						s->p[q->pc+1] = v;
				} else {
					bp = s->p + q->pc + q->mark - 4;
					*bp++ = v;
					*bp++ = v>>8;
					*bp++ = v>>16;
					*bp = v>>24;
				}	
			}
			p->comefrom = P;

			asmins(p);
			p->pc = c;
			m = andptr-and;
			symgrow(s, p->pc+m);
			memmove(s->p+p->pc, and, m);
			p->mark = m;
			c += m;
		}
		if(++n > 20) {
			diag("span must be looping");
			errorexit();
		}
	} while(loop);
	s->size = c;

	if(debug['a'] > 1) {
		print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0);
		for(i=0; i<s->np; i++) {
			print(" %.2ux", s->p[i]);
			if(i%16 == 15)
				print("\n  %.6ux", i+1);
		}
		if(i%16)
			print("\n");
	
		for(i=0; i<s->nr; i++) {
			Reloc *r;
			
			r = &s->r[i];
			print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add);
		}
	}
}
Example #4
0
void
span(void)
{
	Prog *p, *q;
	long v;
	vlong c, idat;
	int m, n, again;

	xdefine("etext", STEXT, 0L);
	idat = INITDAT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		n = 0;
		if(p->to.type == D_BRANCH)
			if(p->pcond == P)
				p->pcond = p;
		if((q = p->pcond) != P)
			if(q->back != 2)
				n = 1;
		p->back = n;
		if(p->as == AADJSP) {
			p->to.type = D_SP;
			v = -p->from.offset;
			p->from.offset = v;
			p->as = p->mode != 64? AADDL: AADDQ;
			if(v < 0) {
				p->as = p->mode != 64? ASUBL: ASUBQ;
				v = -v;
				p->from.offset = v;
			}
			if(v == 0)
				p->as = ANOP;
		}
	}
	n = 0;

start:
	if(debug['v'])
		Bprint(&bso, "%5.2f span\n", cputime());
	Bflush(&bso);
	c = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		if(p->to.type == D_BRANCH)
			if(p->back)
				p->pc = c;
		asmins(p);
		p->pc = c;
		m = andptr-and;
		p->mark = m;
		c += m;
	}

loop:
	n++;
	if(debug['v'])
		Bprint(&bso, "%5.2f span %d\n", cputime(), n);
	Bflush(&bso);
	if(n > 50) {
		print("span must be looping\n");
		errorexit();
	}
	again = 0;
	c = INITTEXT;
	for(p = firstp; p != P; p = p->link) {
		if(p->as == ATEXT)
			curtext = p;
		if(p->to.type == D_BRANCH || p->back & 0100) {
			if(p->back)
				p->pc = c;
			asmins(p);
			m = andptr-and;
			if(m != p->mark) {
				p->mark = m;
				again++;
			}
		}
		p->pc = c;
		c += p->mark;
	}
	if(again) {
		textsize = c;
		goto loop;
	}
	if(INITRND) {
		INITDAT = rnd(c, INITRND);
		if(INITDAT != idat) {
			idat = INITDAT;
			goto start;
		}
	}
	xdefine("etext", STEXT, c);
	if(debug['v'])
		Bprint(&bso, "etext = %llux\n", c);
	Bflush(&bso);
	for(p = textp; p != P; p = p->pcond)
		p->from.sym->value = p->pc;
	textsize = c - INITTEXT;
}