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

📄 ld.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  link editor */#include <signal.h>#include "sys/types.h"#include "sys/stat.h"/*	Layout of a.out file : * *	header of 8 words	magic number 405, 407, 410, 411 *				text size	) *				data size	) in bytes but even *				bss size	) *				symbol table size *				entry point *				{unused} *				flag set if no relocation * * *	header:		0 *	text:		16 *	data:		16+textsize *	relocation:	16+textsize+datasize *	symbol table:	16+2*(textsize+datasize) or 16+textsize+datasize * */#define TRUE	1#define FALSE	0#define	ARCMAGIC 0177545#define OMAGIC	0405#define	FMAGIC	0407#define	NMAGIC	0410#define	IMAGIC	0411#define	EXTERN	040#define	UNDEF	00#define	ABS	01#define	TEXT	02#define	DATA	03#define	BSS	04#define	COMM	05	/* internal use only */#define	RABS	00#define	RTEXT	02#define	RDATA	04#define	RBSS	06#define	REXT	010#define NOVLY	16#define	RELFLG	01#define	NROUT	256#define	NSYM	1103#define	NSYMPR	1000char	premeof[] = "Premature EOF";char	goodnm[] = "__.SYMDEF";/* table of contents stuff */#define TABSZ	700struct tab{	char cname[8];	long cloc;} tab[TABSZ];int tnum;/* overlay management */int	vindex;struct overlay {	int	argsav;	int	symsav;	struct liblist	*libsav;	char	*vname;	int	ctsav, cdsav, cbsav;	int	offt, offd, offb, offs;} vnodes[NOVLY];/* input management */struct page {	int	nuser;	int	bno;	int	nibuf;	int	buff[256];} page[2];struct {	int	nuser;	int	bno;} fpage;struct stream {	int	*ptr;	int	bno;	int	nibuf;	int	size;	struct page	*pno;};struct stream text;struct stream reloc;struct {	char	aname[14];	long	atime;	char	auid, agid;	int	amode;	long	asize;} archdr;struct {	int	fmagic;	int	tsize;	int	dsize;	int	bsize;	int	ssize;	int	entry;	int	pad;	int	relflg;} filhdr;/* one entry for each archive member referenced; * set in first pass; needs restoring for overlays */struct liblist {	long	loc;};struct liblist	liblist[NROUT];struct liblist	*libp = liblist;/* symbol management */struct symbol {	char	sname[8];	char	stype;	char	spare;	int	svalue;};struct local {	int locindex;		/* index to symbol in file */	struct symbol *locsymbol;	/* ptr to symbol table */};struct symbol	cursym;			/* current symbol */struct symbol	symtab[NSYM];		/* actual symbols */struct symbol	**symhash[NSYM];	/* ptr to hash table entry */struct symbol	*lastsym;		/* last symbol entered */int	symindex;		/* next available symbol table entry */struct symbol	*hshtab[NSYM+2];	/* hash table for symbols */struct local	local[NSYMPR];/* internal symbols */struct symbol	*p_etext;struct symbol	*p_edata;struct symbol	*p_end;struct symbol	*entrypt;int	trace;/* flags */int	xflag;		/* discard local symbols */int	Xflag;		/* discard locals starting with 'L' */int	Sflag;		/* discard all except locals and globals*/int	rflag;		/* preserve relocation bits, don't define common */int	arflag;		/* original copy of rflag */int	sflag;		/* discard all symbols */int	nflag;		/* pure procedure */int	Oflag;		/* set magic # to 0405 (overlay) */int	dflag;		/* define common even with rflag */int	iflag;		/* I/D space separated */int	vflag;		/* overlays used */int	ofilfnd;char	*ofilename = "l.out";int	infil;char	*filname;/* cumulative sizes set in pass 1 */int	tsize;int	dsize;int	bsize;int	ssize;/* symbol relocation; both passes */int	ctrel;int	cdrel;int	cbrel;int	errlev;int	delarg	= 4;char	tfname[] = "/tmp/ldaXXXXX";/* output management */struct buf {	int	fildes;	int	nleft;	int	*xnext;	int	iobuf[256];};struct buf	toutb;struct buf	doutb;struct buf	troutb;struct buf	droutb;struct buf	soutb;struct symbol	**lookup();struct symbol	**slookup();struct symbol	*lookloc();delexit(){	unlink("l.out");	if (delarg==0)		chmod(ofilename, 0777 & ~umask(0));	exit(delarg);}main(argc, argv)char **argv;{	register int c, i; 	int num;	register char *ap, **p;	int found; 	int vscan; 	char save;	if (signal(SIGINT, SIG_IGN) != SIG_IGN)		signal(SIGINT, delexit);	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)		signal(SIGTERM, delexit);	if (argc == 1)		exit(4);	p = argv+1;	/* scan files once to find symdefs */	for (c=1; c<argc; c++) {		if (trace) printf("%s:\n", *p);		filname = 0;		ap = *p++;		if (*ap == '-') {			for (i=1; ap[i]; i++) {			switch (ap[i]) {			case 'o':				if (++c >= argc)					error(2, "Bad output file");				ofilename = *p++;				ofilfnd++;				continue;			case 'u':			case 'e':				if (++c >= argc)					error(2, "Bad 'use' or 'entry'");				enter(slookup(*p++));				if (ap[i]=='e')					entrypt = lastsym;				continue;			case 'v':				if (++c >= argc)					error(2, "-v: arg missing");				vflag=TRUE;				vscan = vindex; 				found=FALSE;				while (--vscan>=0 && found==FALSE)					found = eq(vnodes[vscan].vname, *p);				if (found) {					endload(c, argv);					restore(vscan);				} else					record(c, *p);				p++;				continue;			case 'D':				if (++c >= argc)					error(2, "-D: arg missing");				num = atoi(*p++);				if (dsize>num)					error(2, "-D: too small");				dsize = num;				continue;			case 'l':				save = ap[--i]; 				ap[i]='-';				load1arg(&ap[i]); 				ap[i]=save;				break;			case 'x':				xflag++;				continue;			case 'X':				Xflag++;				continue;			case 'S':				Sflag++; 				continue;			case 'r':				rflag++;				arflag++;				continue;			case 's':				sflag++;				xflag++;				continue;			case 'n':				nflag++;				continue;			case 'd':				dflag++;				continue;			case 'i':				iflag++;				continue;			case 'O':				Oflag++;				continue;			case 't':				trace++;				continue;			default:				error(2, "bad flag");			} /*endsw*/			break;			} /*endfor*/		} else			load1arg(ap);	}	endload(argc, argv);}/* used after pass 1 */int	nsym;int	torigin;int	dorigin;int	borigin;endload(argc, argv)int argc; char **argv;{	register int c, i; 	int dnum;	register char *ap, **p;	filname = 0;	middle();	setupout();	p = argv+1;	libp = liblist;	for (c=1; c<argc; c++) {		ap = *p++;		if (trace) printf("%s:\n", ap);		if (*ap == '-') {			for (i=1; ap[i]; i++) {			switch (ap[i]) {			case 'D':				for (dnum = atoi(*p); dorigin<dnum; dorigin += 2) {					putw(0, &doutb);					if (rflag)						putw(0, &droutb);				}			case 'u':			case 'e':			case 'o':			case 'v':				++c; 				++p;			default:				continue;			case 'l':				ap[--i]='-'; 				load2arg(&ap[i]);				break;			} /*endsw*/			break;			} /*endfor*/		} else			load2arg(ap);	}	finishout();}record(c, nam)int c; char *nam;{	register struct overlay *v;	v = &vnodes[vindex++];	v->argsav = c;	v->symsav = symindex;	v->libsav = libp;	v->vname = nam;	v->offt = tsize; 	v->offd = dsize; 	v->offb = bsize; 	v->offs = ssize;	v->ctsav = ctrel; 	v->cdsav = cdrel; 	v->cbsav = cbrel;}restore(vscan)int vscan;{	register struct overlay *v;	register int saved;	v = &vnodes[vscan];	vindex = vscan+1;	libp = v->libsav;	ctrel = v->ctsav; 	cdrel = v->cdsav; 	cbrel = v->cbsav;	tsize = v->offt; 	dsize = v->offd; 	bsize = v->offb; 	ssize = v->offs;	saved = v->symsav;	while (symindex>saved)		*symhash[--symindex]=0;}/* scan file to find defined symbols */load1arg(acp)char *acp;{	register char *cp;	long nloc;	cp = acp;	switch ( getfile(cp)) {	case 0:		load1(0, 0L);		break;	/* regular archive */	case 1:		nloc = 1;		while ( step(nloc))			nloc += (archdr.asize + sizeof(archdr) + 1) >> 1;		break;	/* table of contents */	case 2:		tnum = archdr.asize / sizeof(struct tab);		if (tnum >= TABSZ) {			error(2, "fast load buffer too small");		}		lseek(infil, (long)(sizeof(filhdr.fmagic)+sizeof(archdr)), 0);		read(infil, (char *)tab, tnum * sizeof(struct tab));		while (ldrand());		libp->loc = -1;		libp++;		break;	/* out of date table of contents */	case 3:		error(0, "out of date (warning)");		for(nloc = 1+((archdr.asize+sizeof(archdr)+1) >> 1); step(nloc);			nloc += (archdr.asize + sizeof(archdr) + 1) >> 1);		break;	}	close(infil);}step(nloc)long nloc;{	dseek(&text, nloc, sizeof archdr);	if (text.size <= 0) {		libp->loc = -1;		libp++;		return(0);	}	mget((int *)&archdr, sizeof archdr);	if (load1(1, nloc + (sizeof archdr) / 2)) {		libp->loc = nloc;		libp++;	}	return(1);}ldrand(){	int i;	struct symbol *sp, **pp;	struct liblist *oldp = libp;	for(i = 0; i<tnum; i++) {		if ((pp = slookup(tab[i].cname)) == 0)			continue;		sp = *pp;		if (sp->stype != EXTERN+UNDEF)			continue;		step(tab[i].cloc >> 1);	}	return(oldp != libp);}add(a,b,s)int a, b;char *s;{	long r;	r = (long)(unsigned)a + (unsigned)b;	if (r >= 0200000)		error(1,s);	return(r);}/* single file or archive member */load1(libflg, loc)long loc;{	register struct symbol *sp;	int savindex;	int ndef, nloc, type, mtype;	readhdr(loc);	ctrel = tsize;	cdrel += dsize;	cbrel += bsize;	ndef = 0;	nloc = sizeof cursym;	savindex = symindex;	if ((filhdr.relflg&RELFLG)==1) {		error(1, "No relocation bits");		return(0);	}	loc += (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize;	dseek(&text, loc, filhdr.ssize);	while (text.size > 0) {		mget((int *)&cursym, sizeof cursym);		type = cursym.stype;		if (Sflag) {			mtype = type&037;			if (mtype==1 || mtype>4) {				continue;			}		}		if ((type&EXTERN)==0) {			if (Xflag==0 || cursym.sname[0]!='L')				nloc += sizeof cursym;			continue;		}		symreloc();		if (enter(lookup()))			continue;		if ((sp = lastsym)->stype != EXTERN+UNDEF)			continue;		if (cursym.stype == EXTERN+UNDEF) {			if (cursym.svalue > sp->svalue)				sp->svalue = cursym.svalue;			continue;		}		if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT)			continue;		ndef++;		sp->stype = cursym.stype;		sp->svalue = cursym.svalue;	}	if (libflg==0 || ndef) {		tsize = add(tsize,filhdr.tsize,"text overflow");		dsize = add(dsize,filhdr.dsize,"data overflow");		bsize = add(bsize,filhdr.bsize,"bss overflow");		ssize = add(ssize,nloc,"symbol table overflow");		return(1);	}	/*	 * No symbols defined by this library member.	 * Rip out the hash table entries and reset the symbol table.	 */	while (symindex>savindex)		*symhash[--symindex]=0;	return(0);}middle(){	register struct symbol *sp, *symp;	register t, csize;	int nund, corigin;	torigin=0; 	dorigin=0; 	borigin=0;	p_etext = *slookup("_etext");	p_edata = *slookup("_edata");	p_end = *slookup("_end");	/*	 * If there are any undefined symbols, save the relocation bits.	 */	symp = &symtab[symindex];	if (rflag==0) {		for (sp = symtab; sp<symp; sp++)			if (sp->stype==EXTERN+UNDEF && sp->svalue==0				&& sp!=p_end && sp!=p_edata && sp!=p_etext) {				rflag++;				dflag = 0;				break;			}	}	if (rflag)		nflag = sflag = iflag = Oflag = 0;	/*	 * Assign common locations.	 */	csize = 0;	if (dflag || rflag==0) {		ldrsym(p_etext, tsize, EXTERN+TEXT);		ldrsym(p_edata, dsize, EXTERN+DATA);		ldrsym(p_end, bsize, EXTERN+BSS);		for (sp = symtab; sp<symp; sp++)			if (sp->stype==EXTERN+UNDEF && (t = sp->svalue)!=0) {				t = (t+1) & ~01;				sp->svalue = csize;				sp->stype = EXTERN+COMM;				csize = add(csize, t, "bss overflow");			}	}	/*	 * Now set symbols to their final value	 */	if (nflag || iflag)		tsize = (tsize + 077) & ~077;	dorigin = tsize;	if (nflag)

⌨️ 快捷键说明

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