forsyth20121205-174063a80cc13 years agoHistory
845 lines · 17.6 KB · C
RawDownload
#include	"l.h" #define	KMASK	0xF0000000#define JMPSZ	sizeof(u32int)		/* size of bootstrap jump section */ #define	LPUT(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	CPUT(c)\	{\		cbp[0] = (c);\		cbp++;\		cbc--;\		if(cbc <= 0)\			cflush();\	} void	strnput(char*, int); 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(dlm && s->type == SDATA)		return s->value+INITDAT;	if(s->type != STEXT && s->type != SLEAF)		diag("entry not text: %s", s->name);	return s->value;} voidasmb(void){	Prog *p;	long t;	Optab *o;	long prevpc; 	if(debug['v'])		Bprint(&bso, "%5.2f asm\n", cputime());	Bflush(&bso); 	/* emit text segment */	seek(cout, HEADR, 0);	prevpc = pc = INITTEXT;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			curtext = p;			autosize = p->to.offset + 4;			if(p->from3.type == D_CONST) {				for(; pc < p->pc; pc++)					CPUT(0);			}		}		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 (prevpc & (1<<31) && (pc & (1<<31)) == 0) {			char *tn; 			tn = "?none?";			if(curtext != P && curtext->from.sym != S)				tn = curtext->from.sym->name;			Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);		}		prevpc = pc;	}	/* for virtex 4, inject a jmp instruction after other text */	if(HEADTYPE == 6)		/* branch to absolute entry address (0xfffe2100) */		lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); 	if(debug['a'])		Bprint(&bso, "\n");	Bflush(&bso);	cflush(); 	/* emit data segment */	curtext = P;	switch(HEADTYPE) {	case 6:		textsize += JMPSZ;		/* fall through */	case 0:	case 1:	case 2:	case 5:		seek(cout, HEADR+textsize, 0);		break;	case 3:		seek(cout, rnd(HEADR+textsize, 4), 0);		break;	case 4:		seek(cout, rnd(HEADR+textsize, 4096), 0);		break;	} 	if(dlm){		char buf[8]; 		write(cout, buf, INITDAT-textsize);		textsize = INITDAT;	} 	for(t = 0; t < datsize; t += sizeof(buf)-100) {		if(datsize-t > sizeof(buf)-100)			datblk(t, sizeof(buf)-100);		else			datblk(t, datsize-t);	} 	symsize = 0;	lcsize = 0;	if(!debug['s']) {		if(debug['v'])			Bprint(&bso, "%5.2f sym\n", cputime());		Bflush(&bso);		switch(HEADTYPE) {		case 0:		case 1:		case 2:		case 5:		case 6:			seek(cout, HEADR+textsize+datsize, 0);			break;		case 3:			seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);			break;		case 4:			seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);			break;		}		if(!debug['s'])			asmsym();		if(debug['v'])			Bprint(&bso, "%5.2f sp\n", cputime());		Bflush(&bso);		if(!debug['s'])			asmlc();		if(dlm)			asmdyn();		if(HEADTYPE == 0 || HEADTYPE == 1)	/* round up file length for boot image */			if((symsize+lcsize) & 1)				CPUT(0);		cflush();	}	else if(dlm){		asmdyn();		cflush();	} 	/* back up and write the header */	seek(cout, 0L, 0);	switch(HEADTYPE) {	case 0:		lput(0x1030107);		/* magic and sections */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(symsize);			/* nsyms */		lput(entryvalue());		/* va of entry */		lput(0L);		lput(lcsize);		break;	case 1:		lput(0x4a6f7921);		/* Joy! */		lput(0x70656666);		/* peff */		lput(0x70777063);		/* pwpc */		lput(1);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0x30002);			/*YY*/		lput(0);		lput(~0);		lput(0);		lput(textsize+datsize);		lput(textsize+datsize);		lput(textsize+datsize);		lput(0xd0);			/* header size */		lput(0x10400);		lput(~0);		lput(0);		lput(0xc);		lput(0xc);		lput(0xc);		lput(0xc0);		lput(0x01010400);		lput(~0);		lput(0);		lput(0x38);		lput(0x38);		lput(0x38);		lput(0x80);		lput(0x04040400);		lput(0);		lput(1);		lput(0);		lput(~0);		lput(0);		lput(~0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0);		lput(0x3100);			/* load address */		lput(0);		lput(0);		lput(0);			/* whew! */		break;	case 2:		if(dlm)			lput(0x80000000 | (4*21*21+7));		/* magic */		else			lput(4*21*21+7);	/* magic */		lput(textsize);			/* sizes */		lput(datsize);		lput(bsssize);		lput(symsize);			/* nsyms */		lput(entryvalue());		/* va of entry */		lput(0L);		lput(lcsize);		break;	case 3:		break;	case 4:		lput((0x1DFL<<16)|3L);		/* magic and sections */		lput(time(0));			/* time and date */		lput(rnd(HEADR+textsize, 4096)+datsize);		lput(symsize);			/* nsyms */		lput((0x48L<<16)|15L);		/* size of optional hdr and flags */ 		lput((0413<<16)|01L);		/* 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);			/* address of TOC */		lput((1L<<16)|1);		/* sn(entry) | sn(text) */		lput((2L<<16)|1);		/* sn(data) | sn(toc) */		lput((0L<<16)|3);		/* sn(loader) | sn(bss) */		lput((3L<<16)|3);		/* maxalign(text) | maxalign(data) */		lput(('1'<<24)|('L'<<16)|0);	/* type field, and reserved */		lput(0);			/* max stack allowed */		lput(0);			/* max data allowed */		lput(0); lput(0); lput(0);	/* reserved */ 		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:		/*		 * customised for blue/gene,		 * notably the alignment and KMASK masking.		 */		strnput("\177ELF", 4);		/* e_ident */		CPUT(1);			/* class = 32 bit */		CPUT(2);			/* data = MSB */		CPUT(1);			/* version = CURRENT */		strnput("", 9);		lput((2L<<16)|20L);		/* type = EXEC; machine = PowerPC */		lput(1L);			/* version = CURRENT */		lput(entryvalue() & ~KMASK);	/* entry vaddr */		lput(52L);			/* offset to first phdr */ 		if(debug['S']){			lput(HEADR+textsize+datsize+symsize);	/* offset to first shdr */			lput(0L);		/* flags = PPC */			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/			lput((3L<<16)|40L);	/* # Phdrs & Shdr size */			lput((3L<<16)|2L);	/* # Shdrs & shdr string size */		}		else{			lput(0L);			lput(0L);		/* flags = PPC */			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/			lput((3L<<16)|0L);	/* # Phdrs & Shdr size */			lput((3L<<16)|0L);	/* # Shdrs & shdr string size */		} 		lput(1L);			/* text - type = PT_LOAD */		lput(HEADR);			/* file offset */		lput(INITTEXT & ~KMASK);	/* vaddr */		lput(INITTEXT);			/* paddr */		lput(textsize);			/* file size */		lput(textsize);			/* memory size */		lput(0x05L);			/* protections = RX */		lput(0x10000L);			/* alignment */ 		lput(1L);			/* data - type = PT_LOAD */		lput(HEADR+textsize);		/* file offset */		lput(INITDAT & ~KMASK);		/* vaddr */		lput(INITDAT);			/* paddr */		lput(datsize);			/* file size */		lput(datsize);			/* memory size */		lput(0x07L);			/* protections = RWX */		lput(0x10000L);			/* alignment */ 		lput(0L);			/* data - type = PT_NULL */		lput(HEADR+textsize+datsize);	/* file offset */		lput(0L);			/* vaddr */		lput(0L);			/* paddr */		lput(symsize);			/* symbol table size */		lput(lcsize);			/* line number size */		lput(0x04L);			/* protections = R */		lput(0x04L);			/* alignment code?? */		cflush(); 		if(!debug['S'])			break; 		seek(cout, HEADR+textsize+datsize+symsize, 0);		lput(1);			/* Section name (string tbl index) */		lput(1);			/* Section type */		lput(2|4);			/* Section flags */		lput(INITTEXT & ~KMASK);	/* Section virtual addr at execution */		lput(HEADR);			/* Section file offset */		lput(textsize);			/* Section size in bytes */		lput(0);			/* Link to another section */		lput(0);			/* Additional section information */		lput(0x10000L);			/* Section alignment */		lput(0);			/* Entry size if section holds table */ 		lput(7);			/* Section name (string tbl index) */		lput(1);			/* Section type */		lput(2|1);			/* Section flags */		lput(INITDAT & ~KMASK);		/* Section virtual addr at execution */		lput(HEADR+textsize);		/* Section file offset */		lput(datsize);			/* Section size in bytes */		lput(0);			/* Link to another section */		lput(0);			/* Additional section information */		lput(0x10000L);			/* Section alignment */		lput(0);			/* Entry size if section holds table */ 		/* string section header */		lput(12);			/* Section name (string tbl index) */		lput(3);			/* Section type */		lput(1 << 5);			/* Section flags */		lput(0);			/* Section virtual addr at execution */		lput(HEADR+textsize+datsize+symsize+3*40);	/* Section file offset */		lput(14);			/* Section size in bytes */		lput(0);			/* Link to another section */		lput(0);			/* Additional section information */		lput(1);			/* Section alignment */		lput(0);			/* Entry size if section holds table */ 		/* string table */		cput(0);		strnput(".text", 5);		cput(0);		strnput(".data", 5);		cput(0);		strnput(".strtab", 7);		cput(0);		cput(0); 		break;	case 6:		/*		 * customised for virtex 4 boot,		 * notably the alignment and KMASK masking.		 */		strnput("\177ELF", 4);		/* e_ident */		CPUT(1);			/* class = 32 bit */		CPUT(2);			/* data = MSB */		CPUT(1);			/* version = CURRENT */		strnput("", 9);		lput((2L<<16)|20L);		/* type = EXEC; machine = PowerPC */		lput(1L);			/* version = CURRENT */		lput(entryvalue());		/* entry vaddr */		lput(52L);			/* offset to first phdr */ 		debug['S'] = 1;			/* no symbol table */		if(debug['S']){			lput(HEADR+textsize+datsize+symsize);	/* offset to first shdr */			lput(0L);		/* flags = PPC */			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/			lput((4L<<16)|40L);	/* # Phdrs & Shdr size */			lput((4L<<16)|2L);	/* # Shdrs & shdr string size */		}		else{			lput(0L);			lput(0L);		/* flags = PPC */			lput((52L<<16)|32L);	/* Ehdr & Phdr sizes*/			lput((4L<<16)|0L);	/* # Phdrs & Shdr size */			lput((4L<<16)|0L);	/* # Shdrs & shdr string size */		} 		lput(1L);			/* text - type = PT_LOAD */		lput(HEADR);			/* file offset */		lput(INITTEXT);			/* vaddr */		lput(INITTEXT);			/* paddr */		lput(textsize-JMPSZ);		/* file size */		lput(textsize-JMPSZ);		/* memory size */		lput(0x05L);			/* protections = RX */		lput(0);			/* alignment */ 		lput(1L);			/* data - type = PT_LOAD */		lput(HEADR+textsize);		/* file offset */		lput(INITDAT);			/* vaddr */		lput(INITDAT);			/* paddr */		lput(datsize);			/* file size */		lput(datsize+bsssize);		/* memory size */		lput(0x07L);			/* protections = RWX */		lput(0);			/* alignment */ 		lput(0L);			/* data - type = PT_NULL */		lput(HEADR+textsize+datsize);	/* file offset */		lput(0L);			/* vaddr */		lput(0L);			/* paddr */		lput(symsize);			/* symbol table size */		lput(lcsize);			/* line number size */		lput(0x04L);			/* protections = R */		lput(0x04L);			/* alignment code?? */ 		/* add tiny text section at end with jmp to start */		lput(1L);			/* text - type = PT_LOAD */		lput(HEADR+textsize-JMPSZ);	/* file offset */		lput(0xFFFFFFFC);		/* vaddr */		lput(0xFFFFFFFC);		/* paddr */		lput(JMPSZ);			/* file size */		lput(JMPSZ);			/* memory size */		lput(0x05L);			/* protections = RX */		lput(0);			/* disable alignment */ 		cflush();		break;	}	cflush();} voidstrnput(char *s, int n){	for(; *s; s++){

Lines 1–500 of 845.