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