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