forsyth20121205-174063a80cc13 years agoHistory
1380 lines · 23.3 KB · C
RawDownload
#define	EXTERN#include	"l.h"#include	<ar.h> #ifndef	DEFAULT#define	DEFAULT	'9'#endif char	symname[]	= SYMDEF;char	thechar		= '1';char	*thestring 	= "68000"; /* *	-H0 -T0x40004C -D0x10000000	is garbage unix *	-H1 -T0x80020000 -R4		is garbage format *	-H2 -T8224 -R8192		is plan9 format *	-H3 -Tx -Rx			is next boot *	-H4 -T0 -D0			is pilot relocatable */ voidmain(int argc, char *argv[]){	int i, c;	char *a; 	Binit(&bso, 1, OWRITE);	cout = -1;	listinit();	memset(debug, 0, sizeof(debug));	nerrors = 0;	outfile = "1.out";	HEADTYPE = -1;	INITTEXT = -1;	INITDAT = -1;	INITRND = -1;	INITENTRY = 0; 	ARGBEGIN {	default:		c = ARGC();		if(c >= 0 && c < sizeof(debug))			debug[c]++;		break;	case 'o': /* output to (next arg) */		outfile = ARGF();		break;	case 'E':		a = ARGF();		if(a)			INITENTRY = a;		break;	case 'H':		a = ARGF();		if(a)			HEADTYPE = atolwhex(a);		break;	case 'T':		a = ARGF();		if(a)			INITTEXT = atolwhex(a);		break;	case 'D':		a = ARGF();		if(a)			INITDAT = atolwhex(a);		break;	case 'R':		a = ARGF();		if(a)			INITRND = atolwhex(a);		break;	} ARGEND 	USED(argc); 	if(*argv == 0) {		diag("usage: 1l [-options] objects");		errorexit();	}	if(!debug['9'] && !debug['U'] && !debug['B'])		debug[DEFAULT] = 1;	if(HEADTYPE == -1) {		if(debug['U'])			HEADTYPE = 2;		if(debug['B'])			HEADTYPE = 2;		if(debug['9'])			HEADTYPE = 2;	}	if(INITDAT != -1 && INITRND == -1)		INITRND = 0;	switch(HEADTYPE) {	default:		diag("unknown -H option %d", HEADTYPE);		errorexit(); 	case 0:	/* this is garbage */		HEADR = 20L+56L;		if(INITTEXT == -1)			INITTEXT = 0x40004CL;		if(INITDAT == -1)			INITDAT = 0x10000000L;		if(INITDAT != 0 && INITRND == -1)			INITRND = 0;		if(INITRND == -1)			INITRND = 0;		break;	case 1:	/* plan9 boot data goes into text */		HEADR = 32L;		if(INITTEXT == -1)			INITTEXT = 8224;		if(INITDAT == -1)			INITDAT = 0;		if(INITDAT != 0 && INITRND == -1)			INITRND = 0;		if(INITRND == -1)			INITRND = 8192;		break;	case 2:	/* plan 9 */		HEADR = 32L;		if(INITTEXT == -1)			INITTEXT = 8224;		if(INITDAT == -1)			INITDAT = 0;		if(INITDAT != 0 && INITRND == -1)			INITRND = 0;		if(INITRND == -1)			INITRND = 8192;		break;	case 3:	/* next boot */		HEADR = 28+124+192+24;		if(INITTEXT == -1)			INITTEXT = 0x04002000;		if(INITDAT == -1)			INITDAT = 0;		if(INITDAT != 0 && INITRND == -1)			INITRND = 0;		if(INITRND == -1)			INITRND = 8192L;		break;	case 4:	/* preprocess pilot */		HEADR = 36L;		if(INITTEXT == -1)			INITTEXT = 0;		if(INITDAT == -1)			INITDAT = 0;		if(INITRND == -1)			INITRND = 0;		break;	}	if(INITDAT != 0 && INITRND != 0)		print("warning: -D0x%lux is ignored because of -R0x%lux\n",			INITDAT, INITRND);	if(debug['v'])		Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n",			HEADTYPE, INITTEXT, INITDAT, INITRND);	Bflush(&bso);	for(i=1; optab[i].as; i++)		if(i != optab[i].as) {			diag("phase error in optab: %d", i);			errorexit();		} 	zprg.link = P;	zprg.pcond = P;	zprg.back = 2;	zprg.as = AGOK;	zprg.from.type = D_NONE;	zprg.to = zprg.from; 	memset(special, 0, sizeof(special));	special[D_CCR] = 1;	special[D_SR] = 1;	special[D_SFC] = 1;	special[D_CACR] = 1;	special[D_USP] = 1;	special[D_VBR] = 1;	special[D_CAAR] = 1;	special[D_MSP] = 1;	special[D_ISP] = 1;	special[D_DFC] = 1;	special[D_FPCR] = 1;	special[D_FPSR] = 1;	special[D_FPIAR] = 1; 	special[D_TC] = 1;	special[D_ITT0] = 1;	special[D_ITT1] = 1;	special[D_DTT0] = 1;	special[D_DTT1] = 1;	special[D_MMUSR] = 1;	special[D_URP] = 1;	special[D_SRP] = 1;	memset(simple, 0177, sizeof(simple));	for(i=0; i<8; i++) {		simple[D_R0+i] = i;		simple[D_F0+i] = i+0100;		simple[D_A0+i] = i+010;		simple[D_A0+I_INDIR+i] = i+020;		simple[D_A0+I_INDINC+i] = i+030;		simple[D_A0+I_INDDEC+i] = i+040;	}	nuxiinit();	histgen = 0;	textp = P;	datap = P;	pc = 0;	cout = create(outfile, 1, 0775);	if(cout < 0) {		diag("cannot create %s", outfile);		errorexit();	}	version = 0;	cbp = buf.cbuf;	cbc = sizeof(buf.cbuf);	firstp = prg();	lastp = firstp; 	if(INITENTRY == 0) {		INITENTRY = "_main";		if(debug['p'])			INITENTRY = "_mainp";		if(!debug['l'])			lookup(INITENTRY, 0)->type = SXREF;	} else		lookup(INITENTRY, 0)->type = SXREF; 	initmuldiv1();	while(*argv)		objfile(*argv++);	if(!debug['l'])		loadlib();	firstp = firstp->link;	if(firstp == P)		errorexit();	patch();	if(debug['p'])		if(debug['1'])			doprof1();		else			doprof2();	initmuldiv2();	follow();	dodata();	dostkoff();	span();	asmb();	undef();	if(debug['v']) {		Bprint(&bso, "%5.2f cpu time\n", cputime());		Bprint(&bso, "%ld data statements\n", ndata);		Bprint(&bso, "%ld symbols\n", nsymbol);		Bprint(&bso, "%ld memory used\n", thunk);		Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));		Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));	}	Bflush(&bso); 	errorexit();} voidloadlib(void){	int i;	long h;	Sym *s; loop:	xrefresolv = 0;	for(i=0; i<libraryp; i++) {		if(debug['v'])			Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);		objfile(library[i]);	}	if(xrefresolv)	for(h=0; h<nelem(hash); h++)	for(s = hash[h]; s != S; s = s->link)		if(s->type == SXREF)			goto loop;} voiderrorexit(void){ 	if(nerrors) {		if(cout >= 0)			remove(outfile);		exits("error");	}	exits(0);} voidobjfile(char *file){	long off, esym, cnt, l;	int f, work;	Sym *s;	char magbuf[SARMAG];	char name[100], pname[150];	struct ar_hdr arhdr;	char *e, *start, *stop; 	if(file[0] == '-' && file[1] == 'l') {		sprint(name, "/%s/lib/lib", thestring);		strcat(name, file+2);		strcat(name, ".a");		file = name;	}	if(debug['v'])		Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);	Bflush(&bso);	f = open(file, 0);	if(f < 0) {		diag("cannot open file: %s", file);		errorexit();	}	l = read(f, magbuf, SARMAG);	if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){		/* load it as a regular file */		l = seek(f, 0L, 2);		seek(f, 0L, 0);		ldobj(f, l, file);		close(f);		return;	} 	l = read(f, &arhdr, SAR_HDR);	if(l != SAR_HDR) {		diag("%s: short read on archive file symbol header", file);		goto out;	}	if(strncmp(arhdr.name, symname, strlen(symname))) {		diag("%s: first entry not symbol header", file);		goto out;	} 	esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);	off = SARMAG + SAR_HDR; 	/*	 * just bang the whole symbol file into memory	 */	seek(f, off, 0);	cnt = esym - off;	start = malloc(cnt + 10);	cnt = read(f, start, cnt);	if(cnt <= 0){		close(f);		return;	}	stop = &start[cnt];	memset(stop, 0, 10); 	work = 1;	while(work){		if(debug['v'])			Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file);		Bflush(&bso);		work = 0;		for(e = start; e < stop; e = strchr(e+5, 0) + 1) {			s = lookup(e+5, 0);			if(s->type != SXREF)				continue;			sprint(pname, "%s(%s)", file, s->name);			if(debug['v'])				Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);			Bflush(&bso);			l = e[1] & 0xff;			l |= (e[2] & 0xff) << 8;			l |= (e[3] & 0xff) << 16;			l |= (e[4] & 0xff) << 24;			seek(f, l, 0);			l = read(f, &arhdr, SAR_HDR);			if(l != SAR_HDR)				goto bad;			if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))				goto bad;			l = atolwhex(arhdr.size);			ldobj(f, l, pname);			if(s->type == SXREF) {				diag("%s: failed to load: %s", file, s->name);				errorexit();			}			work = 1;			xrefresolv = 1;		}	}	return; bad:	diag("%s: bad or out of date archive", file);out:	close(f);} intzaddr(uchar *p, Adr *a, Sym *h[]){	int c, t, i;	long l;	Sym *s;	Auto *u; 	t = p[0]; 	/*	 * first try the high-time formats	 */	if(t == 0) {		a->type = p[1];		return 2;	}	if(t == T_OFFSET) {		a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24);		a->type = p[5];		return 6;	}	if(t == (T_OFFSET|T_SYM)) {		a->offset = p[1] | (p[2]<<8) | (p[3]<<16) | (p[4]<<24);		s = h[p[5]];		a->sym = s;		a->type = p[6];		c = 7;		goto dosym;	}	if(t == T_SYM) {		s = h[p[1]];		a->sym = s;		a->type = p[2];		c = 3;		goto dosym;	}	if(t == (T_INDEX|T_OFFSET|T_SYM)) {		a->displace = p[4] | (p[5]<<8) | (p[6]<<16) | (p[7]<<24);		a->offset = p[8] | (p[9]<<8) | (p[10]<<16) | (p[11]<<24);		s = h[p[12]];		a->sym = s;		a->type = p[13];		c = 14;		goto dosym;	} 	/*	 * now do it the hard way	 */	c = 1;	if(t & T_FIELD) {		a->field = p[c] | (p[c+1]<<8);		c += 2;	}	if(t & T_INDEX) {		a->displace = p[c+3] | (p[c+4]<<8) | (p[c+5]<<16) | (p[c+6]<<24);		c += 7;	}	if(t & T_OFFSET) {		a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);		c += 4;	}	if(t & T_SYM) {		a->sym = h[p[c]];		c += 1;	}	if(t & T_FCONST) {		a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);		a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24);		c += 8;		a->type = D_FCONST;	} else	if(t & T_SCONST) {		for(i=0; i<NSNAME; i++)			a->scon[i] = p[c+i];		c += NSNAME;		a->type = D_SCONST;	} else	if(t & T_TYPE) {		a->type = p[c] | (p[c+1]<<8);		c += 2;	} else {		a->type = p[c];		c++;	}	s = a->sym;	if(s == S)		return c; dosym:	t = a->type & D_MASK;	if(t != D_AUTO && t != D_PARAM)		return c;	l = a->offset;	for(u=curauto; u; u=u->link) {		if(u->asym == s)		if(u->type == t) {			if(u->aoffset > l)				u->aoffset = l;			return c;		}

Lines 1–500 of 1380.