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