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