1: #
   2: /*
   3:  *  link editor
   4:  */
   5: 
   6: #define SIGINT  2
   7: #define ARCMAGIC 0177555
   8: #define FMAGIC  0407
   9: #define NMAGIC  0410
  10: #define IMAGIC  0411
  11: 
  12: #define EXTERN  040
  13: #define UNDEF   00
  14: #define ABS 01
  15: #define TEXT    02
  16: #define DATA    03
  17: #define BSS 04
  18: #define COMM    05  /* internal use only */
  19: 
  20: #define RABS    00
  21: #define RTEXT   02
  22: #define RDATA   04
  23: #define RBSS    06
  24: #define REXT    010
  25: 
  26: #define RELFLG  01
  27: #define NROUT   256
  28: #define NSYM    501
  29: #define NSYMPR  500
  30: 
  31: #define RONLY   0400
  32: 
  33: char    premeof[] "Premature EOF on %s";
  34: 
  35: struct  page {
  36:     int nuser;
  37:     int bno;
  38:     int nibuf;
  39:     int buff[256];
  40: } page[2];
  41: 
  42: struct  {
  43:     int nuser;
  44:     int bno;
  45: } fpage;
  46: 
  47: struct  stream {
  48:     int *ptr;
  49:     int bno;
  50:     int nibuf;
  51:     int size;
  52:     struct  page *pno;
  53: };
  54: 
  55: struct  stream text;
  56: struct  stream reloc;
  57: 
  58: struct  archdr {
  59:     char    aname[8];
  60:     int atime[2];
  61:     char    auid, amode;
  62:     int asize;
  63: } archdr;
  64: 
  65: struct  filhdr {
  66:     int fmagic;
  67:     int tsize;
  68:     int dsize;
  69:     int bsize;
  70:     int ssize;
  71:     int entry;
  72:     int pad;
  73:     int relflg;
  74: } filhdr;
  75: 
  76: struct  liblist {
  77:     int off;
  78:     int bno;
  79: };
  80: 
  81: struct  liblist liblist[NROUT];
  82: struct  liblist *libp { &liblist[0] };
  83: 
  84: struct  symbol {
  85:     char    sname[8];
  86:     char    stype;
  87:     char    spad;
  88:     int svalue;
  89: };
  90: 
  91: struct  symbol  cursym;
  92: struct  symbol  symtab[NSYM];
  93: struct  symbol  *hshtab[NSYM+2];
  94: struct  symbol  *symp { symtab };
  95: struct  symbol  **local[NSYMPR];
  96: struct  symbol  *p_etext;
  97: struct  symbol  *p_edata;
  98: struct  symbol  *p_end;
  99: 
 100: int xflag;      /* discard local symbols */
 101: int Xflag;      /* discard locals starting with 'L' */
 102: int rflag;      /* preserve relocation bits, don't define common */
 103: int arflag;     /* original copy of rflag */
 104: int sflag;      /* discard all symbols */
 105: int nflag;      /* pure procedure */
 106: int dflag;      /* define common even with rflag */
 107: int iflag;      /* I/D space separated */
 108: 
 109: int infil;
 110: char    *filname;
 111: 
 112: int tsize;
 113: int dsize;
 114: int bsize;
 115: int ssize;
 116: int nsym;
 117: 
 118: int torigin;
 119: int dorigin;
 120: int borigin;
 121: 
 122: int ctrel;
 123: int cdrel;
 124: int cbrel;
 125: 
 126: int errlev;
 127: int delarg  4;
 128: char    tfname[]    "/tmp/lxyyyyy";
 129: int toutb[259];
 130: int doutb[259];
 131: int troutb[259];
 132: int droutb[259];
 133: int soutb[259];
 134: 
 135: struct  symbol  **lookup();
 136: struct  symbol  **slookup();
 137: 
 138: main(argc, argv)
 139: char **argv;
 140: {
 141:     extern int delexit();
 142:     register c;
 143:     register char *ap, **p;
 144:     struct symbol **hp;
 145: 
 146:     if ((signal(SIGINT, 1) & 01) == 0)
 147:         signal(SIGINT, delexit);
 148:     if (argc == 1)
 149:         exit(4);
 150:     p = argv + 1;
 151:     for (c = 1; c<argc; c++) {
 152:         filname = 0;
 153:         ap = *p++;
 154:         if (*ap == '-') switch (ap[1]) {
 155: 
 156:         case 'u':
 157:             if (++c >= argc)
 158:                 error(1, "Bad 'use'");
 159:             if (*(hp = slookup(*p++)) == 0) {
 160:                 *hp = symp;
 161:                 enter();
 162:             }
 163:             continue;
 164: 
 165:         case 'l':
 166:             break;
 167: 
 168:         case 'x':
 169:             xflag++;
 170:             continue;
 171: 
 172:         case 'X':
 173:             Xflag++;
 174:             continue;
 175: 
 176:         case 'r':
 177:             rflag++;
 178:             arflag++;
 179:             continue;
 180: 
 181:         case 's':
 182:             sflag++;
 183:             xflag++;
 184:             continue;
 185: 
 186:         case 'n':
 187:             nflag++;
 188:             continue;
 189: 
 190:         case 'd':
 191:             dflag++;
 192:             continue;
 193: 
 194:         case 'i':
 195:             iflag++;
 196:             continue;
 197:         }
 198:         load1arg(ap);
 199:         close(infil);
 200:     }
 201:     middle();
 202:     setupout();
 203:     p = argv+1;
 204:     libp = liblist;
 205:     for (c=1; c<argc; c++) {
 206:         ap = *p++;
 207:         if (*ap == '-') switch (ap[1]) {
 208: 
 209:         case 'u':
 210:             ++c;
 211:             ++p;
 212:         default:
 213:             continue;
 214: 
 215:         case 'l':
 216:             break;
 217:         }
 218:         load2arg(ap);
 219:         close(infil);
 220:     }
 221:     finishout();
 222: }
 223: 
 224: load1arg(acp)
 225: char *acp;
 226: {
 227:     register char *cp;
 228:     register noff, nbno;
 229: 
 230:     cp = acp;
 231:     if (getfile(cp)==0) {
 232:         load1(0, 0, 0);
 233:         return;
 234:     }
 235:     nbno = 0;
 236:     noff = 1;
 237:     for (;;) {
 238:         dseek(&text, nbno, noff, sizeof archdr);
 239:         if (text.size <= 0) {
 240:             libp->bno = -1;
 241:             libp++;
 242:             return;
 243:         }
 244:         mget(&archdr, sizeof archdr);
 245:         if (load1(1, nbno, noff + (sizeof archdr) / 2)) {
 246:             libp->bno = nbno;
 247:             libp->off = noff;
 248:             libp++;
 249:         }
 250:         noff =+ (archdr.asize + sizeof archdr)>>1;
 251:         nbno =+ (noff >> 8) & 0377;
 252:         noff =& 0377;
 253:     }
 254: }
 255: 
 256: load1(libflg, bno, off)
 257: {
 258:     register struct symbol *sp, **hp, ***cp;
 259:     struct symbol *ssymp;
 260:     int ndef, nloc;
 261: 
 262:     readhdr(bno, off);
 263:     ctrel = tsize;
 264:     cdrel =+ dsize;
 265:     cbrel =+ bsize;
 266:     ndef = 0;
 267:     nloc = sizeof cursym;
 268:     cp = local;
 269:     ssymp = symp;
 270:     if ((filhdr.relflg&RELFLG)==1) {
 271:         error(0, "No relocation bits");
 272:         return(0);
 273:     }
 274:     off =+ (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize;
 275:     dseek(&text, bno, off, filhdr.ssize);
 276:     while (text.size > 0) {
 277:         mget(&cursym, sizeof cursym);
 278:         if ((cursym.stype&EXTERN)==0) {
 279:             if (Xflag==0 || cursym.sname[0]!='L')
 280:                 nloc =+ sizeof cursym;
 281:             continue;
 282:         }
 283:         symreloc();
 284:         hp = lookup();
 285:         if ((sp = *hp) == 0) {
 286:             *hp = enter();
 287:             *cp++ = hp;
 288:             continue;
 289:         }
 290:         if (sp->stype != EXTERN+UNDEF)
 291:             continue;
 292:         if (cursym.stype == EXTERN+UNDEF) {
 293:             if (cursym.svalue > sp->svalue)
 294:                 sp->svalue = cursym.svalue;
 295:             continue;
 296:         }
 297:         if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT)
 298:             continue;
 299:         ndef++;
 300:         sp->stype = cursym.stype;
 301:         sp->svalue = cursym.svalue;
 302:     }
 303:     if (libflg==0 || ndef) {
 304:         tsize =+ filhdr.tsize;
 305:         dsize =+ filhdr.dsize;
 306:         bsize =+ filhdr.bsize;
 307:         ssize =+ nloc;
 308:         return(1);
 309:     }
 310: /*
 311:  * No symbols defined by this library member.
 312:  * Rip out the hash table entries and reset the symbol table.
 313:  */
 314:     symp = ssymp;
 315:     while (cp > local)
 316:         **--cp = 0;
 317:     return(0);
 318: }
 319: 
 320: middle()
 321: {
 322:     register struct symbol *sp;
 323:     register t, csize;
 324:     int nund, corigin;
 325: 
 326:     p_etext = *slookup("_etext");
 327:     p_edata = *slookup("_edata");
 328:     p_end = *slookup("_end");
 329: /*
 330:  * If there are any undefined symbols, save the relocation bits.
 331:  */
 332:     if (rflag==0) for (sp=symtab; sp<symp; sp++)
 333:         if (sp->stype==EXTERN+UNDEF && sp->svalue==0
 334:          && sp!=p_end && sp!=p_edata && sp!=p_etext) {
 335:             rflag++;
 336:             dflag = 0;
 337:             nflag = 0;
 338:             iflag = 0;
 339:             sflag = 0;
 340:             break;
 341:         }
 342: /*
 343:  * Assign common locations.
 344:  */
 345:     csize = 0;
 346:     if (dflag || rflag==0) {
 347:         for (sp=symtab; sp<symp; sp++)
 348:             if (sp->stype==EXTERN+UNDEF && (t=sp->svalue)!=0) {
 349:                 t = (t+1) & ~01;
 350:                 sp->svalue = csize;
 351:                 sp->stype = EXTERN+COMM;
 352:                 csize =+ t;
 353:             }
 354:         if (p_etext && p_etext->stype==EXTERN+UNDEF) {
 355:             p_etext->stype = EXTERN+TEXT;
 356:             p_etext->svalue = tsize;
 357:         }
 358:         if (p_edata && p_edata->stype==EXTERN+UNDEF) {
 359:             p_edata->stype = EXTERN+DATA;
 360:             p_edata->svalue = dsize;
 361:         }
 362:         if (p_end && p_end->stype==EXTERN+UNDEF) {
 363:             p_end->stype = EXTERN+BSS;
 364:             p_end->svalue = bsize;
 365:         }
 366:     }
 367: /*
 368:  * Now set symbols to their final value
 369:  */
 370:     if (nflag || iflag)
 371:         tsize = (tsize + 077) & ~077;
 372:     dorigin = tsize;
 373:     if (nflag)
 374:         dorigin = (tsize+017777) & ~017777;
 375:     if (iflag)
 376:         dorigin = 0;
 377:     corigin = dorigin + dsize;
 378:     borigin = corigin + csize;
 379:     nund = 0;
 380:     for (sp=symtab; sp<symp; sp++) switch (sp->stype) {
 381:     case EXTERN+UNDEF:
 382:         errlev =| 01;
 383:         if (arflag==0 && sp->svalue==0) {
 384:             if (nund==0)
 385:                 printf("Undefined:\n");
 386:             nund++;
 387:             printf("%.8s\n", sp->sname);
 388:         }
 389:         continue;
 390: 
 391:     case EXTERN+ABS:
 392:     default:
 393:         continue;
 394: 
 395:     case EXTERN+TEXT:
 396:         sp->svalue =+ torigin;
 397:         continue;
 398: 
 399:     case EXTERN+DATA:
 400:         sp->svalue =+ dorigin;
 401:         continue;
 402: 
 403:     case EXTERN+BSS:
 404:         sp->svalue =+ borigin;
 405:         continue;
 406: 
 407:     case EXTERN+COMM:
 408:         sp->stype = EXTERN+BSS;
 409:         sp->svalue =+ corigin;
 410:         continue;
 411:     }
 412:     if (sflag || xflag)
 413:         ssize = 0;
 414:     bsize =+ csize;
 415:     nsym = ssize / (sizeof cursym);
 416: }
 417: 
 418: setupout()
 419: {
 420:     register char *p;
 421:     register pid;
 422: 
 423:     if ((toutb[0] = creat("l.out", 0666)) < 0)
 424:         error(1, "Can't create l.out");
 425:     pid = getpid();
 426:     for (p = &tfname[12]; p > &tfname[7];) {
 427:         *--p = (pid&07) + '0';
 428:         pid =>> 3;
 429:     }
 430:     tcreat(doutb, 'a');
 431:     if (sflag==0 || xflag==0)
 432:         tcreat(soutb, 'b');
 433:     if (rflag) {
 434:         tcreat(troutb, 'c');
 435:         tcreat(droutb, 'd');
 436:     }
 437:     filhdr.fmagic = FMAGIC;
 438:     if (nflag)
 439:         filhdr.fmagic = NMAGIC;
 440:     if (iflag)
 441:         filhdr.fmagic = IMAGIC;
 442:     filhdr.tsize = tsize;
 443:     filhdr.dsize = dsize;
 444:     filhdr.bsize = bsize;
 445:     filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*(symp-symtab));
 446:     filhdr.entry = 0;
 447:     filhdr.pad = 0;
 448:     filhdr.relflg = (rflag==0);
 449:     mput(toutb, &filhdr, sizeof filhdr);
 450:     return;
 451: }
 452: 
 453: tcreat(buf, letter)
 454: int *buf;
 455: {
 456:     tfname[6] = letter;
 457:     if ((buf[0] = creat(tfname, RONLY)) < 0)
 458:         error(1, "Can't create temp");
 459: }
 460: 
 461: load2arg(acp)
 462: char *acp;
 463: {
 464:     register char *cp;
 465:     register struct liblist *lp;
 466: 
 467:     cp = acp;
 468:     if (getfile(cp) == 0) {
 469:         while (*cp)
 470:             cp++;
 471:         while (cp >= acp && *--cp != '/');
 472:         mkfsym(++cp);
 473:         load2(0, 0);
 474:         return;
 475:     }
 476:     for (lp = libp; lp->bno != -1; lp++) {
 477:         dseek(&text, lp->bno, lp->off, sizeof archdr);
 478:         mget(&archdr, sizeof archdr);
 479:         mkfsym(archdr.aname);
 480:         load2(lp->bno, lp->off + (sizeof archdr) / 2);
 481:     }
 482:     libp = ++lp;
 483: }
 484: 
 485: load2(bno, off)
 486: {
 487:     register struct symbol *sp;
 488:     register int *lp, symno;
 489: 
 490:     readhdr(bno, off);
 491:     ctrel = torigin;
 492:     cdrel =+ dorigin;
 493:     cbrel =+ borigin;
 494: /*
 495:  * Reread the symbol table, recording the numbering
 496:  * of symbols for fixing external references.
 497:  */
 498:     lp = local;
 499:     symno = -1;
 500:     off =+ (sizeof filhdr)/2;
 501:     dseek(&text, bno, off+filhdr.tsize+filhdr.dsize, filhdr.ssize);
 502:     while (text.size > 0) {
 503:         symno++;
 504:         mget(&cursym, sizeof cursym);
 505:         symreloc();
 506:         if ((cursym.stype&EXTERN) == 0) {
 507:             if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L'))
 508:                 mput(soutb, &cursym, sizeof cursym);
 509:             continue;
 510:         }
 511:         if ((sp = *lookup()) == 0)
 512:             error(1, "internal error: symbol not found");
 513:         if (cursym.stype == EXTERN+UNDEF) {
 514:             if (lp >= &local[NSYMPR])
 515:                 error(1, "Local symbol overflow");
 516:             *lp++ = symno;
 517:             *lp++ = sp;
 518:             continue;
 519:         }
 520:         if (cursym.stype!=sp->stype || cursym.svalue!=sp->svalue) {
 521:             printf("%.8s: ", cursym.sname);
 522:             error(0, "Multiply defined");
 523:         }
 524:     }
 525:     dseek(&text, bno, off, filhdr.tsize);
 526:     dseek(&reloc, bno, off+(filhdr.tsize+filhdr.dsize)/2, filhdr.tsize);
 527:     load2td(lp, ctrel, toutb, troutb);
 528:     dseek(&text, bno, off+(filhdr.tsize/2), filhdr.dsize);
 529:     dseek(&reloc, bno, off+filhdr.tsize+(filhdr.dsize/2), filhdr.dsize);
 530:     load2td(lp, cdrel, doutb, droutb);
 531:     torigin =+ filhdr.tsize;
 532:     dorigin =+ filhdr.dsize;
 533:     borigin =+ filhdr.bsize;
 534: }
 535: 
 536: load2td(lp, creloc, b1, b2)
 537: int *lp;
 538: {
 539:     register r, t;
 540:     register struct symbol *sp;
 541: 
 542:     for (;;) {
 543:     /*
 544: 	 * The pickup code is copied from "get" for speed.
 545: 	 */
 546:         if (--text.size <= 0) {
 547:             if (text.size < 0)
 548:                 break;
 549:             text.size++;
 550:             t = get(&text);
 551:         } else if (--text.nibuf < 0) {
 552:             text.nibuf++;
 553:             text.size++;
 554:             t = get(&text);
 555:         } else
 556:             t = *text.ptr++;
 557:         if (--reloc.size <= 0) {
 558:             if (reloc.size < 0)
 559:                 error(1, "Relocation error");
 560:             reloc.size++;
 561:             r = get(&reloc);
 562:         } else if (--reloc.nibuf < 0) {
 563:             reloc.nibuf++;
 564:             reloc.size++;
 565:             r = get(&reloc);
 566:         } else
 567:             r = *reloc.ptr++;
 568:         switch (r&016) {
 569: 
 570:         case RTEXT:
 571:             t =+ ctrel;
 572:             break;
 573: 
 574:         case RDATA:
 575:             t =+ cdrel;
 576:             break;
 577: 
 578:         case RBSS:
 579:             t =+ cbrel;
 580:             break;
 581: 
 582:         case REXT:
 583:             sp = lookloc(lp, r);
 584:             if (sp->stype==EXTERN+UNDEF) {
 585:                 r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT;
 586:                 break;
 587:             }
 588:             t =+ sp->svalue;
 589:             r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1);
 590:             break;
 591:         }
 592:         if (r&01)
 593:             t =- creloc;
 594:         putw(t, b1);
 595:         if (rflag)
 596:             putw(r, b2);
 597:     }
 598: }
 599: 
 600: finishout()
 601: {
 602:     register n, *p;
 603: 
 604:     if (nflag||iflag) {
 605:         n = torigin;
 606:         while (n&077) {
 607:             n =+ 2;
 608:             putw(0, toutb);
 609:             if (rflag)
 610:                 putw(0, troutb);
 611:         }
 612:     }
 613:     copy(doutb, 'a');
 614:     if (rflag) {
 615:         copy(troutb, 'c');
 616:         copy(droutb, 'd');
 617:     }
 618:     if (sflag==0) {
 619:         if (xflag==0)
 620:             copy(soutb, 'b');
 621:         for (p=symtab; p < symp;)
 622:             putw(*p++, toutb);
 623:     }
 624:     fflush(toutb);
 625:     close(toutb[0]);
 626:     unlink("a.out");
 627:     link("l.out", "a.out");
 628:     delarg = errlev;
 629:     delexit();
 630: }
 631: 
 632: delexit()
 633: {
 634:     register c;
 635: 
 636:     unlink("l.out");
 637:     for (c = 'a'; c <= 'd'; c++) {
 638:         tfname[6] = c;
 639:         unlink(tfname);
 640:     }
 641:     if (delarg==0)
 642:         chmod("a.out", 0777);
 643:     exit(delarg);
 644: }
 645: 
 646: copy(buf, c)
 647: int *buf;
 648: {
 649:     register f, *p, n;
 650: 
 651:     fflush(buf);
 652:     close(buf[0]);
 653:     tfname[6] = c;
 654:     f = open(tfname, 0);
 655:     while ((n = read(f, doutb, 512)) > 1) {
 656:         n =>> 1;
 657:         p = doutb;
 658:         do
 659:             putw(*p++, toutb);
 660:         while (--n);
 661:     }
 662:     close(f);
 663: }
 664: 
 665: mkfsym(s)
 666: char *s;
 667: {
 668: 
 669:     if (sflag || xflag)
 670:         return;
 671:     cp8c(s, cursym.sname);
 672:     cursym.stype = 037;
 673:     cursym.svalue = torigin;
 674:     mput(soutb, &cursym, sizeof cursym);
 675: }
 676: 
 677: mget(aloc, an)
 678: int *aloc;
 679: {
 680:     register *loc, n;
 681:     register *p;
 682: 
 683:     n = an;
 684:     n =>> 1;
 685:     loc = aloc;
 686:     if ((text.nibuf =- n) >= 0) {
 687:         if ((text.size =- n) > 0) {
 688:             p = text.ptr;
 689:             do
 690:                 *loc++ = *p++;
 691:             while (--n);
 692:             text.ptr = p;
 693:             return;
 694:         } else
 695:             text.size =+ n;
 696:     }
 697:     text.nibuf =+ n;
 698:     do {
 699:         *loc++ = get(&text);
 700:     } while (--n);
 701: }
 702: 
 703: mput(buf, aloc, an)
 704: int *aloc;
 705: {
 706:     register *loc;
 707:     register n;
 708: 
 709:     loc = aloc;
 710:     n = an>>1;
 711:     do {
 712:         putw(*loc++, buf);
 713:     } while (--n);
 714: }
 715: 
 716: dseek(asp, ab, o, s)
 717: {
 718:     register struct stream *sp;
 719:     register struct page *p;
 720:     register b;
 721:     int n;
 722: 
 723:     sp = asp;
 724:     b = ab + ((o>>8) & 0377);
 725:     o =& 0377;
 726:     --sp->pno->nuser;
 727:     if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)
 728:         if (p->nuser==0 || (p = &page[0])->nuser==0) {
 729:             if (page[0].nuser==0 && page[1].nuser==0)
 730:                 if (page[0].bno < page[1].bno)
 731:                     p = &page[0];
 732:             p->bno = b;
 733:             seek(infil, b, 3);
 734:             if ((n = read(infil, p->buff, 512)>>1) < 0)
 735:                 n = 0;
 736:             p->nibuf = n;
 737:         } else
 738:             error(1, "No pages");
 739:     ++p->nuser;
 740:     sp->bno = b;
 741:     sp->pno = p;
 742:     sp->ptr = p->buff + o;
 743:     if (s != -1)
 744:         sp->size = (s>>1) & 077777;
 745:     if ((sp->nibuf = p->nibuf-o) <= 0)
 746:         sp->size = 0;
 747: }
 748: 
 749: get(asp)
 750: struct stream *asp;
 751: {
 752:     register struct stream *sp;
 753: 
 754:     sp = asp;
 755:     if (--sp->nibuf < 0) {
 756:         dseek(sp, sp->bno+1, 0, -1);
 757:         --sp->nibuf;
 758:     }
 759:     if (--sp->size <= 0) {
 760:         if (sp->size < 0)
 761:             error(1, premeof);
 762:         ++fpage.nuser;
 763:         --sp->pno->nuser;
 764:         sp->pno = &fpage;
 765:     }
 766:     return(*sp->ptr++);
 767: }
 768: 
 769: getfile(acp)
 770: char *acp;
 771: {
 772:     register char *cp;
 773:     register c;
 774: 
 775:     cp = acp;
 776:     archdr.aname[0] = '\0';
 777:     if (cp[0]=='-' && cp[1]=='l') {
 778:         if ((c = cp[2]) == '\0')
 779:             c = 'a';
 780:         cp = "/lib/lib?.a";
 781:         cp[8] = c;
 782:     }
 783:     filname = cp;
 784:     if ((infil = open(cp, 0)) < 0)
 785:         error(1, "cannot open");
 786:     page[0].bno = page[1].bno = -1;
 787:     page[0].nuser = page[1].nuser = 0;
 788:     text.pno = reloc.pno = &fpage;
 789:     fpage.nuser = 2;
 790:     dseek(&text, 0, 0, 2);
 791:     if (text.size <= 0)
 792:         error(1, premeof);
 793:     return(get(&text) == ARCMAGIC);
 794: }
 795: 
 796: struct symbol **lookup()
 797: {
 798:     int i;
 799:     register struct symbol **hp;
 800:     register char *cp, *cp1;
 801: 
 802:     i = 0;
 803:     for (cp=cursym.sname; cp < &cursym.sname[8];)
 804:         i = (i<<1) + *cp++;
 805:     for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) {
 806:         cp1 = (*hp)->sname;
 807:         for (cp=cursym.sname; cp < &cursym.sname[8];)
 808:             if (*cp++ != *cp1++)
 809:                 goto no;
 810:         break;
 811:         no:
 812:         if (++hp >= &hshtab[NSYM+2])
 813:             hp = hshtab;
 814:     }
 815:     return(hp);
 816: }
 817: 
 818: struct symbol **slookup(s)
 819: char *s;
 820: {
 821:     cp8c(s, cursym.sname);
 822:     cursym.stype = EXTERN+UNDEF;
 823:     cursym.svalue = 0;
 824:     return(lookup());
 825: }
 826: 
 827: enter()
 828: {
 829:     register struct symbol *sp;
 830: 
 831:     if ((sp=symp) >= &symtab[NSYM])
 832:         error(1, "Symbol table overflow");
 833:     cp8c(cursym.sname, sp->sname);
 834:     sp->stype = cursym.stype;
 835:     sp->svalue = cursym.svalue;
 836:     symp++;
 837:     return(sp);
 838: }
 839: 
 840: symreloc()
 841: {
 842:     switch (cursym.stype) {
 843: 
 844:     case TEXT:
 845:     case EXTERN+TEXT:
 846:         cursym.svalue =+ ctrel;
 847:         return;
 848: 
 849:     case DATA:
 850:     case EXTERN+DATA:
 851:         cursym.svalue =+ cdrel;
 852:         return;
 853: 
 854:     case BSS:
 855:     case EXTERN+BSS:
 856:         cursym.svalue =+ cbrel;
 857:         return;
 858: 
 859:     case EXTERN+UNDEF:
 860:         return;
 861:     }
 862:     if (cursym.stype&EXTERN)
 863:         cursym.stype = EXTERN+ABS;
 864: }
 865: 
 866: error(n, s)
 867: char *s;
 868: {
 869:     if (filname) {
 870:         printf("%s", filname);
 871:         if (archdr.aname[0])
 872:             printf("(%.8s)", archdr.aname);
 873:         printf(": ");
 874:     }
 875:     printf("%s\n", s);
 876:     if (n)
 877:         delexit();
 878:     errlev = 2;
 879: }
 880: 
 881: lookloc(alp, r)
 882: {
 883:     register int *clp, *lp;
 884:     register sn;
 885: 
 886:     lp = alp;
 887:     sn = (r>>4) & 07777;
 888:     for (clp=local; clp<lp; clp =+ 2)
 889:         if (clp[0] == sn)
 890:             return(clp[1]);
 891:     error(1, "Local symbol botch");
 892: }
 893: 
 894: readhdr(bno, off)
 895: {
 896:     register st, sd;
 897: 
 898:     dseek(&text, bno, off, sizeof filhdr);
 899:     mget(&filhdr, sizeof filhdr);
 900:     if (filhdr.fmagic != FMAGIC)
 901:         error(1, "Bad format");
 902:     st = (filhdr.tsize+01) & ~01;
 903:     filhdr.tsize = st;
 904:     cdrel = -st;
 905:     sd = (filhdr.dsize+01) & ~01;
 906:     cbrel = - (st+sd);
 907:     filhdr.bsize = (filhdr.bsize+01) & ~01;
 908: }
 909: 
 910: cp8c(from, to)
 911: char *from, *to;
 912: {
 913:     register char *f, *t, *te;
 914: 
 915:     f = from;
 916:     t = to;
 917:     te = t+8;
 918:     while ((*t++ = *f++) && t<te);
 919:     while (t<te)
 920:         *t++ = 0;
 921: }

