1: # include   "link.h"
   2: # define    MAXREG      8
   3: WORD    getword();
   4: char *sprintf();
   5: 
   6: 
   7: /******************** variables with global scope ************************/
   8: 
   9: 
  10: extern struct objfile   *File_root; /* root of object file link-list */
  11: extern struct symbol    *Sym_root;  /* root of symbol table */
  12: extern struct g_sect    *Gsect_root;    /* root of global psect tree */
  13: WORD    Maxabs;         /* maximum size of absolute files,
  14: 					** also low limit of relocatable code */
  15: extern WORD R_counter;      /* relocation counter, used in
  16: 					** assigning relocation constants,
  17: 					** also high limit of relocatable
  18: 					** code after relocation */
  19: extern long Seekoff;        /* offset for seeking in out file */
  20: extern char Do_410;         /* out file format boolean */
  21: extern char Do_411;         /* out file format boolean */
  22: extern char Do_map;         /* boolean for printing load map */
  23: extern char Do_lpr_map;     /* boolean for line printing map */
  24: extern char Do_bits;        /* boolean for including relocation
  25: 					** bits in .out file */
  26: extern char Do_kludge;      /* boolean to write global symbols in
  27: 					** out file table with underscore */
  28: extern char Do_silent;      /* boolean for not printing zero
  29: 					** errors message */
  30: extern char Do_table;       /* boolean for including symbol table
  31: 					** in out file */
  32: extern char No_locals;      /* boolean for not including local
  33: 					** symbols in out table */
  34: extern WORD Transadd;       /* transfer address */
  35: int     T_counter;      /* used for assigning numbers to the
  36: 					** global symbols so that they may be
  37: 					** referenced in relocation bits */
  38: int     Glc;            /* global location counter */
  39: struct outword  Curr;           /* Curr.val is the current relocation
  40: 					** constant, and Curr.rbits is the
  41: 					** current relocation bits */
  42: WORD    Tex_size;       /* for out file */
  43: WORD    Dat_size;       /* for out file */
  44: WORD    Bss_size;       /* for out file */
  45: char    *Outname;       /* name of out file */
  46: FILE        *Outp = NULL;       /* pointer for out file */
  47: extern char Erstring[80];       /* buffer for error messages */
  48: extern int  Nerrors;        /* the number of user errors */
  49: FILE        *Bitp = NULL;       /* temporary file for relocation bits */
  50: char        Bitname[20];        /* name of temporary bit file */
  51: FILE        *Symp = NULL;       /* temporary file for symbol table */
  52: char        Symname[20];        /* name of temporary file for symbol table */
  53: char    *Mapname;       /* name of the map file */
  54: FILE    *Mapp;          /* pointer for map file */
  55: char    No_out;         /* boolean for no out file */
  56: char        Undefineds = 0;     /* boolean, set if there are any
  57: 					** references to undefined global
  58: 					** symbols in the out file */
  59: struct outword  Vreg[MAXREG];       /* virtual registers */
  60: 
  61: /**************************  warmup  ****************************************/
  62: 
  63: 
  64: warmup()    /* get ready for pass 2: open out file and write header,
  65: 		** open temporary file for out file
  66: 		** symbol table and write global variables to it */
  67: 
  68: {
  69:     WORD h[8];
  70: 
  71:     Outp = fopen(Outname, "w");
  72:     if (Outp == NULL)
  73:     {
  74:         sprintf(Erstring, "%s not accessible\n", Outname);
  75:         lerror(Erstring);
  76:     }
  77:     fseek(Outp, 15L+(long)Tex_size+(long)Dat_size, 0);
  78:     putc(0, Outp);
  79: 
  80:     /* write header for out file */
  81:     if (Do_410)
  82:         h[0] = 0410;
  83:     else if (Do_411)
  84:         h[0] = 0411;
  85:     else
  86:         h[0] = 0407;
  87:     h[1] = Tex_size;
  88:     h[2] = Dat_size;
  89:     h[3] = Bss_size;
  90:     h[4] = 0;
  91:     h[5] = Transadd;
  92:     h[6] = 0;
  93:     h[7] = Do_bits ? 0 : 1;
  94: 
  95:     fseek(Outp, 0L, 0);
  96:     fwrite(h, 8, 2, Outp);
  97: 
  98:     if (Do_table)
  99:     {
 100:         sprintf(Symname, "/tmp/l11.sym.%d", getpid());
 101:         Symp = fopen(Symname, "w");
 102:         if (Symp == NULL)
 103:             lerror("can't open symbol table file");
 104:         else
 105:         {
 106:             T_counter = 0;  /* initialize counter for numbering global
 107: 					** symbols */
 108:             dump_tree(Sym_root);
 109:         }
 110:     }
 111: 
 112:     if (Do_bits)
 113:     {
 114:         sprintf(Bitname, "/tmp/l11.bit.%d", getpid());
 115:         Bitp = fopen(Bitname, "w");
 116:         if (Bitp == NULL)
 117:             lerror("can't open relocation bits file");
 118:     }
 119: }
 120: 
 121: 
 122: /*************************  dump_tree  **************************************/
 123: 
 124: 
 125: dump_tree(sym)      /* dump the sub-tree of symbols pointed to by *sym and
 126: 			** number its contents for future reference to
 127: 			** undefined symbols */
 128: 
 129: register struct symbol  *sym;
 130: {
 131:     if (sym == NULL)
 132:         return;
 133: 
 134:     dump_tree(sym->left);
 135: 
 136:     write_sym(sym->name, Do_kludge);
 137:     if (sym->type & DEF)    /* if the symbol is defined */
 138:         Putw(040 | get_type(sym->prsect->type), Symp);
 139:     else            /* undefined */
 140:         Putw(040, Symp);
 141:     Putw(sym->value, Symp);
 142:     sym->t_numb = T_counter++;
 143: 
 144:     dump_tree(sym->right);
 145: }
 146: 
 147: 
 148: /**************************  write_sym  ***********************************/
 149: 
 150: 
 151: write_sym(sname, flag)  /* write the given symbol as 8 bytes (null padded)
 152: 			** in the symbol file , if flag then write the symbol
 153: 			** with an underscore */
 154: register char   *sname;
 155: register int    flag;
 156: {
 157:     if (flag)
 158:         putc('_', Symp);
 159:     while (*sname)
 160:     {
 161:         if (*sname == ' ')
 162:             putc(0, Symp);
 163:         else
 164:             putc(*sname, Symp);
 165:         sname++;
 166:     }
 167:     putc(0, Symp);
 168:     if (!flag)
 169:         putc(0, Symp);
 170: }
 171: 
 172: 
 173: /****************************  pass2  ****************************************/
 174: 
 175: 
 176: pass2()     /* translate code and write local symbols */
 177: 
 178: {
 179:     struct objfile  *obj;   /* which object file */
 180: 
 181:     obj = File_root;
 182:     while (obj != NULL)
 183:     {
 184:         transcode(obj);
 185:         if (Do_table && !No_locals)
 186:             dump_locals(obj);
 187:         obj = obj->nextfile;
 188:     }
 189: }
 190: 
 191: 
 192: /************************  transcode  ****************************************/
 193: 
 194: 
 195: transcode(obj)      /* translate code */
 196: 
 197: struct objfile  *obj;       /* object file to translate code from */
 198: {
 199:     register int    drctv;      /* directive from obj file */
 200:     register int    value;      /* temporary variable */
 201:     int     vrd;        /* possible virtual register directive */
 202:     static struct outword   wbuff;
 203: 
 204: 
 205:     ch_input(obj->fname, CODE);
 206:     while (morebytes()) /* continue reading code section until
 207: 				** empty */
 208:     {
 209:         switch (drctv = getbyte())
 210:         {
 211:         case 000:
 212:             abswrite((WORD)0, (WORD)0);
 213:             break;
 214: 
 215:         case 002:
 216:             relwrite((WORD)0, (WORD)0);
 217:             break;
 218: 
 219:         case 004:
 220:             abswrite(getword(), (WORD)0);
 221:             break;
 222: 
 223:         case 006:
 224:             relwrite(getword(), (WORD)0);
 225:             break;
 226: 
 227:         case 010:
 228:             abswrite(Curr.val, Curr.rbits);
 229:             break;
 230: 
 231:         case 014:
 232:             abswrite(Curr.val + getword(), Curr.rbits);
 233:             break;
 234: 
 235:         case 020:
 236:             get_sym(&wbuff);
 237:             abswrite(wbuff.val, wbuff.rbits);
 238:             break;
 239: 
 240:         case 022:
 241:             get_sym(&wbuff);
 242:             relwrite(wbuff.val, wbuff.rbits);
 243:             break;
 244: 
 245:         case 030:
 246:             get_rc(&wbuff, obj, (char *)NULL);
 247:             abswrite(wbuff.val, wbuff.rbits);
 248:             break;
 249: 
 250:         case 032:
 251:             get_rc(&wbuff, obj, (char *)NULL);
 252:             relwrite(wbuff.val, wbuff.rbits);
 253:             break;
 254: 
 255:         case 034:
 256:             get_rc(&wbuff, obj, (char *)NULL);
 257:             abswrite(wbuff.val + getword(), wbuff.rbits);
 258:             break;
 259: 
 260:         case 036:
 261:             get_rc(&wbuff, obj, (char *)NULL);
 262:             relwrite(wbuff.val + getword(), wbuff.rbits);
 263:             break;
 264: 
 265:         case 040:
 266:             do040(obj);
 267:             break;
 268: 
 269:         case 044:
 270:             wbuff.val = getword();
 271:             wbuff.rbits = 0;
 272:             vreg_oper(getbyte(), &wbuff);
 273:             break;
 274: 
 275:         case 050:
 276:             if ((vrd = getbyte()) == 0)
 277:                 linkseek(Curr.val, Curr.rbits);
 278:             else
 279:                 vreg_oper(vrd, &Curr);
 280:             break;
 281: 
 282:         case 054:
 283:             value = getword();
 284:             if ((vrd = getbyte()) == 0)
 285:                 linkseek(Curr.val + value, Curr.rbits);
 286:             else
 287:             {
 288:                 wbuff.val = Curr.val + value;
 289:                 wbuff.rbits = Curr.rbits;
 290:                 vreg_oper(vrd, &wbuff);
 291:             }
 292:             break;
 293: 
 294:         case 060:
 295:             get_sym(&wbuff);
 296:             vreg_oper(getbyte(), &wbuff);
 297:             break;
 298: 
 299:         case 070:
 300:             get_rc(&wbuff, obj, (char *)NULL);
 301:             if ((vrd = getbyte()) == 0)
 302:             {
 303:                 linkseek(wbuff.val, wbuff.rbits);
 304:                 Curr.val = wbuff.val;
 305:                 Curr.rbits = wbuff.rbits;
 306:             }
 307:             else
 308:                 vreg_oper(vrd, &wbuff);
 309:             break;
 310: 
 311:         case 074:
 312:             get_rc(&wbuff, obj, (char *)NULL);
 313:             value = getword();
 314:             if ((vrd = getbyte()) == 0)
 315:             {
 316:                 linkseek(wbuff.val + value, wbuff.rbits);
 317:                 Curr.val = wbuff.val;
 318:                 Curr.rbits = wbuff.rbits;
 319:             }
 320:             else
 321:             {
 322:                 wbuff.val += value;
 323:                 vreg_oper(vrd, &wbuff);
 324:             }
 325:             break;
 326: 
 327:         case 0200:
 328:             bytewrite((char)0);
 329:             break;
 330: 
 331:         case 0204:
 332:             bytewrite((char)getbyte());
 333:             break;
 334: 
 335:         case 0220:
 336:             get_sym(&wbuff);
 337:             if (Do_bits && wbuff.rbits != 0)
 338:                 uerror("unrelocatable byte expression");
 339:             bytewrite((char)(0377 & wbuff.val));
 340:             break;
 341: 
 342:         default:
 343:             sprintf(Erstring, "bad code directive %03o", drctv);
 344:             lerror(Erstring);
 345:         }
 346:     }
 347: }
 348: 
 349: 
 350: /*************************  abswrite  *****************************************/
 351: 
 352: 
 353: abswrite(value, rbits)  /* write value in the out file */
 354: register WORD   value;
 355: register WORD   rbits;  /* relocation bits */
 356: {
 357:     Putw(value, Outp);
 358:     Glc += 2;
 359:     if (Do_bits)
 360:         Putw(rbits, Bitp);
 361: }
 362: 
 363: 
 364: /************************  relwrite  ****************************************/
 365: 
 366: 
 367: relwrite(value, rbits)  /* write value in out file relative to
 368: 			** global location counter */
 369: register WORD   value;
 370: register WORD   rbits;
 371: {
 372:     Putw(value - Glc - 2, Outp);
 373:     Glc += 2;
 374:     if (Do_bits)
 375:         Putw((rbits == Curr.rbits) ? 0 : (rbits | 01), Bitp);
 376:             /* if the relocation bits for the word being written are
 377: 			** the same as the current psect's then the word is an
 378: 			** absolute offset, otherwise add 1 to the relocation
 379: 			** bits to indicate relativity to the PC */
 380: }
 381: 
 382: 
 383: /*************************  bytewrite  *************************************/
 384: 
 385: 
 386: bytewrite(value)    /* write the byte in the out file */
 387:     char value;
 388: {
 389:     putc(0377&value, Outp);
 390:     Glc++ ;
 391: }
 392: 
 393: 
 394: /*************************  get_rc  *****************************************/
 395: 
 396: 
 397: get_rc(wbuff, obj, psname)  /* place in wbuff the relocation constant and
 398: 				** relocation bits of psname
 399: 				** or if psname is NULL the psect whose
 400: 				** name is in the input stream, and whose object
 401: 				** file is pointed to by 'obj'. */
 402: 
 403: register struct outword     *wbuff;
 404: struct objfile          *obj;
 405: register char           *psname;
 406: 
 407: {
 408:     char            name[7];    /* the name of the psect */
 409:     register struct psect   *ps;
 410: 
 411:     /* if psname is NULL get name from input stream */
 412:     if (psname == NULL)
 413:     {
 414:         psname = name;
 415:         dc_symbol(psname);
 416:     }
 417: 
 418:     ps = obj->psect_list;
 419: 
 420:     while (strcmp(ps->name, psname))    /* while the strings are
 421: 						** not equal */
 422:     {
 423:         ps = ps->obsame;
 424:         if (ps == NULL)
 425:         {
 426:             sprintf(Erstring, "rc not found for %s", psname);
 427:             lerror(Erstring);
 428:         }
 429:     }
 430:     wbuff->val = ps->rc;
 431:     wbuff->rbits = get_bits(ps->type);
 432: }
 433: 
 434: 
 435: /*****************************  get_bits  **********************************/
 436: 
 437: 
 438: get_bits(attributes)    /* get the out file symbol table bits and convert
 439: 			** to relocation table bits */
 440: 
 441: register int    attributes; /* the M11 attributes of a psect */
 442: {
 443:     return (2 * (get_type(attributes) - 1));
 444: }
 445: 
 446: 
 447: /*****************************  get_type  ***********************************/
 448: 
 449: 
 450: get_type(attr)      /* decode the psect type into out file symbol table
 451: 			** attribute word format */
 452: register int    attr;
 453: {
 454:     if (!(attr & REL))  /* absolute */
 455:         return (01);
 456:     else if (attr & INS)    /* text */
 457:         return (02);
 458:     else if (attr & BSS)    /* bss */
 459:         return (04);
 460:     else            /* data */
 461:         return (03);
 462: }
 463: 
 464: 
 465: /***************************  get_sym  ***************************************/
 466: 
 467: 
 468: get_sym(wbuff)      /* get the value of the symbol in the input stream */
 469: register struct outword *wbuff;
 470: 
 471: {
 472:     char            sname[7];   /* the name of the symbol */
 473:     register struct symbol  *sym;
 474:     register int        cond;       /* used for branching left
 475: 						** or right */
 476:     int         index;      /* virtual register index */
 477: 
 478:     dc_symbol(sname);
 479:     if (*sname != ' ')
 480:     {
 481:         sym = Sym_root;
 482:         while (sym != NULL)
 483:         {
 484:             if ((cond = strcmp(sname, sym->name)) == 0)
 485:             {
 486:                 if (sym->type & DEF)    /* if defined */
 487:                 {
 488:                     wbuff->val = sym->value;
 489:                     wbuff->rbits = get_bits(sym->prsect->type);
 490:                     return;
 491:                 }
 492:                 else if (Do_bits)   /* set relocation bits
 493: 							** for undefined symbol
 494: 							** and return zero */
 495:                 {
 496:                     Undefineds = 1;
 497:                     wbuff->val = 0;
 498:                     wbuff->rbits = 020 * sym->t_numb + 010;
 499:                     return;
 500:                 }
 501:                 else
 502:                 {
 503:                     sprintf(Erstring, "undefined symbol: %s", sname);
 504:                     uerror(Erstring);
 505:                     wbuff->val = 0;
 506:                     wbuff->rbits = 0;
 507:                     return;
 508:                 }
 509:             }
 510:             else if (cond < 0)
 511:                 sym = sym->left;
 512:             else
 513:                 sym = sym->right;
 514:         }
 515:         /* symbol has not been found */
 516:         sprintf(Erstring, "%s not found", sname);
 517:         lerror(Erstring);
 518:         wbuff->val = 0;
 519:         wbuff->rbits = 0;
 520:     }
 521:     else    /* virtual register */
 522:     {
 523:         index = sname[5] - 'a';
 524:         wbuff->val = Vreg[index].val;
 525:         wbuff->rbits = Vreg[index].rbits;
 526:     }
 527: }
 528: 
 529: 
 530: /***************************  vreg_oper  *************************************/
 531: 
 532: vreg_oper(drctv, wbuff)     /* preform an operation on a virtual register */
 533: 
 534: register int        drctv;      /* directive (operation) */
 535: register struct outword *wbuff;     /* source value and relocation bits */
 536: {
 537:     register int    index;      /* index of destination register */
 538:     static char mess[] = "unrelocatable arithmetic expression";
 539: 
 540:     index = getbyte() - 1;
 541:     if (index >= MAXREG)
 542:     {
 543:         uerror("expression involving global symbols too large");
 544:         index %= MAXREG;
 545:     }
 546: 
 547:     switch(drctv)
 548:     {
 549:         case 0200:
 550:             Vreg[index].val = wbuff->val;
 551:             Vreg[index].rbits = wbuff->rbits;
 552:             break;
 553: 
 554:         case 0201:
 555:             Vreg[index].val += wbuff->val;
 556:             if (Do_bits && Vreg[index].rbits && wbuff->rbits)
 557:                 uerror(mess);
 558:             else
 559:                 Vreg[index].rbits |= wbuff->rbits;
 560:             break;
 561: 
 562:         case 0202:
 563:             Vreg[index].val -= wbuff->val;
 564:             if (Do_bits && wbuff->rbits)
 565:                 if (Vreg[index].rbits == wbuff->rbits)
 566:                     Vreg[index].rbits = 0;
 567:                 else
 568:                     uerror(mess);
 569:             break;
 570: 
 571:         case 0203:
 572:             Vreg[index].val *= wbuff->val;
 573:             if (Do_bits)
 574:                 uerror(mess);
 575:             break;
 576: 
 577:         case 0204:
 578:             Vreg[index].val /= wbuff->val;
 579:             if (Do_bits)
 580:                 uerror(mess);
 581:             break;
 582: 
 583:         case 0205:
 584:             Vreg[index].val &= wbuff->val;
 585:             if (Do_bits)
 586:                 uerror(mess);
 587:             break;
 588: 
 589:         case 0206:
 590:             Vreg[index].val |= wbuff->val;
 591:             if (Do_bits)
 592:                 uerror(mess);
 593:             break;
 594: 
 595:         default:
 596:             sprintf(Erstring, "bad v.r. directive: %03o", drctv);
 597:             lerror(Erstring);
 598:     }
 599: }
 600: 
 601: 
 602: /**************************  do040  ***************************************/
 603: 
 604: 
 605: do040(obj)  /* do 040 code directive */
 606: 
 607: register struct objfile *obj;
 608: {
 609:     register int    drctv;
 610:     register int    index;
 611: 
 612:     switch (drctv = getbyte())
 613:     {
 614:         case 001:   /* low limit */
 615:             index = getbyte() - 1;
 616:             Vreg[index].val = Maxabs;
 617:             Vreg[index].rbits = 0;
 618:             if (Do_bits)
 619:                 uerror("'.limit' directive not relocatable");
 620:             break;
 621: 
 622:         case 002:   /* high limit */
 623:             index = getbyte() - 1;
 624:             Vreg[index].val = R_counter;
 625:             Vreg[index].rbits = 0;
 626:             break;
 627: 
 628:         case 003:   /* ^pl */
 629:         case 004:   /* ^ph */
 630:             p_limit(obj, drctv);
 631:             break;
 632: 
 633:         case 0200:  /* clear */
 634:             index = getbyte() - 1;
 635:             Vreg[index].val = Vreg[index].rbits = 0;
 636:             break;
 637: 
 638:         case 0201:  /* add zero */
 639:             index = getbyte();
 640:             break;
 641: 
 642:         default:
 643:             sprintf(Erstring, "bad 040 directive %03o", drctv);
 644:             lerror(Erstring);
 645:     }
 646: }
 647: 
 648: 
 649: /*************************  p_limit  **************************************/
 650: 
 651: 
 652: p_limit(obj, drctv) /* find the low or high limit of a psect */
 653:     struct objfile      *obj;
 654:     int         drctv;
 655: {
 656:     register struct psect   *ps;
 657:     register struct g_sect  *gptr;
 658:     int         cond;
 659:     register int        index;
 660:     char            pname[7];
 661: 
 662:     dc_symbol(pname);
 663:     index = getbyte() - 1;
 664: 
 665:     ps = obj->psect_list;
 666: 
 667:     while (ps != NULL)  /* try to find the psect in local link-list */
 668:     {
 669:         if ( !strcmp(pname, ps->name))
 670:             break;
 671:         ps = ps->obsame;
 672:     }
 673: 
 674:     if (ps != NULL)     /* if it was found in the local list */
 675:     {
 676:         while (ps->pssame != NULL)  /* find bottom of sames, if any.
 677: 					 	** see relocate() */
 678:             ps = ps->pssame;
 679:     }
 680:     else    /* psect not a local so check global tree */
 681:     {
 682:         gptr = Gsect_root;
 683:         while (gptr != NULL)
 684:         {
 685:             if ( !(cond = strcmp(pname, gptr->name)))
 686:             {
 687:                 if (gptr->last_sect->pssame == NULL)
 688:                     /* the psect is solitary */
 689:                     ps = gptr->last_sect;
 690:                 else
 691:                     /* last_psect points to the last psect
 692: 					** in a plural link-list of sames.
 693: 					** there is a psect after last_sect
 694: 					** which contains the conglomeration
 695: 					** of all the sames.
 696: 					** see relocate() */
 697:                     ps = gptr->last_sect->pssame;
 698:                 break;
 699:             }
 700:             else if (cond < 0)
 701:                 gptr = gptr->leftt;
 702:             else
 703:                 gptr = gptr->rightt;
 704:         }
 705: 
 706:         if (ps == NULL)     /* psect not found */
 707:         {
 708:             sprintf(Erstring, "%s not found in ^p reference", pname);
 709:             uerror(Erstring);
 710:             Vreg[index].val = Vreg[index].rbits = 0;
 711:             return;
 712:         }
 713:     }
 714: 
 715:     if (drctv == 003)   /* low */
 716:         Vreg[index].val = ps->rc;
 717:     else            /* high */
 718:         Vreg[index].val = ps->rc + ps->nbytes;
 719: 
 720:     Vreg[index].rbits = get_bits(ps->type);
 721: }
 722: 
 723: 
 724: /***************************  linkseek  *************************************/
 725: 
 726: 
 727: linkseek(nlc, nrbits)
 728: 
 729: register WORD nlc;  /* new location counter */
 730: register WORD nrbits;   /* new relocation bits */
 731: {
 732:     long    where;
 733: 
 734:     Glc = nlc;
 735: 
 736:     if (nrbits == 04)   /* if data section add offset */
 737:         where = nlc + Seekoff + 020;
 738:     else
 739:         where = nlc + 020;
 740: 
 741:     if (fseek(Outp, where, 0) == -1)
 742:     {
 743: skerr:      fprintf(stderr, "Fseek error\n");
 744:         bail_out();
 745:     }
 746:     if (Do_bits)
 747:         if (fseek(Bitp, where - 020L, 0) == -1)
 748:             goto skerr;
 749: 
 750:     if (nrbits == 06)   /* bss section about to be writen */
 751:         uerror("error: initialized data in bss psect");
 752: }
 753: 
 754: 
 755: /****************************  dump_locals  ********************************/
 756: 
 757: 
 758: # define    MAXCONSTS   10
 759: 
 760: 
 761: dump_locals(obj)    /* dump local symbols */
 762: 
 763: struct objfile  *obj;
 764: {
 765:     int     rconst[MAXCONSTS];  /* relocation constants */
 766:     int     segment[MAXCONSTS]; /* segment type for out file */
 767:     struct psect    *last;
 768:     struct psect    *temp;
 769:     char        sname[7];       /* symbol name */
 770:     char        index;
 771:     char        type;
 772:     int     value;
 773:     int     i;
 774: 
 775:     /* fill rconst and segment arrays from the first MAXCONSTS psects */
 776:     temp = obj->psect_list;
 777:     i = 0;
 778:     while (temp != NULL && i < MAXCONSTS)
 779:     {
 780:         rconst[i] = temp->rc;
 781:         segment[i++] = get_type(temp->type);
 782:         temp = temp->obsame;
 783:     }
 784:     last = temp;    /* (in case there are more psects than MAXCONSTS) */
 785: 
 786:     /* write 'em */
 787: 
 788:     ch_input(obj->fname, SYMBOLS);
 789:     while (morebytes())
 790:     {
 791:         dc_symbol(sname);
 792:         type = getbyte();
 793:         index = getbyte();
 794:         value = getword();
 795: 
 796:         if (type & 001)     /* if internal m11 symbol, forget it */
 797:             continue;
 798: 
 799:         write_sym(sname, 0);
 800:         if (index >= MAXCONSTS)
 801:         {
 802:             temp = last;
 803:             for (i = MAXCONSTS; i < index; i++)
 804:                 temp = temp->obsame;
 805:             Putw(get_type(temp->type), Symp);
 806:             Putw(value + temp->rc, Symp);
 807:         }
 808:         else
 809:         {
 810:             Putw(segment[index], Symp);
 811:             Putw(value + rconst[index], Symp);
 812:         }
 813:     }
 814: }
 815: 
 816: 
 817: /************************  uerror  ******************************************/
 818: 
 819: 
 820: uerror(mess)    /* print user error message and increment Nerrors */
 821: 
 822: register char   *mess;
 823: {
 824:     Nerrors++;
 825:     fprintf(stderr, "%s\n", mess);
 826:     if (Do_map)
 827:         fprintf(Mapp, "%s\n", mess);
 828: }
 829: 
 830: 
 831: /**************************  loose_ends  ************************************/
 832: 
 833: 
 834: loose_ends()
 835: {
 836:     register c;
 837:     register int    nbytes; /* number of bytes in out file symbol table */
 838: 
 839: 
 840:     if (Do_bits)
 841:     {
 842:         if (ferror(Bitp))
 843:             werror(Bitname);
 844: 
 845:         Bitp = freopen(Bitname, "r", Bitp);
 846:         if (Bitp == NULL)
 847:             lerror("can't reopen relocation bits file");
 848: 
 849:         fseek(Outp, (long) (Tex_size + Dat_size + 020L), 0);
 850: 
 851:         while ((c = getc(Bitp)) != EOF)
 852:             putc(0377&c, Outp);
 853: 
 854:         unlink(Bitname);
 855:     }
 856: 
 857:     if (Do_table)
 858:     {
 859:         if (ferror(Symp))
 860:             werror(Symname);
 861: 
 862:         Symp = freopen(Symname, "r", Symp);
 863:         if (Symp == NULL)
 864:             lerror("can't reopen symbol table file");
 865: 
 866:         /* send r/w head to end of rbits or code section in out file */
 867: 
 868:         fseek(Outp, (long) ((Tex_size + Dat_size) * (Do_bits + 1) + 020L), 0);
 869: 
 870:         nbytes = 0;
 871:         while ((c = getc(Symp)) != EOF)
 872:         {
 873:             nbytes++;
 874:             putc(0377&c, Outp);
 875:         }
 876: 
 877:         /* write size of symbol table */
 878:         fseek(Outp, 010L, 0);
 879:         Putw(nbytes, Outp);
 880: 
 881:         unlink(Symname);
 882:     }
 883: 
 884:     if (Do_map)
 885:     {
 886:         fprintf(Mapp, "errors detected:  %d\n", Nerrors);
 887:         if (ferror(Mapp))
 888:             werror(Mapname);
 889:         fclose(Mapp);
 890:         if (Do_lpr_map)
 891:             execl("/usr/bin/lpr", "lpr", Mapname, 0);
 892:     }
 893: 
 894:     if (ferror(Outp))
 895:         werror(Outname);
 896: 
 897:     /* change out file to be executable if no errors */
 898:     chmod(Outname, Nerrors ? 0644 : 0755);
 899: 
 900:     if (Nerrors || !Do_silent)
 901:         fprintf(stderr, "errors detected:  %d\n", Nerrors);
 902: 
 903:     exit(Nerrors ? 1 : 0);
 904: }
 905: 
 906: 
 907: /****************************  bail_out  ***********************************/
 908: 
 909: 
 910: bail_out()  /* unlink any opened output file then exit */
 911: 
 912: {
 913:     if (Outp != NULL)
 914:         unlink(Outname);
 915:     if (Mapp != NULL)
 916:         unlink(Mapname);
 917:     if (Symp != NULL)
 918:         unlink(Symname);
 919:     if (Bitp != NULL)
 920:         unlink(Bitname);
 921:     exit(1);
 922: }
 923: 
 924: 
 925: /********************************  werror  **********************************/
 926: 
 927: 
 928: werror(fname)       /* write error handler */
 929: char    *fname;
 930: 
 931: {
 932:     perror(fname);
 933:     if (Symp != NULL)
 934:         unlink(Symname);
 935:     if (Bitp != NULL)
 936:         unlink(Bitname);
 937:     exit(1);
 938: }
 939: Putw(x, p)
 940:     FILE *p;
 941: {
 942:     putc(x & 0377, p);
 943:     x >>= 8;
 944:     putc(x & 0377, p);
 945: }

