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