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