Charles.Forsyth20060303644188019 years agoHistory
1433 lines · 30.7 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++;\*/ voidcput(int c){	cbp[0] = c;	cbp++;	cbc--;	if(cbc <= 0)		cflush();} voidbput(long l){	cbp[0] = l>>24;	cbp[1] = l>>16;	cbp[2] = l>>8;	cbp[3] = l;	cbp += 4;	cbc -= 4;	if(cbc <= 0)		cflush();} voidlput(long l){ 	cbp[0] = l;	cbp[1] = l>>8;	cbp[2] = l>>16;	cbp[3] = l>>24;	cbp += 4;	cbc -= 4;	if(cbc <= 0)		cflush();} 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;	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 + 8;		}		if(p->pc != pc) {			diag("phase error %lux sb %lux\n",				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(); 	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);		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 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:		bput(0x160L<<16);		/* magic and sections */		bput(0L);			/* time and date */		bput(rnd(HEADR+textsize, 4096)+datsize);		bput(symsize);			/* nsyms */		bput((0x38L<<16)|7L);		/* size of optional hdr and flags */		bput((0413<<16)|0437L);		/* magic and version */		bput(rnd(HEADR+textsize, 4096));	/* sizes */		bput(datsize);		bput(bsssize);		bput(entryvalue());		/* va of entry */		bput(INITTEXT-HEADR);		/* va of base of text */		bput(INITDAT);			/* va of base of data */		bput(INITDAT+datsize);		/* va of base of bss */		bput(~0L);			/* gp reg mask */		bput(0L);		bput(0L);		bput(0L);		bput(0L);		bput(~0L);			/* gp value ?? */		break;	case 1:		bput(0x160L<<16);		/* magic and sections */		bput(0L);			/* time and date */		bput(HEADR+textsize+datsize);		bput(symsize);			/* nsyms */		bput((0x38L<<16)|7L);		/* size of optional hdr and flags */ 		bput((0407<<16)|0437L);		/* magic and version */		bput(textsize);			/* sizes */		bput(datsize);		bput(bsssize);		bput(entryvalue());		/* va of entry */		bput(INITTEXT);			/* va of base of text */		bput(INITDAT);			/* va of base of data */		bput(INITDAT+datsize);		/* va of base of bss */		bput(~0L);			/* gp reg mask */		bput(lcsize);		bput(0L);		bput(0L);		bput(0L);		bput(~0L);			/* gp value ?? */		bput(0L);			/* complete mystery */		break;	case 2:		t = 22;		bput(((((4*t)+0)*t)+7));	/* magic */		bput(textsize);			/* sizes */		bput(datsize);		bput(bsssize);		bput(symsize);			/* nsyms */		bput(entryvalue());		/* va of entry */		bput(0L);		bput(lcsize);		break;	case 3:		bput((0x160L<<16)|3L);		/* magic and sections */		bput(time(0));			/* time and date */		bput(HEADR+textsize+datsize);		bput(symsize);			/* nsyms */		bput((0x38L<<16)|7L);		/* size of optional hdr and flags */ 		bput((0407<<16)|0437L);		/* magic and version */		bput(textsize);			/* sizes */		bput(datsize);		bput(bsssize);		bput(entryvalue());		/* va of entry */		bput(INITTEXT);			/* va of base of text */		bput(INITDAT);			/* va of base of data */		bput(INITDAT+datsize);		/* va of base of bss */		bput(~0L);			/* gp reg mask */		bput(lcsize);		bput(0L);		bput(0L);		bput(0L);		bput(~0L);			/* gp value ?? */ 		strnput(".text", 8);		/* text segment */		bput(INITTEXT);			/* address */		bput(INITTEXT);		bput(textsize);		bput(HEADR);		bput(0L);		bput(HEADR+textsize+datsize+symsize);		bput(lcsize);			/* line number size */		bput(0x20L);			/* flags */ 		strnput(".data", 8);		/* data segment */		bput(INITDAT);			/* address */		bput(INITDAT);		bput(datsize);		bput(HEADR+textsize);		bput(0L);		bput(0L);		bput(0L);		bput(0x40L);			/* flags */ 		strnput(".bss", 8);		/* bss segment */		bput(INITDAT+datsize);		/* address */		bput(INITDAT+datsize);		bput(bsssize);		bput(0L);		bput(0L);		bput(0L);		bput(0L);		bput(0x80L);			/* flags */		break;	case 4: 		bput((0x160L<<16)|3L);		/* magic and sections */		bput(time(0));			/* time and date */		bput(rnd(HEADR+textsize, 4096)+datsize);		bput(symsize);			/* nsyms */		bput((0x38L<<16)|7L);		/* size of optional hdr and flags */ 		bput((0413<<16)|01012L);	/* magic and version */		bput(textsize);			/* sizes */		bput(datsize);		bput(bsssize);		bput(entryvalue());		/* va of entry */		bput(INITTEXT);			/* va of base of text */		bput(INITDAT);			/* va of base of data */		bput(INITDAT+datsize);		/* va of base of bss */		bput(~0L);			/* gp reg mask */		bput(lcsize);		bput(0L);		bput(0L);		bput(0L);		bput(~0L);			/* gp value ?? */ 		strnput(".text", 8);		/* text segment */		bput(INITTEXT);			/* address */		bput(INITTEXT);		bput(textsize);		bput(HEADR);		bput(0L);		bput(HEADR+textsize+datsize+symsize);		bput(lcsize);			/* line number size */		bput(0x20L);			/* flags */ 		strnput(".data", 8);		/* data segment */		bput(INITDAT);			/* address */		bput(INITDAT);		bput(datsize);		bput(rnd(HEADR+textsize, 4096));	/* sizes */		bput(0L);		bput(0L);		bput(0L);		bput(0x40L);			/* flags */ 		strnput(".bss", 8);		/* bss segment */		bput(INITDAT+datsize);		/* address */		bput(INITDAT+datsize);		bput(bsssize);		bput(0L);		bput(0L);		bput(0L);		bput(0L);		bput(0x80L);			/* flags */		break;	case 5:		strnput("\177ELF", 4);		/* e_ident */		cput(1);			/* class = 32 bit */		cput(2);			/* data = MSB */		cput(1);			/* version = CURRENT */		strnput("", 9);		bput((2L<<16)|8L);		/* type = EXEC; machine = MIPS */		bput(1L);			/* version = CURRENT */		bput(entryvalue());		/* entry vaddr */		bput(52L);			/* offset to first phdr */		bput(0L);			/* offset to first shdr */		bput(0L);			/* flags = MIPS */		bput((52L<<16)|32L);		/* Ehdr & Phdr sizes*/		bput((3L<<16)|0L);		/* # Phdrs & Shdr size */		bput((0L<<16)|0L);		/* # Shdrs & shdr string size */ 		bput(1L);			/* text - type = PT_LOAD */		bput(0L);			/* file offset */		bput(INITTEXT-HEADR);		/* vaddr */		bput(INITTEXT-HEADR);		/* paddr */		bput(HEADR+textsize);		/* file size */		bput(HEADR+textsize);		/* memory size */		bput(0x05L);			/* protections = RX */		bput(0x10000L);			/* alignment code?? */ 		bput(1L);			/* data - type = PT_LOAD */		bput(HEADR+textsize);		/* file offset */		bput(INITDAT);			/* vaddr */		bput(INITDAT);			/* paddr */		bput(datsize);			/* file size */		bput(datsize+bsssize);		/* memory size */		bput(0x06L);			/* protections = RW */		bput(0x10000L);			/* alignment code?? */ 		bput(0L);			/* data - type = PT_NULL */		bput(HEADR+textsize+datsize);	/* file offset */		bput(0L);		bput(0L);		bput(symsize);			/* symbol table size */		bput(lcsize);			/* line number size */		bput(0x04L);			/* protections = R */		bput(0x04L);			/* alignment code?? */		break;	case 6:		t = 22;		bput(((((4*t)+0)*t)+7));	/* magic */		bput(textsize);			/* sizes */		bput(datsize);		bput(bsssize);		bput(symsize);			/* nsyms */		bput(entryvalue());		/* va of entry */		bput(0L);		bput(lcsize);		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 = (uchar*)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)		putsymb(s->name, 'T', s->value, s->version); 	for(h=0; h<NHASH; h++)		for(s=hash[h]; s!=S; s=s->link)			switch(s->type) {			case SCONST:				putsymb(s->name, 'D', s->value, s->version);				continue; 			case SDATA:				putsymb(s->name, 'D', s->value+INITDAT, s->version);				continue; 			case SBSS:				putsymb(s->name, 'B', s->value+INITDAT, s->version);				continue; 			case SFILE:				putsymb(s->name, 'f', s->value, s->version);				continue;			} 	for(p=textp; p!=P; p=p->cond) {		s = p->from.sym;		if(s->type != STEXT && s->type != SLEAF)			continue; 		/* filenames first */		for(a=p->to.autom; a; a=a->link)			if(a->type == D_FILE)				putsymb(a->asym->name, 'z', a->aoffset, 0);			else			if(a->type == D_FILE1)				putsymb(a->asym->name, 'Z', a->aoffset, 0); 		if(s->type == STEXT)			putsymb(s->name, 'T', s->value, s->version);		else			putsymb(s->name, 'L', s->value, s->version); 		/* frame, auto and param after */		putsymb(".frame", 'm', p->to.offset+8, 0);		for(a=p->to.autom; a; a=a->link)			if(a->type == D_AUTO)				putsymb(a->asym->name, 'a', -a->aoffset, 0);			else			if(a->type == D_PARAM)				putsymb(a->asym->name, 'p', a->aoffset, 0);	}	if(debug['v'] || debug['n'])		Bprint(&bso, "symsize = %lud\n", symsize);	Bflush(&bso);} voidputsymb(char *s, int t, long v, int ver){	int i, f; 	if(t == 'f')		s++;	bput(v);	if(ver)		t += 'a' - 'A';	cput(t+0x80);			/* 0x80 is variable length */ 	if(t == 'Z' || t == 'z') {		cput(s[0]);		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {			cput(s[i]);			cput(s[i+1]);		}		cput(0);

Lines 1–500 of 1433.