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

📄 obj.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	version++;	histfrogp = 0;	ipc = pc;loop:	if(c <= 0)		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 .%c file\n", thechar);		errorexit();	}	if(o == ANAME || o == ASIGNAME) {		if(o == ASIGNAME) {			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['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 ADATA:		p->link = datap;		datap = p;		ndata++;		goto loop;	case AGOK:		diag("%s: unknown opcode in %s", pn, TNAME);		pc++;		goto loop;	case ATEXT:		if(curtext != P) {			histtoauto();			curtext->to.autom = curauto;			curauto = 0;		}		curtext = p;		lastp->link = p;		lastp = p;		p->pc = pc;		s = p->from.sym;		if(s->type != 0 && s->type != SXREF)			diag("%s: redefinition: %s", pn, s->name);		s->type = STEXT;		s->value = p->pc;		pc++;		p->pcond = P;		if(textp == P) {			textp = p;			etextp = p;			goto loop;		}		etextp->pcond = p;		etextp = p;		goto loop;	case AJSR:		p->as = ABSR;	case ABSR:		if(p->to.type != D_EXTERN && p->to.type != D_STATIC)			p->as = AJSR;		goto casdef;	case AMOVL:	case AMOVB:	case AMOVW:		if(p->from.type != D_CONST)			goto casdef;		lv = p->from.offset;		if(lv >= -128 && lv < 128)		if(p->to.type >= D_R0 && p->to.type < D_R0+8) {			p->from.type = D_QUICK;			goto casdef;		}		if(lv >= -0x7fff && lv <= 0x7fff)		if(p->to.type >= D_A0 && p->to.type < D_A0+8)		if(p->as == AMOVL)			p->as = AMOVW;		goto casdef;	case AADDB:	case AADDL:	case AADDW:		if(p->from.type != D_CONST)			goto casdef;		lv = p->from.offset;		if(lv < 0) {			lv = -lv;			p->from.offset = lv;			if(p->as == AADDB)				p->as = ASUBB;			else			if(p->as == AADDW)				p->as = ASUBW;			else			if(p->as == AADDL)				p->as = ASUBL;		}		if(lv > 0)		if(lv <= 8)			p->from.type = D_QUICK;		goto casdef;	case ASUBB:	case ASUBL:	case ASUBW:		if(p->from.type != D_CONST)			goto casdef;		lv = p->from.offset;		if(lv < 0) {			lv = -lv;			p->from.offset = lv;			if(p->as == ASUBB)				p->as = AADDB;			else			if(p->as == ASUBW)				p->as = AADDW;			else			if(p->as == ASUBL)				p->as = AADDL;		}		if(lv > 0)		if(lv <= 8)			p->from.type = D_QUICK;		goto casdef;	case AROTRB:	case AROTRL:	case AROTRW:	case AROTLB:	case AROTLL:	case AROTLW:	case AASLB:	case AASLL:	case AASLW:	case AASRB:	case AASRL:	case AASRW:	case ALSLB:	case ALSLL:	case ALSLW:	case ALSRB:	case ALSRL:	case ALSRW:		if(p->from.type == D_CONST)		if(p->from.offset > 0)		if(p->from.offset <= 8)			p->from.type = D_QUICK;		goto casdef;	case ATSTL:		if(p->to.type >= D_A0 && p->to.type < D_A0+8) {			p->as = ACMPW;			p->from = p->to;			p->to.type = D_CONST;			p->to.offset = 0;		}		goto casdef;	case ACMPL:		if(p->to.type != D_CONST)			goto casdef;		lv = p->to.offset;		if(lv >= -0x7fff && lv <= 0x7fff)		if(p->from.type >= D_A0 && p->from.type < D_A0+8)			p->as = ACMPW;		goto casdef;	case ACLRL:		if(p->to.type >= D_A0 && p->to.type < D_A0+8) {			p->as = AMOVW;			p->from.type = D_CONST;			p->from.offset = 0;		}		goto casdef;	casdef:	default:		if(p->from.type == D_FCONST)		if(optab[p->as].fas != AXXX) {			dv = ieeedtod(&p->from.ieee);			if(dv >= -(1L<<30) && dv <= (1L<<30)) {				lv = dv;				if(lv == dv) {					p->as = optab[p->as].fas;					p->from.type = D_CONST;					p->from.offset = lv;					p->from.displace = 0;				}			}		}		if(p->to.type == D_BRANCH)			p->to.offset += ipc;		lastp->link = p;		lastp = p;		p->pc = pc;		pc++;		goto loop;	}	/* not reached */eof:	diag("%s: truncated object file in %s", pn, TNAME);}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;	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*nprg(Prog *p){	Prog *q;	q = prg();	q->line = p->line;	q->pc = p->pc;	q->stkoff = p->stkoff;	q->link = p->link;	p->link = q;	return q;}Prog*copyp(Prog *q){	Prog *p;	p = prg();	*p = *q;	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->as = AADDL;			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			q->from.type = D_CONST;			q->from.offset = 1;			q->to.type = D_EXTERN;			q->to.sym = s;			q->to.offset = n*4 + 4;			q = prg();			q->as = ADATA;			q->line = p->line;			q->link = datap;			datap = q;			q->from.type = D_EXTERN;			q->from.sym = s;			q->from.offset = n*4;			q->from.displace = 4;			q->to.type = D_EXTERN;			q->to.sym = p->from.sym;			n += 2;			continue;		}	}	q = prg();	q->line = 0;	q->as = ADATA;	q->link = datap;	datap = q;	q->from.type = D_EXTERN;	q->from.sym = s;	q->from.displace = 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) {				ps2 = p;				p->from.displace = 1;			}			if(p->from.sym == s4) {				ps4 = p;				p->from.displace = 1;			}		}	}	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			if(p->from.displace != 0) {				for(;;) {					q = p->link;					if(q == P)						break;					if(q->as == ATEXT)						break;					p = q;				}				continue;			}			q = prg();			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			p = q;			p->as = ABSR;			p->to.type = D_BRANCH;			p->pcond = ps2;			p->to.sym = s2;			continue;		}		if(p->as == ARTS) {			/*			 * RTS			 */			q = prg();			q->as = ARTS;			q->from = p->from;			q->to = p->to;			q->link = p->link;			p->link = q;			/*			 * BSR	profout			 */			p->as = ABSR;			p->from = zprg.from;			p->to = zprg.to;			p->to.type = D_BRANCH;			p->pcond = ps4;			p->to.sym = s4;			p = q;			continue;		}	}}longreuse(Prog *r, Sym *s){	Prog *p;	if(r == P)		return 0;	for(p = datap; p != r; p = p->link)		if(p->to.sym == s)			return p->from.offset;	return 0;}voidnuxiinit(void){	int i, c;	for(i=0; i<4; i++) {		c = find1(0x01020304L, i+1);		if(i >= 2)			inuxi2[i-2] = c;		if(i >= 3)			inuxi1[i-3] = c;		inuxi4[i] = c;		fnuxi8[i] = c+4;		fnuxi8[i+4] = c;		c = find2(0x01020304L, i+1);		gnuxi8[i] = c+4;		gnuxi8[i+4] = c;	}	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, "\n[fg]nuxi = ");		for(i=0; i<8; i++)			Bprint(&bso, "%d", fnuxi8[i]);		Bprint(&bso, " ");		for(i=0; i<8; i++)			Bprint(&bso, "%d", gnuxi8[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);}

⌨️ 快捷键说明

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