1: /*
   2:  *  link editor
   3:  *  modified to be a overlayed segmentation register loader by wnj 6/79
   4:  *  touched up by bill jolitz 9/79.
   5:  *  working with emt trap thunk fmt 5/80 bill jolitz.
   6:  *  8-byte thunks, more touch-ups, mjk 9/81.
   7:  */
   8: 
   9: #include <stdio.h>
  10: #include <signal.h>
  11: #include <sys/types.h>
  12: #include <sys/stat.h>
  13: 
  14: /*	Layout of a.out file :
  15:  *
  16:  *	header of 8 words	magic number 405, 407, 410, 411
  17:  *				text size	)
  18:  *				data size	) in bytes but even
  19:  *				bss size	)
  20:  *				symbol table size
  21:  *				entry point
  22:  *				{unused}
  23:  *				flag set if no relocation
  24:  *
  25:  *
  26:  *	header:		0
  27:  *	text:		16
  28:  *	data:		16+textsize
  29:  *	relocation:	16+textsize+datasize
  30:  *	symbol table:	16+2*(textsize+datasize) or 16+textsize+datasize
  31:  *
  32:  */
  33: #define TRUE    1
  34: #define FALSE   0
  35: 
  36: 
  37: #define ARCMAGIC 0177545
  38: #define OMAGIC  0405
  39: #define FMAGIC  0407
  40: #define NMAGIC  0410
  41: #define IMAGIC  0411
  42: 
  43: #define EXTERN  040
  44: #define UNDEF   00
  45: #define ABS 01
  46: #define TEXT    02
  47: #define DATA    03
  48: #define BSS 04
  49: #define COMM    05  /* internal use only */
  50: 
  51: #define RABS    00
  52: #define RTEXT   02
  53: #define RDATA   04
  54: #define RBSS    06
  55: #define REXT    010
  56: 
  57: #define NOVLY   16
  58: #define RELFLG  01
  59: #define NROUT   256
  60: #define NSYM    1103
  61: #define NSYMPR  1000
  62: 
  63: char    premeof[] = "Premature EOF";
  64: char    goodnm[] = "__.SYMDEF";
  65: 
  66: /* table of contents stuff */
  67: #define TABSZ   700
  68: struct tab
  69: {   char cname[8];
  70:     long cloc;
  71: } tab[TABSZ];
  72: int tnum;
  73: 
  74: 
  75: /* overlay management */
  76: int vindex;
  77: struct overlay {
  78:     int argsav;
  79:     int symsav;
  80:     struct liblist  *libsav;
  81:     char    *vname;
  82:     int ctsav, cdsav, cbsav;
  83:     int offt, offd, offb, offs;
  84: } vnodes[NOVLY];
  85: 
  86: /* input management */
  87: struct page {
  88:     int nuser;
  89:     int bno;
  90:     int nibuf;
  91:     int buff[256];
  92: } page[2];
  93: 
  94: struct {
  95:     int nuser;
  96:     int bno;
  97: } fpage;
  98: 
  99: struct stream {
 100:     int *ptr;
 101:     int bno;
 102:     int nibuf;
 103:     int size;
 104:     struct page *pno;
 105: };
 106: 
 107: struct stream text;
 108: struct stream reloc;
 109: 
 110: struct {
 111:     char    aname[14];
 112:     long    atime;
 113:     char    auid, agid;
 114:     int amode;
 115:     long    asize;
 116: } archdr;
 117: 
 118: struct {
 119:     int fmagic;
 120:     int tsize;
 121:     int dsize;
 122:     int bsize;
 123:     int ssize;
 124:     int entry;
 125:     int pad;
 126:     int relflg;
 127: } filhdr;
 128: 
 129: 
 130: /* one entry for each archive member referenced;
 131:  * set in first pass; needs restoring for overlays
 132:  */
 133: struct liblist {
 134:     long    loc;
 135: };
 136: 
 137: struct liblist  liblist[NROUT];
 138: struct liblist  *libp = liblist;
 139: 
 140: 
 141: /* symbol management */
 142: struct symbol {
 143:     char    sname[8];
 144:     char    stype;
 145:     char    sovly;
 146:     int svalue;
 147:     int sovalue;
 148: };
 149: 
 150: struct xsymbol {
 151:     char    sname[8];
 152:     char    stype;
 153:     char    sovly;
 154:     int svalue;
 155: };
 156: struct local {
 157:     int locindex;       /* index to symbol in file */
 158:     struct symbol *locsymbol;   /* ptr to symbol table */
 159: };
 160: 
 161: struct xsymbol  cursym;         /* current symbol */
 162: struct symbol   symtab[NSYM];       /* actual symbols */
 163: struct symbol   **symhash[NSYM];    /* ptr to hash table entry */
 164: struct symbol   *lastsym;       /* last symbol entered */
 165: int symindex;       /* next available symbol table entry */
 166: struct symbol   *hshtab[NSYM+2];    /* hash table for symbols */
 167: struct local    local[NSYMPR];
 168: 
 169: /* internal symbols */
 170: struct symbol   *p_etext;
 171: struct symbol   *p_edata;
 172: struct symbol   *p_end;
 173: struct symbol   *entrypt;
 174: 
 175: int trace;
 176: /* flags */
 177: int xflag;      /* discard local symbols */
 178: int Xflag;      /* discard locals starting with 'L' */
 179: int Sflag;      /* discard all except locals and globals*/
 180: int rflag;      /* preserve relocation bits, don't define common */
 181: int arflag;     /* original copy of rflag */
 182: int sflag;      /* discard all symbols */
 183: int nflag;      /* pure procedure */
 184: int Oflag;      /* set magic # to 0405 (overlay) */
 185: int dflag;      /* define common even with rflag */
 186: int iflag;      /* I/D space separated */
 187: int vflag;      /* overlays used */
 188: 
 189: int ofilfnd;
 190: char    *ofilename = "l.out";
 191: int infil;
 192: char    *filname;
 193: 
 194: /* cumulative sizes set in pass 1 */
 195: int tsize;
 196: int dsize;
 197: int bsize;
 198: int ssize;
 199: 
 200: /* symbol relocation; both passes */
 201: int ctrel;
 202: int cdrel;
 203: int cbrel;
 204: 
 205: int errlev;
 206: int delarg  = 4;
 207: char    tfname[] = "/tmp/ldaXXXXX";
 208: 
 209: 
 210: /* output management */
 211: struct buf {
 212:     int fildes;
 213:     int nleft;
 214:     int *xnext;
 215:     int iobuf[256];
 216: };
 217: struct buf  toutb;
 218: struct buf  doutb;
 219: struct buf  troutb;
 220: struct buf  droutb;
 221: struct buf  soutb;
 222: 
 223: /* wnj added for text overlay register */
 224: 
 225: #define NOVL        7   /* max number of overlays; this defines
 226: 				 * the header format and must agree with
 227: 				 * the kernel limit. */
 228: #define THUNKSIZ    8
 229: 
 230: int torgwas;        /* Saves torigin while doing overlays */
 231: int tsizwas;        /* Saves tsize while doing overlays */
 232: int numov;          /* Total number of overlays */
 233: int curov;          /* Overlay being worked on just now */
 234: int inov;           /* 1 if working on an overlay */
 235: int ovsize[NOVL+1]; /* The sizes of the overlays */
 236: 
 237: #define max ovsize[0]
 238: 
 239: struct buf  voutb;      /* Overlay text goes here */
 240: /*
 241: struct buf	dummyb;
 242: */
 243: 
 244:                 /* Kernel overlays have a special
 245: 				   subroutine to do the switch */
 246: struct  xsymbol ovhndlr =
 247:     { "ovhndlr1", EXTERN+UNDEF, 0, 0 };
 248: #define HNDLR_NUM 7 /* position of ov number in ovhndlr.sname[] */
 249: int ovbase;         /* The base address of the overlays */
 250: /* end overlay stuff */
 251: 
 252: struct symbol   **lookup();
 253: struct symbol   **slookup();
 254: struct symbol   *lookloc();
 255: 
 256: delexit()
 257: {
 258:     unlink("l.out");
 259:     if (delarg==0)
 260:         chmod(ofilename, 0777 & ~umask(0));
 261:     exit(delarg);
 262: }
 263: 
 264: main(argc, argv)
 265: char **argv;
 266: {
 267:     register int c, i;
 268:     int num;
 269:     register char *ap, **p;
 270:     int found;
 271:     int vscan;
 272:     char save;
 273: 
 274:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
 275:         signal(SIGINT, delexit);
 276:     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
 277:         signal(SIGTERM, delexit);
 278:     if (argc == 1)
 279:         exit(4);
 280:     p = argv+1;
 281: 
 282:     /* scan files once to find symdefs */
 283:     for (c=1; c<argc; c++) {
 284:         if (trace) printf("%s:\n", *p);
 285:         filname = 0;
 286:         ap = *p++;
 287: 
 288:         if (*ap == '-') {
 289:             for (i=1; ap[i]; i++) {
 290:             switch (ap[i]) {
 291:             case 'o':
 292:                 if (++c >= argc)
 293:                     error(2, "Bad output file");
 294:                 ofilename = *p++;
 295:                 ofilfnd++;
 296:                 continue;
 297: 
 298:             case 'u':
 299:             case 'e':
 300:                 if (++c >= argc)
 301:                     error(2, "Bad 'use' or 'entry'");
 302:                 enter(slookup(*p++));
 303:                 if (ap[i]=='e')
 304:                     entrypt = lastsym;
 305:                 continue;
 306: 
 307:             case 'v':
 308:                 if (++c >= argc)
 309:                     error(2, "-v: arg missing");
 310:                 vflag=TRUE;
 311:                 vscan = vindex;
 312:                 found=FALSE;
 313:                 while (--vscan>=0 && found==FALSE)
 314:                     found = eq(vnodes[vscan].vname, *p);
 315:                 if (found) {
 316:                     endload(c, argv);
 317:                     restore(vscan);
 318:                 } else
 319:                     record(c, *p);
 320:                 p++;
 321:                 continue;
 322: 
 323:             case 'D':
 324:                 if (++c >= argc)
 325:                     error(2, "-D: arg missing");
 326:                 num = atoi(*p++);
 327:                 if (dsize>num)
 328:                     error(2, "-D: too small");
 329:                 dsize = num;
 330:                 continue;
 331: 
 332:             case 'l':
 333:                 save = ap[--i];
 334:                 ap[i]='-';
 335:                 load1arg(&ap[i]);
 336:                 ap[i]=save;
 337:                 break;
 338: 
 339:             case 'x':
 340:                 xflag++;
 341:                 continue;
 342: 
 343:             case 'X':
 344:                 Xflag++;
 345:                 continue;
 346: 
 347:             case 'S':
 348:                 Sflag++;
 349:                 continue;
 350: 
 351:             case 'r':
 352:                 rflag++;
 353:                 arflag++;
 354:                 continue;
 355: 
 356:             case 's':
 357:                 sflag++;
 358:                 xflag++;
 359:                 continue;
 360: 
 361:             case 'n':
 362:                 nflag++;
 363:                 continue;
 364: 
 365:             case 'd':
 366:                 dflag++;
 367:                 continue;
 368: 
 369:             case 'i':
 370:                 iflag++;
 371:                 continue;
 372: 
 373:             case 'O':
 374:                 Oflag++;
 375:                 continue;
 376: 
 377:             case 't':
 378:                 trace++;
 379:                 continue;
 380: 
 381: /* wnj added for overlay text registers */
 382:             case 'Z':
 383:                 if (!inov) {
 384:                     tsizwas = tsize;
 385:                     if (numov == 0) {
 386:                         cursym = ovhndlr;
 387:                         enter(lookup());
 388:                     }
 389:                 } else {
 390:                     ovsize[curov] = tsize;
 391:                     if (trace)
 392:                     printf("overlay %d size %d\n", curov, ovsize[curov]);
 393:                 }
 394:                 tsize = 0;
 395:                 inov = 1;
 396:                 numov++;
 397:                 if (numov > NOVL)
 398:                     error(2, "Too many overlays, limit 7");
 399:                 curov++;
 400:                 continue;
 401: 
 402:             case 'L':
 403:                 if (inov == 0)
 404:                     error(2, "-L: Not in overlay");
 405:                 ovsize[curov] = tsize;
 406:                 if (trace)
 407:                 printf("overlay %d size %d\n", curov, ovsize[curov]);
 408:                 curov = inov = 0;
 409:                 tsize = tsizwas;
 410:                 continue;
 411: /* end overlay text addition */
 412: 
 413:             default:
 414:                 error(2, "bad flag");
 415:             } /*endsw*/
 416:             break;
 417:             } /*endfor*/
 418:         } else
 419:             load1arg(ap);
 420:     }
 421:     endload(argc, argv);
 422: }
 423: 
 424: /* used after pass 1 */
 425: int nsym;
 426: int torigin;
 427: int dorigin;
 428: int borigin;
 429: 
 430: endload(argc, argv)
 431: int argc;
 432: char **argv;
 433: {
 434:     register int c, i;
 435:     int dnum;
 436:     register char *ap, **p;
 437: 
 438:     if (numov)
 439:         rflag = 0;
 440:     filname = 0;
 441:     middle();
 442:     setupout();
 443:     p = argv+1;
 444:     libp = liblist;
 445:     for (c=1; c<argc; c++) {
 446:         ap = *p++;
 447:         if (trace) printf("%s:\n", ap);
 448:         if (*ap == '-') {
 449:             for (i=1; ap[i]; i++) {
 450:             switch (ap[i]) {
 451:             case 'D':
 452:                 for (dnum = atoi(*p); dorigin<dnum; dorigin += 2) {
 453:                     putw(0, &doutb);
 454:                     if (rflag)
 455:                         putw(0, &droutb);
 456:                 }
 457:             case 'u':
 458:             case 'e':
 459:             case 'o':
 460:             case 'v':
 461:                 ++c;
 462:                 ++p;
 463: 
 464:             default:
 465:                 continue;
 466: 
 467:             case 'l':
 468:                 ap[--i]='-';
 469:                 load2arg(&ap[i]);
 470:                 break;
 471: 
 472: /* wnj added for overlay text segmentation registers */
 473:             case 'Z':
 474:                 if (inov == 0)
 475:                     torgwas = torigin;
 476:                 else
 477:                     roundov();
 478:                 torigin = ovbase;
 479:                 inov = 1;
 480:                 curov++;
 481:                 continue;
 482: 
 483:             case 'L':
 484:                 roundov();
 485:                 inov = 0;
 486:                 if (trace)
 487:                     printf("end overlay generation\n");
 488:                 torigin = torgwas;
 489:                 continue;
 490: /* end wnj added for text overlay registers */
 491:             } /*endsw*/
 492:             break;
 493:             } /*endfor*/
 494:         } else
 495:             load2arg(ap);
 496:     }
 497:     finishout();
 498: }
 499: 
 500: roundov()
 501: {
 502: 
 503:     while (torigin & 077) {
 504:         putw(0, &voutb);
 505:         torigin += sizeof (int);
 506:     }
 507: }
 508: 
 509: record(c, nam)
 510: int c;
 511: char *nam;
 512: {
 513:     register struct overlay *v;
 514: 
 515:     v = &vnodes[vindex++];
 516:     v->argsav = c;
 517:     v->symsav = symindex;
 518:     v->libsav = libp;
 519:     v->vname = nam;
 520:     v->offt = tsize;
 521:     v->offd = dsize;
 522:     v->offb = bsize;
 523:     v->offs = ssize;
 524:     v->ctsav = ctrel;
 525:     v->cdsav = cdrel;
 526:     v->cbsav = cbrel;
 527: }
 528: 
 529: restore(vscan)
 530: int vscan;
 531: {
 532:     register struct overlay *v;
 533:     register int saved;
 534: 
 535:     v = &vnodes[vscan];
 536:     vindex = vscan+1;
 537:     libp = v->libsav;
 538:     ctrel = v->ctsav;
 539:     cdrel = v->cdsav;
 540:     cbrel = v->cbsav;
 541:     tsize = v->offt;
 542:     dsize = v->offd;
 543:     bsize = v->offb;
 544:     ssize = v->offs;
 545:     saved = v->symsav;
 546:     while (symindex>saved)
 547:         *symhash[--symindex]=0;
 548: }
 549: 
 550: /* scan file to find defined symbols */
 551: load1arg(acp)
 552: char *acp;
 553: {
 554:     register char *cp;
 555:     long nloc;
 556: 
 557:     cp = acp;
 558:     switch ( getfile(cp)) {
 559:     case 0:
 560:         load1(0, 0L);
 561:         break;
 562: 
 563:     /* regular archive */
 564:     case 1:
 565:         nloc = 1;
 566:         while ( step(nloc))
 567:             nloc += (archdr.asize + sizeof(archdr) + 1) >> 1;
 568:         break;
 569: 
 570:     /* table of contents */
 571:     case 2:
 572:         tnum = archdr.asize / sizeof(struct tab);
 573:         if (tnum >= TABSZ) {
 574:             error(2, "fast load buffer too small");
 575:         }
 576:         lseek(infil, (long)(sizeof(filhdr.fmagic)+sizeof(archdr)), 0);
 577:         read(infil, (char *)tab, tnum * sizeof(struct tab));
 578:         while (ldrand());
 579:         libp->loc = -1;
 580:         libp++;
 581:         break;
 582:     /* out of date table of contents */
 583:     case 3:
 584:         error(0, "out of date (warning)");
 585:         for(nloc = 1+((archdr.asize+sizeof(archdr)+1) >> 1); step(nloc);
 586:             nloc += (archdr.asize + sizeof(archdr) + 1) >> 1);
 587:         break;
 588:     }
 589:     close(infil);
 590: }
 591: 
 592: step(nloc)
 593: long nloc;
 594: {
 595:     dseek(&text, nloc, sizeof archdr);
 596:     if (text.size <= 0) {
 597:         libp->loc = -1;
 598:         libp++;
 599:         return(0);
 600:     }
 601:     mget((int *)&archdr, sizeof archdr);
 602:     if (load1(1, nloc + (sizeof archdr) / 2)) {
 603:         libp->loc = nloc;
 604:         libp++;
 605:     }
 606:     return(1);
 607: }
 608: 
 609: ldrand()
 610: {
 611:     int i;
 612:     struct symbol *sp, **pp;
 613:     struct liblist *oldp = libp;
 614:     for(i = 0; i<tnum; i++) {
 615:         if ((pp = slookup(tab[i].cname)) == 0)
 616:             continue;
 617:         sp = *pp;
 618:         if (sp->stype != EXTERN+UNDEF)
 619:             continue;
 620:         step(tab[i].cloc >> 1);
 621:     }
 622:     return(oldp != libp);
 623: }
 624: 
 625: add(a,b,s)
 626: int a, b;
 627: char *s;
 628: {
 629:     long r;
 630: 
 631:     r = (long)(unsigned)a + (unsigned)b;
 632:     if (r >= 0200000)
 633:         error(1,s);
 634:     return(r);
 635: }
 636: 
 637: 
 638: /* single file or archive member */
 639: load1(libflg, loc)
 640: long loc;
 641: {
 642:     register struct symbol *sp;
 643:     int savindex;
 644:     int ndef, nloc, type, mtype;
 645: 
 646:     readhdr(loc);
 647:     ctrel = tsize;
 648:     cdrel += dsize;
 649:     cbrel += bsize;
 650:     ndef = 0;
 651:     nloc = sizeof cursym;
 652:     savindex = symindex;
 653:     if ((filhdr.relflg&RELFLG)==1) {
 654:         error(1, "No relocation bits");
 655:         return(0);
 656:     }
 657:     loc += (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize;
 658:     dseek(&text, loc, filhdr.ssize);
 659:     while (text.size > 0) {
 660:         mget((int *)&cursym, sizeof cursym);
 661:         type = cursym.stype;
 662:         if (Sflag) {
 663:             mtype = type&037;
 664:             if (mtype==1 || mtype>4) {
 665:                 continue;
 666:             }
 667:         }
 668:         if ((type&EXTERN)==0) {
 669:             if (Xflag==0 || cursym.sname[0]!='L')
 670:                 nloc += sizeof cursym;
 671:             continue;
 672:         }
 673:         symreloc();
 674:         if (enter(lookup()))
 675:             continue;
 676:         if ((sp = lastsym)->stype != EXTERN+UNDEF)
 677:             continue;
 678:         if (cursym.stype == EXTERN+UNDEF) {
 679:             if (cursym.svalue > sp->svalue)
 680:                 sp->svalue = cursym.svalue;
 681:             continue;
 682:         }
 683:         if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT)
 684:             continue;
 685:         ndef++;
 686:         sp->stype = cursym.stype;
 687:         sp->svalue = cursym.svalue;
 688:         if ((sp->stype &~ EXTERN) == TEXT)
 689:             sp->sovly = curov;
 690:         if (trace)
 691:         printf("found %8.8s in overlay %d at %d\n", sp->sname, sp->sovly, sp->svalue);
 692:     }
 693:     if (libflg==0 || ndef) {
 694:         tsize = add(tsize,filhdr.tsize,"text overflow");
 695:         dsize = add(dsize,filhdr.dsize,"data overflow");
 696:         bsize = add(bsize,filhdr.bsize,"bss overflow");
 697:         ssize = add(ssize,nloc,"symbol table overflow");
 698:         return(1);
 699:     }
 700:     /*
 701: 	 * No symbols defined by this library member.
 702: 	 * Rip out the hash table entries and reset the symbol table.
 703: 	 */
 704:     while (symindex>savindex)
 705:         *symhash[--symindex]=0;
 706:     return(0);
 707: }
 708: 
 709: middle()
 710: {
 711:     register struct symbol *sp, *symp;
 712:     register t, csize;
 713:     int nund, corigin;
 714:     int ttsize;
 715: 
 716:     torigin=0;
 717:     dorigin=0;
 718:     borigin=0;
 719: 
 720:     p_etext = *slookup("_etext");
 721:     p_edata = *slookup("_edata");
 722:     p_end = *slookup("_end");
 723:     /*
 724: 	 * If there are any undefined symbols, save the relocation bits.
 725: 	 * (Unless we are overlaying.)
 726: 	 */
 727:     symp = &symtab[symindex];
 728:     if (rflag==0 && !numov) {
 729:         for (sp = symtab; sp<symp; sp++)
 730:             if (sp->stype==EXTERN+UNDEF && sp->svalue==0
 731:                 && sp!=p_end && sp!=p_edata && sp!=p_etext) {
 732:                 rflag++;
 733:                 dflag = 0;
 734:                 break;
 735:             }
 736:     }
 737:     if (rflag)
 738:         nflag = sflag = iflag = Oflag = 0;
 739:     /*
 740: 	 * Assign common locations.
 741: 	 */
 742:     csize = 0;
 743:     if (dflag || rflag==0) {
 744:         ldrsym(p_etext, tsize, EXTERN+TEXT);
 745:         ldrsym(p_edata, dsize, EXTERN+DATA);
 746:         ldrsym(p_end, bsize, EXTERN+BSS);
 747:         for (sp = symtab; sp<symp; sp++)
 748:             if (sp->stype==EXTERN+UNDEF && (t = sp->svalue)!=0) {
 749:                 t = (t+1) & ~01;
 750:                 sp->svalue = csize;
 751:                 sp->stype = EXTERN+COMM;
 752:                 csize = add(csize, t, "bss overflow");
 753:             }
 754:     }
 755: /* wnj added for overlay text */
 756:     if (numov) {
 757:         for (sp = symtab; sp < symp; sp++) {
 758:             if (trace)
 759:             printf("%8.8s stype %o svalue %o sovalue %o sovly %d\n",
 760:                sp->sname, sp->stype, sp->svalue, sp->sovalue, sp->sovly);
 761:             if (sp->sovly && sp->stype == EXTERN+TEXT) {
 762:                 sp->sovalue = sp->svalue;
 763:                 sp->svalue = tsize;
 764:                 tsize += THUNKSIZ;
 765:                 if (trace)
 766:                     printf("relocating %s in overlay %d from %o to %o\n",
 767:                         sp->sname, sp->sovly,
 768:                         sp->sovalue, sp->svalue);
 769:             }
 770:         }
 771:     }
 772: /* end wnj added */
 773:     /*
 774: 	 * Now set symbols to their final value
 775: 	 */
 776:     if (nflag || iflag)
 777:         tsize = (tsize + 077) & ~077;
 778: /* wnj added */
 779:     ttsize = tsize;
 780:     if (numov) {
 781:         register int i;
 782: 
 783:         ovbase = (tsize + 017777) &~ 017777;
 784:         if (trace)
 785:             printf("overlay base is %d.\n", ovbase);
 786:         for (sp = symtab; sp < symp; sp++)
 787:             if (sp->sovly && sp->stype == EXTERN+TEXT) {
 788:                 sp->sovalue += ovbase;
 789:                 if (trace)
 790:                     printf("%.8s at %d overlay %d\n", sp->sname, sp->sovalue, sp->sovly);
 791:             }
 792:         for (i = 1; i < 8; i++) {
 793:             ovsize[i] = (ovsize[i] + 077) &~ 077;
 794:             if (ovsize[i] > max)
 795:                 max = ovsize[i];
 796:         }
 797:         if (trace)
 798:             printf("maximum overlay size is %d.\n", max);
 799:         ttsize = ovbase + max;
 800:         ttsize = (ttsize + 017777) &~ 017777;
 801:         if (trace)
 802:             printf("overlays end before %u.\n", ttsize);
 803:     }
 804: /* end wnj added */
 805:     dorigin = ttsize;
 806:     if (nflag)
 807:         dorigin = (ttsize+017777) & ~017777;
 808:     if (iflag)
 809:         dorigin = 0;
 810:     corigin = dorigin + dsize;
 811:     borigin = corigin + csize;
 812:     nund = 0;
 813:     for (sp = symtab; sp<symp; sp++) switch (sp->stype) {
 814:     case EXTERN+UNDEF:
 815:         errlev |= 01;
 816:         if (arflag==0 && sp->svalue==0) {
 817:             if (nund==0)
 818:                 printf("Undefined:\n");
 819:             nund++;
 820:             printf("%.8s\n", sp->sname);
 821:         }
 822:         continue;
 823: 
 824:     case EXTERN+ABS:
 825:     default:
 826:         continue;
 827: 
 828:     case EXTERN+TEXT:
 829:         sp->svalue += torigin;
 830:         continue;
 831: 
 832:     case EXTERN+DATA:
 833:         sp->svalue += dorigin;
 834:         continue;
 835: 
 836:     case EXTERN+BSS:
 837:         sp->svalue += borigin;
 838:         continue;
 839: 
 840:     case EXTERN+COMM:
 841:         sp->stype = EXTERN+BSS;
 842:         sp->svalue += corigin;
 843:         continue;
 844:     }
 845:     if (sflag || xflag)
 846:         ssize = 0;
 847:     bsize = add(bsize, csize, "bss overflow");
 848:     nsym = ssize / (sizeof cursym);
 849: }
 850: 
 851: ldrsym(asp, val, type)
 852: struct symbol *asp;
 853: {
 854:     register struct symbol *sp;
 855: 
 856:     if ((sp = asp) == 0)
 857:         return;
 858:     if (sp->stype != EXTERN+UNDEF || sp->svalue) {
 859:         printf("%.8s: ", sp->sname);
 860: /* 		if (trace) */
 861:             printf("svalue %o ", sp->svalue);
 862:         error(1, "Multiply defined");
 863:         return;
 864:     }
 865:     sp->stype = type;
 866:     sp->svalue = val;
 867: }
 868: 
 869: setupout()
 870: {
 871:     tcreat(&toutb, 0);
 872:     mktemp(tfname);
 873:     tcreat(&doutb, 1);
 874:     if (sflag==0 || xflag==0)
 875:         tcreat(&soutb, 1);
 876:     if (rflag) {
 877:         tcreat(&troutb, 1);
 878:         tcreat(&droutb, 1);
 879:     }
 880: /* wnj added */
 881:     if (numov)
 882:         tcreat(&voutb, 1);
 883: /* end wnj added */
 884:     filhdr.fmagic = (Oflag ? OMAGIC :( iflag ? IMAGIC : ( nflag ? NMAGIC : FMAGIC )));
 885:     if (numov) {
 886:         if (filhdr.fmagic == FMAGIC)
 887:             error(2, "-n or -i must be used for overlays");
 888:         filhdr.fmagic |= 020;
 889:     }
 890:     filhdr.tsize = tsize;
 891:     filhdr.dsize = dsize;
 892:     filhdr.bsize = bsize;
 893:     filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*symindex);
 894:     if (entrypt) {
 895:         if (entrypt->stype!=EXTERN+TEXT)
 896:             error(1, "Entry point not in text");
 897:         else if (entrypt->sovly)
 898:             error(1, "Entry point in overlay");
 899:         else
 900:             filhdr.entry = entrypt->svalue | 01;
 901:     } else
 902:         filhdr.entry=0;
 903:     filhdr.pad = 0;
 904:     filhdr.relflg = (rflag==0);
 905:     mput(&toutb, (int *)&filhdr, sizeof filhdr);
 906: /* wnj added */
 907:     if (numov) {
 908:         register int i;
 909:         for (i = 0; i < 8; i++)
 910:             putw(ovsize[i], &toutb);
 911:     }
 912: /* end wnj */
 913: }
 914: 
 915: tcreat(buf, tempflg)
 916: struct buf *buf;
 917: {
 918:     register int ufd;
 919:     char *nam;
 920:     nam = (tempflg ? tfname : ofilename);
 921:     if ((ufd = creat(nam, 0666)) < 0)
 922:         error(2, tempflg?"cannot create temp":"cannot create output");
 923:     close(ufd);
 924:     buf->fildes = open(nam, 2);
 925:     if (tempflg)
 926:         unlink(tfname);
 927:     buf->nleft = sizeof(buf->iobuf)/sizeof(int);
 928:     buf->xnext = buf->iobuf;
 929: }
 930: 
 931: load2arg(acp)
 932: char *acp;
 933: {
 934:     register char *cp;
 935:     register struct liblist *lp;
 936: 
 937:     cp = acp;
 938:     if (getfile(cp) == 0) {
 939:         while (*cp)
 940:             cp++;
 941:         while (cp >= acp && *--cp != '/');
 942:         mkfsym(++cp);
 943:         load2(0L);
 944:     } else {    /* scan archive members referenced */
 945:         for (lp = libp; lp->loc != -1; lp++) {
 946:             dseek(&text, lp->loc, sizeof archdr);
 947:             mget((int *)&archdr, sizeof archdr);
 948:             mkfsym(archdr.aname);
 949:             load2(lp->loc + (sizeof archdr) / 2);
 950:         }
 951:         libp = ++lp;
 952:     }
 953:     close(infil);
 954: }
 955: 
 956: load2(loc)
 957: long loc;
 958: {
 959:     register struct symbol *sp;
 960:     register struct local *lp;
 961:     register int symno;
 962:     int type, mtype;
 963: 
 964:     readhdr(loc);
 965:     ctrel = torigin;
 966:     cdrel += dorigin;
 967:     cbrel += borigin;
 968:     /*
 969: 	 * Reread the symbol table, recording the numbering
 970: 	 * of symbols for fixing external references.
 971: 	 */
 972:     lp = local;
 973:     symno = -1;
 974:     loc += (sizeof filhdr)/2;
 975:     dseek(&text, loc + filhdr.tsize + filhdr.dsize, filhdr.ssize);
 976:     while (text.size > 0) {
 977:         symno++;
 978:         mget((int *)&cursym, sizeof cursym);
 979:         symreloc();
 980:         type = cursym.stype;
 981:         if (Sflag) {
 982:             mtype = type&037;
 983:             if (mtype==1 || mtype>4) continue;
 984:         }
 985:         if ((type&EXTERN) == 0) {
 986:             if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L')) {
 987:                 /* preserve overlay number for locals */
 988:                 /* mostly for adb.   mjk 7/81 */
 989:                 if ((type==TEXT) && inov)
 990:                     cursym.sovly = curov;
 991:                 mput(&soutb, (int *)&cursym, sizeof cursym);
 992:             }
 993:             continue;
 994:         }
 995:         if ((sp = *lookup()) == 0)
 996:             error(2, "internal error: symbol not found");
 997:         /*
 998: 		 * Bill Shannon's fix to the 'local symbol botch'
 999: 		 * message. -wfj 5/80
1000: 		 */
1001:         if (cursym.stype == EXTERN+UNDEF || cursym.stype == EXTERN+TEXT)
1002:         {
1003: /*
1004: 		if (cursym.stype == EXTERN+UNDEF) {
1005: */
1006:             if (lp >= &local[NSYMPR])
1007:                 error(2, "Local symbol overflow");
1008:             lp->locindex = symno;
1009:             lp++->locsymbol = sp;
1010:             continue;
1011:         }
1012:         if (cursym.stype!=sp->stype
1013:             || cursym.svalue!=sp->svalue && !sp->sovly
1014:             || sp->sovly && cursym.svalue!=sp->sovalue) {
1015:             printf("%.8s: ", cursym.sname);
1016:             if (trace) {
1017:                 printf(" sovly %d sovalue %o ", sp->sovly, sp->sovalue);
1018:                 printf("new %o hav %o ", cursym.svalue, sp->svalue);
1019:             }
1020:             error(1, "Multiply defined");
1021:         }
1022:     }
1023:     dseek(&text, loc, filhdr.tsize);
1024:     dseek(&reloc, loc + half(filhdr.tsize + filhdr.dsize), filhdr.tsize);
1025:     load2td(lp, ctrel, inov ? &voutb : &toutb, &troutb);
1026:     dseek(&text, loc+half(filhdr.tsize), filhdr.dsize);
1027:     dseek(&reloc, loc+filhdr.tsize+half(filhdr.dsize), filhdr.dsize);
1028:     load2td(lp, cdrel, &doutb, &droutb);
1029:     torigin += filhdr.tsize;
1030:     dorigin += filhdr.dsize;
1031:     borigin += filhdr.bsize;
1032: }
1033: 
1034: load2td(lp, creloc, b1, b2)
1035: struct local *lp;
1036: struct buf *b1, *b2;
1037: {
1038:     register r, t;
1039:     register struct symbol *sp;
1040: 
1041:     for (;;) {
1042:         /*
1043: 			 * The pickup code is copied from "get" for speed.
1044: 			 */
1045: 
1046:         /* next text or data word */
1047:         if (--text.size <= 0) {
1048:             if (text.size < 0)
1049:                 break;
1050:             text.size++;
1051:             t = get(&text);
1052:         } else if (--text.nibuf < 0) {
1053:             text.nibuf++;
1054:             text.size++;
1055:             t = get(&text);
1056:         } else
1057:             t = *text.ptr++;
1058: 
1059:         /* next relocation word */
1060:         if (--reloc.size <= 0) {
1061:             if (reloc.size < 0)
1062:                 error(2, "Relocation error");
1063:             reloc.size++;
1064:             r = get(&reloc);
1065:         } else if (--reloc.nibuf < 0) {
1066:             reloc.nibuf++;
1067:             reloc.size++;
1068:             r = get(&reloc);
1069:         } else
1070:             r = *reloc.ptr++;
1071: 
1072:         switch (r&016) {
1073: 
1074:         case RTEXT:
1075:             t += ctrel;
1076:             break;
1077: 
1078:         case RDATA:
1079:             t += cdrel;
1080:             break;
1081: 
1082:         case RBSS:
1083:             t += cbrel;
1084:             break;
1085: 
1086:         case REXT:
1087:             sp = lookloc(lp, r);
1088:             if (sp->stype==EXTERN+UNDEF) {
1089:                 r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT;
1090:                 break;
1091:             }
1092:             t += sp->svalue;
1093:             r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1);
1094:             break;
1095:         }
1096:         if (r&01)
1097:             t -= creloc;
1098:         putw(t, b1);
1099:         if (rflag)
1100:             putw(r, b2);
1101:     }
1102: }
1103: 
1104: finishout()
1105: {
1106:     register n, *p;
1107:     register struct symbol *sp, *symp;
1108: 
1109: /* wnj added */
1110:     if (numov) {
1111:         int aovno = adrof("__ovno");
1112:         int aovhndlr[NOVL+1];
1113:         for (n=1; n<=numov; n++) {
1114:             ovhndlr.sname[HNDLR_NUM] = '0' + n;
1115:             aovhndlr[n] = adrof(ovhndlr.sname);
1116:         }
1117:         symp = &symtab[symindex];
1118:         for (sp = symtab; sp < symp; sp++)
1119:             if (sp->sovly && (sp->stype & (EXTERN+TEXT))) {
1120:                 putw(012701, &toutb);   /* mov $~foo+4, r1*/
1121:                 putw(sp->sovalue+4, &toutb);
1122:                 putw(04537, &toutb); /* jsr r5,ovhndlrx */
1123:                 putw(aovhndlr[sp->sovly], &toutb);
1124:                 torigin += THUNKSIZ;
1125:             }
1126:     }
1127: /* end wnj */
1128:     if (nflag||iflag) {
1129:         n = torigin;
1130:         while (n&077) {
1131:             n += 2;
1132:             putw(0, &toutb);
1133:             if (rflag)
1134:                 putw(0, &troutb);
1135:         }
1136:     }
1137:     if (numov)
1138:         copy(&voutb);
1139:     copy(&doutb);
1140:     if (rflag) {
1141:         copy(&troutb);
1142:         copy(&droutb);
1143:     }
1144:     if (sflag==0) {
1145:         if (xflag==0)
1146:             copy(&soutb);
1147:         for (p = (int *)symtab; p < (int *)&symtab[symindex];) {
1148: /* wnj changed.... this is bad machine dependent code... */
1149:             /* this does the symbol */
1150:             putw(*p++, &toutb); putw(*p++, &toutb);
1151:             putw(*p++, &toutb); putw(*p++, &toutb);
1152:             /* these do the flags and value */
1153:             putw(*p++, &toutb); putw(*p++, &toutb);
1154:             /* skip sovalue */
1155:             p++;
1156:         }
1157: /* end wnj changed */
1158:     }
1159:     flush(&toutb);
1160:     close(toutb.fildes);
1161:     if (!ofilfnd) {
1162:         unlink("a.out");
1163:         link("l.out", "a.out");
1164:         ofilename = "a.out";
1165:     }
1166:     delarg = errlev;
1167:     delexit();
1168: }
1169: 
1170: /* wnj added for overlay txt regs */
1171: adrof(s)
1172:     char *s;
1173: {
1174:     register struct symbol **p = slookup(s);
1175: 
1176:     if (*p == 0) {
1177:         printf("%.8s: ", s);
1178:         error(1, "Undefined!");
1179:         return (0);
1180:     }
1181:     return ((*p)->svalue);
1182: }
1183: /* end wnj added */
1184: 
1185: copy(buf)
1186: struct buf *buf;
1187: {
1188:     register f, *p, n;
1189: 
1190:     flush(buf);
1191:     lseek(f = buf->fildes, (long)0, 0);
1192:     while ((n = read(f, (char *)buf->iobuf, sizeof(buf->iobuf))) > 1) {
1193:         n >>= 1;
1194:         p = (int *)buf->iobuf;
1195:         do
1196:             putw(*p++, &toutb);
1197:         while (--n);
1198:     }
1199:     close(f);
1200: }
1201: 
1202: mkfsym(s)
1203: char *s;
1204: {
1205: 
1206:     if (sflag || xflag)
1207:         return;
1208:     cp8c(s, cursym.sname);
1209:     cursym.stype = 037;
1210:     cursym.svalue = torigin;
1211:     mput(&soutb, (int *)&cursym, sizeof cursym);
1212: }
1213: 
1214: mget(aloc, an)
1215: int *aloc;
1216: {
1217:     register *loc, n;
1218:     register *p;
1219: 
1220:     n = an;
1221:     n >>= 1;
1222:     loc = aloc;
1223:     if ((text.nibuf -= n) >= 0) {
1224:         if ((text.size -= n) > 0) {
1225:             p = text.ptr;
1226:             do
1227:                 *loc++ = *p++;
1228:             while (--n);
1229:             text.ptr = p;
1230:             return;
1231:         } else
1232:             text.size += n;
1233:     }
1234:     text.nibuf += n;
1235:     do {
1236:         *loc++ = get(&text);
1237:     }
1238:     while (--n);
1239: }
1240: 
1241: mput(buf, aloc, an)
1242: struct buf *buf;
1243: int *aloc;
1244: {
1245:     register *loc;
1246:     register n;
1247: 
1248:     loc = aloc;
1249:     n = an>>1;
1250:     do {
1251:         putw(*loc++, buf);
1252:     }
1253:     while (--n);
1254: }
1255: 
1256: dseek(asp, aloc, s)
1257: long aloc;
1258: struct stream *asp;
1259: {
1260:     register struct stream *sp;
1261:     register struct page *p;
1262:     /* register */ long b, o;
1263:     int n;
1264: 
1265:     b = aloc >> 8;
1266:     o = aloc & 0377;
1267:     sp = asp;
1268:     --sp->pno->nuser;
1269:     if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)
1270:         if (p->nuser==0 || (p = &page[0])->nuser==0) {
1271:             if (page[0].nuser==0 && page[1].nuser==0)
1272:                 if (page[0].bno < page[1].bno)
1273:                     p = &page[0];
1274:             p->bno = b;
1275:             lseek(infil, (aloc & ~0377L) << 1, 0);
1276:             if ((n = read(infil, (char *)p->buff, 512)>>1) < 0)
1277:                 n = 0;
1278:             p->nibuf = n;
1279:     } else
1280:         error(2, "No pages");
1281:     ++p->nuser;
1282:     sp->bno = b;
1283:     sp->pno = p;
1284:     sp->ptr = p->buff + o;
1285:     if (s != -1)
1286:         sp->size = half(s);
1287:     if ((sp->nibuf = p->nibuf-o) <= 0)
1288:         sp->size = 0;
1289: }
1290: 
1291: half(i)
1292: {
1293:     return((i>>1)&077777);
1294: }
1295: 
1296: get(asp)
1297: struct stream *asp;
1298: {
1299:     register struct stream *sp;
1300: 
1301:     sp = asp;
1302:     if (--sp->nibuf < 0) {
1303:         dseek(sp, (long)(sp->bno + 1) << 8, -1);
1304:         --sp->nibuf;
1305:     }
1306:     if (--sp->size <= 0) {
1307:         if (sp->size < 0)
1308:             error(2, premeof);
1309:         ++fpage.nuser;
1310:         --sp->pno->nuser;
1311:         sp->pno = (struct page *)&fpage;
1312:     }
1313:     return(*sp->ptr++);
1314: }
1315: 
1316: getfile(acp)
1317: char *acp;
1318: {
1319:     register char *cp;
1320:     register int c;
1321:     struct stat x;
1322: 
1323:     cp = acp;
1324:     infil = -1;
1325:     archdr.aname[0] = '\0';
1326:     filname = cp;
1327:     if (cp[0]=='-' && cp[1]=='l') {
1328:         if(cp[2] == '\0')
1329:             cp = "-la";
1330:         filname = "/usr/lib/libxxxxxxxxxxxxxxx";
1331:         for(c=0; cp[c+2]; c++)
1332:             filname[c+12] = cp[c+2];
1333:         filname[c+12] = '.';
1334:         filname[c+13] = 'a';
1335:         filname[c+14] = '\0';
1336:         if ((infil = open(filname+4, 0)) >= 0) {
1337:             filname += 4;
1338:         }
1339:     }
1340:     if (infil == -1 && (infil = open(filname, 0)) < 0)
1341:         error(2, "cannot open");
1342:     page[0].bno = page[1].bno = -1;
1343:     page[0].nuser = page[1].nuser = 0;
1344:     text.pno = reloc.pno = (struct page *)&fpage;
1345:     fpage.nuser = 2;
1346:     dseek(&text, 0L, 2);
1347:     if (text.size <= 0)
1348:         error(2, premeof);
1349:     if(get(&text) != ARCMAGIC)
1350:         return(0);  /* regualr file */
1351:     dseek(&text, 1L, sizeof archdr);    /* word addressing */
1352:     if(text.size <= 0)
1353:         return(1);  /* regular archive */
1354:     mget((int *)&archdr, sizeof archdr);
1355:     if(strncmp(archdr.aname, goodnm, 14) != 0)
1356:         return(1);  /* regular archive */
1357:     else {
1358:         fstat(infil, &x);
1359:         if(x.st_mtime > archdr.atime)
1360:         {
1361:             return(3);
1362:         }
1363:         else return(2);
1364:     }
1365: }
1366: 
1367: struct symbol **lookup()
1368: {
1369:     int i;
1370:     int clash;
1371:     register struct symbol **hp;
1372:     register char *cp, *cp1;
1373: 
1374:     i = 0;
1375:     for (cp = cursym.sname; cp < &cursym.sname[8];)
1376:         i = (i<<1) + *cp++;
1377:     for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) {
1378:         cp1 = (*hp)->sname;
1379:         clash=FALSE;
1380:         for (cp = cursym.sname; cp < &cursym.sname[8];)
1381:             if (*cp++ != *cp1++) {
1382:                 clash=TRUE;
1383:                 break;
1384:             }
1385:         if (clash) {
1386:             if (++hp >= &hshtab[NSYM+2])
1387:                 hp = hshtab;
1388:         } else
1389:             break;
1390:     }
1391:     return(hp);
1392: }
1393: 
1394: struct symbol **slookup(s)
1395: char *s;
1396: {
1397:     cp8c(s, cursym.sname);
1398:     cursym.stype = EXTERN+UNDEF;
1399:     cursym.svalue = 0;
1400:     return(lookup());
1401: }
1402: 
1403: enter(hp)
1404: struct symbol **hp;
1405: {
1406:     register struct symbol *sp;
1407: 
1408:     if (*hp==0) {
1409:         if (symindex>=NSYM)
1410:             error(2, "Symbol table overflow");
1411:         symhash[symindex] = hp;
1412:         *hp = lastsym = sp = &symtab[symindex++];
1413:         cp8c(cursym.sname, sp->sname);
1414:         sp->stype = cursym.stype;
1415:         sp->svalue = cursym.svalue;
1416:         if (sp->stype == EXTERN+TEXT) {
1417:             sp->sovly = curov;
1418:             if (trace)
1419:                 printf("found %8.8s in overlay %d at %d\n",
1420:                     sp->sname, sp->sovly, sp->svalue);
1421:         }
1422:         return(1);
1423:     } else {
1424:         lastsym = *hp;
1425:         return(0);
1426:     }
1427: }
1428: 
1429: symreloc()
1430: {
1431:     switch (cursym.stype) {
1432: 
1433:     case TEXT:
1434:     case EXTERN+TEXT:
1435:         cursym.svalue += ctrel;
1436:         return;
1437: 
1438:     case DATA:
1439:     case EXTERN+DATA:
1440:         cursym.svalue += cdrel;
1441:         return;
1442: 
1443:     case BSS:
1444:     case EXTERN+BSS:
1445:         cursym.svalue += cbrel;
1446:         return;
1447: 
1448:     case EXTERN+UNDEF:
1449:         return;
1450:     }
1451:     if (cursym.stype&EXTERN)
1452:         cursym.stype = EXTERN+ABS;
1453: }
1454: 
1455: error(n, s)
1456: char *s;
1457: {
1458:     if (errlev==0)
1459:         printf("ld:");
1460:     if (filname) {
1461:         printf("%s", filname);
1462:         if (archdr.aname[0])
1463:             printf("(%.14s)", archdr.aname);
1464:         printf(": ");
1465:     }
1466:     printf("%s\n", s);
1467:     if (n > 1)
1468:         delexit();
1469:     errlev = n;
1470: }
1471: 
1472: struct symbol *
1473: lookloc(alp, r)
1474: struct local *alp;
1475: {
1476:     register struct local *clp, *lp;
1477:     register sn;
1478: 
1479:     lp = alp;
1480:     sn = (r>>4) & 07777;
1481:     for (clp = local; clp<lp; clp++)
1482:         if (clp->locindex == sn)
1483:             return(clp->locsymbol);
1484:     error(2, "Local symbol botch");
1485: }
1486: 
1487: readhdr(loc)
1488: long loc;
1489: {
1490:     register st, sd;
1491: 
1492:     dseek(&text, loc, sizeof filhdr);
1493:     mget((int *)&filhdr, sizeof filhdr);
1494:     if (filhdr.fmagic != FMAGIC)
1495:         error(2, "Bad format");
1496:     st = (filhdr.tsize+01) & ~01;
1497:     filhdr.tsize = st;
1498:     cdrel = -st;
1499:     sd = (filhdr.dsize+01) & ~01;
1500:     cbrel = - (st+sd);
1501:     filhdr.bsize = (filhdr.bsize+01) & ~01;
1502: }
1503: 
1504: cp8c(from, to)
1505: char *from, *to;
1506: {
1507:     register char *f, *t, *te;
1508: 
1509:     f = from;
1510:     t = to;
1511:     te = t+8;
1512:     while ((*t++ = *f++) && t<te);
1513:     while (t<te)
1514:         *t++ = 0;
1515: }
1516: 
1517: eq(s1, s2)
1518: char *s1;
1519: char *s2;
1520: {
1521:     while (*s1==*s2++)
1522:         if ((*s1++)==0)
1523:             return(TRUE);
1524:     return(FALSE);
1525: }
1526: 
1527: putw(w, b)
1528: register struct buf *b;
1529: {
1530:     *(b->xnext)++ = w;
1531:     if (--b->nleft <= 0)
1532:         flush(b);
1533: }
1534: 
1535: flush(b)
1536: register struct buf *b;
1537: {
1538:     register n;
1539: 
1540:     if ((n = (char *)b->xnext - (char *)b->iobuf) > 0)
1541:         if (write(b->fildes, (char *)b->iobuf, n) != n)
1542:             error(2, "output error");
1543:     b->xnext = b->iobuf;
1544:     b->nleft = sizeof(b->iobuf)/sizeof(int);
1545: }

