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

📄 ld.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
		dorigin = (tsize+017777) & ~017777;	if (iflag)		dorigin = 0;	corigin = dorigin + dsize;	borigin = corigin + csize;	nund = 0;	for (sp = symtab; sp<symp; sp++) switch (sp->stype) {	case EXTERN+UNDEF:		errlev |= 01;		if (arflag==0 && sp->svalue==0) {			if (nund==0)				printf("Undefined:\n");			nund++;			printf("%.8s\n", sp->sname);		}		continue;	case EXTERN+ABS:	default:		continue;	case EXTERN+TEXT:		sp->svalue += torigin;		continue;	case EXTERN+DATA:		sp->svalue += dorigin;		continue;	case EXTERN+BSS:		sp->svalue += borigin;		continue;	case EXTERN+COMM:		sp->stype = EXTERN+BSS;		sp->svalue += corigin;		continue;	}	if (sflag || xflag)		ssize = 0;	bsize = add(bsize, csize, "bss overflow");	nsym = ssize / (sizeof cursym);}ldrsym(asp, val, type)struct symbol *asp;{	register struct symbol *sp;	if ((sp = asp) == 0)		return;	if (sp->stype != EXTERN+UNDEF || sp->svalue) {		printf("%.8s: ", sp->sname);		error(1, "Multiply defined");		return;	}	sp->stype = type;	sp->svalue = val;}setupout(){	tcreat(&toutb, 0);	mktemp(tfname);	tcreat(&doutb, 1);	if (sflag==0 || xflag==0)		tcreat(&soutb, 1);	if (rflag) {		tcreat(&troutb, 1);		tcreat(&droutb, 1);	}	filhdr.fmagic = (Oflag ? OMAGIC :( iflag ? IMAGIC : ( nflag ? NMAGIC : FMAGIC )));	filhdr.tsize = tsize;	filhdr.dsize = dsize;	filhdr.bsize = bsize;	filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*symindex);	if (entrypt) {		if (entrypt->stype!=EXTERN+TEXT)			error(1, "Entry point not in text");		else			filhdr.entry = entrypt->svalue | 01;	} else		filhdr.entry=0;	filhdr.pad = 0;	filhdr.relflg = (rflag==0);	mput(&toutb, (int *)&filhdr, sizeof filhdr);}tcreat(buf, tempflg)struct buf *buf;{	register int ufd; 	char *nam;	nam = (tempflg ? tfname : ofilename);	if ((ufd = creat(nam, 0666)) < 0)		error(2, tempflg?"cannot create temp":"cannot create output");	close(ufd); 	buf->fildes = open(nam, 2);	if (tempflg)		unlink(tfname);	buf->nleft = sizeof(buf->iobuf)/sizeof(int);	buf->xnext = buf->iobuf;}load2arg(acp)char *acp;{	register char *cp;	register struct liblist *lp;	cp = acp;	if (getfile(cp) == 0) {		while (*cp)			cp++;		while (cp >= acp && *--cp != '/');		mkfsym(++cp);		load2(0L);	} else {	/* scan archive members referenced */		for (lp = libp; lp->loc != -1; lp++) {			dseek(&text, lp->loc, sizeof archdr);			mget((int *)&archdr, sizeof archdr);			mkfsym(archdr.aname);			load2(lp->loc + (sizeof archdr) / 2);		}		libp = ++lp;	}	close(infil);}load2(loc)long loc;{	register struct symbol *sp;	register struct local *lp;	register int symno;	int type, mtype;	readhdr(loc);	ctrel = torigin;	cdrel += dorigin;	cbrel += borigin;	/*	 * Reread the symbol table, recording the numbering	 * of symbols for fixing external references.	 */	lp = local;	symno = -1;	loc += (sizeof filhdr)/2;	dseek(&text, loc + filhdr.tsize + filhdr.dsize, filhdr.ssize);	while (text.size > 0) {		symno++;		mget((int *)&cursym, sizeof cursym);		symreloc();		type = cursym.stype;		if (Sflag) {			mtype = type&037;			if (mtype==1 || mtype>4) continue;		}		if ((type&EXTERN) == 0) {			if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L'))				mput(&soutb, (int *)&cursym, sizeof cursym);			continue;		}		if ((sp = *lookup()) == 0)			error(2, "internal error: symbol not found");		if (cursym.stype == EXTERN+UNDEF) {			if (lp >= &local[NSYMPR])				error(2, "Local symbol overflow");			lp->locindex = symno;			lp++->locsymbol = sp;			continue;		}		if (cursym.stype!=sp->stype || cursym.svalue!=sp->svalue) {			printf("%.8s: ", cursym.sname);			error(1, "Multiply defined");		}	}	dseek(&text, loc, filhdr.tsize);	dseek(&reloc, loc + half(filhdr.tsize + filhdr.dsize), filhdr.tsize);	load2td(lp, ctrel, &toutb, &troutb);	dseek(&text, loc+half(filhdr.tsize), filhdr.dsize);	dseek(&reloc, loc+filhdr.tsize+half(filhdr.dsize), filhdr.dsize);	load2td(lp, cdrel, &doutb, &droutb);	torigin += filhdr.tsize;	dorigin += filhdr.dsize;	borigin += filhdr.bsize;}load2td(lp, creloc, b1, b2)struct local *lp;struct buf *b1, *b2;{	register r, t;	register struct symbol *sp;	for (;;) {		/*			 * The pickup code is copied from "get" for speed.			 */		/* next text or data word */		if (--text.size <= 0) {			if (text.size < 0)				break;			text.size++;			t = get(&text);		} else if (--text.nibuf < 0) {			text.nibuf++;			text.size++;			t = get(&text);		} else			t = *text.ptr++;		/* next relocation word */		if (--reloc.size <= 0) {			if (reloc.size < 0)				error(2, "Relocation error");			reloc.size++;			r = get(&reloc);		} else if (--reloc.nibuf < 0) {			reloc.nibuf++;			reloc.size++;			r = get(&reloc);		} else			r = *reloc.ptr++;		switch (r&016) {		case RTEXT:			t += ctrel;			break;		case RDATA:			t += cdrel;			break;		case RBSS:			t += cbrel;			break;		case REXT:			sp = lookloc(lp, r);			if (sp->stype==EXTERN+UNDEF) {				r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT;				break;			}			t += sp->svalue;			r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1);			break;		}		if (r&01)			t -= creloc;		putw(t, b1);		if (rflag)			putw(r, b2);	}}finishout(){	register n, *p;	if (nflag||iflag) {		n = torigin;		while (n&077) {			n += 2;			putw(0, &toutb);			if (rflag)				putw(0, &troutb);		}	}	copy(&doutb);	if (rflag) {		copy(&troutb);		copy(&droutb);	}	if (sflag==0) {		if (xflag==0)			copy(&soutb);		for (p = (int *)symtab; p < (int *)&symtab[symindex];)			putw(*p++, &toutb);	}	flush(&toutb);	close(toutb.fildes);	if (!ofilfnd) {		unlink("a.out");		link("l.out", "a.out");		ofilename = "a.out";	}	delarg = errlev;	delexit();}copy(buf)struct buf *buf;{	register f, *p, n;	flush(buf);	lseek(f = buf->fildes, (long)0, 0);	while ((n = read(f, (char *)doutb.iobuf, sizeof(doutb.iobuf))) > 1) {		n >>= 1;		p = (int *)doutb.iobuf;		do			putw(*p++, &toutb);		while (--n);	}	close(f);}mkfsym(s)char *s;{	if (sflag || xflag)		return;	cp8c(s, cursym.sname);	cursym.stype = 037;	cursym.svalue = torigin;	mput(&soutb, (int *)&cursym, sizeof cursym);}mget(aloc, an)int *aloc;{	register *loc, n;	register *p;	n = an;	n >>= 1;	loc = aloc;	if ((text.nibuf -= n) >= 0) {		if ((text.size -= n) > 0) {			p = text.ptr;			do				*loc++ = *p++;			while (--n);			text.ptr = p;			return;		} else			text.size += n;	}	text.nibuf += n;	do {		*loc++ = get(&text);	} 	while (--n);}mput(buf, aloc, an)struct buf *buf; int *aloc;{	register *loc;	register n;	loc = aloc;	n = an>>1;	do {		putw(*loc++, buf);	} 	while (--n);}dseek(asp, aloc, s)long aloc;struct stream *asp;{	register struct stream *sp;	register struct page *p;	/* register */ long b, o;	int n;	b = aloc >> 8;	o = aloc & 0377;	sp = asp;	--sp->pno->nuser;	if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)		if (p->nuser==0 || (p = &page[0])->nuser==0) {			if (page[0].nuser==0 && page[1].nuser==0)				if (page[0].bno < page[1].bno)					p = &page[0];			p->bno = b;			lseek(infil, (aloc & ~0377L) << 1, 0);			if ((n = read(infil, (char *)p->buff, 512)>>1) < 0)				n = 0;			p->nibuf = n;	} else		error(2, "No pages");	++p->nuser;	sp->bno = b;	sp->pno = p;	sp->ptr = p->buff + o;	if (s != -1)		sp->size = half(s);	if ((sp->nibuf = p->nibuf-o) <= 0)		sp->size = 0;}half(i){	return((i>>1)&077777);}get(asp)struct stream *asp;{	register struct stream *sp;	sp = asp;	if (--sp->nibuf < 0) {		dseek(sp, (long)(sp->bno + 1) << 8, -1);		--sp->nibuf;	}	if (--sp->size <= 0) {		if (sp->size < 0)			error(2, premeof);		++fpage.nuser;		--sp->pno->nuser;		sp->pno = (struct page *)&fpage;	}	return(*sp->ptr++);}getfile(acp)char *acp;{	register char *cp;	register int c;	struct stat x;	cp = acp; 	infil = -1;	archdr.aname[0] = '\0';	filname = cp;	if (cp[0]=='-' && cp[1]=='l') {		if(cp[2] == '\0')			cp = "-la";		filname = "/usr/lib/libxxxxxxxxxxxxxxx";		for(c=0; cp[c+2]; c++)			filname[c+12] = cp[c+2];		filname[c+12] = '.';		filname[c+13] = 'a';		filname[c+14] = '\0';		if ((infil = open(filname+4, 0)) >= 0) {			filname += 4;		}	}	if (infil == -1 && (infil = open(filname, 0)) < 0)		error(2, "cannot open");	page[0].bno = page[1].bno = -1;	page[0].nuser = page[1].nuser = 0;	text.pno = reloc.pno = (struct page *)&fpage;	fpage.nuser = 2;	dseek(&text, 0L, 2);	if (text.size <= 0)		error(2, premeof);	if(get(&text) != ARCMAGIC)		return(0);	/* regualr file */	dseek(&text, 1L, sizeof archdr);	/* word addressing */	if(text.size <= 0)		return(1);	/* regular archive */	mget((int *)&archdr, sizeof archdr);	if(strncmp(archdr.aname, goodnm, 14) != 0)		return(1);	/* regular archive */	else {		fstat(infil, &x);		if(x.st_mtime > archdr.atime)		{			return(3);		}		else return(2);	}}struct symbol **lookup(){	int i; 	int clash;	register struct symbol **hp;	register char *cp, *cp1;	i = 0;	for (cp = cursym.sname; cp < &cursym.sname[8];)		i = (i<<1) + *cp++;	for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) {		cp1 = (*hp)->sname; 		clash=FALSE;		for (cp = cursym.sname; cp < &cursym.sname[8];)			if (*cp++ != *cp1++) {				clash=TRUE; 				break;			}		if (clash) {			if (++hp >= &hshtab[NSYM+2])				hp = hshtab;		} else			break;	}	return(hp);}struct symbol **slookup(s)char *s;{	cp8c(s, cursym.sname);	cursym.stype = EXTERN+UNDEF;	cursym.svalue = 0;	return(lookup());}enter(hp)struct symbol **hp;{	register struct symbol *sp;	if (*hp==0) {		if (symindex>=NSYM)			error(2, "Symbol table overflow");		symhash[symindex] = hp;		*hp = lastsym = sp = &symtab[symindex++];		cp8c(cursym.sname, sp->sname);		sp->stype = cursym.stype;		sp->svalue = cursym.svalue;		return(1);	} else {		lastsym = *hp;		return(0);	}}symreloc(){	switch (cursym.stype) {	case TEXT:	case EXTERN+TEXT:		cursym.svalue += ctrel;		return;	case DATA:	case EXTERN+DATA:		cursym.svalue += cdrel;		return;	case BSS:	case EXTERN+BSS:		cursym.svalue += cbrel;		return;	case EXTERN+UNDEF:		return;	}	if (cursym.stype&EXTERN)		cursym.stype = EXTERN+ABS;}error(n, s)char *s;{	if (errlev==0)		printf("ld:");	if (filname) {		printf("%s", filname);		if (archdr.aname[0])			printf("(%.14s)", archdr.aname);		printf(": ");	}	printf("%s\n", s);	if (n > 1)		delexit();	errlev = n;}struct symbol *lookloc(alp, r)struct local *alp;{	register struct local *clp, *lp;	register sn;	lp = alp;	sn = (r>>4) & 07777;	for (clp = local; clp<lp; clp++)		if (clp->locindex == sn)			return(clp->locsymbol);	error(2, "Local symbol botch");}readhdr(loc)long loc;{	register st, sd;	dseek(&text, loc, sizeof filhdr);	mget((int *)&filhdr, sizeof filhdr);	if (filhdr.fmagic != FMAGIC)		error(2, "Bad format");	st = (filhdr.tsize+01) & ~01;	filhdr.tsize = st;	cdrel = -st;	sd = (filhdr.dsize+01) & ~01;	cbrel = - (st+sd);	filhdr.bsize = (filhdr.bsize+01) & ~01;}cp8c(from, to)char *from, *to;{	register char *f, *t, *te;	f = from;	t = to;	te = t+8;	while ((*t++ = *f++) && t<te);	while (t<te)		*t++ = 0;}eq(s1, s2)char *s1; char *s2;{	while (*s1==*s2++)		if ((*s1++)==0)			return(TRUE);	return(FALSE);}putw(w, b)register struct buf *b;{	*(b->xnext)++ = w;	if (--b->nleft <= 0)		flush(b);}flush(b)register struct buf *b;{	register n;	if ((n = (char *)b->xnext - (char *)b->iobuf) > 0)		if (write(b->fildes, (char *)b->iobuf, n) != n)			error(2, "output error");	b->xnext = b->iobuf;	b->nleft = sizeof(b->iobuf)/sizeof(int);}

⌨️ 快捷键说明

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