Defined functions

copy defined in line 646; used 4 times
cp8c defined in line 910; used 3 times
delexit defined in line 632; used 4 times
dseek defined in line 716; used 11 times
enter defined in line 827; used 2 times
error defined in line 866; used 15 times
finishout defined in line 600; used 1 times
get defined in line 749; used 6 times
getfile defined in line 769; used 2 times
load1 defined in line 256; used 2 times
load1arg defined in line 224; used 1 times
load2 defined in line 485; used 2 times
load2arg defined in line 461; used 1 times
load2td defined in line 536; used 2 times
lookloc defined in line 881; used 1 times
lookup defined in line 796; used 4 times
main defined in line 138; never used
mget defined in line 677; used 5 times
middle defined in line 320; used 1 times
mkfsym defined in line 665; used 2 times
mput defined in line 703; used 3 times
readhdr defined in line 894; used 2 times
setupout defined in line 418; used 1 times
slookup defined in line 818; used 5 times
symreloc defined in line 840; used 2 times
tcreat defined in line 453; used 4 times

Defined variables

Xflag defined in line 101; used 3 times
archdr defined in line 63; used 14 times
arflag defined in line 103; used 2 times
borigin defined in line 120; used 4 times
bsize defined in line 114; used 11 times
cbrel defined in line 124; used 5 times
cdrel defined in line 123; used 6 times
ctrel defined in line 122; used 5 times
cursym defined in line 91; used 45 times
delarg defined in line 127; used 3 times
dflag defined in line 106; used 3 times
dorigin defined in line 119; used 7 times
doutb defined in line 130; used 5 times
droutb defined in line 132; used 3 times
dsize defined in line 113; used 16 times
errlev defined in line 126; used 3 times
filhdr defined in line 74; used 45 times
filname defined in line 110; used 4 times
hshtab defined in line 93; used 3 times
iflag defined in line 107; used 6 times
infil defined in line 109; used 5 times
liblist defined in line 81; used 2 times
libp defined in line 82; used 8 times
local defined in line 95; used 5 times
nflag defined in line 105; used 6 times
nsym defined in line 116; used 2 times
p_edata defined in line 97; used 6 times
p_end defined in line 98; used 6 times
p_etext defined in line 96; used 6 times
page defined in line 40; used 12 times
premeof defined in line 33; used 2 times
reloc defined in line 56; used 12 times
rflag defined in line 102; used 9 times
sflag defined in line 104; used 8 times
soutb defined in line 133; used 4 times
ssize defined in line 115; used 8 times
symp defined in line 94; used 10 times
symtab defined in line 92; used 8 times
text defined in line 55; used 30 times
tfname defined in line 128; used 8 times
torigin defined in line 118; used 5 times
toutb defined in line 129; used 8 times
troutb defined in line 131; used 4 times
tsize defined in line 112; used 21 times
xflag defined in line 100; used 7 times

