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