⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obj.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#define	EXTERN#include	"l.h"#include	<ar.h>#ifndef	DEFAULT#define	DEFAULT	'9'#endifchar	*noname		= "<none>";char	symname[]	= SYMDEF;char	thechar		= '8';char	*thestring 	= "386";/* *	-H0 -T0x40004C -D0x10000000	is garbage unix *	-H1 -T0xd0 -R4			is unix coff *	-H2 -T4128 -R4096		is plan9 format *	-H3 -Tx -Rx			is MS-DOS .COM *	-H4 -Tx -Rx			is fake MS-DOS .EXE *	-H5 -T0x80100020 -R4096		is ELF */static intisobjfile(char *f){	int n, v;	Biobuf *b;	char buf1[5], buf2[SARMAG];	b = Bopen(f, OREAD);	if(b == nil)		return 0;	n = Bread(b, buf1, 5);	if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<'))		v = 1;	/* good enough for our purposes */	else{		Bseek(b, 0, 0);		n = Bread(b, buf2, SARMAG);		v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0;	}	Bterm(b);	return v;}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 = "8.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;	case 'x':	/* produce export table */		doexp = 1;		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))			readundefs(ARGF(), SEXPORT);		break;	case 'u':	/* produce dynamically loadable module */		dlm = 1;		debug['l']++;		if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))			readundefs(ARGF(), SIMPORT);		break;	} ARGEND	USED(argc);	if(*argv == 0) {		diag("usage: 8l [-options] objects");		errorexit();	}	if(!debug['9'] && !debug['U'] && !debug['B'])		debug[DEFAULT] = 1;	if(HEADTYPE == -1) {		if(debug['U'])			HEADTYPE = 1;		if(debug['B'])			HEADTYPE = 2;		if(debug['9'])			HEADTYPE = 2;	}	switch(HEADTYPE) {	default:		diag("unknown -H option");		errorexit();	case 0:	/* this is garbage */		HEADR = 20L+56L;		if(INITTEXT == -1)			INITTEXT = 0x40004CL;		if(INITDAT == -1)			INITDAT = 0x10000000L;		if(INITRND == -1)			INITRND = 0;		break;	case 1:	/* is unix coff */		HEADR = 0xd0L;		if(INITTEXT == -1)			INITTEXT = 0xd0;		if(INITDAT == -1)			INITDAT = 0x400000;		if(INITRND == -1)			INITRND = 0;		break;	case 2:	/* plan 9 */		HEADR = 32L;		if(INITTEXT == -1)			INITTEXT = 4096+32;		if(INITDAT == -1)			INITDAT = 0;		if(INITRND == -1)			INITRND = 4096;		break;	case 3:	/* MS-DOS .COM */		HEADR = 0;		if(INITTEXT == -1)			INITTEXT = 0x0100;		if(INITDAT == -1)			INITDAT = 0;		if(INITRND == -1)			INITRND = 4;		break;	case 4:	/* fake MS-DOS .EXE */		HEADR = 0x200;		if(INITTEXT == -1)			INITTEXT = 0x0100;		if(INITDAT == -1)			INITDAT = 0;		if(INITRND == -1)			INITRND = 4;		HEADR += (INITTEXT & 0xFFFF);		if(debug['v'])			Bprint(&bso, "HEADR = 0x%ld\n", HEADR);		break;	case 5:	/* elf executable */		HEADR = rnd(52L+3*32L, 16);		if(INITTEXT == -1)			INITTEXT = 0x80100020L;		if(INITDAT == -1)			INITDAT = 0;		if(INITRND == -1)			INITRND = 4096;		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();		}	for(i=0; i<Ymax; i++)		ycover[i*Ymax + i] = 1;	ycover[Yi0*Ymax + Yi8] = 1;	ycover[Yi1*Ymax + Yi8] = 1;	ycover[Yi0*Ymax + Yi32] = 1;	ycover[Yi1*Ymax + Yi32] = 1;	ycover[Yi8*Ymax + Yi32] = 1;	ycover[Yal*Ymax + Yrb] = 1;	ycover[Ycl*Ymax + Yrb] = 1;	ycover[Yax*Ymax + Yrb] = 1;	ycover[Ycx*Ymax + Yrb] = 1;	ycover[Yrx*Ymax + Yrb] = 1;	ycover[Yax*Ymax + Yrx] = 1;	ycover[Ycx*Ymax + Yrx] = 1;	ycover[Yax*Ymax + Yrl] = 1;	ycover[Ycx*Ymax + Yrl] = 1;	ycover[Yrx*Ymax + Yrl] = 1;	ycover[Yf0*Ymax + Yrf] = 1;	ycover[Yal*Ymax + Ymb] = 1;	ycover[Ycl*Ymax + Ymb] = 1;	ycover[Yax*Ymax + Ymb] = 1;	ycover[Ycx*Ymax + Ymb] = 1;	ycover[Yrx*Ymax + Ymb] = 1;	ycover[Yrb*Ymax + Ymb] = 1;	ycover[Ym*Ymax + Ymb] = 1;	ycover[Yax*Ymax + Yml] = 1;	ycover[Ycx*Ymax + Yml] = 1;	ycover[Yrx*Ymax + Yml] = 1;	ycover[Yrl*Ymax + Yml] = 1;	ycover[Ym*Ymax + Yml] = 1;	for(i=0; i<D_NONE; i++) {		reg[i] = -1;		if(i >= D_AL && i <= D_BH)			reg[i] = (i-D_AL) & 7;		if(i >= D_AX && i <= D_DI)			reg[i] = (i-D_AX) & 7;		if(i >= D_F0 && i <= D_F0+7)			reg[i] = (i-D_F0) & 7;	}	zprg.link = P;	zprg.pcond = P;	zprg.back = 2;	zprg.as = AGOK;	zprg.from.type = D_NONE;	zprg.from.index = D_NONE;	zprg.from.scale = 1;	zprg.to = zprg.from;	pcstr = "%.6lux ";	nuxiinit();	histgen = 0;	textp = P;	datap = P;	edatap = P;	pc = 0;	dtype = 4;	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;	while(*argv)		objfile(*argv++);	if(!debug['l'])		loadlib();	firstp = firstp->link;	if(firstp == P)		errorexit();	if(doexp || dlm){		EXPTAB = "_exporttab";		zerosig(EXPTAB);		zerosig("etext");		zerosig("edata");		zerosig("end");		if(dlm){			import();			HEADTYPE = 2;			INITTEXT = INITDAT = 0;			INITRND = 8;			INITENTRY = EXPTAB;		}		export();	}	patch();	follow();	dodata();	dostkoff();	if(debug['p'])		if(debug['1'])			doprof1();		else			doprof2();	span();	doinit();	asmb();	undef();	if(debug['v']) {		Bprint(&bso, "%5.2f cpu time\n", cputime());		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') {		if(debug['9'])			sprint(name, "/%s/lib/lib", thestring);		else			sprint(name, "/usr/%clib/lib", thechar);		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];	c = 1;	if(t & T_INDEX) {		a->index = p[c];		a->scale = p[c+1];		c += 2;	} else {		a->index = D_NONE;		a->scale = 0;	}	a->offset = 0;	if(t & T_OFFSET) {		a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);		c += 4;	}	a->sym = S;	if(t & T_SYM) {		a->sym = h[p[c]];		c++;	}	a->type = D_NONE;	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;	}	if(t & T_TYPE) {		a->type = p[c];		c++;	}	s = a->sym;	if(s == S)		return c;	t = a->type;	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;		}	}	while(nhunk < sizeof(Auto))		gethunk();	u = (Auto*)hunk;	nhunk -= sizeof(Auto);	hunk += sizeof(Auto);	u->link = curauto;	curauto = u;	u->asym = s;	u->aoffset = l;	u->type = t;	return c;}voidaddlib(char *obj){	char name[1024], comp[256], *p;	int i;	if(histfrogp <= 0)		return;	if(histfrog[0]->name[1] == '/') {		sprint(name, "");		i = 1;	} else	if(histfrog[0]->name[1] == '.') {		sprint(name, ".");		i = 0;	} else {		if(debug['9'])			sprint(name, "/%s/lib", thestring);		else			sprint(name, "/usr/%clib", thechar);		i = 0;	}	for(; i<histfrogp; i++) {		snprint(comp, sizeof comp, histfrog[i]->name+1);		for(;;) {			p = strstr(comp, "$O");			if(p == 0)				break;			memmove(p+1, p+2, strlen(p+2)+1);			p[0] = thechar;		}		for(;;) {			p = strstr(comp, "$M");			if(p == 0)				break;			if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {				diag("library component too long");				return;			}			memmove(p+strlen(thestring), p+2, strlen(p+2)+1);			memmove(p, thestring, strlen(thestring));		}		if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {			diag("library component too long");			return;		}		strcat(name, "/");		strcat(name, comp);	}	for(i=0; i<libraryp; i++)		if(strcmp(name, library[i]) == 0)			return;	if(libraryp == nelem(library)){		diag("too many autolibs; skipping %s", name);		return;	}	p = malloc(strlen(name) + 1);	strcpy(p, name);	library[libraryp] = p;	p = malloc(strlen(obj) + 1);	strcpy(p, obj);	libraryobj[libraryp] = p;	libraryp++;}voidaddhist(long line, int type){	Auto *u;	Sym *s;	int i, j, k;	u = malloc(sizeof(Auto));	s = malloc(sizeof(Sym));	s->name = malloc(2*(histfrogp+1) + 1);	u->asym = s;	u->type = type;	u->aoffset = line;	u->link = curhist;	curhist = u;	j = 1;	for(i=0; i<histfrogp; i++) {		k = histfrog[i]->value;		s->name[j+0] = k>>8;		s->name[j+1] = k;		j += 2;	}}voidhisttoauto(void){	Auto *l;	while(l = curhist) {		curhist = l->link;		l->link = curauto;		curauto = l;	}}voidcollapsefrog(Sym *s){	int i;	/*	 * bad encoding of path components only allows	 * MAXHIST components. if there is an overflow,	 * first try to collapse xxx/..	 */	for(i=1; i<histfrogp; i++)		if(strcmp(histfrog[i]->name+1, "..") == 0) {			memmove(histfrog+i-1, histfrog+i+1,				(histfrogp-i-1)*sizeof(histfrog[0]));			histfrogp--;			goto out;		}	/*	 * next try to collapse .	 */	for(i=0; i<histfrogp; i++)		if(strcmp(histfrog[i]->name+1, ".") == 0) {			memmove(histfrog+i, histfrog+i+1,				(histfrogp-i-1)*sizeof(histfrog[0]));			goto out;		}	/*	 * last chance, just truncate from front	 */	memmove(histfrog+0, histfrog+1,		(histfrogp-1)*sizeof(histfrog[0]));out:	histfrog[histfrogp-1] = s;}voidnopout(Prog *p){	p->as = ANOP;	p->from.type = D_NONE;	p->to.type = D_NONE;}uchar*readsome(int f, uchar *buf, uchar *good, uchar *stop, int max){	int n;	n = stop - good;	memmove(buf, good, stop - good);	stop = buf + n;	n = MAXIO - n;	if(n > max)		n = max;	n = read(f, stop, n);	if(n <= 0)		return 0;	return stop + n;}voidldobj(int f, long c, char *pn){	long ipc;	Prog *p, *t;	uchar *bloc, *bsize, *stop;	int v, o, r, skip;	Sym *h[NSYM], *s, *di;	ulong sig;	static int files;	static char **filen;	char **nfilen;	if((files&15) == 0){		nfilen = malloc((files+16)*sizeof(char*));		memmove(nfilen, filen, files*sizeof(char*));		free(filen);		filen = nfilen;	}	filen[files++] = strdup(pn);	bsize = buf.xbuf;	bloc = buf.xbuf;	di = S;newloop:	memset(h, 0, sizeof(h));	version++;	histfrogp = 0;	ipc = pc;	skip = 0;loop:	if(c <= 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -