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

📄 obj.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		goto eof;	r = bsize - bloc;	if(r < 100 && r < c) {		/* enough for largest prog */		bsize = readsome(f, buf.xbuf, bloc, bsize, c);		if(bsize == 0)			goto eof;		bloc = buf.xbuf;		goto loop;	}	o = bloc[0] | (bloc[1] << 8);	if(o <= AXXX || o >= ALAST) {		if(o < 0)			goto eof;		diag("%s: opcode out of range %d", pn, o);		print("	probably not a .8 file\n");		errorexit();	}	if(o == ANAME || o == ASIGNAME) {		sig = 0;		if(o == ASIGNAME) {			sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);			bloc += 4;			c -= 4;		}		stop = memchr(&bloc[4], 0, bsize-&bloc[4]);		if(stop == 0){			bsize = readsome(f, buf.xbuf, bloc, bsize, c);			if(bsize == 0)				goto eof;			bloc = buf.xbuf;			stop = memchr(&bloc[4], 0, bsize-&bloc[4]);			if(stop == 0){				fprint(2, "%s: name too long\n", pn);				errorexit();			}		}		v = bloc[2];	/* type */		o = bloc[3];	/* sym */		bloc += 4;		c -= 4;		r = 0;		if(v == D_STATIC)			r = version;		s = lookup((char*)bloc, r);		c -= &stop[1] - bloc;		bloc = stop + 1;		if(debug['S'] && r == 0)			sig = 1729;		if(sig != 0){			if(s->sig != 0 && s->sig != sig)				diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name);			s->sig = sig;			s->file = files-1;		}		if(debug['W'])			print("	ANAME	%s\n", s->name);		h[o] = s;		if((v == D_EXTERN || v == D_STATIC) && s->type == 0)			s->type = SXREF;		if(v == D_FILE) {			if(s->type != SFILE) {				histgen++;				s->type = SFILE;				s->value = histgen;			}			if(histfrogp < MAXHIST) {				histfrog[histfrogp] = s;				histfrogp++;			} else				collapsefrog(s);		}		goto loop;	}	while(nhunk < sizeof(Prog))		gethunk();	p = (Prog*)hunk;	nhunk -= sizeof(Prog);	hunk += sizeof(Prog);	p->as = o;	p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24);	p->back = 2;	r = zaddr(bloc+6, &p->from, h) + 6;	r += zaddr(bloc+r, &p->to, h);	bloc += r;	c -= r;	if(debug['W'])		print("%P\n", p);	switch(p->as) {	case AHISTORY:		if(p->to.offset == -1) {			addlib(pn);			histfrogp = 0;			goto loop;		}		addhist(p->line, D_FILE);		/* 'z' */		if(p->to.offset)			addhist(p->to.offset, D_FILE1);	/* 'Z' */		histfrogp = 0;		goto loop;	case AEND:		histtoauto();		if(curtext != P)			curtext->to.autom = curauto;		curauto = 0;		curtext = P;		if(c)			goto newloop;		return;	case AGLOBL:		s = p->from.sym;		if(s->type == 0 || s->type == SXREF) {			s->type = SBSS;			s->value = 0;		}		if(s->type != SBSS) {			diag("%s: redefinition: %s in %s",				pn, s->name, TNAME);			s->type = SBSS;			s->value = 0;		}		if(p->to.offset > s->value)			s->value = p->to.offset;		goto loop;	case ADYNT:		if(p->to.sym == S) {			diag("DYNT without a sym\n%P", p);			break;		}		di = p->to.sym;		p->from.scale = 4;		if(di->type == SXREF) {			if(debug['z'])				Bprint(&bso, "%P set to %d\n", p, dtype);			di->type = SCONST;			di->value = dtype;			dtype += 4;		}		if(p->from.sym == S)			break;		p->from.offset = di->value;		p->from.sym->type = SDATA;		if(curtext == P) {			diag("DYNT not in text: %P", p);			break;		}		p->to.sym = curtext->from.sym;		p->to.type = D_ADDR;		p->to.index = D_EXTERN;		goto data;	case AINIT:		if(p->from.sym == S) {			diag("INIT without a sym\n%P", p);			break;		}		if(di == S) {			diag("INIT without previous DYNT\n%P", p);			break;		}		p->from.offset = di->value;		p->from.sym->type = SDATA;		goto data;	case ADATA:	data:		if(edatap == P)			datap = p;		else			edatap->link = p;		edatap = p;		p->link = P;		goto loop;	case AGOK:		diag("%s: GOK opcode in %s", pn, TNAME);		pc++;		goto loop;	case ATEXT:		if(curtext != P) {			histtoauto();			curtext->to.autom = curauto;			curauto = 0;		}		skip = 0;		curtext = p;		s = p->from.sym;		if(s == S) {			diag("%s: no TEXT symbol: %P", pn, p);			errorexit();		}		if(s->type != 0 && s->type != SXREF) {			if(p->from.scale & DUPOK) {				skip = 1;				goto casdef;			}			diag("%s: redefinition: %s\n%P", pn, s->name, p);		}		s->type = STEXT;		s->value = pc;		lastp->link = p;		lastp = p;		p->pc = pc;		pc++;		if(textp == P) {			textp = p;			etextp = p;			goto loop;		}		etextp->pcond = p;		etextp = p;		goto loop;	case AFMOVF:	case AFADDF:	case AFSUBF:	case AFSUBRF:	case AFMULF:	case AFDIVF:	case AFDIVRF:	case AFCOMF:	case AFCOMFP:		if(skip)			goto casdef;		if(p->from.type == D_FCONST) {			/* size sb 9 max */			sprint(literal, "$%lux", ieeedtof(&p->from.ieee));			s = lookup(literal, 0);			if(s->type == 0) {				s->type = SBSS;				s->value = 4;				t = prg();				t->as = ADATA;				t->line = p->line;				t->from.type = D_EXTERN;				t->from.sym = s;				t->from.scale = 4;				t->to = p->from;				if(edatap == P)					datap = t;				else					edatap->link = t;				edatap = t;				t->link = P;			}			p->from.type = D_EXTERN;			p->from.sym = s;			p->from.offset = 0;		}		goto casdef;	case AFMOVD:	case AFADDD:	case AFSUBD:	case AFSUBRD:	case AFMULD:	case AFDIVD:	case AFDIVRD:	case AFCOMD:	case AFCOMDP:		if(skip)			goto casdef;		if(p->from.type == D_FCONST) {			/* size sb 18 max */			sprint(literal, "$%lux.%lux",				p->from.ieee.l, p->from.ieee.h);			s = lookup(literal, 0);			if(s->type == 0) {				s->type = SBSS;				s->value = 8;				t = prg();				t->as = ADATA;				t->line = p->line;				t->from.type = D_EXTERN;				t->from.sym = s;				t->from.scale = 8;				t->to = p->from;				if(edatap == P)					datap = t;				else					edatap->link = t;				edatap = t;				t->link = P;			}			p->from.type = D_EXTERN;			p->from.sym = s;			p->from.offset = 0;		}		goto casdef;	casdef:	default:		if(skip)			nopout(p);		if(p->to.type == D_BRANCH)			p->to.offset += ipc;		lastp->link = p;		lastp = p;		p->pc = pc;		pc++;		goto loop;	}	goto loop;eof:	diag("truncated object file: %s", pn);}Sym*lookup(char *symb, int v){	Sym *s;	char *p;	long h;	int l, c;	h = v;	for(p=symb; c = *p; p++)		h = h+h+h + c;	l = (p - symb) + 1;	if(h < 0)		h = ~h;	h %= NHASH;	for(s = hash[h]; s != S; s = s->link)		if(s->version == v)		if(memcmp(s->name, symb, l) == 0)			return s;	while(nhunk < sizeof(Sym))		gethunk();	s = (Sym*)hunk;	nhunk -= sizeof(Sym);	hunk += sizeof(Sym);	s->name = malloc(l + 1);	memmove(s->name, symb, l);	s->link = hash[h];	s->type = 0;	s->version = v;	s->value = 0;	s->sig = 0;	hash[h] = s;	nsymbol++;	return s;}Prog*prg(void){	Prog *p;	while(nhunk < sizeof(Prog))		gethunk();	p = (Prog*)hunk;	nhunk -= sizeof(Prog);	hunk += sizeof(Prog);	*p = zprg;	return p;}Prog*copyp(Prog *q){	Prog *p;	p = prg();	*p = *q;	return p;}Prog*appendp(Prog *q){	Prog *p;	p = prg();	p->link = q->link;	q->link = p;	p->line = q->line;	return p;}voidgethunk(void){	char *h;	long nh;	nh = NHUNK;	if(thunk >= 5L*NHUNK) {		nh = 5L*NHUNK;		if(thunk >= 25L*NHUNK)			nh = 25L*NHUNK;	}	h = mysbrk(nh);	if(h == (char*)-1) {		diag("out of memory");		errorexit();	}	hunk = h;	nhunk = nh;	thunk += nh;}voiddoprof1(void){	Sym *s;	long n;	Prog *p, *q;	if(debug['v'])		Bprint(&bso, "%5.2f profile 1\n", cputime());	Bflush(&bso);	s = lookup("__mcount", 0);	n = 1;	for(p = firstp->link; p != P; p = p->link) {		if(p->as == ATEXT) {			q = prg();			q->line = p->line;			q->link = datap;			datap = q;			q->as = ADATA;			q->from.type = D_EXTERN;			q->from.offset = n*4;			q->from.sym = s;			q->from.scale = 4;			q->to = p->from;			q->to.type = D_CONST;			q = prg();			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			p = q;			p->as = AADDL;			p->from.type = D_CONST;			p->from.offset = 1;			p->to.type = D_EXTERN;			p->to.sym = s;			p->to.offset = n*4 + 4;			n += 2;			continue;		}	}	q = prg();	q->line = 0;	q->link = datap;	datap = q;	q->as = ADATA;	q->from.type = D_EXTERN;	q->from.sym = s;	q->from.scale = 4;	q->to.type = D_CONST;	q->to.offset = n;	s->type = SBSS;	s->value = n*4;}voiddoprof2(void){	Sym *s2, *s4;	Prog *p, *q, *ps2, *ps4;	if(debug['v'])		Bprint(&bso, "%5.2f profile 2\n", cputime());	Bflush(&bso);	s2 = lookup("_profin", 0);	s4 = lookup("_profout", 0);	if(s2->type != STEXT || s4->type != STEXT) {		diag("_profin/_profout not defined");		return;	}	ps2 = P;	ps4 = P;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			if(p->from.sym == s2) {				p->from.scale = 1;				ps2 = p;			}			if(p->from.sym == s4) {				p->from.scale = 1;				ps4 = p;			}		}	}	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			curtext = p;			if(p->from.scale & NOPROF) {	/* dont profile */				for(;;) {					q = p->link;					if(q == P)						break;					if(q->as == ATEXT)						break;					p = q;				}				continue;			}			/*			 * JMPL	profin			 */			q = prg();			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			p = q;			p->as = ACALL;			p->to.type = D_BRANCH;			p->pcond = ps2;			p->to.sym = s2;			continue;		}		if(p->as == ARET) {			/*			 * RET			 */			q = prg();			q->as = ARET;			q->from = p->from;			q->to = p->to;			q->link = p->link;			p->link = q;			/*			 * JAL	profout			 */			p->as = ACALL;			p->from = zprg.from;			p->to = zprg.to;			p->to.type = D_BRANCH;			p->pcond = ps4;			p->to.sym = s4;			p = q;			continue;		}	}}voidnuxiinit(void){	int i, c;	for(i=0; i<4; i++) {		c = find1(0x04030201L, i+1);		if(i < 2)			inuxi2[i] = c;		if(i < 1)			inuxi1[i] = c;		inuxi4[i] = c;		fnuxi4[i] = c;		fnuxi8[i] = c;		fnuxi8[i+4] = c+4;	}	if(debug['v']) {		Bprint(&bso, "inuxi = ");		for(i=0; i<1; i++)			Bprint(&bso, "%d", inuxi1[i]);		Bprint(&bso, " ");		for(i=0; i<2; i++)			Bprint(&bso, "%d", inuxi2[i]);		Bprint(&bso, " ");		for(i=0; i<4; i++)			Bprint(&bso, "%d", inuxi4[i]);		Bprint(&bso, "\nfnuxi = ");		for(i=0; i<4; i++)			Bprint(&bso, "%d", fnuxi4[i]);		Bprint(&bso, " ");		for(i=0; i<8; i++)			Bprint(&bso, "%d", fnuxi8[i]);		Bprint(&bso, "\n");	}	Bflush(&bso);}intfind1(long l, int c){	char *p;	int i;	p = (char*)&l;	for(i=0; i<4; i++)		if(*p++ == c)			return i;	return 0;}intfind2(long l, int c){	short *p;	int i;	p = (short*)&l;	for(i=0; i<4; i+=2) {		if(((*p >> 8) & 0xff) == c)			return i;		if((*p++ & 0xff) == c)			return i+1;	}	return 0;}longieeedtof(Ieee *e){	int exp;	long v;	if(e->h == 0)		return 0;	exp = (e->h>>20) & ((1L<<11)-1L);	exp -= (1L<<10) - 2L;	v = (e->h & 0xfffffL) << 3;	v |= (e->l >> 29) & 0x7L;	if((e->l >> 28) & 1) {		v++;		if(v & 0x800000L) {			v = (v & 0x7fffffL) >> 1;			exp++;		}	}	if(exp <= -126 || exp >= 130)		diag("double fp to single fp overflow");	v |= ((exp + 126) & 0xffL) << 23;	v |= e->h & 0x80000000L;	return v;}doubleieeedtod(Ieee *ieeep){	Ieee e;	double fr;	int exp;	if(ieeep->h & (1L<<31)) {		e.h = ieeep->h & ~(1L<<31);		e.l = ieeep->l;		return -ieeedtod(&e);	}	if(ieeep->l == 0 && ieeep->h == 0)		return 0;	fr = ieeep->l & ((1L<<16)-1L);	fr /= 1L<<16;	fr += (ieeep->l>>16) & ((1L<<16)-1L);	fr /= 1L<<16;	fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);	fr /= 1L<<21;	exp = (ieeep->h>>20) & ((1L<<11)-1L);	exp -= (1L<<10) - 2L;	return ldexp(fr, exp);}voidundefsym(Sym *s){	int n;	n = imports;	if(s->value != 0)		diag("value != 0 on SXREF");	if(n >= 1<<Rindex)		diag("import index %d out of range", n);	s->value = n<<Roffset;	s->type = SUNDEF;	imports++;}voidzerosig(char *sp){	Sym *s;	s = lookup(sp, 0);	s->sig = 0;}voidreadundefs(char *f, int t){	int i, n;	Sym *s;	Biobuf *b;	char *l, buf[256], *fields[64];	if(f == nil)		return;	b = Bopen(f, OREAD);	if(b == nil){		diag("could not open %s: %r", f);		errorexit();	}	while((l = Brdline(b, '\n')) != nil){		n = Blinelen(b);		if(n >= sizeof(buf)){			diag("%s: line too long", f);			errorexit();		}		memmove(buf, l, n);		buf[n-1] = '\0';		n = getfields(buf, fields, nelem(fields), 1, " \t\r\n");		if(n == nelem(fields)){			diag("%s: bad format", f);			errorexit();		}		for(i = 0; i < n; i++){			s = lookup(fields[i], 0);			s->type = SXREF;			s->subtype = t;			if(t == SIMPORT)				nimports++;			else				nexports++;		}	}	Bterm(b);}

⌨️ 快捷键说明

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