Defined functions

add defined in line 625; used 6 times
adrof defined in line 1171; used 2 times
copy defined in line 1185; used 5 times
cp8c defined in line 1504; used 3 times
delexit defined in line 256; used 4 times
dseek defined in line 1256; used 12 times
endload defined in line 430; used 2 times
enter defined in line 1403; used 3 times
eq defined in line 1517; used 1 times
error defined in line 1455; used 30 times
finishout defined in line 1104; used 1 times
flush defined in line 1535; used 3 times
get defined in line 1296; used 6 times
getfile defined in line 1316; used 2 times
half defined in line 1291; used 4 times
ldrand defined in line 609; used 1 times
ldrsym defined in line 851; used 3 times
load1 defined in line 639; used 2 times
load1arg defined in line 551; used 2 times
load2 defined in line 956; used 2 times
load2arg defined in line 931; used 2 times
load2td defined in line 1034; used 2 times
lookloc defined in line 1472; used 2 times
lookup defined in line 1367; used 5 times
main defined in line 264; never used
mget defined in line 1214; used 6 times
middle defined in line 709; used 1 times
mkfsym defined in line 1202; used 2 times
mput defined in line 1241; used 3 times
putw defined in line 1527; used 20 times
readhdr defined in line 1487; used 2 times
record defined in line 509; used 1 times
restore defined in line 529; used 1 times
roundov defined in line 500; used 2 times
setupout defined in line 869; used 1 times
slookup defined in line 1394; used 7 times
step defined in line 592; used 3 times
symreloc defined in line 1429; used 2 times
tcreat defined in line 915; used 6 times

