fixes for range locking
[unix-history] / usr / src / old / ld / ld.c
CommitLineData
bcf1365c
DF
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
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
7ea0db89 13#ifndef lint
9ac70037 14static char sccsid[] = "@(#)ld.c 5.17 (Berkeley) %G%";
bcf1365c 15#endif not lint
c0278934 16
c4e4978a 17/*
a8cefc6a 18 * ld - string table version for VAX
c4e4978a
BJ
19 */
20
9706079d 21#include <sys/param.h>
7af1139d
KB
22#include <sys/stat.h>
23#include <sys/file.h>
24#include <sys/signal.h>
537f7e17
BJ
25#include <ar.h>
26#include <a.out.h>
c4e4978a 27#include <ranlib.h>
7af1139d
KB
28#include <stdio.h>
29#include <ctype.h>
30#include <string.h>
dca4fc85 31#include "pathnames.h"
c4e4978a
BJ
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 */
92struct 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
119struct nlist cursym; /* current symbol */
120struct nlist *lastsym; /* last symbol entered */
121struct nlist *nextsym; /* next available symbol table entry */
122struct nlist *addsym; /* first sym defined during incr load */
123int nsym; /* pass2: number of local symbols in a.out */
124/* nsym + symx(nextsym) is the symbol table size during pass2 */
125
126struct nlist **lookup(), **slookup();
537f7e17 127struct nlist *p_etext, *p_edata, *p_end, *entrypt;
c4e4978a
BJ
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 */
136off_t li_init[NROUT];
137struct 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.
c4e4978a
BJ
154 */
155#define LHSIZ 31
156struct 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];
161struct 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 */
180int tnum; /* number of symbols in table of contents */
181int ssiz; /* size of string table for table of contents */
182struct ranlib *tab; /* the table of contents (dynamically allocated) */
183char *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,
537f7e17 189 * and now serve only to catch ``Premature EOF''.
c0278934 190 * In order to make I/O more efficient, we provide routines which
175b0d05 191 * use the optimal block size returned by stat().
c4e4978a 192 */
c0278934 193#define BLKSIZE 1024
c4e4978a
BJ
194typedef struct {
195 short *fakeptr;
196 int bno;
197 int nibuf;
198 int nuser;
175b0d05
RC
199 char *buff;
200 int bufsize;
c4e4978a
BJ
201} PAGE;
202
203PAGE page[2];
175b0d05
RC
204int p_blksize;
205int p_blkshift;
206int p_blkmask;
c4e4978a
BJ
207
208struct {
209 short *fakeptr;
210 int bno;
211 int nibuf;
212 int nuser;
213} fpage;
214
215typedef struct {
216 char *ptr;
217 int bno;
218 int nibuf;
219 long size;
220 long pos;
221 PAGE *pno;
222} STREAM;
223
224STREAM text;
225STREAM reloc;
226
227/*
228 * Header from the a.out and the archive it is from (if any).
229 */
230struct exec filhdr;
231struct ar_hdr archdr;
232#define OARMAG 0177545
233
234/*
235 * Options.
236 */
237int trace;
238int xflag; /* discard local symbols */
239int Xflag; /* discard locals starting with 'L' */
240int Sflag; /* discard all except locals and globals*/
241int rflag; /* preserve relocation bits, don't define common */
242int arflag; /* original copy of rflag */
243int sflag; /* discard all symbols */
a8cefc6a 244int Mflag; /* print rudimentary load map */
c4e4978a
BJ
245int nflag; /* pure procedure */
246int dflag; /* define common even with rflag */
537f7e17 247int zflag; /* demand paged */
c4e4978a
BJ
248long hsize; /* size of hole at beginning of data to be squashed */
249int Aflag; /* doing incremental load */
537f7e17 250int Nflag; /* want impure a.out */
c4e4978a 251int funding; /* reading fundamental file for incremental load */
a8cefc6a
BJ
252int yflag; /* number of symbols to be traced */
253char **ytab; /* the symbols */
c4e4978a
BJ
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 */
259off_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.
537f7e17
BJ
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.)
c4e4978a
BJ
268 */
269long ctrel, cdrel, cbrel;
270
271/*
537f7e17 272 * Textbase is the start address of all text, 0 unless given by -T.
c4e4978a 273 * Database is the base of all data, computed before and used during pass2.
537f7e17
BJ
274 */
275long textbase, database;
276
277/*
c4e4978a
BJ
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 */
c4e4978a
BJ
281long 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 */
290int errlev;
291int 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 */
301struct biobuf {
302 short b_nleft; /* Number free spaces left in b_buf */
175b0d05 303/* Initialize to be less than b_bufsize initially, to boundary align in file */
c4e4978a 304 char *b_ptr; /* Next place to stuff characters */
175b0d05
RC
305 char *b_buf; /* Pointer to the buffer */
306 int b_bufsize; /* Size of the buffer */
c4e4978a
BJ
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))
312int biofd;
313off_t boffset;
314struct 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 */
322off_t offset = sizeof (off_t);
323
324int ofilfnd; /* -o given; otherwise move l.out to a.out */
f0e1a97a 325char *ofilename = "l.out";
68694648 326int ofilemode; /* respect umask even for unsucessful ld's */
c4e4978a
BJ
327int infil; /* current input file descriptor */
328char *filname; /* and its name */
329
9706079d 330#define NDIRS 25
f6318ea9 331#define NDEFDIRS 3 /* number of default directories in dirs[] */
9706079d
SL
332char *dirs[NDIRS]; /* directories for library search */
333int ndir; /* number of directories */
334
c4e4978a
BJ
335/*
336 * Base of the string table of the current module (pass1 and pass2).
337 */
338char *curstr;
339
7ea0db89
SL
340/*
341 * System software page size, as returned by getpagesize.
342 */
343int pagesize;
344
c4e4978a
BJ
345char get();
346int delexit();
347char *savestr();
9706079d 348char *malloc();
c4e4978a
BJ
349
350main(argc, argv)
351char **argv;
352{
353 register int c, i;
354 int num;
355 register char *ap, **p;
356 char save;
357
537f7e17 358 if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
c4e4978a 359 signal(SIGINT, delexit);
537f7e17
BJ
360 signal(SIGTERM, delexit);
361 }
c4e4978a
BJ
362 if (argc == 1)
363 exit(4);
7ea0db89 364 pagesize = getpagesize();
c4e4978a 365
9706079d
SL
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");
f6318ea9 374 if (ndir >= NDIRS - NDEFDIRS)
9706079d
SL
375 error(1, "-L: too many directories");
376 dirs[ndir++] = &ap[2];
377 }
378 }
379 /* add default search directories */
dca4fc85
KB
380 dirs[ndir++] = _PATH_USRLIB;
381 dirs[ndir++] = _PATH_LOCALLIB;
9706079d
SL
382
383 p = argv+1;
537f7e17
BJ
384 /*
385 * Scan files once to find where symbols are defined.
386 */
c4e4978a
BJ
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?");
f0e1a97a 401 ofilename = *p++;
c4e4978a
BJ
402 ofilfnd++;
403 continue;
404 case 'u':
405 case 'e':
406 if (++c >= argc)
356a04c5 407 error(1, " -u or -e: arg missing");
c4e4978a
BJ
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;
a8cefc6a
BJ
454 case 'M':
455 Mflag++;
456 continue;
c4e4978a
BJ
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++;
c4e4978a
BJ
469 continue;
470 case 's':
471 sflag++;
472 xflag++;
473 continue;
474 case 'n':
475 nflag++;
537f7e17 476 Nflag = zflag = 0;
c4e4978a
BJ
477 continue;
478 case 'N':
537f7e17
BJ
479 Nflag++;
480 nflag = zflag = 0;
c4e4978a
BJ
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;
a8cefc6a
BJ
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;
c4e4978a
BJ
501 case 'z':
502 zflag++;
537f7e17 503 Nflag = nflag = 0;
c4e4978a 504 continue;
9706079d
SL
505 case 'L':
506 goto next;
c4e4978a
BJ
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 }
513next:
514 ;
515 }
537f7e17
BJ
516 if (rflag == 0 && Nflag == 0 && nflag == 0)
517 zflag++;
c4e4978a
BJ
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 */
526htoi(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
546delexit()
547{
a7acd2d7
KM
548 struct stat stbuf;
549 long size;
550 char c = 0;
c4e4978a
BJ
551
552 bflush();
f0e1a97a 553 unlink("l.out");
a7acd2d7
KM
554 /*
555 * We have to insure that the last block of the data segment
175b0d05
RC
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
a7acd2d7
KM
559 * that when it is demand paged, the paged in block will be
560 * appropriately filled with zeros.
561 */
562 fstat(biofd, &stbuf);
175b0d05 563 size = round(stbuf.st_size, pagesize);
c5aa50e2 564 if (!rflag && size > stbuf.st_size) {
a7acd2d7 565 lseek(biofd, size - 1, 0);
3d7aefd6
JB
566 if (write(biofd, &c, 1) != 1)
567 delarg |= 4;
a7acd2d7 568 }
3d7aefd6
JB
569 if (delarg==0 && Aflag==0)
570 (void) chmod(ofilename, ofilemode);
c4e4978a
BJ
571 exit (delarg);
572}
573
574endload(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;
a8cefc6a 619 case 'y':
9706079d 620 case 'L':
a8cefc6a 621 goto next;
c4e4978a
BJ
622 case 'l':
623 ap[--i]='-';
624 load2arg(&ap[i]);
625 goto next;
626 }
627next:
628 ;
629 }
630 finishout();
631}
632
633/*
634 * Scan file to find defined symbols.
635 */
636load1arg(cp)
637 register char *cp;
638{
639 register struct ranlib *tp;
640 off_t nloc;
a8cefc6a 641 int kind;
c4e4978a 642
a8cefc6a
BJ
643 kind = getfile(cp);
644 if (Mflag)
645 printf("%s\n", filname);
646 switch (kind) {
c4e4978a
BJ
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:
a8cefc6a
BJ
660 error(-1,
661"warning: archive has no table of contents; add one using ranlib(1)");
c4e4978a
BJ
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;
b4257678
JL
703 free((char *)tab);
704 free(tabstr);
c4e4978a
BJ
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:
a8cefc6a
BJ
713 error(-1,
714"warning: table of contents for archive is out of date; rerun ranlib(1)");
c4e4978a
BJ
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 */
731step(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 */
751nextlibp(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;
a8cefc6a
BJ
763 if (val != -1 && Mflag)
764 printf("\t%s\n", archdr.ar_name);
c4e4978a
BJ
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 */
774ldrand()
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++) {
b4257678 783 if ((hp = slookup(tp->ran_un.ran_name)) == 0 || *hp == 0)
c4e4978a
BJ
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 */
799load1(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) {
65871749
KB
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);
c4e4978a 815 return (0);
65871749 816 }
c4e4978a
BJ
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
897middle()
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
c4e4978a
BJ
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 &&
537f7e17 921 sp!=p_end && sp!=p_edata && sp!=p_etext) {
c4e4978a
BJ
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,
7ea0db89 937 (nflag||zflag? pagesize : sizeof (long)));
c4e4978a
BJ
938 database += hsize;
939 if (dflag || rflag==0) {
c4e4978a
BJ
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:
45e82142
RE
980 if (arflag == 0)
981 errlev |= 01;
c4e4978a 982 if ((arflag==0 || dflag) && sp->n_value==0) {
537f7e17
BJ
983 if (sp==p_end || sp==p_etext || sp==p_edata)
984 continue;
c4e4978a
BJ
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) {
c4e4978a
BJ
1014 fixspec(p_etext,torigin);
1015 fixspec(p_edata,dorigin);
1016 fixspec(p_end,borigin);
1017 }
1018}
1019
1020fixspec(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
1029ldrsym(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
1045off_t wroff;
1046struct biobuf toutb;
1047
1048setupout()
1049{
7af1139d 1050 extern int errno;
c4e4978a 1051 int bss;
175b0d05 1052 struct stat stbuf;
c4e4978a 1053
68694648
KS
1054 ofilemode = 0777 & ~umask(0);
1055 biofd = creat(ofilename, 0666 & ofilemode);
a8cefc6a
BJ
1056 if (biofd < 0) {
1057 filname = ofilename; /* kludge */
1058 archdr.ar_name[0] = 0; /* kludge */
7af1139d 1059 error(1, strerror(errno)); /* kludge */
a8cefc6a 1060 }
175b0d05
RC
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 }
6a1f8741
KB
1066#ifdef hp300
1067 filhdr.a_mid = (rflag ? MID_ZERO : MID_HP300);
1068#endif
c4e4978a
BJ
1069 filhdr.a_magic = nflag ? NMAGIC : (zflag ? ZMAGIC : OMAGIC);
1070 filhdr.a_text = nflag ? tsize :
7ea0db89
SL
1071 round(tsize, zflag ? pagesize : sizeof (long));
1072 filhdr.a_data = zflag ? round(dsize, pagesize) : dsize;
c4e4978a
BJ
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);
175b0d05
RC
1089 tout = &toutb;
1090 bopen(tout, 0, stbuf.st_blksize);
c4e4978a 1091 bwrite((char *)&filhdr, sizeof (filhdr), tout);
175b0d05
RC
1092 if (zflag)
1093 bseek(tout, pagesize);
c4e4978a 1094 wroff = N_TXTOFF(filhdr) + filhdr.a_text;
175b0d05 1095 outb(&dout, filhdr.a_data, stbuf.st_blksize);
c4e4978a 1096 if (rflag) {
175b0d05
RC
1097 outb(&trout, filhdr.a_trsize, stbuf.st_blksize);
1098 outb(&drout, filhdr.a_drsize, stbuf.st_blksize);
c4e4978a
BJ
1099 }
1100 if (sflag==0 || xflag==0) {
175b0d05 1101 outb(&sout, filhdr.a_syms, stbuf.st_blksize);
c4e4978a 1102 wroff += sizeof (offset);
175b0d05 1103 outb(&strout, 0, stbuf.st_blksize);
c4e4978a
BJ
1104 }
1105}
1106
175b0d05 1107outb(bp, inc, bufsize)
c4e4978a
BJ
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)");
175b0d05 1114 bopen(*bp, wroff, bufsize);
c4e4978a
BJ
1115 wroff += inc;
1116}
1117
1118load2arg(acp)
1119char *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
1150load2(loc)
1151long 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);
537f7e17 1160 if (!funding) {
c4e4978a
BJ
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;
a8cefc6a
BJ
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 }
c4e4978a
BJ
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);
537f7e17 1267 load2td(ctrel, torigin - textbase, tout, trout);
c4e4978a
BJ
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);
537f7e17 1271 load2td(cdrel, dorigin - database, dout, drout);
c4e4978a
BJ
1272 while (filhdr.a_data & (sizeof(long)-1)) {
1273 bputc(0, dout);
1274 filhdr.a_data++;
1275 }
1276 torigin += filhdr.a_text;
168b3434
BJ
1277 dorigin += round(filhdr.a_data, sizeof (long));
1278 borigin += round(filhdr.a_bss, sizeof (long));
c4e4978a
BJ
1279 free(curstr);
1280}
1281
a8cefc6a
BJ
1282struct 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
1295tracesym()
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
1eb0f2eb
SL
1321#if !defined(tahoe)
1322/* for machines which allow arbitrarily aligned word and longword accesses */
9ac70037 1323#define getword(cp) (*(short *)(cp))
1eb0f2eb
SL
1324#define getl(cp) (*(long *)(cp))
1325#define putw(cp, w) (*(short *)(cp) = (w))
1326#define putl(cp, l) (*(long *)(cp) = (l))
1327#else
1328short
9ac70037 1329getword(cp)
1eb0f2eb
SL
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
1342getl(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
1357putw(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
1371putl(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
537f7e17
BJ
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 */
1401load2td(creloc, position, b1, b2)
eef82c2c 1402 long creloc, position;
c4e4978a
BJ
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;
c4e4978a
BJ
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++) {
c4e4978a 1424 cp = codep + rp->r_address;
537f7e17
BJ
1425 /*
1426 * Pick up previous value at location to be relocated.
1427 */
c4e4978a
BJ
1428 switch (rp->r_length) {
1429
1430 case 0: /* byte */
1431 tw = *cp;
1432 break;
1433
1434 case 1: /* word */
9ac70037 1435 tw = getword(cp);
c4e4978a
BJ
1436 break;
1437
1438 case 2: /* long */
1eb0f2eb 1439 tw = getl(cp);
c4e4978a
BJ
1440 break;
1441
1442 default:
1443 error(1, "load2td botch: bad length");
1444 }
537f7e17
BJ
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 */
c4e4978a 1452 if (rp->r_extern) {
537f7e17
BJ
1453 /*
1454 * Search the hash table which maps local
1455 * symbol numbers to symbol tables entries
1456 * in the new a.out file.
1457 */
c4e4978a
BJ
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) {
537f7e17
BJ
1473 /*
1474 * Relocation is relative to the loaded position
1475 * of another segment. Update by the change in position
1476 * of that segment.
1477 */
c4e4978a
BJ
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 }
537f7e17
BJ
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 */
c4e4978a 1501 if (rp->r_pcrel)
c4e4978a 1502 tw -= creloc;
537f7e17
BJ
1503 /*
1504 * Put the value back in the segment,
1505 * while checking for overflow.
1506 */
c4e4978a
BJ
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");
1eb0f2eb 1517 putw(cp, tw);
c4e4978a
BJ
1518 break;
1519 case 2: /* long */
1eb0f2eb 1520 putl(cp, tw);
c4e4978a
BJ
1521 break;
1522 }
537f7e17
BJ
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 */
c4e4978a 1530 if (rflag)
537f7e17 1531 rp->r_address += position;
c4e4978a
BJ
1532 }
1533 bwrite(codep, codesz, b1);
1534 if (rflag)
1535 bwrite(relp, relsz, b2);
b4257678
JL
1536 free((char *)relp);
1537 free(codep);
c4e4978a
BJ
1538}
1539
1540finishout()
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) {
f0e1a97a
KB
1552 unlink("a.out");
1553 if (link("l.out", "a.out") < 0)
a8cefc6a 1554 error(1, "cannot move l.out to a.out");
f0e1a97a 1555 ofilename = "a.out";
c4e4978a
BJ
1556 }
1557 delarg = errlev;
1558 delexit();
1559}
1560
1561mkfsym(s)
1562char *s;
1563{
1564
1565 if (sflag || xflag)
1566 return;
1567 cursym.n_un.n_name = s;
97cf0e7b 1568 cursym.n_type = N_EXT | N_FN;
c4e4978a
BJ
1569 cursym.n_value = torigin;
1570 symwrite(&cursym, sout);
1571}
1572
1573getarhdr()
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
1585mget(loc, n, sp)
1586register STREAM *sp;
1587register char *loc;
1588{
1589 register char *p;
1590 register int take;
1591
1592top:
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 }
175b0d05
RC
1612 if (n > p_blksize) {
1613 take = n - n % p_blksize;
1614 lseek(infil, (sp->bno+1)<<p_blkshift, 0);
c4e4978a
BJ
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;
175b0d05 1621 dseek(sp, (sp->bno+1+(take>>p_blkshift))<<p_blkshift, -1);
c4e4978a
BJ
1622 goto top;
1623 }
1624 *loc++ = get(sp);
1625 --n;
1626 goto top;
1627}
1628
1629symwrite(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
1647dseek(sp, loc, s)
1648register STREAM *sp;
1649long loc, s;
1650{
1651 register PAGE *p;
1652 register b, o;
1653 int n;
1654
175b0d05
RC
1655 b = loc>>p_blkshift;
1656 o = loc&p_blkmask;
c4e4978a
BJ
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;
175b0d05
RC
1666 lseek(infil, loc & ~(long)p_blkmask, 0);
1667 if ((n = read(infil, p->buff, p_blksize)) < 0)
c4e4978a
BJ
1668 n = 0;
1669 p->nibuf = n;
175b0d05
RC
1670 } else
1671 error(1, "botch: no pages");
c4e4978a
BJ
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
1681char
1682get(asp)
1683STREAM *asp;
1684{
1685 register STREAM *sp;
1686
1687 sp = asp;
1688 if ((sp->nibuf -= sizeof(char)) < 0) {
175b0d05 1689 dseek(sp, ((long)(sp->bno+1)<<p_blkshift), (long)-1);
c4e4978a
BJ
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
1703getfile(acp)
1704char *acp;
1705{
c4e4978a
BJ
1706 register int c;
1707 char arcmag[SARMAG+1];
1708 struct stat stb;
1709
c4e4978a 1710 archdr.ar_name[0] = '\0';
9706079d
SL
1711 filname = acp;
1712 if (filname[0] == '-' && filname[1] == 'l')
1713 infil = libopen(filname + 2, O_RDONLY);
1714 else
f0e1a97a 1715 infil = open(filname, O_RDONLY);
9706079d 1716 if (infil < 0)
c4e4978a 1717 error(1, "cannot open");
175b0d05 1718 fstat(infil, &stb);
c4e4978a
BJ
1719 page[0].bno = page[1].bno = -1;
1720 page[0].nuser = page[1].nuser = 0;
175b0d05
RC
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 }
c4e4978a
BJ
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);
9706079d 1752 if (text.size <= 0)
c4e4978a
BJ
1753 return (1);
1754 getarhdr();
d93c729e 1755 if (strncmp(archdr.ar_name, RANLIBMAG, sizeof(archdr.ar_name)) != 0)
c4e4978a 1756 return (1);
c4e4978a
BJ
1757 return (stb.st_mtime > atol(archdr.ar_date) ? 3 : 2);
1758}
1759
9706079d
SL
1760/*
1761 * Search for a library with given name
1762 * using the directory search array.
1763 */
1764libopen(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
c4e4978a
BJ
1794struct nlist **
1795lookup()
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
1844symfree(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
1870struct nlist **
1871slookup(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
1881enter(hp)
1882register 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
1903symx(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
1918symreloc()
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
1948error(n, s)
1949char *s;
1950{
a8cefc6a 1951
c4e4978a
BJ
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
1968readhdr(loc)
1969off_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) {
7ea0db89 1982 cdrel = -round(filhdr.a_text, pagesize);
c4e4978a
BJ
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
1991round(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
2003char *savetab;
2004int saveleft;
2005
2006char *
2007savestr(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;
9706079d 2017 savetab = malloc(saveleft);
c4e4978a
BJ
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
175b0d05
RC
2028bopen(bp, off, bufsize)
2029 register struct biobuf *bp;
c4e4978a
BJ
2030{
2031
9706079d 2032 bp->b_ptr = bp->b_buf = malloc(bufsize);
175b0d05
RC
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);
c4e4978a
BJ
2037 bp->b_off = off;
2038 bp->b_link = biobufs;
2039 biobufs = bp;
2040}
2041
2042int bwrerror;
2043
2044bwrite(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
2052top:
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;
3d7aefd6 2061 bcopy(p, to, put);
c4e4978a
BJ
2062 bp->b_ptr += put;
2063 p += put;
2064 cnt -= put;
2065 goto top;
2066 }
175b0d05 2067 if (cnt >= bp->b_bufsize) {
c4e4978a
BJ
2068 if (bp->b_ptr != bp->b_buf)
2069 bflush1(bp);
175b0d05 2070 put = cnt - cnt % bp->b_bufsize;
c4e4978a
BJ
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
2087bflush()
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
2097bflush1(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;
175b0d05 2113 bp->b_nleft = bp->b_bufsize;
c4e4978a
BJ
2114}
2115
2116bflushc(bp, c)
2117 register struct biobuf *bp;
2118{
2119
2120 bflush1(bp);
2121 bputc(c, bp);
2122}
175b0d05
RC
2123
2124bseek(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}