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

📄 ld.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		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++;			Nflag = zflag = 0;			continue;		case 'N':			Nflag++;			nflag = zflag = 0;			continue;		case 'd':			dflag++;			continue;		case 'i':			printf("ld: -i ignored\n");			continue;		case 't':			trace++;			continue;		case 'y':			if (ap[i+1] == 0)				error(1, "-y: symbol name missing");			if (yflag == 0) {				ytab = (char **)calloc(argc, sizeof (char **));				if (ytab == 0)					error(1, "ran out of memory (-y)");			}			ytab[yflag++] = &ap[i+1];			goto next;		case 'z':			zflag++;			Nflag = nflag = 0;			continue;		case 'Y':			if (ap[++i] == '\0')				ex_mode = sys_v; /* For pre-V2.4 compatibility */			else if (strcmp("SYSTEM_FIVE", &ap[i]) == 0)				ex_mode = sys_v;			else if (strcmp("POSIX", &ap[i]) == 0)				ex_mode = posix;			else if (strcmp("BSD", &ap[i]) == 0)				ex_mode = bsd;			else				error(-1, "warning: bad -Y argument");			goto next;		case 'L':			goto next;		default:			filname = savestr("-x");	/* kludge */			filname[1] = ap[i];		/* kludge */			archdr.ar_name[0] = 0;		/* kludge */			error(1, "bad flag");		}next:		;	}	if (rflag == 0 && Nflag == 0 && nflag == 0)		zflag++;	endload(argc, argv);	exit(0);}/* * Convert a ascii string which is a hex number. * Used by -T and -D options. */htoi(p)	register char *p;{	register int c, n;	n = 0;	while (c = *p++) {		n <<= 4;		if (isdigit(c))			n += c - '0';		else if (c >= 'a' && c <= 'f')			n += 10 + (c - 'a');		else if (c >= 'A' && c <= 'F')			n += 10 + (c - 'A');		else			error(1, "badly formed hex number");	}	return (n);}voiddelexit(){	struct stat stbuf;	long size;	char c = 0;	bflush();	unlink("l.out");	/*	 * We have to insure that the last block of the data segment	 * is allocated a full pagesize block. If the underlying	 * file system allocates frags that are smaller than pagesize,	 * a full zero filled pagesize block needs to be allocated so 	 * that when it is demand paged, the paged in block will be 	 * appropriately filled with zeros.	 */	fstat(biofd, &stbuf);	size = round(stbuf.st_size, pagesize);	if (!rflag && size > stbuf.st_size) {		lseek(biofd, size - 1, 0);		if (write(biofd, &c, 1) != 1)			delarg |= 4;	}	if (delarg==0 && (arflag==0 || dflag) && Aflag==0)	/*009*/		(void) chmod(ofilename, ofilemode);	exit (delarg);}endload(argc, argv)	int argc; 	char **argv;{	register int c, i; 	long dnum;	register char *ap, **p;	clibseg = libseg;	filname = 0;	middle();	setupout();	p = argv+1;	for (c=1; c<argc; c++) {		ap = *p++;		if (trace)			printf("%s:\n", ap);		if (*ap != '-') {			load2arg(ap);			continue;		}		for (i=1; ap[i]; i++) switch (ap[i]) {		case 'D':			dnum = htoi(*p);			if (dorigin < dnum)				while (dorigin < dnum)					bputc(0, dout), dorigin++;			/* fall into ... */		case 'T':		case 'u':		case 'e':		case 'o':		case 'H':			++c; 			++p;			/* fall into ... */		default:			continue;		case 'A':			funding = 1;			load2arg(*p++);			funding = 0;			c++;			continue;		case 'Y':		case 'y':		case 'L':			goto next;		case 'l':			ap[--i]='-'; 			load2arg(&ap[i]);			goto next;		}next:		;	}	finishout();}/* * Scan file to find defined symbols. */load1arg(cp)	register char *cp;{	register struct ranlib *tp;	off_t nloc;	int kind;	kind = getfile(cp);	if (Mflag)		printf("%s\n", filname);	switch (kind) {	/*	 * Plain file.	 */	case 0:		load1(0, 0L);		break;	/*	 * Archive without table of contents.	 * (Slowly) process each member.	 */	case 1:		error(-1,"warning: archive has no table of contents; add one using ranlib(1)");		nloc = SARMAG;		while (step(nloc))			nloc += sizeof(archdr) +			    round(atol(archdr.ar_size), sizeof (short));		break;	/*	 * Archive with table of contents.	 * Read the table of contents and its associated string table.	 * Pass through the library resolving symbols until nothing changes	 * for an entire pass (i.e. you can get away with backward references	 * when there is a table of contents!)	 */	case 2:		nloc = SARMAG + sizeof (archdr);		dseek(&text, nloc, sizeof (tnum));		mget((char *)&tnum, sizeof (tnum), &text);		nloc += sizeof (tnum);		tab = (struct ranlib *)malloc(tnum);		if (tab == 0)			error(1, "ran out of memory (toc)");		dseek(&text, nloc, tnum);		mget((char *)tab, tnum, &text);		nloc += tnum;		tnum /= sizeof (struct ranlib);		dseek(&text, nloc, sizeof (ssiz));		mget((char *)&ssiz, sizeof (ssiz), &text);		nloc += sizeof (ssiz);		tabstr = (char *)malloc(ssiz);		if (tabstr == 0)			error(1, "ran out of memory (tocstr)");		dseek(&text, nloc, ssiz);		mget((char *)tabstr, ssiz, &text);		for (tp = &tab[tnum]; --tp >= tab;) {			if (tp->ran_un.ran_strx < 0 ||			    tp->ran_un.ran_strx >= ssiz)				error(1, "mangled archive table of contents");			tp->ran_un.ran_name = tabstr + tp->ran_un.ran_strx;		}		while (ldrand())			continue;		free((char *)tab);		free(tabstr);		nextlibp(-1);		break;	/*	 * Table of contents is out of date, so search	 * as a normal library (but skip the __.SYMDEF file).	 */	case 3:		error(-1,"warning: table of contents for archive is out of date; rerun ranlib(1)");		nloc = SARMAG;		do			nloc += sizeof(archdr) +			    round(atol(archdr.ar_size), sizeof(short));		while (step(nloc));		break;	}	close(infil);}/* * Advance to the next archive member, which * is at offset nloc in the archive.  If the member * is useful, record its location in the liblist structure * for use in pass2.  Mark the end of the archive in libilst with a -1. */step(nloc)	off_t nloc;{	dseek(&text, nloc, (long) sizeof archdr);	if (text.size <= 0) {		nextlibp(-1);		return (0);	}	getarhdr();	if (load1(1, nloc + (sizeof archdr)))		nextlibp(nloc);	return (1);}/* * Record the location of a useful archive member. * Recording -1 marks the end of files from an archive. * The liblist data structure is dynamically extended here. */nextlibp(val)	off_t val;{	if (clibseg->li_used == NROUT) {		if (++clibseg == &libseg[NSEG])			error(1, "too many files loaded from libraries");		clibseg->li_first = (off_t *)malloc(NROUT * sizeof (off_t));		if (clibseg->li_first == 0)			error(1, "ran out of memory (nextlibp)");	}	clibseg->li_first[clibseg->li_used++] = val;	if (val != -1 && Mflag)		printf("\t%s\n", archdr.ar_name);}/* * One pass over an archive with a table of contents. * Remember the number of symbols currently defined, * then call step on members which look promising (i.e. * that define a symbol which is currently externally undefined). * Indicate to our caller whether this process netted any more symbols. */ldrand(){	register struct nlist *sp, **hp;	register struct ranlib *tp, *tplast;	off_t loc;	int nsymt = symx(nextsym);	tplast = &tab[tnum-1];	for (tp = tab; tp <= tplast; tp++) {		if ((hp = slookup(tp->ran_un.ran_name)) == 0 || *hp == 0)			continue;		sp = *hp;		if (sp->n_type != N_EXT+N_UNDF)			continue;		step(tp->ran_off);		loc = tp->ran_off;		while (tp < tplast && (tp+1)->ran_off == loc)			tp++;	}	return (symx(nextsym) != nsymt);}/* * Examine a single file or archive member on pass 1. */load1(libflg, loc)	off_t loc;{	register struct nlist *sp;	struct nlist *savnext;	int ndef, nlocal, type, size, nsymt;	register int i;	off_t maxoff;	struct stat stb;	readhdr(loc);	if (filhdr.a_syms == 0) {		if (filhdr.a_text+filhdr.a_data == 0) {/*	Even though there's nothing here, we still mkfsym the name.  011 */			if (libflg == 0) /* 011 */				ssize += sizeof cursym; /* 011 */			return (0);		}		error(1, "no namelist");	}	if (libflg)		maxoff = atol(archdr.ar_size);	else {		fstat(infil, &stb);		maxoff = stb.st_size;	}	if (N_STROFF(filhdr) + sizeof (off_t) >= maxoff)		error(1, "too small (old format .o?)");	ctrel = tsize; cdrel += dsize; cbrel += bsize;	ndef = 0;	nlocal = sizeof cursym;	savnext = nextsym;	loc += N_SYMOFF(filhdr);	dseek(&text, loc, filhdr.a_syms);	dseek(&reloc, loc + filhdr.a_syms, sizeof(off_t));	mget(&size, sizeof (size), &reloc);	dseek(&reloc, loc + filhdr.a_syms+sizeof (off_t), size-sizeof (off_t));	curstr = (char *)malloc(size);	if (curstr == NULL)		error(1, "no space for string table");	mget(curstr+sizeof(off_t), size-sizeof(off_t), &reloc);	while (text.size > 0) {		mget((char *)&cursym, sizeof(struct nlist), &text);		if (cursym.n_un.n_strx) {			if (cursym.n_un.n_strx<sizeof(size) ||			    cursym.n_un.n_strx>=size)				error(1, "bad string table index (pass 1)");			cursym.n_un.n_name = curstr + cursym.n_un.n_strx;		}		type = cursym.n_type;		/* Count the number of source lines and source files		 * found in the symbol table.  This information is used by		 * dbx.  Unnamed blocks are counted as functions, but		 * real procedures are counted from the loader namelist		 * (N_TEXT+N_EXT, and N_TEXT symbols).		 */		if (type & N_STAB) {		    switch (type) {		        case N_LBRAC:			case N_RBRAC:	/* unnamed blocks go in the functab */			    nfun++;			    break;		        case N_SLINE:	/* source lines */			    nsline++;			    break;			case N_SO:	/* source files with stab info */			case N_SOL:	/* textual include files */			    nsol++;			    break;			default:			    break;		    }		}		if ((type&N_EXT)==0) {			if (Xflag==0 || type & N_STAB ||				cursym.n_un.n_name[0]!='L'  )	/* SLR001 */				nlocal += sizeof cursym;			if (type == N_TEXT) nfun++;	/* vjh007 */			continue;		}		symreloc();		if (enter(lookup()))			continue;		if ((sp = lastsym)->n_type != N_EXT+N_UNDF)			continue;		if (cursym.n_type == N_EXT+N_UNDF) {			if (cursym.n_value > sp->n_value)				sp->n_value = cursym.n_value;			continue;		}		if (sp->n_value != 0 && cursym.n_type == N_EXT+N_TEXT)			continue;		ndef++;		sp->n_type = cursym.n_type;		sp->n_value = cursym.n_value;	}	if (libflg==0 || ndef) {		tsize += filhdr.a_text;		dsize += round(filhdr.a_data, sizeof (long));		bsize += round(filhdr.a_bss, sizeof (long));		ssize += nlocal;		trsize += filhdr.a_trsize;		drsize += filhdr.a_drsize;		if (funding)			textbase = (*slookup("_end"))->n_value;		nsymt = symx(nextsym);		for (i = symx(savnext); i < nsymt; i++) {			sp = xsym(i);			sp->n_un.n_name = savestr(sp->n_un.n_name);		}		free(curstr);		return (1);	}	/*	 * No symbols defined by this library member.	 * Rip out the hash table entries and reset the symbol table.	 */	symfree(savnext);	free(curstr);	return(0);}middle(){	register struct nlist *sp;	long csize, t, corigin, ocsize;	int nund, rnd;	char s;	register int i;	int nsymt;	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.	 */	nsymt = symx(nextsym);	if (rflag==0) {		for (i = 0; i < nsymt; i++) {			sp = xsym(i);			if (sp->n_type==N_EXT+N_UNDF && sp->n_value==0 &&			    sp!=p_end && sp!=p_edata && sp!=p_etext) {				rflag++;				dflag = 0;				break;			}		}	}	if (rflag) 		sflag = zflag = 0;	/*	 * Assign common locations.	 */	csize = 0;	if (!Aflag)		addsym = symseg[0].sy_first;	tsize += hsize ;	/* Increase by size given with -H option */	database = round(tsize+textbase,	    (nflag||zflag? pagesize : sizeof (long)));	/*	 * If requested, start BSS on a 512 byte hardware page boundary	 * (the 'pagesize' used in the rest of ld is the software page size).	 * This code causes the data size to be padded out to a 512 byte	 * interval.  BSS is started directly after data, and may still be	 * included in data (not bss) since data (later in ld) is rounded	 * up to a 'pagesize' boundary.	 */	if (Bflag)		dsize = round(dsize, 512);	if (dflag || rflag==0) {		ldrsym(p_etext, tsize, N_EXT+N_TEXT);		ldrsym(p_edata, dsize, N_EXT+N_DATA);		ldrsym(p_end, bsize, N_EXT+N_BSS);		for (i = symx(addsym); i < nsymt; i++) {			sp = xsym(i);			if ((s=sp->n_type)==N_EXT+N_UNDF &&			    (t = sp->n_value)!=0) {				if (t >= sizeof (double))					rnd = sizeof (double);				else if (t >= sizeof (long))					rnd = sizeof (long);				else					rnd = sizeof (short);				csize = round(csize, rnd);				sp->n_value = csize;				sp->n_type = N_EXT+N_COMM;				ocsize = csize;					csize += t;			}			if (s&N_EXT && (s&N_TYPE)==N_UNDF && s&N_STAB) {				sp->n_value = ocsize;				sp->n_type = (s&N_STAB) | (N_EXT+N_COMM);			}		}	}	/*	 * Now set symbols to their final value	 */	csize = round(csize, sizeof (long));	torigin = textbase;	dorigin = database;	corigin = dorigin + dsize;	borigin = corigin + csize;	nund = 0;	nsymt = symx(nextsym);	for (i = symx(addsym); i<nsymt; i++) {

⌨️ 快捷键说明

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