|
|
1.1 ! root 1: static char *ID_pass1 = "@(#) pass1.c: 1.9 12/10/83"; ! 2: ! 3: #include <stdio.h> ! 4: #include <ctype.h> ! 5: #include <signal.h> ! 6: #include <paths.h> ! 7: #include "systems.h" ! 8: #include "symbols.h" ! 9: #include "gendefs.h" ! 10: ! 11: /* ! 12: * ! 13: * "pass1.c" is a file containing the main routine for the first ! 14: * pass of the assembler. It is invoked with the command: ! 15: * ! 16: * as1 [flags] ifile ofile t1 t2 t3 t4 t5 t6 t7 ! 17: * ! 18: * where {flags] are optional flags passed from pass 0, ! 19: * "ifile" is the name of the assembly language input file, ! 20: * "t1" through "t7" are the names of temporary files to be used ! 21: * by the assembler, and "ofile" is the file where the object code ! 22: * is to be written. Pass 1 of the assembler reads "ifile" and ! 23: * writes the temporary text section to "t1", the temporary data ! 24: * section to "t2", and the symbol table to "t3". ! 25: * ! 26: * The following things are done by this function: ! 27: * ! 28: * 1. Initialization. This consists of calling signal to catch ! 29: * interrupt signals for hang-up, break, and terminate. Then ! 30: * the argument list is processed by "getargs" followed by the ! 31: * initialization of the symbol table with mnemonics for ! 32: * instructions and pseudos-ops. ! 33: * ! 34: * 2. "yyparse" is called to do the actual first pass processing. ! 35: * This is followed by a call to "cgsect". Normally this ! 36: * function is used to change the section into which code ! 37: * is generated. In this case, it is only called to make ! 38: * sure that "dottxt", "dotdat", and "dotbss" contain the ! 39: * proper values for the program counters for the respective ! 40: * sections. The following symbols are then defined: ! 41: * ! 42: * .text This has a type of text and a value of zero. ! 43: * It is used to label the beginning of the text ! 44: * section, and later as a reference for relocation ! 45: * entries that are relative to the text section. ! 46: * ! 47: * .data This has a type of data and a value of zero. ! 48: * It is used to label the beginning of the data ! 49: * section, and later as a reference for relocation ! 50: * entries that are relative to the data section. ! 51: * ! 52: * .bss This has a type of bss and a value of zero. It ! 53: * is used to label the beginning of the bss ! 54: * section, and later as a reference for relocation ! 55: * entries that are relative to the bss section. ! 56: * ! 57: * (text) This is a totally internal symbol used to ! 58: * remember the size of the text section. It has ! 59: * characters in it that cannot legally be used in ! 60: * a symbol, and hence cannot be referenced or ! 61: * redefined by a user. ! 62: * ! 63: * (data) This is an internal symbol used to remember the ! 64: * size of the data section. ! 65: * ! 66: * (bss) This is an internal symbol used to remember the ! 67: * size of the bss section. ! 68: * ! 69: * (sdicnt) This is the internal symbol used to remember ! 70: * the number of span dependent instructions ! 71: * on which optimizations were performed. ! 72: * ! 73: * 3. The function "dmpstb" is called to dump the symbol ! 74: * table out to a temporary file to be used by pass 2 of ! 75: * the assembler. ! 76: * ! 77: * 4. The temporary files are closed and the next pass (if any) ! 78: * is called. ! 79: * ! 80: */ ! 81: ! 82: #if ONEPROC ! 83: extern short passnbr; ! 84: #endif ! 85: ! 86: extern char file[]; ! 87: ! 88: extern char *filenames[]; ! 89: ! 90: extern unsigned short ! 91: line, ! 92: sdicnt; ! 93: ! 94: ! 95: #if DEBUG ! 96: extern unsigned ! 97: numcalls, ! 98: numids, ! 99: numcoll; ! 100: #endif ! 101: ! 102: extern short ! 103: anyerrs; ! 104: ! 105: extern int ! 106: aerror(), ! 107: delexit(), ! 108: #if !ONEPROC ! 109: dmpstb(), ! 110: #endif ! 111: fixsyms(), ! 112: flags(), ! 113: flushbuf(), ! 114: onintr(); ! 115: ! 116: extern FILE ! 117: *fderr; ! 118: ! 119: #if !ONEPROC ! 120: extern FILE ! 121: *fdstab; ! 122: #endif ! 123: ! 124: extern upsymins ! 125: *lookup(); ! 126: ! 127: extern long ! 128: #if MULTSECT ! 129: dottxt[4], ! 130: dotdat[4], ! 131: #else ! 132: dottxt, ! 133: dotdat, ! 134: #endif ! 135: dotbss; ! 136: ! 137: #if !ONEPROC ! 138: char *xargp[15]; ! 139: #endif ! 140: ! 141: short opt = YES, ! 142: workaround = YES, ! 143: Oflag = NO; ! 144: ! 145: #if M4ON ! 146: extern short rflag; ! 147: #endif ! 148: ! 149: #if M32RSTFIX ! 150: short rstflag = YES; ! 151: #endif /* M32RSTFIX */ ! 152: #if ONEPROC ! 153: extern short ! 154: transvec; ! 155: #else ! 156: short ! 157: transvec = NO, ! 158: argindex = 1; ! 159: #endif ! 160: ! 161: #if ONEPROC ! 162: extern long newdot; ! 163: extern symbol *dot; ! 164: #else ! 165: long newdot; ! 166: symbol *dot; ! 167: #endif ! 168: ! 169: FILE *fdin, ! 170: #if !ONEPROC ! 171: *fdstring, ! 172: *fdlong, ! 173: #endif ! 174: *fdtext, ! 175: #if MULTSECT ! 176: *fdtxt1, ! 177: *fdtxt2, ! 178: *fdtxt3, ! 179: *fddat1, ! 180: *fddat2, ! 181: *fddat3, ! 182: #endif ! 183: #if DEBUG ! 184: *perfile, /* performance data file descriptor */ ! 185: #endif ! 186: *fddata, ! 187: *fdcomment; ! 188: ! 189: #if MULTSECT ! 190: add1text(ptr) ! 191: symbol *ptr; ! 192: { ! 193: addsect(ptr,TXT,1); ! 194: } /* add1text() */ ! 195: ! 196: ! 197: add2text(ptr) ! 198: symbol *ptr; ! 199: { ! 200: addsect(ptr,TXT,2); ! 201: } /* add2text() */ ! 202: ! 203: ! 204: add3text(ptr) ! 205: symbol *ptr; ! 206: { ! 207: addsect(ptr,TXT,3); ! 208: } /* add3text() */ ! 209: ! 210: ! 211: add1data(ptr) ! 212: symbol *ptr; ! 213: { ! 214: addsect(ptr,DAT,1); ! 215: } /* add1data() */ ! 216: ! 217: ! 218: add2data(ptr) ! 219: symbol *ptr; ! 220: { ! 221: addsect(ptr,DAT,2); ! 222: } /* add2data() */ ! 223: ! 224: ! 225: add3data(ptr) ! 226: symbol *ptr; ! 227: { ! 228: addsect(ptr,DAT,3); ! 229: } /* add3data() */ ! 230: ! 231: addsect(ptr,sectclass,sectnum) ! 232: symbol *ptr; ! 233: short sectclass, ! 234: sectnum; ! 235: { ! 236: if (((ptr->styp & TYPE) == sectclass) && (ptr->sectnum == sectnum)) ! 237: ptr->value += (sectclass == TXT) ? dottxt[0] : dotdat[0]; ! 238: } /* addsect() */ ! 239: ! 240: #endif ! 241: ! 242: #if !ONEPROC ! 243: static char ! 244: nextpass[80]; ! 245: ! 246: static char ! 247: teststr[4] = {'-','t','\0'}; ! 248: #endif ! 249: ! 250: short tstlookup = NO; ! 251: ! 252: static short ! 253: #if !ONEPROC ! 254: filecnt = 0, ! 255: #endif ! 256: testas = TESTVAL; ! 257: ! 258: #if DEBUG ! 259: /* ! 260: * Performance data structure ! 261: */ ! 262: long ttime; ! 263: struct tbuffer { ! 264: long proc_user_time; ! 265: long proc_system_time; ! 266: long child_user_time; ! 267: long child_system_time; ! 268: } ptimes; ! 269: extern long times(); ! 270: ! 271: #endif ! 272: #if !ONEPROC ! 273: /* ! 274: * ! 275: * "getargs" is a general purpose argument parsing routine. ! 276: * It locates flags (identified by a preceding minus sign ('-')) ! 277: * and initializes any associated flags for the assembler. ! 278: * If there are any file names in the argument list, then a ! 279: * pointer to the name is stored in the array "filenames" for ! 280: * later use. ! 281: * ! 282: */ ! 283: ! 284: getargs(xargc,xargv) ! 285: register int xargc; ! 286: register char **xargv; ! 287: { ! 288: register char ch; ! 289: ! 290: while (xargc-- > 0) { ! 291: if (**xargv == '-') { ! 292: while ((ch = *++*xargv) != '\0') ! 293: switch (ch) { ! 294: case 'n': ! 295: if( *++*xargv == 'f' ) { ! 296: /* -nf option; disable work arounds */ ! 297: workaround = NO; ! 298: #if M32RSTFIX ! 299: rstflag = NO; ! 300: #endif /* M32RSTFIX */ ! 301: } else { /* -n option */ ! 302: opt = NO; ! 303: *--*xargv; ! 304: } ! 305: break; ! 306: #if DEBUG ! 307: case 'O': ! 308: Oflag = YES; ! 309: break; ! 310: #endif ! 311: #if M4ON ! 312: case 'R': ! 313: rflag = YES; ! 314: xargp[argindex++] = "-R"; ! 315: break; ! 316: #endif ! 317: case 'd': ! 318: if (*++*xargv == 'l') ! 319: xargp[argindex++] = "-dl"; ! 320: break; ! 321: case 't': { ! 322: ++*xargv; ! 323: #if TRANVEC ! 324: if (**xargv == 'v'){ ! 325: transvec = YES; ! 326: xargp[argindex++]="-tv"; ! 327: break; ! 328: } ! 329: #endif ! 330: if (isdigit(**xargv)) { ! 331: testas = **xargv - '0' -1; ! 332: if (testas > TESTVAL + 1) { ! 333: teststr[2] = (char)(testas + '0'); ! 334: } ! 335: } ! 336: else { ! 337: --*xargv; ! 338: testas += 2; ! 339: } ! 340: xargp[argindex++] = teststr; ! 341: break; ! 342: } ! 343: #if DEBUG ! 344: case 'T': { ! 345: switch (*++*xargv) { ! 346: case 'L': { ! 347: tstlookup = YES; ! 348: break; ! 349: } ! 350: } ! 351: break; ! 352: } ! 353: #endif ! 354: #if M32RSTFIX ! 355: case 'r': ! 356: rstflag = NO; ! 357: break; ! 358: #endif /* M32RSTFIX */ ! 359: default: { ! 360: /* installation dependent flag? */ ! 361: flags(ch); ! 362: break; ! 363: } ! 364: } ! 365: xargv++; ! 366: } ! 367: else { ! 368: filenames[filecnt++] = *xargv++; ! 369: } ! 370: } ! 371: } ! 372: ! 373: main(argc,argv) ! 374: int argc; ! 375: char **argv; ! 376: #else ! 377: ! 378: aspass1() ! 379: ! 380: #endif ! 381: { ! 382: register short i; ! 383: register symbol *ptr; ! 384: ! 385: #if ONEPROC ! 386: passnbr = 1; ! 387: #endif ! 388: if (signal(SIGHUP,SIG_IGN) == SIG_DFL) ! 389: signal(SIGHUP,onintr); ! 390: if (signal(SIGINT,SIG_IGN) == SIG_DFL) ! 391: signal(SIGINT,onintr); ! 392: if (signal(SIGTERM,SIG_IGN) == SIG_DFL) ! 393: signal(SIGTERM,onintr); ! 394: fderr = stderr; ! 395: ! 396: #if DEBUG ! 397: /* Performance data collected */ ! 398: ttime = times(&ptimes); ! 399: #endif ! 400: ! 401: #if !ONEPROC ! 402: strcpy(nextpass,argv[0]); ! 403: argv++; ! 404: argc--; ! 405: getargs(argc,argv); ! 406: if (filecnt < NFILES) ! 407: aerror("Illegal number of temporary files"); ! 408: strcpy(file,filenames[0]); ! 409: #endif ! 410: if ((fdin = fopen(file, "r")) == NULL) ! 411: aerror("Unable to open input file"); ! 412: if ((fdtext = fopen(filenames[2], "w")) == NULL) ! 413: aerror("Unable to open temporary (text) file"); ! 414: #if MULTSECT ! 415: if ((fdtxt1 = fopen(filenames[9],"w")) == NULL) ! 416: aerror("Unable to open temporary (text 1) file"); ! 417: if ((fdtxt2 = fopen(filenames[10],"w")) == NULL) ! 418: aerror("Unable to open temporary (text 2) file"); ! 419: if ((fdtxt3 = fopen(filenames[11],"w")) == NULL) ! 420: aerror("Unable to open temporary (text 3) file"); ! 421: if ((fddat1 = fopen(filenames[12],"w")) == NULL) ! 422: aerror("Unable to open temporary (data 1) file"); ! 423: if ((fddat2 = fopen(filenames[13],"w")) == NULL) ! 424: aerror("Unable to open temporary (data 2) file"); ! 425: if ((fddat3 = fopen(filenames[14],"w")) == NULL) ! 426: aerror("Unable to open temporary (data 3) file"); ! 427: #endif ! 428: if ((fddata = fopen(filenames[3], "w")) == NULL) ! 429: aerror("Unable to open temporary (data) file"); ! 430: if ((fdcomment = fopen(filenames[8], "w")) == NULL) ! 431: aerror("Unable to open temporary (comment) file"); ! 432: #if !ONEPROC ! 433: if ((fdstring = fopen(filenames[6], "w")) == NULL) ! 434: aerror("Unable to open temporary (string) file"); ! 435: #endif ! 436: #if FLEXNAMES ! 437: strtabinit(); ! 438: #endif ! 439: creasyms(); ! 440: dot = (*lookup(".",INSTALL, USRNAME)).stp; ! 441: dot->styp = TXT; ! 442: dot->value = newdot = 0L; ! 443: #if MULTSECT ! 444: dot->sectnum = 0; ! 445: #endif ! 446: yyparse(); /* pass 1 */ ! 447: fclose(fdin); ! 448: #if !ONEPROC ! 449: fflush(fdstring); ! 450: if (ferror(fdstring)) ! 451: aerror("trouble writing; probably out of temp-file space"); ! 452: fclose(fdstring); ! 453: #endif ! 454: #if MULTSECT ! 455: cgsect(TXT,0); ! 456: #else ! 457: cgsect(TXT); ! 458: #endif ! 459: flushbuf(); ! 460: #if MULTSECT ! 461: fclose(fdtxt1); ! 462: fclose(fdtxt2); ! 463: fclose(fdtxt3); ! 464: fclose(fddat1); ! 465: fclose(fddat2); ! 466: fclose(fddat3); ! 467: ! 468: traverse(add1text); ! 469: dottxt[0] += dottxt[1]; ! 470: traverse(add2text); ! 471: dottxt[0] += dottxt[2]; ! 472: traverse(add3text); ! 473: dottxt[0] += dottxt[3]; ! 474: ! 475: traverse(add1data); ! 476: dotdat[0] += dotdat[1]; ! 477: traverse(add2data); ! 478: dotdat[0] += dotdat[2]; ! 479: traverse(add3data); ! 480: dotdat[0] += dotdat[3]; ! 481: #endif ! 482: fflush(fdtext); ! 483: if (ferror(fdtext)) ! 484: aerror("trouble writing; probably out of temp-file space"); ! 485: fclose(fdtext); ! 486: fflush(fddata); ! 487: if (ferror(fddata)) ! 488: aerror("trouble writing; probably out of temp-file space"); ! 489: fclose(fddata); ! 490: fflush(fdcomment); ! 491: if (ferror(fdcomment)) ! 492: aerror("trouble writing; probably out of temp-file space"); ! 493: fclose(fdcomment); ! 494: ! 495: #if !ONEPROC ! 496: if ((fdlong = fopen(filenames[5], "w")) == NULL) ! 497: aerror("Unable to open temporary (sdi) file"); ! 498: #endif ! 499: fixsyms(); ! 500: #if MULTSECT ! 501: cgsect(TXT,0); ! 502: #else ! 503: cgsect(TXT); /* update "dottxt" */ ! 504: #endif ! 505: #if !ONEPROC ! 506: fflush(fdlong); ! 507: if (ferror(fdlong)) ! 508: aerror("trouble writing; probably out of temp-file space"); ! 509: fclose(fdlong); ! 510: #endif ! 511: ! 512: ptr = (*lookup(".text", INSTALL, USRNAME)).stp; ! 513: ptr->styp = TXT; ! 514: ptr->value = 0L; ! 515: ptr = (*lookup("(text)", INSTALL, USRNAME)).stp; ! 516: ptr->styp = TXT; ! 517: #if MULTSECT ! 518: ptr->value = dottxt[0]; ! 519: #else ! 520: ptr->value = dottxt; ! 521: #endif ! 522: ptr = (*lookup(".data", INSTALL, USRNAME)).stp; ! 523: ptr->styp = DAT; ! 524: ptr->value = 0L; ! 525: ptr = (*lookup("(data)", INSTALL, USRNAME)).stp; ! 526: ptr->styp = DAT; ! 527: #if MULTSECT ! 528: ptr->value = dotdat[0]; ! 529: #else ! 530: ptr->value = dotdat; ! 531: #endif ! 532: ptr = (*lookup(".bss", INSTALL, USRNAME)).stp; ! 533: ptr->styp = BSS; ! 534: ptr->value = 0L; ! 535: ptr = (*lookup("(bss)", INSTALL, USRNAME)).stp; ! 536: ptr->styp = BSS; ! 537: ptr->value = dotbss; ! 538: ! 539: #if !ONEPROC ! 540: ptr = (*lookup("(sdicnt)",INSTALL,USRNAME)).stp; ! 541: ptr->value = (long)sdicnt; /* has to be set after fixsyms is called */ ! 542: ptr->styp = ABS; ! 543: ! 544: if ((fdstab = fopen(filenames[4], "w")) == NULL) ! 545: aerror("Unable to open temporary (symtab) file"); ! 546: dmpstb(); /* dump the symbol table for the next pass */ ! 547: fflush(fdstab); ! 548: if (ferror(fdstab)) ! 549: aerror("trouble writing; probably out of temp-file space"); ! 550: fclose(fdstab); ! 551: #endif ! 552: ! 553: #if DEBUG ! 554: if (tstlookup) { ! 555: printf("Number of calls to lookup: %u\n",numcalls); ! 556: printf("Number of identifiers: %u\n",numids); ! 557: printf("Number of identifier collisions: %u\n",numcoll); ! 558: fflush(stdout); ! 559: } ! 560: /* ! 561: * Performance data collected and written out here ! 562: */ ! 563: ! 564: ttime = times(&ptimes) - ttime; ! 565: if ((perfile = fopen("as.info", "r")) != NULL ) { ! 566: fclose(perfile); ! 567: if ((perfile = fopen("as.info", "a")) != NULL ) { ! 568: fprintf(perfile, ! 569: "as1\t%07ld\t%07ld\t%07ld\t%07ld\t%07ld\tpass 1\n", ! 570: ttime, ptimes); ! 571: fclose(perfile); ! 572: } ! 573: } ! 574: ! 575: #endif ! 576: ! 577: if (!anyerrs) { ! 578: #if ONEPROC ! 579: return(aspass2()); ! 580: #else ! 581: nextpass[strlen(nextpass) - 1] = '2'; ! 582: xargp[0] = nextpass; ! 583: for (i=0; i < filecnt; ++i) ! 584: xargp[argindex++] = filenames[i]; ! 585: if (testas != TESTVAL + 1) { ! 586: if (testas > TESTVAL + 1){ ! 587: execv(NAS2,xargp); ! 588: } ! 589: else ! 590: execv(AS2,xargp); ! 591: aerror("Unable to exec pass 2"); ! 592: } ! 593: #endif ! 594: } ! 595: else { ! 596: delexit(); ! 597: } ! 598: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.