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