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