Defined struct's

archdr defined in line 58; never used
filhdr defined in line 65; never used
liblist defined in line 76; used 6 times
page defined in line 35; used 4 times
stream defined in line 47; used 10 times
symbol defined in line 84; used 40 times

Defined macros

ABS defined in line 14; used 2 times
ARCMAGIC defined in line 7; used 1 times
BSS defined in line 17; used 2 times
COMM defined in line 18; used 1 times
DATA defined in line 16; used 1 times
EXTERN defined in line 12; used 31 times
FMAGIC defined in line 8; used 2 times
IMAGIC defined in line 10; used 1 times
NMAGIC defined in line 9; used 1 times
NROUT defined in line 27; used 1 times
  • in line 81
NSYM defined in line 28; used 5 times
NSYMPR defined in line 29; used 2 times
RABS defined in line 20; never used
RBSS defined in line 23; never used
RDATA defined in line 22; never used
RELFLG defined in line 26; used 1 times
REXT defined in line 24; used 1 times
RONLY defined in line 31; used 1 times
RTEXT defined in line 21; never used
SIGINT defined in line 6; used 2 times
TEXT defined in line 15; used 2 times
UNDEF defined in line 13; used 10 times
Last modified: 1975-07-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2847
Valid CSS Valid XHTML 1.0 Strict