Defined variables

Oflag defined in line 184; used 3 times
Sflag defined in line 179; used 3 times
Xflag defined in line 178; used 3 times
arflag defined in line 181; used 2 times
borigin defined in line 428; used 5 times
bsize defined in line 197; used 15 times
cbrel defined in line 203; used 7 times
cdrel defined in line 202; used 8 times
ctrel defined in line 201; used 7 times
curov defined in line 233; used 12 times
cursym defined in line 161; used 50 times
delarg defined in line 206; used 3 times
dflag defined in line 185; used 3 times
dorigin defined in line 427; used 10 times
doutb defined in line 218; used 4 times
droutb defined in line 220; used 4 times
dsize defined in line 196; used 21 times
entrypt defined in line 173; used 5 times
errlev defined in line 205; used 4 times
filname defined in line 192; used 13 times
goodnm defined in line 64; used 1 times
hshtab defined in line 166; used 3 times
iflag defined in line 186; used 6 times
infil defined in line 191; used 11 times
inov defined in line 234; used 9 times
lastsym defined in line 164; used 4 times
liblist defined in line 137; used 2 times
libp defined in line 138; used 13 times
local defined in line 167; used 3 times
nflag defined in line 183; used 6 times
nsym defined in line 425; used 2 times
numov defined in line 232; used 13 times
ofilename defined in line 190; used 4 times
ofilfnd defined in line 189; used 2 times
ovbase defined in line 249; used 5 times
ovhndlr defined in line 246; used 3 times
ovsize defined in line 235; used 10 times
p_edata defined in line 171; used 3 times
p_end defined in line 172; used 3 times
p_etext defined in line 170; used 3 times
page defined in line 92; used 12 times
premeof defined in line 63; used 2 times
reloc defined in line 108; used 12 times
rflag defined in line 180; used 12 times
sflag defined in line 182; used 8 times
soutb defined in line 221; used 4 times
ssize defined in line 198; used 11 times
symhash defined in line 163; used 3 times
symindex defined in line 165; used 13 times
symtab defined in line 162; used 12 times
tab defined in line 71; used 3 times
text defined in line 107; used 32 times
tfname defined in line 207; used 3 times
tnum defined in line 72; used 4 times
torgwas defined in line 230; used 2 times
torigin defined in line 426; used 12 times
toutb defined in line 217; used 18 times
trace defined in line 175; used 15 times
troutb defined in line 219; used 4 times
tsize defined in line 195; used 31 times
tsizwas defined in line 231; used 2 times
vflag defined in line 187; used 1 times
vindex defined in line 76; used 3 times
vnodes defined in line 84; used 3 times
voutb defined in line 239; used 4 times
xflag defined in line 177; used 7 times

