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