Defined functions

Putw defined in line 939; used 12 times
abswrite defined in line 353; used 7 times
bail_out defined in line 910; used 7 times
bytewrite defined in line 386; used 3 times
do040 defined in line 605; used 1 times
dump_locals defined in line 761; used 1 times
dump_tree defined in line 125; used 3 times
get_bits defined in line 438; used 3 times
get_rc defined in line 397; used 7 times
get_sym defined in line 468; used 4 times
get_type defined in line 450; used 4 times
linkseek defined in line 727; used 4 times
loose_ends defined in line 834; used 1 times
p_limit defined in line 652; used 1 times
pass2 defined in line 176; used 1 times
relwrite defined in line 367; used 5 times
transcode defined in line 195; used 1 times
uerror defined in line 820; used 14 times
vreg_oper defined in line 532; used 6 times
warmup defined in line 64; used 1 times
werror defined in line 928; used 4 times
write_sym defined in line 151; used 2 times

Defined variables

Bitname defined in line 50; used 7 times
Curr defined in line 39; used 16 times
Glc defined in line 38; used 5 times
Mapname defined in line 53; used 3 times
No_out defined in line 55; never used
Outname defined in line 45; used 5 times
Symname defined in line 52; used 7 times
T_counter defined in line 35; used 2 times
Undefineds defined in line 56; used 1 times
Vreg defined in line 59; used 25 times

Defined macros

MAXCONSTS defined in line 758; used 5 times
MAXREG defined in line 2; used 3 times
Last modified: 1982-12-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2323
Valid CSS Valid XHTML 1.0 Strict