Defined struct's

buf defined in line 211; used 24 times
liblist defined in line 133; used 9 times
local defined in line 156; used 10 times
overlay defined in line 77; used 4 times
page defined in line 87; used 8 times
stream defined in line 99; used 12 times
symbol defined in line 142; used 54 times
tab defined in line 68; used 4 times
xsymbol defined in line 150; used 4 times

Defined macros

ABS defined in line 45; used 2 times
ARCMAGIC defined in line 37; used 1 times
BSS defined in line 48; used 2 times
COMM defined in line 49; used 1 times
DATA defined in line 47; used 1 times
EXTERN defined in line 43; used 38 times
FALSE defined in line 34; used 4 times
FMAGIC defined in line 39; used 3 times
HNDLR_NUM defined in line 248; used 1 times
IMAGIC defined in line 41; used 1 times
NMAGIC defined in line 40; used 1 times
NOVL defined in line 225; used 3 times
NOVLY defined in line 57; used 1 times
  • in line 84
NROUT defined in line 59; used 1 times
NSYM defined in line 60; used 6 times
NSYMPR defined in line 61; used 2 times
OMAGIC defined in line 38; used 1 times
RABS defined in line 51; never used
RBSS defined in line 54; never used
RDATA defined in line 53; never used
RELFLG defined in line 58; used 1 times
REXT defined in line 55; used 1 times
RTEXT defined in line 52; never used
TABSZ defined in line 67; used 2 times
TEXT defined in line 46; used 10 times
THUNKSIZ defined in line 228; used 2 times
TRUE defined in line 33; used 3 times
UNDEF defined in line 44; used 10 times
max defined in line 237; used 4 times
Last modified: 1981-11-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4040
Valid CSS Valid XHTML 1.0 Strict