xref: /original-bsd/old/ld/ld.c (revision 4b9b56dc)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)ld.c	5.13 (Berkeley) 03/11/90";
15 #endif not lint
16 
17 /*
18  * ld - string table version for VAX
19  */
20 
21 #include <sys/param.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <ar.h>
26 #include <a.out.h>
27 #include <ranlib.h>
28 #include <sys/stat.h>
29 #include <sys/file.h>
30 #include "pathnames.h"
31 
32 /*
33  * Basic strategy:
34  *
35  * The loader takes a number of files and libraries as arguments.
36  * A first pass examines each file in turn.  Normal files are
37  * unconditionally loaded, and the (external) symbols they define and require
38  * are noted in the symbol table.   Libraries are searched, and the
39  * library members which define needed symbols are remembered
40  * in a special data structure so they can be selected on the second
41  * pass.  Symbols defined and required by library members are also
42  * recorded.
43  *
44  * After the first pass, the loader knows the size of the basic text
45  * data, and bss segments from the sum of the sizes of the modules which
46  * were required.  It has computed, for each ``common'' symbol, the
47  * maximum size of any reference to it, and these symbols are then assigned
48  * storage locations after their sizes are appropriately rounded.
49  * The loader now knows all sizes for the eventual output file, and
50  * can determine the final locations of external symbols before it
51  * begins a second pass.
52  *
53  * On the second pass each normal file and required library member
54  * is processed again.  The symbol table for each such file is
55  * reread and relevant parts of it are placed in the output.  The offsets
56  * in the local symbol table for externally defined symbols are recorded
57  * since relocation information refers to symbols in this way.
58  * Armed with all necessary information, the text and data segments
59  * are relocated and the result is placed in the output file, which
60  * is pasted together, ``in place'', by writing to it in several
61  * different places concurrently.
62  */
63 
64 /*
65  * Internal data structures
66  *
67  * All internal data structures are segmented and dynamically extended.
68  * The basic structures hold 1103 (NSYM) symbols, ~~200 (NROUT)
69  * referenced library members, and 100 (NSYMPR) private (local) symbols
70  * per object module.  For large programs and/or modules, these structures
71  * expand to be up to 40 (NSEG) times as large as this as necessary.
72  */
73 #define	NSEG	40		/* Number of segments, each data structure */
74 #define	NSYM	1103		/* Number of symbols per segment */
75 #define	NROUT	250		/* Number of library references per segment */
76 #define	NSYMPR	100		/* Number of private symbols per segment */
77 
78 /*
79  * Structure describing each symbol table segment.
80  * Each segment has its own hash table.  We record the first
81  * address in and first address beyond both the symbol and hash
82  * tables, for use in the routine symx and the lookup routine respectively.
83  * The symfree routine also understands this structure well as it used
84  * to back out symbols from modules we decide that we don't need in pass 1.
85  *
86  * Csymseg points to the current symbol table segment;
87  * csymseg->sy_first[csymseg->sy_used] is the next symbol slot to be allocated,
88  * (unless csymseg->sy_used == NSYM in which case we will allocate another
89  * symbol table segment first.)
90  */
91 struct	symseg {
92 	struct	nlist *sy_first;	/* base of this alloc'ed segment */
93 	struct	nlist *sy_last;		/* end of this segment, for n_strx */
94 	int	sy_used;		/* symbols used in this seg */
95 	struct	nlist **sy_hfirst;	/* base of hash table, this seg */
96 	struct	nlist **sy_hlast;	/* end of hash table, this seg */
97 } symseg[NSEG], *csymseg;
98 
99 /*
100  * The lookup routine uses quadratic rehash.  Since a quadratic rehash
101  * only probes 1/2 of the buckets in the table, and since the hash
102  * table is segmented the same way the symbol table is, we make the
103  * hash table have twice as many buckets as there are symbol table slots
104  * in the segment.  This guarantees that the quadratic rehash will never
105  * fail to find an empty bucket if the segment is not full and the
106  * symbol is not there.
107  */
108 #define	HSIZE	(NSYM*2)
109 
110 /*
111  * Xsym converts symbol table indices (ala x) into symbol table pointers.
112  * Symx (harder, but never used in loops) inverts pointers into the symbol
113  * table into indices using the symseg[] structure.
114  */
115 #define	xsym(x)	(symseg[(x)/NSYM].sy_first+((x)%NSYM))
116 /* symx() is a function, defined below */
117 
118 struct	nlist cursym;		/* current symbol */
119 struct	nlist *lastsym;		/* last symbol entered */
120 struct	nlist *nextsym;		/* next available symbol table entry */
121 struct	nlist *addsym;		/* first sym defined during incr load */
122 int	nsym;			/* pass2: number of local symbols in a.out */
123 /* nsym + symx(nextsym) is the symbol table size during pass2 */
124 
125 struct	nlist **lookup(), **slookup();
126 struct	nlist *p_etext, *p_edata, *p_end, *entrypt;
127 
128 /*
129  * Definitions of segmentation for library member table.
130  * For each library we encounter on pass 1 we record pointers to all
131  * members which we will load on pass 2.  These are recorded as offsets
132  * into the archive in the library member table.  Libraries are
133  * separated in the table by the special offset value -1.
134  */
135 off_t	li_init[NROUT];
136 struct	libseg {
137 	off_t	*li_first;
138 	int	li_used;
139 	int	li_used2;
140 } libseg[NSEG] = {
141 	li_init, 0, 0,
142 }, *clibseg = libseg;
143 
144 /*
145  * In processing each module on pass 2 we must relocate references
146  * relative to external symbols.  These references are recorded
147  * in the relocation information as relative to local symbol numbers
148  * assigned to the external symbols when the module was created.
149  * Thus before relocating the module in pass 2 we create a table
150  * which maps these internal numbers to symbol table entries.
151  * A hash table is constructed, based on the local symbol table indices,
152  * for quick lookup of these symbols.
153  */
154 #define	LHSIZ	31
155 struct	local {
156 	int	l_index;		/* index to symbol in file */
157 	struct	nlist *l_symbol;	/* ptr to symbol table */
158 	struct	local *l_link;		/* hash link */
159 } *lochash[LHSIZ], lhinit[NSYMPR];
160 struct	locseg {
161 	struct	local *lo_first;
162 	int	lo_used;
163 } locseg[NSEG] = {
164 	lhinit, 0
165 }, *clocseg;
166 
167 /*
168  * Libraries are typically built with a table of contents,
169  * which is the first member of a library with special file
170  * name __.SYMDEF and contains a list of symbol names
171  * and with each symbol the offset of the library member which defines
172  * it.  The loader uses this table to quickly tell which library members
173  * are (potentially) useful.  The alternative, examining the symbol
174  * table of each library member, is painfully slow for large archives.
175  *
176  * See <ranlib.h> for the definition of the ranlib structure and an
177  * explanation of the __.SYMDEF file format.
178  */
179 int	tnum;		/* number of symbols in table of contents */
180 int	ssiz;		/* size of string table for table of contents */
181 struct	ranlib *tab;	/* the table of contents (dynamically allocated) */
182 char	*tabstr;	/* string table for table of contents */
183 
184 /*
185  * We open each input file or library only once, but in pass2 we
186  * (historically) read from such a file at 2 different places at the
187  * same time.  These structures are remnants from those days,
188  * and now serve only to catch ``Premature EOF''.
189  * In order to make I/O more efficient, we provide routines which
190  * use the optimal block size returned by stat().
191  */
192 #define BLKSIZE 1024
193 typedef struct {
194 	short	*fakeptr;
195 	int	bno;
196 	int	nibuf;
197 	int	nuser;
198 	char	*buff;
199 	int	bufsize;
200 } PAGE;
201 
202 PAGE	page[2];
203 int	p_blksize;
204 int	p_blkshift;
205 int	p_blkmask;
206 
207 struct {
208 	short	*fakeptr;
209 	int	bno;
210 	int	nibuf;
211 	int	nuser;
212 } fpage;
213 
214 typedef struct {
215 	char	*ptr;
216 	int	bno;
217 	int	nibuf;
218 	long	size;
219 	long	pos;
220 	PAGE	*pno;
221 } STREAM;
222 
223 STREAM	text;
224 STREAM	reloc;
225 
226 /*
227  * Header from the a.out and the archive it is from (if any).
228  */
229 struct	exec filhdr;
230 struct	ar_hdr archdr;
231 #define	OARMAG 0177545
232 
233 /*
234  * Options.
235  */
236 int	trace;
237 int	xflag;		/* discard local symbols */
238 int	Xflag;		/* discard locals starting with 'L' */
239 int	Sflag;		/* discard all except locals and globals*/
240 int	rflag;		/* preserve relocation bits, don't define common */
241 int	arflag;		/* original copy of rflag */
242 int	sflag;		/* discard all symbols */
243 int	Mflag;		/* print rudimentary load map */
244 int	nflag;		/* pure procedure */
245 int	dflag;		/* define common even with rflag */
246 int	zflag;		/* demand paged  */
247 long	hsize;		/* size of hole at beginning of data to be squashed */
248 int	Aflag;		/* doing incremental load */
249 int	Nflag;		/* want impure a.out */
250 int	funding;	/* reading fundamental file for incremental load */
251 int	yflag;		/* number of symbols to be traced */
252 char	**ytab;		/* the symbols */
253 
254 /*
255  * These are the cumulative sizes, set in pass 1, which
256  * appear in the a.out header when the loader is finished.
257  */
258 off_t	tsize, dsize, bsize, trsize, drsize, ssize;
259 
260 /*
261  * Symbol relocation: c?rel is a scale factor which is
262  * added to an old relocation to convert it to new units;
263  * i.e. it is the difference between segment origins.
264  * (Thus if we are loading from a data segment which began at location
265  * 4 in a .o file into an a.out where it will be loaded starting at
266  * 1024, cdrel will be 1020.)
267  */
268 long	ctrel, cdrel, cbrel;
269 
270 /*
271  * Textbase is the start address of all text, 0 unless given by -T.
272  * Database is the base of all data, computed before and used during pass2.
273  */
274 long	textbase, database;
275 
276 /*
277  * The base addresses for the loaded text, data and bss from the
278  * current module during pass2 are given by torigin, dorigin and borigin.
279  */
280 long	torigin, dorigin, borigin;
281 
282 /*
283  * Errlev is nonzero when errors have occured.
284  * Delarg is an implicit argument to the routine delexit
285  * which is called on error.  We do ``delarg = errlev'' before normal
286  * exits, and only if delarg is 0 (i.e. errlev was 0) do we make the
287  * result file executable.
288  */
289 int	errlev;
290 int	delarg	= 4;
291 
292 /*
293  * The biobuf structure and associated routines are used to write
294  * into one file at several places concurrently.  Calling bopen
295  * with a biobuf structure sets it up to write ``biofd'' starting
296  * at the specified offset.  You can then use ``bwrite'' and/or ``bputc''
297  * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
298  * Calling bflush drains all the buffers and MUST be done before exit.
299  */
300 struct	biobuf {
301 	short	b_nleft;		/* Number free spaces left in b_buf */
302 /* Initialize to be less than b_bufsize initially, to boundary align in file */
303 	char	*b_ptr;			/* Next place to stuff characters */
304 	char	*b_buf;			/* Pointer to the buffer */
305 	int	b_bufsize;		/* Size of the buffer */
306 	off_t	b_off;			/* Current file offset */
307 	struct	biobuf *b_link;		/* Link in chain for bflush() */
308 } *biobufs;
309 #define	bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
310 		       : bflushc(b, c))
311 int	biofd;
312 off_t	boffset;
313 struct	biobuf *tout, *dout, *trout, *drout, *sout, *strout;
314 
315 /*
316  * Offset is the current offset in the string file.
317  * Its initial value reflects the fact that we will
318  * eventually stuff the size of the string table at the
319  * beginning of the string table (i.e. offset itself!).
320  */
321 off_t	offset = sizeof (off_t);
322 
323 int	ofilfnd;		/* -o given; otherwise move l.out to a.out */
324 char	*defaultname;		/* l.out */
325 char	*ofilename;		/* name given to -o */
326 int	ofilemode;		/* respect umask even for unsucessful ld's */
327 int	infil;			/* current input file descriptor */
328 char	*filname;		/* and its name */
329 
330 #define	NDIRS	25
331 #define NDEFDIRS 3		/* number of default directories in dirs[] */
332 char	*dirs[NDIRS];		/* directories for library search */
333 int	ndir;			/* number of directories */
334 
335 /*
336  * Base of the string table of the current module (pass1 and pass2).
337  */
338 char	*curstr;
339 
340 /*
341  * System software page size, as returned by getpagesize.
342  */
343 int	pagesize;
344 
345 char 	get();
346 int	delexit();
347 char	*savestr();
348 char	*malloc();
349 
350 main(argc, argv)
351 char **argv;
352 {
353 	register int c, i;
354 	int num;
355 	register char *ap, **p;
356 	char save;
357 
358 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
359 		signal(SIGINT, delexit);
360 		signal(SIGTERM, delexit);
361 	}
362 	if (argc == 1)
363 		exit(4);
364 	ofilename = defaultname = (char *)genbuildname("l.out");
365 	pagesize = getpagesize();
366 
367 	/*
368 	 * Pull out search directories.
369 	 */
370 	for (c = 1; c < argc; c++) {
371 		ap = argv[c];
372 		if (ap[0] == '-' && ap[1] == 'L') {
373 			if (ap[2] == 0)
374 				error(1, "-L: pathname missing");
375 			if (ndir >= NDIRS - NDEFDIRS)
376 				error(1, "-L: too many directories");
377 			dirs[ndir++] = &ap[2];
378 		}
379 	}
380 	/* add default search directories */
381 	dirs[ndir++] = _PATH_USRLIB;
382 	dirs[ndir++] = _PATH_LOCALLIB;
383 
384 	p = argv+1;
385 	/*
386 	 * Scan files once to find where symbols are defined.
387 	 */
388 	for (c=1; c<argc; c++) {
389 		if (trace)
390 			printf("%s:\n", *p);
391 		filname = 0;
392 		ap = *p++;
393 		if (*ap != '-') {
394 			load1arg(ap);
395 			continue;
396 		}
397 		for (i=1; ap[i]; i++) switch (ap[i]) {
398 
399 		case 'o':
400 			if (++c >= argc)
401 				error(1, "-o where?");
402 			ofilename = (char *)genbuildname(*p++);
403 			ofilfnd++;
404 			continue;
405 		case 'u':
406 		case 'e':
407 			if (++c >= argc)
408 				error(1, " -u or -e: arg missing");
409 			enter(slookup(*p++));
410 			if (ap[i]=='e')
411 				entrypt = lastsym;
412 			continue;
413 		case 'H':
414 			if (++c >= argc)
415 				error(1, "-H: arg missing");
416 			if (tsize!=0)
417 				error(1, "-H: too late, some text already loaded");
418 			hsize = atoi(*p++);
419 			continue;
420 		case 'A':
421 			if (++c >= argc)
422 				error(1, "-A: arg missing");
423 			if (Aflag)
424 				error(1, "-A: only one base file allowed");
425 			Aflag = 1;
426 			nflag = 0;
427 			funding = 1;
428 			load1arg(*p++);
429 			trsize = drsize = tsize = dsize = bsize = 0;
430 			ctrel = cdrel = cbrel = 0;
431 			funding = 0;
432 			addsym = nextsym;
433 			continue;
434 		case 'D':
435 			if (++c >= argc)
436 				error(1, "-D: arg missing");
437 			num = htoi(*p++);
438 			if (dsize > num)
439 				error(1, "-D: too small");
440 			dsize = num;
441 			continue;
442 		case 'T':
443 			if (++c >= argc)
444 				error(1, "-T: arg missing");
445 			if (tsize!=0)
446 				error(1, "-T: too late, some text already loaded");
447 			textbase = htoi(*p++);
448 			continue;
449 		case 'l':
450 			save = ap[--i];
451 			ap[i]='-';
452 			load1arg(&ap[i]);
453 			ap[i]=save;
454 			goto next;
455 		case 'M':
456 			Mflag++;
457 			continue;
458 		case 'x':
459 			xflag++;
460 			continue;
461 		case 'X':
462 			Xflag++;
463 			continue;
464 		case 'S':
465 			Sflag++;
466 			continue;
467 		case 'r':
468 			rflag++;
469 			arflag++;
470 			continue;
471 		case 's':
472 			sflag++;
473 			xflag++;
474 			continue;
475 		case 'n':
476 			nflag++;
477 			Nflag = zflag = 0;
478 			continue;
479 		case 'N':
480 			Nflag++;
481 			nflag = zflag = 0;
482 			continue;
483 		case 'd':
484 			dflag++;
485 			continue;
486 		case 'i':
487 			printf("ld: -i ignored\n");
488 			continue;
489 		case 't':
490 			trace++;
491 			continue;
492 		case 'y':
493 			if (ap[i+1] == 0)
494 				error(1, "-y: symbol name missing");
495 			if (yflag == 0) {
496 				ytab = (char **)calloc(argc, sizeof (char **));
497 				if (ytab == 0)
498 					error(1, "ran out of memory (-y)");
499 			}
500 			ytab[yflag++] = &ap[i+1];
501 			goto next;
502 		case 'z':
503 			zflag++;
504 			Nflag = nflag = 0;
505 			continue;
506 		case 'L':
507 			goto next;
508 		default:
509 			filname = savestr("-x");	/* kludge */
510 			filname[1] = ap[i];		/* kludge */
511 			archdr.ar_name[0] = 0;		/* kludge */
512 			error(1, "bad flag");
513 		}
514 next:
515 		;
516 	}
517 	if (rflag == 0 && Nflag == 0 && nflag == 0)
518 		zflag++;
519 	endload(argc, argv);
520 	exit(0);
521 }
522 
523 /*
524  * Convert a ascii string which is a hex number.
525  * Used by -T and -D options.
526  */
527 htoi(p)
528 	register char *p;
529 {
530 	register int c, n;
531 
532 	n = 0;
533 	while (c = *p++) {
534 		n <<= 4;
535 		if (isdigit(c))
536 			n += c - '0';
537 		else if (c >= 'a' && c <= 'f')
538 			n += 10 + (c - 'a');
539 		else if (c >= 'A' && c <= 'F')
540 			n += 10 + (c - 'A');
541 		else
542 			error(1, "badly formed hex number");
543 	}
544 	return (n);
545 }
546 
547 delexit()
548 {
549 	struct stat stbuf;
550 	long size;
551 	char c = 0;
552 
553 	bflush();
554 	unlink(defaultname);
555 	/*
556 	 * We have to insure that the last block of the data segment
557 	 * is allocated a full pagesize block. If the underlying
558 	 * file system allocates frags that are smaller than pagesize,
559 	 * a full zero filled pagesize block needs to be allocated so
560 	 * that when it is demand paged, the paged in block will be
561 	 * appropriately filled with zeros.
562 	 */
563 	fstat(biofd, &stbuf);
564 	size = round(stbuf.st_size, pagesize);
565 	if (!rflag && size > stbuf.st_size) {
566 		lseek(biofd, size - 1, 0);
567 		if (write(biofd, &c, 1) != 1)
568 			delarg |= 4;
569 	}
570 	if (delarg==0 && Aflag==0)
571 		(void) chmod(ofilename, ofilemode);
572 	exit (delarg);
573 }
574 
575 endload(argc, argv)
576 	int argc;
577 	char **argv;
578 {
579 	register int c, i;
580 	long dnum;
581 	register char *ap, **p;
582 
583 	clibseg = libseg;
584 	filname = 0;
585 	middle();
586 	setupout();
587 	p = argv+1;
588 	for (c=1; c<argc; c++) {
589 		ap = *p++;
590 		if (trace)
591 			printf("%s:\n", ap);
592 		if (*ap != '-') {
593 			load2arg(ap);
594 			continue;
595 		}
596 		for (i=1; ap[i]; i++) switch (ap[i]) {
597 
598 		case 'D':
599 			dnum = htoi(*p);
600 			if (dorigin < dnum)
601 				while (dorigin < dnum)
602 					bputc(0, dout), dorigin++;
603 			/* fall into ... */
604 		case 'T':
605 		case 'u':
606 		case 'e':
607 		case 'o':
608 		case 'H':
609 			++c;
610 			++p;
611 			/* fall into ... */
612 		default:
613 			continue;
614 		case 'A':
615 			funding = 1;
616 			load2arg(*p++);
617 			funding = 0;
618 			c++;
619 			continue;
620 		case 'y':
621 		case 'L':
622 			goto next;
623 		case 'l':
624 			ap[--i]='-';
625 			load2arg(&ap[i]);
626 			goto next;
627 		}
628 next:
629 		;
630 	}
631 	finishout();
632 }
633 
634 /*
635  * Scan file to find defined symbols.
636  */
637 load1arg(cp)
638 	register char *cp;
639 {
640 	register struct ranlib *tp;
641 	off_t nloc;
642 	int kind;
643 
644 	kind = getfile(cp);
645 	if (Mflag)
646 		printf("%s\n", filname);
647 	switch (kind) {
648 
649 	/*
650 	 * Plain file.
651 	 */
652 	case 0:
653 		load1(0, 0L);
654 		break;
655 
656 	/*
657 	 * Archive without table of contents.
658 	 * (Slowly) process each member.
659 	 */
660 	case 1:
661 		error(-1,
662 "warning: archive has no table of contents; add one using ranlib(1)");
663 		nloc = SARMAG;
664 		while (step(nloc))
665 			nloc += sizeof(archdr) +
666 			    round(atol(archdr.ar_size), sizeof (short));
667 		break;
668 
669 	/*
670 	 * Archive with table of contents.
671 	 * Read the table of contents and its associated string table.
672 	 * Pass through the library resolving symbols until nothing changes
673 	 * for an entire pass (i.e. you can get away with backward references
674 	 * when there is a table of contents!)
675 	 */
676 	case 2:
677 		nloc = SARMAG + sizeof (archdr);
678 		dseek(&text, nloc, sizeof (tnum));
679 		mget((char *)&tnum, sizeof (tnum), &text);
680 		nloc += sizeof (tnum);
681 		tab = (struct ranlib *)malloc(tnum);
682 		if (tab == 0)
683 			error(1, "ran out of memory (toc)");
684 		dseek(&text, nloc, tnum);
685 		mget((char *)tab, tnum, &text);
686 		nloc += tnum;
687 		tnum /= sizeof (struct ranlib);
688 		dseek(&text, nloc, sizeof (ssiz));
689 		mget((char *)&ssiz, sizeof (ssiz), &text);
690 		nloc += sizeof (ssiz);
691 		tabstr = (char *)malloc(ssiz);
692 		if (tabstr == 0)
693 			error(1, "ran out of memory (tocstr)");
694 		dseek(&text, nloc, ssiz);
695 		mget((char *)tabstr, ssiz, &text);
696 		for (tp = &tab[tnum]; --tp >= tab;) {
697 			if (tp->ran_un.ran_strx < 0 ||
698 			    tp->ran_un.ran_strx >= ssiz)
699 				error(1, "mangled archive table of contents");
700 			tp->ran_un.ran_name = tabstr + tp->ran_un.ran_strx;
701 		}
702 		while (ldrand())
703 			continue;
704 		free((char *)tab);
705 		free(tabstr);
706 		nextlibp(-1);
707 		break;
708 
709 	/*
710 	 * Table of contents is out of date, so search
711 	 * as a normal library (but skip the __.SYMDEF file).
712 	 */
713 	case 3:
714 		error(-1,
715 "warning: table of contents for archive is out of date; rerun ranlib(1)");
716 		nloc = SARMAG;
717 		do
718 			nloc += sizeof(archdr) +
719 			    round(atol(archdr.ar_size), sizeof(short));
720 		while (step(nloc));
721 		break;
722 	}
723 	close(infil);
724 }
725 
726 /*
727  * Advance to the next archive member, which
728  * is at offset nloc in the archive.  If the member
729  * is useful, record its location in the liblist structure
730  * for use in pass2.  Mark the end of the archive in libilst with a -1.
731  */
732 step(nloc)
733 	off_t nloc;
734 {
735 
736 	dseek(&text, nloc, (long) sizeof archdr);
737 	if (text.size <= 0) {
738 		nextlibp(-1);
739 		return (0);
740 	}
741 	getarhdr();
742 	if (load1(1, nloc + (sizeof archdr)))
743 		nextlibp(nloc);
744 	return (1);
745 }
746 
747 /*
748  * Record the location of a useful archive member.
749  * Recording -1 marks the end of files from an archive.
750  * The liblist data structure is dynamically extended here.
751  */
752 nextlibp(val)
753 	off_t val;
754 {
755 
756 	if (clibseg->li_used == NROUT) {
757 		if (++clibseg == &libseg[NSEG])
758 			error(1, "too many files loaded from libraries");
759 		clibseg->li_first = (off_t *)malloc(NROUT * sizeof (off_t));
760 		if (clibseg->li_first == 0)
761 			error(1, "ran out of memory (nextlibp)");
762 	}
763 	clibseg->li_first[clibseg->li_used++] = val;
764 	if (val != -1 && Mflag)
765 		printf("\t%s\n", archdr.ar_name);
766 }
767 
768 /*
769  * One pass over an archive with a table of contents.
770  * Remember the number of symbols currently defined,
771  * then call step on members which look promising (i.e.
772  * that define a symbol which is currently externally undefined).
773  * Indicate to our caller whether this process netted any more symbols.
774  */
775 ldrand()
776 {
777 	register struct nlist *sp, **hp;
778 	register struct ranlib *tp, *tplast;
779 	off_t loc;
780 	int nsymt = symx(nextsym);
781 
782 	tplast = &tab[tnum-1];
783 	for (tp = tab; tp <= tplast; tp++) {
784 		if ((hp = slookup(tp->ran_un.ran_name)) == 0 || *hp == 0)
785 			continue;
786 		sp = *hp;
787 		if (sp->n_type != N_EXT+N_UNDF)
788 			continue;
789 		step(tp->ran_off);
790 		loc = tp->ran_off;
791 		while (tp < tplast && (tp+1)->ran_off == loc)
792 			tp++;
793 	}
794 	return (symx(nextsym) != nsymt);
795 }
796 
797 /*
798  * Examine a single file or archive member on pass 1.
799  */
800 load1(libflg, loc)
801 	off_t loc;
802 {
803 	register struct nlist *sp;
804 	struct nlist *savnext;
805 	int ndef, nlocal, type, size, nsymt;
806 	register int i;
807 	off_t maxoff;
808 	struct stat stb;
809 
810 	readhdr(loc);
811 	if (filhdr.a_syms == 0) {
812 		if (filhdr.a_text+filhdr.a_data == 0) {
813 			/* load2() adds a symbol for the file name */
814 			if (!libflg)
815 				ssize += sizeof (cursym);
816 			return (0);
817 		}
818 		error(1, "no namelist");
819 	}
820 	if (libflg)
821 		maxoff = atol(archdr.ar_size);
822 	else {
823 		fstat(infil, &stb);
824 		maxoff = stb.st_size;
825 	}
826 	if (N_STROFF(filhdr) + sizeof (off_t) >= maxoff)
827 		error(1, "too small (old format .o?)");
828 	ctrel = tsize; cdrel += dsize; cbrel += bsize;
829 	ndef = 0;
830 	nlocal = sizeof(cursym);
831 	savnext = nextsym;
832 	loc += N_SYMOFF(filhdr);
833 	dseek(&text, loc, filhdr.a_syms);
834 	dseek(&reloc, loc + filhdr.a_syms, sizeof(off_t));
835 	mget(&size, sizeof (size), &reloc);
836 	dseek(&reloc, loc + filhdr.a_syms+sizeof (off_t), size-sizeof (off_t));
837 	curstr = (char *)malloc(size);
838 	if (curstr == NULL)
839 		error(1, "no space for string table");
840 	mget(curstr+sizeof(off_t), size-sizeof(off_t), &reloc);
841 	while (text.size > 0) {
842 		mget((char *)&cursym, sizeof(struct nlist), &text);
843 		if (cursym.n_un.n_strx) {
844 			if (cursym.n_un.n_strx<sizeof(size) ||
845 			    cursym.n_un.n_strx>=size)
846 				error(1, "bad string table index (pass 1)");
847 			cursym.n_un.n_name = curstr + cursym.n_un.n_strx;
848 		}
849 		type = cursym.n_type;
850 		if ((type&N_EXT)==0) {
851 			if (Xflag==0 || cursym.n_un.n_name[0]!='L' ||
852 			    type & N_STAB)
853 				nlocal += sizeof cursym;
854 			continue;
855 		}
856 		symreloc();
857 		if (enter(lookup()))
858 			continue;
859 		if ((sp = lastsym)->n_type != N_EXT+N_UNDF)
860 			continue;
861 		if (cursym.n_type == N_EXT+N_UNDF) {
862 			if (cursym.n_value > sp->n_value)
863 				sp->n_value = cursym.n_value;
864 			continue;
865 		}
866 		if (sp->n_value != 0 && cursym.n_type == N_EXT+N_TEXT)
867 			continue;
868 		ndef++;
869 		sp->n_type = cursym.n_type;
870 		sp->n_value = cursym.n_value;
871 	}
872 	if (libflg==0 || ndef) {
873 		tsize += filhdr.a_text;
874 		dsize += round(filhdr.a_data, sizeof (long));
875 		bsize += round(filhdr.a_bss, sizeof (long));
876 		ssize += nlocal;
877 		trsize += filhdr.a_trsize;
878 		drsize += filhdr.a_drsize;
879 		if (funding)
880 			textbase = (*slookup("_end"))->n_value;
881 		nsymt = symx(nextsym);
882 		for (i = symx(savnext); i < nsymt; i++) {
883 			sp = xsym(i);
884 			sp->n_un.n_name = savestr(sp->n_un.n_name);
885 		}
886 		free(curstr);
887 		return (1);
888 	}
889 	/*
890 	 * No symbols defined by this library member.
891 	 * Rip out the hash table entries and reset the symbol table.
892 	 */
893 	symfree(savnext);
894 	free(curstr);
895 	return(0);
896 }
897 
898 middle()
899 {
900 	register struct nlist *sp;
901 	long csize, t, corigin, ocsize;
902 	int nund, rnd;
903 	char s;
904 	register int i;
905 	int nsymt;
906 
907 	torigin = 0;
908 	dorigin = 0;
909 	borigin = 0;
910 
911 	p_etext = *slookup("_etext");
912 	p_edata = *slookup("_edata");
913 	p_end = *slookup("_end");
914 	/*
915 	 * If there are any undefined symbols, save the relocation bits.
916 	 */
917 	nsymt = symx(nextsym);
918 	if (rflag==0) {
919 		for (i = 0; i < nsymt; i++) {
920 			sp = xsym(i);
921 			if (sp->n_type==N_EXT+N_UNDF && sp->n_value==0 &&
922 			    sp!=p_end && sp!=p_edata && sp!=p_etext) {
923 				rflag++;
924 				dflag = 0;
925 				break;
926 			}
927 		}
928 	}
929 	if (rflag)
930 		sflag = zflag = 0;
931 	/*
932 	 * Assign common locations.
933 	 */
934 	csize = 0;
935 	if (!Aflag)
936 		addsym = symseg[0].sy_first;
937 	database = round(tsize+textbase,
938 	    (nflag||zflag? pagesize : sizeof (long)));
939 	database += hsize;
940 	if (dflag || rflag==0) {
941 		ldrsym(p_etext, tsize, N_EXT+N_TEXT);
942 		ldrsym(p_edata, dsize, N_EXT+N_DATA);
943 		ldrsym(p_end, bsize, N_EXT+N_BSS);
944 		for (i = symx(addsym); i < nsymt; i++) {
945 			sp = xsym(i);
946 			if ((s=sp->n_type)==N_EXT+N_UNDF &&
947 			    (t = sp->n_value)!=0) {
948 				if (t >= sizeof (double))
949 					rnd = sizeof (double);
950 				else if (t >= sizeof (long))
951 					rnd = sizeof (long);
952 				else
953 					rnd = sizeof (short);
954 				csize = round(csize, rnd);
955 				sp->n_value = csize;
956 				sp->n_type = N_EXT+N_COMM;
957 				ocsize = csize;
958 				csize += t;
959 			}
960 			if (s&N_EXT && (s&N_TYPE)==N_UNDF && s&N_STAB) {
961 				sp->n_value = ocsize;
962 				sp->n_type = (s&N_STAB) | (N_EXT+N_COMM);
963 			}
964 		}
965 	}
966 	/*
967 	 * Now set symbols to their final value
968 	 */
969 	csize = round(csize, sizeof (long));
970 	torigin = textbase;
971 	dorigin = database;
972 	corigin = dorigin + dsize;
973 	borigin = corigin + csize;
974 	nund = 0;
975 	nsymt = symx(nextsym);
976 	for (i = symx(addsym); i<nsymt; i++) {
977 		sp = xsym(i);
978 		switch (sp->n_type & (N_TYPE+N_EXT)) {
979 
980 		case N_EXT+N_UNDF:
981 			if (arflag == 0)
982 				errlev |= 01;
983 			if ((arflag==0 || dflag) && sp->n_value==0) {
984 				if (sp==p_end || sp==p_etext || sp==p_edata)
985 					continue;
986 				if (nund==0)
987 					printf("Undefined:\n");
988 				nund++;
989 				printf("%s\n", sp->n_un.n_name);
990 			}
991 			continue;
992 		case N_EXT+N_ABS:
993 		default:
994 			continue;
995 		case N_EXT+N_TEXT:
996 			sp->n_value += torigin;
997 			continue;
998 		case N_EXT+N_DATA:
999 			sp->n_value += dorigin;
1000 			continue;
1001 		case N_EXT+N_BSS:
1002 			sp->n_value += borigin;
1003 			continue;
1004 		case N_EXT+N_COMM:
1005 			sp->n_type = (sp->n_type & N_STAB) | (N_EXT+N_BSS);
1006 			sp->n_value += corigin;
1007 			continue;
1008 		}
1009 	}
1010 	if (sflag || xflag)
1011 		ssize = 0;
1012 	bsize += csize;
1013 	nsym = ssize / (sizeof cursym);
1014 	if (Aflag) {
1015 		fixspec(p_etext,torigin);
1016 		fixspec(p_edata,dorigin);
1017 		fixspec(p_end,borigin);
1018 	}
1019 }
1020 
1021 fixspec(sym,offset)
1022 	struct nlist *sym;
1023 	long offset;
1024 {
1025 
1026 	if(symx(sym) < symx(addsym) && sym!=0)
1027 		sym->n_value += offset;
1028 }
1029 
1030 ldrsym(sp, val, type)
1031 	register struct nlist *sp;
1032 	long val;
1033 {
1034 
1035 	if (sp == 0)
1036 		return;
1037 	if ((sp->n_type != N_EXT+N_UNDF || sp->n_value) && !Aflag) {
1038 		printf("%s: ", sp->n_un.n_name);
1039 		error(0, "user attempt to redfine loader-defined symbol");
1040 		return;
1041 	}
1042 	sp->n_type = type;
1043 	sp->n_value = val;
1044 }
1045 
1046 off_t	wroff;
1047 struct	biobuf toutb;
1048 
1049 setupout()
1050 {
1051 	int bss;
1052 	struct stat stbuf;
1053 	extern char *sys_errlist[];
1054 	extern int errno;
1055 
1056 	ofilemode = 0777 & ~umask(0);
1057 	biofd = creat(ofilename, 0666 & ofilemode);
1058 	if (biofd < 0) {
1059 		filname = ofilename;		/* kludge */
1060 		archdr.ar_name[0] = 0;		/* kludge */
1061 		error(1, sys_errlist[errno]);	/* kludge */
1062 	}
1063 	fstat(biofd, &stbuf);		/* suppose file exists, wrong*/
1064 	if (stbuf.st_mode & 0111) {	/* mode, ld fails? */
1065 		chmod(ofilename, stbuf.st_mode & 0666);
1066 		ofilemode = stbuf.st_mode;
1067 	}
1068 	filhdr.a_magic = nflag ? NMAGIC : (zflag ? ZMAGIC : OMAGIC);
1069 	filhdr.a_text = nflag ? tsize :
1070 	    round(tsize, zflag ? pagesize : sizeof (long));
1071 	filhdr.a_data = zflag ? round(dsize, pagesize) : dsize;
1072 	bss = bsize - (filhdr.a_data - dsize);
1073 	if (bss < 0)
1074 		bss = 0;
1075 	filhdr.a_bss = bss;
1076 	filhdr.a_trsize = trsize;
1077 	filhdr.a_drsize = drsize;
1078 	filhdr.a_syms = sflag? 0: (ssize + (sizeof cursym)*symx(nextsym));
1079 	if (entrypt) {
1080 		if (entrypt->n_type!=N_EXT+N_TEXT)
1081 			error(0, "entry point not in text");
1082 		else
1083 			filhdr.a_entry = entrypt->n_value;
1084 	} else
1085 		filhdr.a_entry = 0;
1086 	filhdr.a_trsize = (rflag ? trsize:0);
1087 	filhdr.a_drsize = (rflag ? drsize:0);
1088 	tout = &toutb;
1089 	bopen(tout, 0, stbuf.st_blksize);
1090 	bwrite((char *)&filhdr, sizeof (filhdr), tout);
1091 	if (zflag)
1092 		bseek(tout, pagesize);
1093 	wroff = N_TXTOFF(filhdr) + filhdr.a_text;
1094 	outb(&dout, filhdr.a_data, stbuf.st_blksize);
1095 	if (rflag) {
1096 		outb(&trout, filhdr.a_trsize, stbuf.st_blksize);
1097 		outb(&drout, filhdr.a_drsize, stbuf.st_blksize);
1098 	}
1099 	if (sflag==0 || xflag==0) {
1100 		outb(&sout, filhdr.a_syms, stbuf.st_blksize);
1101 		wroff += sizeof (offset);
1102 		outb(&strout, 0, stbuf.st_blksize);
1103 	}
1104 }
1105 
1106 outb(bp, inc, bufsize)
1107 	register struct biobuf **bp;
1108 {
1109 
1110 	*bp = (struct biobuf *)malloc(sizeof (struct biobuf));
1111 	if (*bp == 0)
1112 		error(1, "ran out of memory (outb)");
1113 	bopen(*bp, wroff, bufsize);
1114 	wroff += inc;
1115 }
1116 
1117 load2arg(acp)
1118 char *acp;
1119 {
1120 	register char *cp;
1121 	off_t loc;
1122 
1123 	cp = acp;
1124 	if (getfile(cp) == 0) {
1125 		while (*cp)
1126 			cp++;
1127 		while (cp >= acp && *--cp != '/');
1128 		mkfsym(++cp);
1129 		load2(0L);
1130 	} else {	/* scan archive members referenced */
1131 		for (;;) {
1132 			if (clibseg->li_used2 == clibseg->li_used) {
1133 				if (clibseg->li_used < NROUT)
1134 					error(1, "libseg botch");
1135 				clibseg++;
1136 			}
1137 			loc = clibseg->li_first[clibseg->li_used2++];
1138 			if (loc == -1)
1139 				break;
1140 			dseek(&text, loc, (long)sizeof(archdr));
1141 			getarhdr();
1142 			mkfsym(archdr.ar_name);
1143 			load2(loc + (long)sizeof(archdr));
1144 		}
1145 	}
1146 	close(infil);
1147 }
1148 
1149 load2(loc)
1150 long loc;
1151 {
1152 	int size;
1153 	register struct nlist *sp;
1154 	register struct local *lp;
1155 	register int symno, i;
1156 	int type;
1157 
1158 	readhdr(loc);
1159 	if (!funding) {
1160 		ctrel = torigin;
1161 		cdrel += dorigin;
1162 		cbrel += borigin;
1163 	}
1164 	/*
1165 	 * Reread the symbol table, recording the numbering
1166 	 * of symbols for fixing external references.
1167 	 */
1168 	for (i = 0; i < LHSIZ; i++)
1169 		lochash[i] = 0;
1170 	clocseg = locseg;
1171 	clocseg->lo_used = 0;
1172 	symno = -1;
1173 	loc += N_TXTOFF(filhdr);
1174 	dseek(&text, loc+filhdr.a_text+filhdr.a_data+
1175 		filhdr.a_trsize+filhdr.a_drsize+filhdr.a_syms, sizeof(off_t));
1176 	mget(&size, sizeof(size), &text);
1177 	dseek(&text, loc+filhdr.a_text+filhdr.a_data+
1178 		filhdr.a_trsize+filhdr.a_drsize+filhdr.a_syms+sizeof(off_t),
1179 		size - sizeof(off_t));
1180 	curstr = (char *)malloc(size);
1181 	if (curstr == NULL)
1182 		error(1, "out of space reading string table (pass 2)");
1183 	mget(curstr+sizeof(off_t), size-sizeof(off_t), &text);
1184 	dseek(&text, loc+filhdr.a_text+filhdr.a_data+
1185 		filhdr.a_trsize+filhdr.a_drsize, filhdr.a_syms);
1186 	while (text.size > 0) {
1187 		symno++;
1188 		mget((char *)&cursym, sizeof(struct nlist), &text);
1189 		if (cursym.n_un.n_strx) {
1190 			if (cursym.n_un.n_strx<sizeof(size) ||
1191 			    cursym.n_un.n_strx>=size)
1192 				error(1, "bad string table index (pass 2)");
1193 			cursym.n_un.n_name = curstr + cursym.n_un.n_strx;
1194 		}
1195 /* inline expansion of symreloc() */
1196 		switch (cursym.n_type & 017) {
1197 
1198 		case N_TEXT:
1199 		case N_EXT+N_TEXT:
1200 			cursym.n_value += ctrel;
1201 			break;
1202 		case N_DATA:
1203 		case N_EXT+N_DATA:
1204 			cursym.n_value += cdrel;
1205 			break;
1206 		case N_BSS:
1207 		case N_EXT+N_BSS:
1208 			cursym.n_value += cbrel;
1209 			break;
1210 		case N_EXT+N_UNDF:
1211 			break;
1212 		default:
1213 			if (cursym.n_type&N_EXT)
1214 				cursym.n_type = N_EXT+N_ABS;
1215 		}
1216 /* end inline expansion of symreloc() */
1217 		type = cursym.n_type;
1218 		if (yflag && cursym.n_un.n_name)
1219 			for (i = 0; i < yflag; i++)
1220 				/* fast check for 2d character! */
1221 				if (ytab[i][1] == cursym.n_un.n_name[1] &&
1222 				    !strcmp(ytab[i], cursym.n_un.n_name)) {
1223 					tracesym();
1224 					break;
1225 				}
1226 		if ((type&N_EXT) == 0) {
1227 			if (!sflag&&!xflag&&
1228 			    (!Xflag||cursym.n_un.n_name[0]!='L'||type&N_STAB))
1229 				symwrite(&cursym, sout);
1230 			continue;
1231 		}
1232 		if (funding)
1233 			continue;
1234 		if ((sp = *lookup()) == 0)
1235 			error(1, "internal error: symbol not found");
1236 		if (cursym.n_type == N_EXT+N_UNDF) {
1237 			if (clocseg->lo_used == NSYMPR) {
1238 				if (++clocseg == &locseg[NSEG])
1239 					error(1, "local symbol overflow");
1240 				clocseg->lo_used = 0;
1241 			}
1242 			if (clocseg->lo_first == 0) {
1243 				clocseg->lo_first = (struct local *)
1244 				    malloc(NSYMPR * sizeof (struct local));
1245 				if (clocseg->lo_first == 0)
1246 					error(1, "out of memory (clocseg)");
1247 			}
1248 			lp = &clocseg->lo_first[clocseg->lo_used++];
1249 			lp->l_index = symno;
1250 			lp->l_symbol = sp;
1251 			lp->l_link = lochash[symno % LHSIZ];
1252 			lochash[symno % LHSIZ] = lp;
1253 			continue;
1254 		}
1255 		if (cursym.n_type & N_STAB)
1256 			continue;
1257 		if (cursym.n_type!=sp->n_type || cursym.n_value!=sp->n_value) {
1258 			printf("%s: ", cursym.n_un.n_name);
1259 			error(0, "multiply defined");
1260 		}
1261 	}
1262 	if (funding)
1263 		return;
1264 	dseek(&text, loc, filhdr.a_text);
1265 	dseek(&reloc, loc+filhdr.a_text+filhdr.a_data, filhdr.a_trsize);
1266 	load2td(ctrel, torigin - textbase, tout, trout);
1267 	dseek(&text, loc+filhdr.a_text, filhdr.a_data);
1268 	dseek(&reloc, loc+filhdr.a_text+filhdr.a_data+filhdr.a_trsize,
1269 	    filhdr.a_drsize);
1270 	load2td(cdrel, dorigin - database, dout, drout);
1271 	while (filhdr.a_data & (sizeof(long)-1)) {
1272 		bputc(0, dout);
1273 		filhdr.a_data++;
1274 	}
1275 	torigin += filhdr.a_text;
1276 	dorigin += round(filhdr.a_data, sizeof (long));
1277 	borigin += round(filhdr.a_bss, sizeof (long));
1278 	free(curstr);
1279 }
1280 
1281 struct tynames {
1282 	int	ty_value;
1283 	char	*ty_name;
1284 } tynames[] = {
1285 	N_UNDF,	"undefined",
1286 	N_ABS,	"absolute",
1287 	N_TEXT,	"text",
1288 	N_DATA,	"data",
1289 	N_BSS,	"bss",
1290 	N_COMM,	"common",
1291 	0,	0,
1292 };
1293 
1294 tracesym()
1295 {
1296 	register struct tynames *tp;
1297 
1298 	if (cursym.n_type & N_STAB)
1299 		return;
1300 	printf("%s", filname);
1301 	if (archdr.ar_name[0])
1302 		printf("(%s)", archdr.ar_name);
1303 	printf(": ");
1304 	if ((cursym.n_type&N_TYPE) == N_UNDF && cursym.n_value) {
1305 		printf("definition of common %s size %d\n",
1306 		    cursym.n_un.n_name, cursym.n_value);
1307 		return;
1308 	}
1309 	for (tp = tynames; tp->ty_name; tp++)
1310 		if (tp->ty_value == (cursym.n_type&N_TYPE))
1311 			break;
1312 	printf((cursym.n_type&N_TYPE) ? "definition of" : "reference to");
1313 	if (cursym.n_type&N_EXT)
1314 		printf(" external");
1315 	if (tp->ty_name)
1316 		printf(" %s", tp->ty_name);
1317 	printf(" %s\n", cursym.n_un.n_name);
1318 }
1319 
1320 #if !defined(tahoe)
1321 /* for machines which allow arbitrarily aligned word and longword accesses */
1322 #define	getw(cp)	(*(short *)(cp))
1323 #define	getl(cp)	(*(long *)(cp))
1324 #define	putw(cp, w)	(*(short *)(cp) = (w))
1325 #define	putl(cp, l)	(*(long *)(cp) = (l))
1326 #else
1327 short
1328 getw(cp)
1329 	char *cp;
1330 {
1331 	union {
1332 		short	w;
1333 		char	c[2];
1334 	} w;
1335 
1336 	w.c[0] = *cp++;
1337 	w.c[1] = *cp++;
1338 	return (w.w);
1339 }
1340 
1341 getl(cp)
1342 	char *cp;
1343 {
1344 	union {
1345 		long	l;
1346 		char	c[4];
1347 	} l;
1348 
1349 	l.c[0] = *cp++;
1350 	l.c[1] = *cp++;
1351 	l.c[2] = *cp++;
1352 	l.c[3] = *cp++;
1353 	return (l.l);
1354 }
1355 
1356 putw(cp, v)
1357 	char *cp;
1358 	short v;
1359 {
1360 	union {
1361 		short	w;
1362 		char	c[2];
1363 	} w;
1364 
1365 	w.w = v;
1366 	*cp++ = w.c[0];
1367 	*cp++ = w.c[1];
1368 }
1369 
1370 putl(cp, v)
1371 	char *cp;
1372 	long v;
1373 {
1374 	union {
1375 		long	l;
1376 		char	c[4];
1377 	} l;
1378 
1379 	l.l = v;
1380 	*cp++ = l.c[0];
1381 	*cp++ = l.c[1];
1382 	*cp++ = l.c[2];
1383 	*cp++ = l.c[3];
1384 }
1385 #endif
1386 
1387 /*
1388  * This routine relocates the single text or data segment argument.
1389  * Offsets from external symbols are resolved by adding the value
1390  * of the external symbols.  Non-external reference are updated to account
1391  * for the relative motion of the segments (ctrel, cdrel, ...).  If
1392  * a relocation was pc-relative, then we update it to reflect the
1393  * change in the positioning of the segments by adding the displacement
1394  * of the referenced segment and subtracting the displacement of the
1395  * current segment (creloc).
1396  *
1397  * If we are saving the relocation information, then we increase
1398  * each relocation datum address by our base position in the new segment.
1399  */
1400 load2td(creloc, position, b1, b2)
1401 	long creloc, position;
1402 	struct biobuf *b1, *b2;
1403 {
1404 	register struct nlist *sp;
1405 	register struct local *lp;
1406 	long tw;
1407 	register struct relocation_info *rp, *rpend;
1408 	struct relocation_info *relp;
1409 	char *codep;
1410 	register char *cp;
1411 	int relsz, codesz;
1412 
1413 	relsz = reloc.size;
1414 	relp = (struct relocation_info *)malloc(relsz);
1415 	codesz = text.size;
1416 	codep = (char *)malloc(codesz);
1417 	if (relp == 0 || codep == 0)
1418 		error(1, "out of memory (load2td)");
1419 	mget((char *)relp, relsz, &reloc);
1420 	rpend = &relp[relsz / sizeof (struct relocation_info)];
1421 	mget(codep, codesz, &text);
1422 	for (rp = relp; rp < rpend; rp++) {
1423 		cp = codep + rp->r_address;
1424 		/*
1425 		 * Pick up previous value at location to be relocated.
1426 		 */
1427 		switch (rp->r_length) {
1428 
1429 		case 0:		/* byte */
1430 			tw = *cp;
1431 			break;
1432 
1433 		case 1:		/* word */
1434 			tw = getw(cp);
1435 			break;
1436 
1437 		case 2:		/* long */
1438 			tw = getl(cp);
1439 			break;
1440 
1441 		default:
1442 			error(1, "load2td botch: bad length");
1443 		}
1444 		/*
1445 		 * If relative to an external which is defined,
1446 		 * resolve to a simpler kind of reference in the
1447 		 * result file.  If the external is undefined, just
1448 		 * convert the symbol number to the number of the
1449 		 * symbol in the result file and leave it undefined.
1450 		 */
1451 		if (rp->r_extern) {
1452 			/*
1453 			 * Search the hash table which maps local
1454 			 * symbol numbers to symbol tables entries
1455 			 * in the new a.out file.
1456 			 */
1457 			lp = lochash[rp->r_symbolnum % LHSIZ];
1458 			while (lp->l_index != rp->r_symbolnum) {
1459 				lp = lp->l_link;
1460 				if (lp == 0)
1461 					error(1, "local symbol botch");
1462 			}
1463 			sp = lp->l_symbol;
1464 			if (sp->n_type == N_EXT+N_UNDF)
1465 				rp->r_symbolnum = nsym+symx(sp);
1466 			else {
1467 				rp->r_symbolnum = sp->n_type & N_TYPE;
1468 				tw += sp->n_value;
1469 				rp->r_extern = 0;
1470 			}
1471 		} else switch (rp->r_symbolnum & N_TYPE) {
1472 		/*
1473 		 * Relocation is relative to the loaded position
1474 		 * of another segment.  Update by the change in position
1475 		 * of that segment.
1476 		 */
1477 		case N_TEXT:
1478 			tw += ctrel;
1479 			break;
1480 		case N_DATA:
1481 			tw += cdrel;
1482 			break;
1483 		case N_BSS:
1484 			tw += cbrel;
1485 			break;
1486 		case N_ABS:
1487 			break;
1488 		default:
1489 			error(1, "relocation format botch (symbol type))");
1490 		}
1491 		/*
1492 		 * Relocation is pc relative, so decrease the relocation
1493 		 * by the amount the current segment is displaced.
1494 		 * (E.g if we are a relative reference to a text location
1495 		 * from data space, we added the increase in the text address
1496 		 * above, and subtract the increase in our (data) address
1497 		 * here, leaving the net change the relative change in the
1498 		 * positioning of our text and data segments.)
1499 		 */
1500 		if (rp->r_pcrel)
1501 			tw -= creloc;
1502 		/*
1503 		 * Put the value back in the segment,
1504 		 * while checking for overflow.
1505 		 */
1506 		switch (rp->r_length) {
1507 
1508 		case 0:		/* byte */
1509 			if (tw < -128 || tw > 127)
1510 				error(0, "byte displacement overflow");
1511 			*cp = tw;
1512 			break;
1513 		case 1:		/* word */
1514 			if (tw < -32768 || tw > 32767)
1515 				error(0, "word displacement overflow");
1516 			putw(cp, tw);
1517 			break;
1518 		case 2:		/* long */
1519 			putl(cp, tw);
1520 			break;
1521 		}
1522 		/*
1523 		 * If we are saving relocation information,
1524 		 * we must convert the address in the segment from
1525 		 * the old .o file into an address in the segment in
1526 		 * the new a.out, by adding the position of our
1527 		 * segment in the new larger segment.
1528 		 */
1529 		if (rflag)
1530 			rp->r_address += position;
1531 	}
1532 	bwrite(codep, codesz, b1);
1533 	if (rflag)
1534 		bwrite(relp, relsz, b2);
1535 	free((char *)relp);
1536 	free(codep);
1537 }
1538 
1539 finishout()
1540 {
1541 	register int i;
1542 	char *newname;
1543 	int nsymt;
1544 
1545 	if (sflag==0) {
1546 		nsymt = symx(nextsym);
1547 		for (i = 0; i < nsymt; i++)
1548 			symwrite(xsym(i), sout);
1549 		bwrite(&offset, sizeof offset, sout);
1550 	}
1551 	if (!ofilfnd) {
1552 		newname = (char *)genbuildname("a.out");
1553 		unlink(newname);
1554 		if (link(defaultname, newname) < 0)
1555 			error(1, "cannot move l.out to a.out");
1556 		ofilename = newname;
1557 	}
1558 	delarg = errlev;
1559 	delexit();
1560 }
1561 
1562 mkfsym(s)
1563 char *s;
1564 {
1565 
1566 	if (sflag || xflag)
1567 		return;
1568 	cursym.n_un.n_name = s;
1569 	cursym.n_type = N_EXT | N_FN;
1570 	cursym.n_value = torigin;
1571 	symwrite(&cursym, sout);
1572 }
1573 
1574 getarhdr()
1575 {
1576 	register char *cp;
1577 
1578 	mget((char *)&archdr, sizeof archdr, &text);
1579 	for (cp=archdr.ar_name; cp<&archdr.ar_name[sizeof(archdr.ar_name)];)
1580 		if (*cp++ == ' ') {
1581 			cp[-1] = 0;
1582 			return;
1583 		}
1584 }
1585 
1586 mget(loc, n, sp)
1587 register STREAM *sp;
1588 register char *loc;
1589 {
1590 	register char *p;
1591 	register int take;
1592 
1593 top:
1594 	if (n == 0)
1595 		return;
1596 	if (sp->size && sp->nibuf) {
1597 		p = sp->ptr;
1598 		take = sp->size;
1599 		if (take > sp->nibuf)
1600 			take = sp->nibuf;
1601 		if (take > n)
1602 			take = n;
1603 		n -= take;
1604 		sp->size -= take;
1605 		sp->nibuf -= take;
1606 		sp->pos += take;
1607 		do
1608 			*loc++ = *p++;
1609 		while (--take > 0);
1610 		sp->ptr = p;
1611 		goto top;
1612 	}
1613 	if (n > p_blksize) {
1614 		take = n - n % p_blksize;
1615 		lseek(infil, (sp->bno+1)<<p_blkshift, 0);
1616 		if (take > sp->size || read(infil, loc, take) != take)
1617 			error(1, "premature EOF");
1618 		loc += take;
1619 		n -= take;
1620 		sp->size -= take;
1621 		sp->pos += take;
1622 		dseek(sp, (sp->bno+1+(take>>p_blkshift))<<p_blkshift, -1);
1623 		goto top;
1624 	}
1625 	*loc++ = get(sp);
1626 	--n;
1627 	goto top;
1628 }
1629 
1630 symwrite(sp, bp)
1631 	struct nlist *sp;
1632 	struct biobuf *bp;
1633 {
1634 	register int len;
1635 	register char *str;
1636 
1637 	str = sp->n_un.n_name;
1638 	if (str) {
1639 		sp->n_un.n_strx = offset;
1640 		len = strlen(str) + 1;
1641 		bwrite(str, len, strout);
1642 		offset += len;
1643 	}
1644 	bwrite(sp, sizeof (*sp), bp);
1645 	sp->n_un.n_name = str;
1646 }
1647 
1648 dseek(sp, loc, s)
1649 register STREAM *sp;
1650 long loc, s;
1651 {
1652 	register PAGE *p;
1653 	register b, o;
1654 	int n;
1655 
1656 	b = loc>>p_blkshift;
1657 	o = loc&p_blkmask;
1658 	if (o&01)
1659 		error(1, "loader error; odd offset");
1660 	--sp->pno->nuser;
1661 	if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)
1662 		if (p->nuser==0 || (p = &page[0])->nuser==0) {
1663 			if (page[0].nuser==0 && page[1].nuser==0)
1664 				if (page[0].bno < page[1].bno)
1665 					p = &page[0];
1666 			p->bno = b;
1667 			lseek(infil, loc & ~(long)p_blkmask, 0);
1668 			if ((n = read(infil, p->buff, p_blksize)) < 0)
1669 				n = 0;
1670 			p->nibuf = n;
1671 		} else
1672 			error(1, "botch: no pages");
1673 	++p->nuser;
1674 	sp->bno = b;
1675 	sp->pno = p;
1676 	if (s != -1) {sp->size = s; sp->pos = 0;}
1677 	sp->ptr = (char *)(p->buff + o);
1678 	if ((sp->nibuf = p->nibuf-o) <= 0)
1679 		sp->size = 0;
1680 }
1681 
1682 char
1683 get(asp)
1684 STREAM *asp;
1685 {
1686 	register STREAM *sp;
1687 
1688 	sp = asp;
1689 	if ((sp->nibuf -= sizeof(char)) < 0) {
1690 		dseek(sp, ((long)(sp->bno+1)<<p_blkshift), (long)-1);
1691 		sp->nibuf -= sizeof(char);
1692 	}
1693 	if ((sp->size -= sizeof(char)) <= 0) {
1694 		if (sp->size < 0)
1695 			error(1, "premature EOF");
1696 		++fpage.nuser;
1697 		--sp->pno->nuser;
1698 		sp->pno = (PAGE *) &fpage;
1699 	}
1700 	sp->pos += sizeof(char);
1701 	return(*sp->ptr++);
1702 }
1703 
1704 getfile(acp)
1705 char *acp;
1706 {
1707 	register int c;
1708 	char arcmag[SARMAG+1];
1709 	struct stat stb;
1710 
1711 	archdr.ar_name[0] = '\0';
1712 	filname = acp;
1713 	if (filname[0] == '-' && filname[1] == 'l')
1714 		infil = libopen(filname + 2, O_RDONLY);
1715 	else
1716 		infil = open((char *)genbuildname(filname), O_RDONLY);
1717 	if (infil < 0)
1718 		error(1, "cannot open");
1719 	fstat(infil, &stb);
1720 	page[0].bno = page[1].bno = -1;
1721 	page[0].nuser = page[1].nuser = 0;
1722 	c = stb.st_blksize;
1723 	if (c == 0 || (c & (c - 1)) != 0) {
1724 		/* use default size if not a power of two */
1725 		c = BLKSIZE;
1726 	}
1727 	if (p_blksize != c) {
1728 		p_blksize = c;
1729 		p_blkmask = c - 1;
1730 		for (p_blkshift = 0; c > 1 ; p_blkshift++)
1731 			c >>= 1;
1732 		if (page[0].buff != NULL)
1733 			free(page[0].buff);
1734 		page[0].buff = (char *)malloc(p_blksize);
1735 		if (page[0].buff == NULL)
1736 			error(1, "ran out of memory (getfile)");
1737 		if (page[1].buff != NULL)
1738 			free(page[1].buff);
1739 		page[1].buff = (char *)malloc(p_blksize);
1740 		if (page[1].buff == NULL)
1741 			error(1, "ran out of memory (getfile)");
1742 	}
1743 	text.pno = reloc.pno = (PAGE *) &fpage;
1744 	fpage.nuser = 2;
1745 	dseek(&text, 0L, SARMAG);
1746 	if (text.size <= 0)
1747 		error(1, "premature EOF");
1748 	mget((char *)arcmag, SARMAG, &text);
1749 	arcmag[SARMAG] = 0;
1750 	if (strcmp(arcmag, ARMAG))
1751 		return (0);
1752 	dseek(&text, SARMAG, sizeof archdr);
1753 	if (text.size <= 0)
1754 		return (1);
1755 	getarhdr();
1756 	if (strncmp(archdr.ar_name, RANLIBMAG, sizeof(archdr.ar_name)) != 0)
1757 		return (1);
1758 	return (stb.st_mtime > atol(archdr.ar_date) ? 3 : 2);
1759 }
1760 
1761 /*
1762  * Search for a library with given name
1763  * using the directory search array.
1764  */
1765 libopen(name, oflags)
1766 	char *name;
1767 	int oflags;
1768 {
1769 	register char *p, *cp;
1770 	register int i;
1771 	static char buf[MAXPATHLEN+1];
1772 	int fd = -1;
1773 
1774 	if (*name == '\0')			/* backwards compat */
1775 		name = "a";
1776 	for (i = 0; i < ndir && fd == -1; i++) {
1777 		p = buf;
1778 		for (cp = dirs[i]; *cp; *p++ = *cp++)
1779 			;
1780 		*p++ = '/';
1781 		for (cp = "lib"; *cp; *p++ = *cp++)
1782 			;
1783 		for (cp = name; *cp; *p++ = *cp++)
1784 			;
1785 		cp = ".a";
1786 		while (*p++ = *cp++)
1787 			;
1788 		fd = open(buf, oflags);
1789 	}
1790 	if (fd != -1)
1791 		filname = buf;
1792 	return (fd);
1793 }
1794 
1795 struct nlist **
1796 lookup()
1797 {
1798 	register int sh;
1799 	register struct nlist **hp;
1800 	register char *cp, *cp1;
1801 	register struct symseg *gp;
1802 	register int i;
1803 
1804 	sh = 0;
1805 	for (cp = cursym.n_un.n_name; *cp;)
1806 		sh = (sh<<1) + *cp++;
1807 	sh = (sh & 0x7fffffff) % HSIZE;
1808 	for (gp = symseg; gp < &symseg[NSEG]; gp++) {
1809 		if (gp->sy_first == 0) {
1810 			gp->sy_first = (struct nlist *)
1811 			    calloc(NSYM, sizeof (struct nlist));
1812 			gp->sy_hfirst = (struct nlist **)
1813 			    calloc(HSIZE, sizeof (struct nlist *));
1814 			if (gp->sy_first == 0 || gp->sy_hfirst == 0)
1815 				error(1, "ran out of space for symbol table");
1816 			gp->sy_last = gp->sy_first + NSYM;
1817 			gp->sy_hlast = gp->sy_hfirst + HSIZE;
1818 		}
1819 		if (gp > csymseg)
1820 			csymseg = gp;
1821 		hp = gp->sy_hfirst + sh;
1822 		i = 1;
1823 		do {
1824 			if (*hp == 0) {
1825 				if (gp->sy_used == NSYM)
1826 					break;
1827 				return (hp);
1828 			}
1829 			cp1 = (*hp)->n_un.n_name;
1830 			for (cp = cursym.n_un.n_name; *cp == *cp1++;)
1831 				if (*cp++ == 0)
1832 					return (hp);
1833 			hp += i;
1834 			i += 2;
1835 			if (hp >= gp->sy_hlast)
1836 				hp -= HSIZE;
1837 		} while (i < HSIZE);
1838 		if (i > HSIZE)
1839 			error(1, "hash table botch");
1840 	}
1841 	error(1, "symbol table overflow");
1842 	/*NOTREACHED*/
1843 }
1844 
1845 symfree(saved)
1846 	struct nlist *saved;
1847 {
1848 	register struct symseg *gp;
1849 	register struct nlist *sp;
1850 
1851 	for (gp = csymseg; gp >= symseg; gp--, csymseg--) {
1852 		sp = gp->sy_first + gp->sy_used;
1853 		if (sp == saved) {
1854 			nextsym = sp;
1855 			return;
1856 		}
1857 		for (sp--; sp >= gp->sy_first; sp--) {
1858 			gp->sy_hfirst[sp->n_hash] = 0;
1859 			gp->sy_used--;
1860 			if (sp == saved) {
1861 				nextsym = sp;
1862 				return;
1863 			}
1864 		}
1865 	}
1866 	if (saved == 0)
1867 		return;
1868 	error(1, "symfree botch");
1869 }
1870 
1871 struct nlist **
1872 slookup(s)
1873 	char *s;
1874 {
1875 
1876 	cursym.n_un.n_name = s;
1877 	cursym.n_type = N_EXT+N_UNDF;
1878 	cursym.n_value = 0;
1879 	return (lookup());
1880 }
1881 
1882 enter(hp)
1883 register struct nlist **hp;
1884 {
1885 	register struct nlist *sp;
1886 
1887 	if (*hp==0) {
1888 		if (hp < csymseg->sy_hfirst || hp >= csymseg->sy_hlast)
1889 			error(1, "enter botch");
1890 		*hp = lastsym = sp = csymseg->sy_first + csymseg->sy_used;
1891 		csymseg->sy_used++;
1892 		sp->n_un.n_name = cursym.n_un.n_name;
1893 		sp->n_type = cursym.n_type;
1894 		sp->n_hash = hp - csymseg->sy_hfirst;
1895 		sp->n_value = cursym.n_value;
1896 		nextsym = lastsym + 1;
1897 		return(1);
1898 	} else {
1899 		lastsym = *hp;
1900 		return(0);
1901 	}
1902 }
1903 
1904 symx(sp)
1905 	struct nlist *sp;
1906 {
1907 	register struct symseg *gp;
1908 
1909 	if (sp == 0)
1910 		return (0);
1911 	for (gp = csymseg; gp >= symseg; gp--)
1912 		/* <= is sloppy so nextsym will always work */
1913 		if (sp >= gp->sy_first && sp <= gp->sy_last)
1914 			return ((gp - symseg) * NSYM + sp - gp->sy_first);
1915 	error(1, "symx botch");
1916 	/*NOTREACHED*/
1917 }
1918 
1919 symreloc()
1920 {
1921 	if(funding) return;
1922 	switch (cursym.n_type & 017) {
1923 
1924 	case N_TEXT:
1925 	case N_EXT+N_TEXT:
1926 		cursym.n_value += ctrel;
1927 		return;
1928 
1929 	case N_DATA:
1930 	case N_EXT+N_DATA:
1931 		cursym.n_value += cdrel;
1932 		return;
1933 
1934 	case N_BSS:
1935 	case N_EXT+N_BSS:
1936 		cursym.n_value += cbrel;
1937 		return;
1938 
1939 	case N_EXT+N_UNDF:
1940 		return;
1941 
1942 	default:
1943 		if (cursym.n_type&N_EXT)
1944 			cursym.n_type = N_EXT+N_ABS;
1945 		return;
1946 	}
1947 }
1948 
1949 error(n, s)
1950 char *s;
1951 {
1952 
1953 	if (errlev==0)
1954 		printf("ld:");
1955 	if (filname) {
1956 		printf("%s", filname);
1957 		if (n != -1 && archdr.ar_name[0])
1958 			printf("(%s)", archdr.ar_name);
1959 		printf(": ");
1960 	}
1961 	printf("%s\n", s);
1962 	if (n == -1)
1963 		return;
1964 	if (n)
1965 		delexit();
1966 	errlev = 2;
1967 }
1968 
1969 readhdr(loc)
1970 off_t loc;
1971 {
1972 
1973 	dseek(&text, loc, (long)sizeof(filhdr));
1974 	mget((short *)&filhdr, sizeof(filhdr), &text);
1975 	if (N_BADMAG(filhdr)) {
1976 		if (filhdr.a_magic == OARMAG)
1977 			error(1, "old archive");
1978 		error(1, "bad magic number");
1979 	}
1980 	if (filhdr.a_text&01 || filhdr.a_data&01)
1981 		error(1, "text/data size odd");
1982 	if (filhdr.a_magic == NMAGIC || filhdr.a_magic == ZMAGIC) {
1983 		cdrel = -round(filhdr.a_text, pagesize);
1984 		cbrel = cdrel - filhdr.a_data;
1985 	} else if (filhdr.a_magic == OMAGIC) {
1986 		cdrel = -filhdr.a_text;
1987 		cbrel = cdrel - filhdr.a_data;
1988 	} else
1989 		error(1, "bad format");
1990 }
1991 
1992 round(v, r)
1993 	int v;
1994 	u_long r;
1995 {
1996 
1997 	r--;
1998 	v += r;
1999 	v &= ~(long)r;
2000 	return(v);
2001 }
2002 
2003 #define	NSAVETAB	8192
2004 char	*savetab;
2005 int	saveleft;
2006 
2007 char *
2008 savestr(cp)
2009 	register char *cp;
2010 {
2011 	register int len;
2012 
2013 	len = strlen(cp) + 1;
2014 	if (len > saveleft) {
2015 		saveleft = NSAVETAB;
2016 		if (len > saveleft)
2017 			saveleft = len;
2018 		savetab = malloc(saveleft);
2019 		if (savetab == 0)
2020 			error(1, "ran out of memory (savestr)");
2021 	}
2022 	strncpy(savetab, cp, len);
2023 	cp = savetab;
2024 	savetab += len;
2025 	saveleft -= len;
2026 	return (cp);
2027 }
2028 
2029 bopen(bp, off, bufsize)
2030 	register struct biobuf *bp;
2031 {
2032 
2033 	bp->b_ptr = bp->b_buf = malloc(bufsize);
2034 	if (bp->b_ptr == (char *)0)
2035 		error(1, "ran out of memory (bopen)");
2036 	bp->b_bufsize = bufsize;
2037 	bp->b_nleft = bufsize - (off % bufsize);
2038 	bp->b_off = off;
2039 	bp->b_link = biobufs;
2040 	biobufs = bp;
2041 }
2042 
2043 int	bwrerror;
2044 
2045 bwrite(p, cnt, bp)
2046 	register char *p;
2047 	register int cnt;
2048 	register struct biobuf *bp;
2049 {
2050 	register int put;
2051 	register char *to;
2052 
2053 top:
2054 	if (cnt == 0)
2055 		return;
2056 	if (bp->b_nleft) {
2057 		put = bp->b_nleft;
2058 		if (put > cnt)
2059 			put = cnt;
2060 		bp->b_nleft -= put;
2061 		to = bp->b_ptr;
2062 		bcopy(p, to, put);
2063 		bp->b_ptr += put;
2064 		p += put;
2065 		cnt -= put;
2066 		goto top;
2067 	}
2068 	if (cnt >= bp->b_bufsize) {
2069 		if (bp->b_ptr != bp->b_buf)
2070 			bflush1(bp);
2071 		put = cnt - cnt % bp->b_bufsize;
2072 		if (boffset != bp->b_off)
2073 			lseek(biofd, bp->b_off, 0);
2074 		if (write(biofd, p, put) != put) {
2075 			bwrerror = 1;
2076 			error(1, "output write error");
2077 		}
2078 		bp->b_off += put;
2079 		boffset = bp->b_off;
2080 		p += put;
2081 		cnt -= put;
2082 		goto top;
2083 	}
2084 	bflush1(bp);
2085 	goto top;
2086 }
2087 
2088 bflush()
2089 {
2090 	register struct biobuf *bp;
2091 
2092 	if (bwrerror)
2093 		return;
2094 	for (bp = biobufs; bp; bp = bp->b_link)
2095 		bflush1(bp);
2096 }
2097 
2098 bflush1(bp)
2099 	register struct biobuf *bp;
2100 {
2101 	register int cnt = bp->b_ptr - bp->b_buf;
2102 
2103 	if (cnt == 0)
2104 		return;
2105 	if (boffset != bp->b_off)
2106 		lseek(biofd, bp->b_off, 0);
2107 	if (write(biofd, bp->b_buf, cnt) != cnt) {
2108 		bwrerror = 1;
2109 		error(1, "output write error");
2110 	}
2111 	bp->b_off += cnt;
2112 	boffset = bp->b_off;
2113 	bp->b_ptr = bp->b_buf;
2114 	bp->b_nleft = bp->b_bufsize;
2115 }
2116 
2117 bflushc(bp, c)
2118 	register struct biobuf *bp;
2119 {
2120 
2121 	bflush1(bp);
2122 	bputc(c, bp);
2123 }
2124 
2125 bseek(bp, off)
2126 	register struct biobuf *bp;
2127 	register off_t off;
2128 {
2129 	bflush1(bp);
2130 
2131 	bp->b_nleft = bp->b_bufsize - (off % bp->b_bufsize);
2132 	bp->b_off = off;
2133 }
2134