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

📄 obj.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
		stop = memchr(&bloc[3], 0, bsize-&bloc[3]);		if(stop == 0){			bsize = readsome(f, buf.xbuf, bloc, bsize, c);			if(bsize == 0)				goto eof;			bloc = buf.xbuf;			stop = memchr(&bloc[3], 0, bsize-&bloc[3]);			if(stop == 0){				fprint(2, "%s: name too long\n", pn);				errorexit();			}		}		v = bloc[1];	/* type */		o = bloc[2];	/* sym */		bloc += 3;		c -= 3;		r = 0;		if(v == D_STATIC)			r = version;		s = lookup((char*)bloc, r);		c -= &stop[1] - bloc;		bloc = stop + 1;		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;	}	if(nhunk < sizeof(Prog))		gethunk();	p = (Prog*)hunk;	nhunk -= sizeof(Prog);	hunk += sizeof(Prog);	p->as = o;	p->reg = bloc[1] & 0x3f;	if(bloc[1] & 0x80)		p->mark = NOSCHED;	p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);	r = zaddr(bloc+6, &p->from, h) + 6;	if(bloc[1] & 0x40)		r += zaddr(bloc+r, &p->from3, h);	else		p->from3 = zprg.from3;	r += zaddr(bloc+r, &p->to, h);	bloc += r;	c -= r;	if(p->reg < 0 || p->reg > NREG)		diag("register out of range %d", p->reg);	p->link = P;	p->cond = P;	if(debug['W'])		print("%P\n", p);	switch(o) {	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 == S) {			diag("GLOBL must have a name\n%P", p);			errorexit();		}		if(s->type == 0 || s->type == SXREF) {			s->type = SBSS;			s->value = 0;		}		if(s->type != SBSS) {			diag("redefinition: %s\n%P", s->name, p);			s->type = SBSS;			s->value = 0;		}		if(p->to.offset > s->value)			s->value = p->to.offset;		break;	case ADYNT:		if(p->to.sym == S) {			diag("DYNT without a sym\n%P", p);			break;		}		di = p->to.sym;		p->reg = 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_CONST;		p->link = datap;		datap = p;		break;	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;		p->link = datap;		datap = p;		break;	case ADATA:		p->link = datap;		datap = p;		break;	case AGOK:		diag("unknown opcode\n%P", p);		p->pc = pc;		pc++;		break;	case ATEXT:		if(curtext != P) {			histtoauto();			curtext->to.autom = curauto;			curauto = 0;		}		curtext = p;		autosize = (p->to.offset+3L) & ~3L;		p->to.offset = autosize;		autosize += 4;		s = p->from.sym;		if(s == S) {			diag("TEXT must have a name\n%P", p);			errorexit();		}		if(s->type != 0 && s->type != SXREF) {			if(p->reg & DUPOK) {				skip = 1;				goto casedef;			}			diag("redefinition: %s\n%P", s->name, p);		}		s->type = STEXT;		s->value = pc;		if(textp != P) {			for(t = textp; t->cond != P; t = t->cond)				;			t->cond = p;		} else			textp = p;		lastp->link = p;		lastp = p;		p->pc = pc;		pc++;		break;	case AFMOVS:		if(skip)			goto casedef;		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_OREG;				t->from.sym = s;				t->from.name = D_EXTERN;				t->reg = 4;				t->to = p->from;				t->link = datap;				datap = t;			}			p->from.type = D_OREG;			p->from.sym = s;			p->from.name = D_EXTERN;			p->from.offset = 0;		}		goto casedef;	case AFMOVD:		if(skip)			goto casedef;		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_OREG;				t->from.sym = s;				t->from.name = D_EXTERN;				t->reg = 8;				t->to = p->from;				t->link = datap;				datap = t;			}			p->from.type = D_OREG;			p->from.sym = s;			p->from.name = D_EXTERN;			p->from.offset = 0;		}		goto casedef;	case ASUBC:		if(p->from.type == D_CONST) {			p->from.offset = -p->from.offset;			p->as = AADDC;		}		goto casedef;	case ASUBCCC:		if(p->from.type == D_CONST) {			p->from.offset = -p->from.offset;			p->as = AADDCCC;		}		goto casedef;	case ASUB:		if(p->from.type == D_CONST) {			p->from.offset = -p->from.offset;			p->as = AADD;		}		goto casedef;	default:	casedef:		if(skip)			nopout(p);		if(p->to.type == D_BRANCH)			p->to.offset += ipc;		lastp->link = p;		lastp = p;		p->pc = pc;		pc++;		break;	}	goto loop;eof:	diag("truncated object file: %s", pn);}Sym*lookup(char *symb, int v){	Sym *s;	char *p;	long h;	int c, l;	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;	return s;}Prog*prg(void){	Prog *p;	int n;	n = (sizeof(Prog) + 3) & ~3;	while(nhunk < n)		gethunk();	p = (Prog*)hunk;	nhunk -= n;	hunk += n;	*p = zprg;	return p;}voidgethunk(void){	char *h;	long nh;	nh = NHUNK;	if(tothunk >= 5L*NHUNK) {		nh = 5L*NHUNK;		if(tothunk >= 25L*NHUNK)			nh = 25L*NHUNK;	}	h = mysbrk(nh);	if(h == (char *)-1) {		diag("out of memory");		errorexit();	}	hunk = h;	nhunk = nh;	tothunk += 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_OREG;			q->from.name = D_EXTERN;			q->from.offset = n*4;			q->from.sym = s;			q->reg = 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 = AMOVW;			p->from.type = D_OREG;			p->from.name = D_EXTERN;			p->from.sym = s;			p->from.offset = n*4 + 4;			p->to.type = D_REG;			p->to.reg = REGTMP;			q = prg();			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			p = q;			p->as = AADD;			p->from.type = D_CONST;			p->from.offset = 1;			p->to.type = D_REG;			p->to.reg = REGTMP;			q = prg();			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			p = q;			p->as = AMOVW;			p->from.type = D_REG;			p->from.reg = REGTMP;			p->to.type = D_OREG;			p->to.name = 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_OREG;	q->from.name = D_EXTERN;	q->from.sym = s;	q->reg = 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->reg = 1;				ps2 = p;			}			if(p->from.sym == s4) {				p->reg = 1;				ps4 = p;			}		}	}	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT) {			curtext = p;			if(p->reg & NOPROF) {	/* dont profile */				for(;;) {					q = p->link;					if(q == P)						break;					if(q->as == ATEXT)						break;					p = q;				}				continue;			}			/*			 * BL	profin			 */			q = prg();			q->line = p->line;			q->pc = p->pc;			q->link = p->link;			p->link = q;			p = q;			p->as = ABL;			p->to.type = D_BRANCH;			p->cond = ps2;			p->to.sym = s2;			continue;		}		if(p->as == ARETURN) {			/*			 * RETURN			 */			q = prg();			q->as = ARETURN;			q->from = p->from;			q->to = p->to;			q->link = p->link;			p->link = q;			/*			 * BL profout			 */			p->as = ABL;			p->from = zprg.from;			p->to = zprg.to;			p->to.type = D_BRANCH;			p->cond = ps4;			p->to.sym = s4;			p = q;			continue;		}	}}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;	}	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<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;}longieeedtof(Ieee *ieeep){	int exp;	long v;	if(ieeep->h == 0)		return 0;	exp = (ieeep->h>>20) & ((1L<<11)-1L);	exp -= (1L<<10) - 2L;	v = (ieeep->h & 0xfffffL) << 3;	v |= (ieeep->l >> 29) & 0x7L;	if((ieeep->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 |= ieeep->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 + -