forsyth20121205-174063a80cc13 years agoHistory
1489 lines · 31.5 KB · C
RawDownload
#include	"l.h" long	OFFSET;/*long	BADOFFSET	=	-1; 		if(OFFSET <= BADOFFSET && OFFSET+4 > BADOFFSET)\			abort();\		OFFSET += 4;\ 		if(OFFSET == BADOFFSET)\			abort();\		OFFSET++;\*/ #define LPUT(l) { \		if (little) { \			LLEPUT(l); \		} else { \			LBEPUT(l); \		} \	} #define	LLEPUT(c)\	{\		cbp[0] = (c);\		cbp[1] = (c)>>8;\		cbp[2] = (c)>>16;\		cbp[3] = (c)>>24;\		cbp += 4;\		cbc -= 4;\		if(cbc <= 0)\			cflush();\	} #define	LBEPUT(c)\	{\		cbp[0] = (c)>>24;\		cbp[1] = (c)>>16;\		cbp[2] = (c)>>8;\		cbp[3] = (c);\		cbp += 4;\		cbc -= 4;\		if(cbc <= 0)\			cflush();\	} #define HPUT(h) { \		if (little) { \			HLEPUT(h); \		} else { \			HBEPUT(h); \		} \	} #define	HLEPUT(c)\	{\		cbp[0] = (c);\		cbp[1] = (c)>>8;\		cbp += 2;\		cbc -= 2;\		if(cbc <= 0)\			cflush();\	} #define	HBEPUT(c)\	{\		cbp[0] = (c)>>8;\		cbp[1] = (c);\		cbp += 2;\		cbc -= 2;\		if(cbc <= 0)\			cflush();\	}  #define	CPUT(c)\	{\		cbp[0] = (c);\		cbp++;\		cbc--;\		if(cbc <= 0)\			cflush();\	} voidobjput(long l)	/* emit long in byte order appropriate to object machine */{	LPUT(l);} voidobjhput(short s){	HPUT(s);} voidlput(long l)		/* emit long in big-endian byte order */{	LBEPUT(l);} longentryvalue(void){	char *a;	Sym *s; 	a = INITENTRY;	if(*a >= '0' && *a <= '9')		return atolwhex(a);	s = lookup(a, 0);	if(s->type == 0)		return INITTEXT;	if(s->type != STEXT && s->type != SLEAF)		diag("entry not text: %s", s->name);	return s->value;} voidasmb(void){	Prog *p;	long t, etext;	Optab *o; 	if(debug['v'])		Bprint(&bso, "%5.2f asm\n", cputime());	Bflush(&bso);	OFFSET = HEADR;	seek(cout, OFFSET, 0);	pc = INITTEXT;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			curtext = p;			autosize = p->to.offset + 4;		}		if(p->pc != pc) {			diag("phase error %lux sb %lux",				p->pc, pc);			if(!debug['a'])				prasm(curp);			pc = p->pc;		}		curp = p;		o = oplook(p);	/* could probably avoid this call */		if(asmout(p, o, 0)) {			p = p->link;			pc += 4;		}		pc += o->size;	}	if(debug['a'])		Bprint(&bso, "\n");	Bflush(&bso);	cflush(); 	etext = INITTEXT + textsize;	for(t = pc; t < etext; t += sizeof(buf)-100) {		if(etext-t > sizeof(buf)-100)			datblk(t, sizeof(buf)-100, 1);		else			datblk(t, etext-t, 1);	} 	Bflush(&bso);	cflush(); 	curtext = P;	switch(HEADTYPE) {	case 0:	case 4:		OFFSET = rnd(HEADR+textsize, 4096);		seek(cout, OFFSET, 0);		break;	case 1:	case 2:	case 3:	case 5:	case 6:		OFFSET = HEADR+textsize;		seek(cout, OFFSET, 0);		break;	}	for(t = 0; t < datsize; t += sizeof(buf)-100) {		if(datsize-t > sizeof(buf)-100)			datblk(t, sizeof(buf)-100, 0);		else			datblk(t, datsize-t, 0);	} 	symsize = 0;	lcsize = 0;	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f sym\n", cputime());		Bflush(&bso);		switch(HEADTYPE) {		case 0:		case 4:			OFFSET = rnd(HEADR+textsize, 4096)+datsize;			seek(cout, OFFSET, 0);			break;		case 3:		case 2:		case 1:		case 5:		case 6:			OFFSET = HEADR+textsize+datsize;			seek(cout, OFFSET, 0);			break;		}		if(!debug['s'])			asmsym();		if(debug['v'])			Bprint(&bso, "%5.2f pc\n", cputime());		Bflush(&bso);		if(!debug['s'])			asmlc();		cflush();	} 	if(debug['v'])		Bprint(&bso, "%5.2f header\n", cputime());	Bflush(&bso);	OFFSET = 0;	seek(cout, OFFSET, 0);	switch(HEADTYPE) {	case 0:		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:		lput(0x160L<<16);		/* magic and sections */		lput(0L);			/* time and date */		lput(HEADR+textsize+datsize);		lput(symsize);			/* nsyms */		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */ 		lput((0407<<16)|0437L);		/* magic and version */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(entryvalue());		/* va of entry */		lput(INITTEXT);			/* 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(lcsize);		lput(0L);		lput(0L);		lput(0L);		lput(~0L);			/* gp value ?? */		lput(0L);			/* complete mystery */		break;	case 2:		if (little)			t = 24;		else			t = 16;		lput(((((4*t)+0)*t)+7));	/* magic */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(symsize);			/* nsyms */		lput(entryvalue());		/* va of entry */		lput(0L);		lput(lcsize);		break;	case 3:		lput((0x160L<<16)|3L);		/* magic and sections */		lput(time(0));			/* time and date */		lput(HEADR+textsize+datsize);		lput(symsize);			/* nsyms */		lput((0x38L<<16)|7L);		/* size of optional hdr and flags */ 		lput((0407<<16)|0437L);		/* magic and version */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(entryvalue());		/* va of entry */		lput(INITTEXT);			/* 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(lcsize);		lput(0L);		lput(0L);		lput(0L);		lput(~0L);			/* gp value ?? */ 		strnput(".text", 8);		/* text segment */		lput(INITTEXT);			/* address */		lput(INITTEXT);		lput(textsize);		lput(HEADR);		lput(0L);		lput(HEADR+textsize+datsize+symsize);		lput(lcsize);			/* line number size */		lput(0x20L);			/* flags */ 		strnput(".data", 8);		/* data segment */		lput(INITDAT);			/* address */		lput(INITDAT);		lput(datsize);		lput(HEADR+textsize);		lput(0L);		lput(0L);		lput(0L);		lput(0x40L);			/* flags */ 		strnput(".bss", 8);		/* bss segment */		lput(INITDAT+datsize);		/* address */		lput(INITDAT+datsize);		lput(bsssize);		lput(0L);		lput(0L);		lput(0L);		lput(0L);		lput(0x80L);			/* flags */		break;	case 4: 		lput((0x160L<<16)|3L);		/* magic and sections */		lput(time(0));			/* 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)|01012L);	/* magic and version */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(entryvalue());		/* va of entry */		lput(INITTEXT);			/* 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(lcsize);		lput(0L);		lput(0L);		lput(0L);		lput(~0L);			/* gp value ?? */ 		strnput(".text", 8);		/* text segment */		lput(INITTEXT);			/* address */		lput(INITTEXT);		lput(textsize);		lput(HEADR);		lput(0L);		lput(HEADR+textsize+datsize+symsize);		lput(lcsize);			/* line number size */		lput(0x20L);			/* flags */ 		strnput(".data", 8);		/* data segment */		lput(INITDAT);			/* address */		lput(INITDAT);		lput(datsize);		lput(rnd(HEADR+textsize, 4096));	/* sizes */		lput(0L);		lput(0L);		lput(0L);		lput(0x40L);			/* flags */ 		strnput(".bss", 8);		/* bss segment */		lput(INITDAT+datsize);		/* address */		lput(INITDAT+datsize);		lput(bsssize);		lput(0L);		lput(0L);		lput(0L);		lput(0L);		lput(0x80L);			/* flags */		break;	case 5:		/* first part of ELF is byte-wide parts, thus no byte-order issues */		strnput("\177ELF", 4);		/* e_ident */		CPUT(1);			/* class = 32 bit */		CPUT(little? 1: 2);		/* data: 1 = LSB, 2 = MSB */		CPUT(1);			/* version = 1 */		strnput("", 9);			/* reserved for expansion */		/* entire remainder of ELF file is in target byte order */ 		/* file header part of ELF header */		objhput(2);			/* type = EXEC */		objhput(8);			/* machine = MIPS */		objput(1L);			/* version = CURRENT */		objput(entryvalue());		/* entry vaddr */		objput(52L);			/* offset to first phdr */		objput(0L);			/* offset to first shdr */		objput(0L);			/* flags (no MIPS flags defined) */		objhput(52);			/* Ehdr size */		objhput(32);			/* Phdr size */		objhput(3);			/* # of Phdrs */		objhput(0);			/* Shdr size */		objhput(0);			/* # of Shdrs */		objhput(0);			/* Shdr string size */ 		/* "Program headers" - one per chunk of file to load */ 		/*		 * include ELF headers in text -- 8l doesn't,		 * but in theory it aids demand loading.		 */		objput(1L);			/* text: type = PT_LOAD */		objput(0L);			/* file offset */		objput(INITTEXT-HEADR);		/* vaddr */		objput(INITTEXT-HEADR);		/* paddr */		objput(HEADR+textsize);		/* file size */		objput(HEADR+textsize);		/* memory size */		objput(0x05L);			/* protections = RX */		objput(0x1000L);		/* page-align text off's & vaddrs */ 		objput(1L);			/* data: type = PT_LOAD */		objput(HEADR+textsize);		/* file offset */		objput(INITDAT);		/* vaddr */		objput(INITDAT);		/* paddr */		objput(datsize);		/* file size */		objput(datsize+bsssize);	/* memory size */		objput(0x06L);			/* protections = RW */		if(INITDAT % 4096 == 0 && (HEADR + textsize) % 4096 == 0)			objput(0x1000L);	/* page-align data off's & vaddrs */		else			objput(0L);		/* do not claim alignment */ 		objput(0L);			/* P9 symbols: type = PT_NULL */		objput(HEADR+textsize+datsize);	/* file offset */		objput(0L);		objput(0L);		objput(symsize);		/* symbol table size */		objput(lcsize);			/* line number size */		objput(0x04L);			/* protections = R */		objput(0L);			/* do not claim alignment */		break;	case 6:		break;	}	cflush();} voidstrnput(char *s, int n){	for(; *s; s++){		CPUT(*s);		n--;	}	for(; n > 0; n--)		CPUT(0);} voidcflush(void){	int n; 	n = sizeof(buf.cbuf) - cbc;	if(n)		write(cout, buf.cbuf, n);	cbp = buf.cbuf;	cbc = sizeof(buf.cbuf);} voidnopstat(char *f, Count *c){	if(c->outof)	Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,		c->outof - c->count, c->outof,		(double)(c->outof - c->count)/c->outof);} voidasmsym(void){	Prog *p;	Auto *a;	Sym *s;	int h; 	s = lookup("etext", 0);	if(s->type == STEXT)

Lines 1–500 of 1489.