|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1982 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)asmain.c 5.6 (Berkeley) 6/30/90"; ! 15: #endif not lint ! 16: ! 17: #include <stdio.h> ! 18: #include <ctype.h> ! 19: #include <signal.h> ! 20: ! 21: #include "as.h" ! 22: #include "assyms.h" ! 23: #include "asscan.h" ! 24: #include "asexpr.h" ! 25: #include <paths.h> ! 26: ! 27: #include <sys/stat.h> ! 28: ! 29: #define unix_lang_name "VAX/UNIX Assembler V6/30/90 5.6" ! 30: /* ! 31: * variables to manage reading the assembly source files ! 32: */ ! 33: char *dotsname; /*the current file name; managed by the parser*/ ! 34: int lineno; /*current line number; managed by the parser*/ ! 35: char **innames; /*names of the files being assembled*/ ! 36: int ninfiles; /*how many interesting files there are*/ ! 37: /* ! 38: * Flags settable from the argv process argument list ! 39: */ ! 40: int silent = 0; /*don't complain about any errors*/ ! 41: int savelabels = 0; /*write the labels to the a.out file*/ ! 42: int d124 = 4; /*default allocate 4 bytes for unknown pointers*/ ! 43: int maxalign = 2; /*default .align maximum*/ ! 44: int anyerrs = 0; /*no errors yet*/ ! 45: int anywarnings=0; /*no warnings yet*/ ! 46: int orgwarn = 0; /*Bad origins*/ ! 47: int passno = 1; /* current pass*/ ! 48: int jxxxJUMP = 0; /* in jxxxes that branch too far, use jmp instead of brw */ ! 49: int readonlydata = 0; /* initialzed data -> text space */ ! 50: ! 51: int nGHnumbers = 0; /* GH numbers used */ ! 52: int nGHopcodes = 0; /* GH opcodes used */ ! 53: int nnewopcodes = 0; /* new opcodes used */ ! 54: ! 55: #ifdef DEBUG ! 56: int debug = 0; ! 57: int toktrace = 0; ! 58: #endif ! 59: ! 60: int useVM = 0; ! 61: ! 62: char *endcore; /*where to get more symbol space*/ ! 63: ! 64: /* ! 65: * Managers of the a.out file. ! 66: */ ! 67: struct exec hdr; ! 68: #define MAGIC 0407 ! 69: u_long tsize; /* total text size */ ! 70: u_long dsize; /* total data size */ ! 71: u_long datbase; /* base of the data segment */ ! 72: u_long trsize; /* total text relocation size */ ! 73: u_long drsize; /* total data relocation size */ ! 74: ! 75: /* ! 76: * Information about the current segment is accumulated in ! 77: * usedot; the most important information stored is the ! 78: * accumulated size of each of the text and data segments ! 79: * ! 80: * dotp points to the correct usedot expression for the current segment ! 81: */ ! 82: struct exp usedot[NLOC+NLOC]; /* info about all segments */ ! 83: struct exp *dotp; /* data/text location pointer */ ! 84: /* ! 85: * The inter pass temporary token file is opened and closed by stdio, but ! 86: * is written to using direct read/write, as the temporary file ! 87: * is composed of buffers exactly BUFSIZ long. ! 88: */ ! 89: FILE *tokfile; /* interpass communication file */ ! 90: char tokfilename[TNAMESIZE]; ! 91: /* ! 92: * The string file is the string table ! 93: * cat'ed to the end of the built up a.out file ! 94: */ ! 95: FILE *strfile; /* interpass string file */ ! 96: char strfilename[TNAMESIZE]; ! 97: int strfilepos = 0; /* position within the string file */ ! 98: /* ! 99: * a.out is created during the second pass. ! 100: * It is opened by stdio, but is filled with the parallel ! 101: * block I/O library ! 102: */ ! 103: char *outfile = "a.out"; ! 104: FILE *a_out_file; ! 105: off_t a_out_off; /* cumulative offsets for segments */ ! 106: /* ! 107: * The logical files containing the assembled data for each of ! 108: * the text and data segments are ! 109: * managed by the parallel block I/O library. ! 110: * a.out is logically opened in many places at once to ! 111: * receive the assembled data from the various segments as ! 112: * it all trickles in, but is physically opened only once ! 113: * to minimize file overhead. ! 114: */ ! 115: BFILE *usefile[NLOC+NLOC]; /* text/data files */ ! 116: BFILE *txtfil; /* current text/data file */ ! 117: /* ! 118: * Relocation information is accumulated seperately for each ! 119: * segment. This is required by the old loader (from BTL), ! 120: * but not by the new loader (Bill Joy). ! 121: * ! 122: * However, the size of the relocation information can not be computed ! 123: * during or after the 1st pass because the ''absoluteness' of values ! 124: * is unknown until all locally declared symbols have been seen. ! 125: * Thus, the size of the relocation information is only ! 126: * known after the second pass is finished. ! 127: * This obviates the use of the block I/O ! 128: * library, which requires knowing the exact offsets in a.out. ! 129: * ! 130: * So, we save the relocation information internally (we don't ! 131: * go to internal files to minimize overhead). ! 132: * ! 133: * Empirically, we studied 259 files composing the system, ! 134: * two compilers and a compiler generator: (all of which have ! 135: * fairly large source files) ! 136: * ! 137: * Number of files = 259 ! 138: * Number of non zero text reloc files: 233 ! 139: * Number of non zero data reloc files: 53 ! 140: * Average text relocation = 889 ! 141: * Average data relocation = 346 ! 142: * Number of files > BUFSIZ text relocation = 71 ! 143: * Number of files > BUFSIZ data relocation = 6 ! 144: * ! 145: * For compiled C code, there is usually one text segment and two ! 146: * data segments; we see that allocating our own buffers and ! 147: * doing our internal handling of relocation information will, ! 148: * on the average, not use more memory than taken up by the buffers ! 149: * allocated for doing file I/O in parallel to a number of file. ! 150: * ! 151: * If we are assembling with the -V option, we ! 152: * use the left over token buffers from the 2nd pass, ! 153: * otherwise, we create our own. ! 154: * ! 155: * When the 2nd pass is complete, closeoutrel flushes the token ! 156: * buffers out to a BFILE. ! 157: * ! 158: * The internals to relbufdesc are known only in assyms.c ! 159: * ! 160: * outrel constructs the relocation information. ! 161: * closeoutrel flushes the relocation information to relfil. ! 162: */ ! 163: struct relbufdesc *rusefile[NLOC+NLOC]; ! 164: struct relbufdesc *relfil; /* un concatnated relocation info */ ! 165: BFILE *relocfile; /* concatnated relocation info */ ! 166: /* ! 167: * Once the relocation information has been written, ! 168: * we can write out the symbol table using the Block I/O ! 169: * mechanisms, as we once again know the offsets into ! 170: * the a.out file. ! 171: * ! 172: * We use relfil to output the symbol table information. ! 173: */ ! 174: char *tmpdirprefix = "/tmp/"; ! 175: int delexit(); ! 176: ! 177: main(argc, argv) ! 178: int argc; ! 179: char **argv; ! 180: { ! 181: char *sbrk(); ! 182: ! 183: tokfilename[0] = 0; ! 184: strfilename[0] = 0; ! 185: endcore = sbrk(0); ! 186: ! 187: argprocess(argc, argv); /* process argument lists */ ! 188: if (anyerrs) exit(1); ! 189: ! 190: initialize(); ! 191: zeroorigins(); /* set origins to zero */ ! 192: zerolocals(); /* fix local label counters */ ! 193: ! 194: i_pass1(); /* open temp files, etc */ ! 195: pass1(); /* first pass through .s files */ ! 196: testlocals(); /* check for undefined locals */ ! 197: if (anyerrs) delexit(); ! 198: ! 199: pass1_5(); /* resolve jxxx */ ! 200: if (anyerrs) delexit(); ! 201: ! 202: open_a_out(); /* open a.out */ ! 203: roundsegments(); /* round segments to FW */ ! 204: build_hdr(); /* build initial header, and output */ ! 205: ! 206: i_pass2(); /* reopen temporary file, etc */ ! 207: pass2(); /* second pass through the virtual .s */ ! 208: if (anyerrs) delexit(); ! 209: ! 210: fillsegments(); /* fill segments with 0 to FW */ ! 211: reloc_syms(); /* dump relocation and symbol table */ ! 212: ! 213: delete(); /* remove tmp file */ ! 214: bflush(); /* close off block I/O view of a.out */ ! 215: fix_a_out(); /* add in text and data reloc counts */ ! 216: ! 217: if (anyerrs == 0 && orgwarn) ! 218: yyerror("Caution: absolute origins.\n"); ! 219: ! 220: if (nGHnumbers) ! 221: yywarning("Caution: G or H format floating point numbers"); ! 222: if (nGHopcodes) ! 223: yywarning("Caution: G or H format floating point operators"); ! 224: if (nnewopcodes) ! 225: yywarning("Caution: New Opcodes"); ! 226: if (nGHnumbers || nGHopcodes || nnewopcodes) ! 227: yywarning("These are not defined for all implementations of the VAX architecture.\n"); ! 228: ! 229: exit(anyerrs != 0); ! 230: } ! 231: ! 232: argprocess(argc, argv) ! 233: int argc; ! 234: char *argv[]; ! 235: { ! 236: register char *cp; ! 237: ! 238: ninfiles = 0; ! 239: silent = 0; ! 240: #ifdef DEBUG ! 241: debug = 0; ! 242: #endif ! 243: innames = (char **)ClearCalloc(argc+1, sizeof (innames[0])); ! 244: dotsname = "<argv error>"; ! 245: while (argc > 1) { ! 246: if (argv[1][0] != '-') ! 247: innames[ninfiles++] = argv[1]; ! 248: else { ! 249: cp = argv[1] + 1; ! 250: /* ! 251: * We can throw away single minus signs, so ! 252: * that make scripts for the PDP 11 assembler work ! 253: * on this assembler too ! 254: */ ! 255: while (*cp){ ! 256: switch(*cp++){ ! 257: default: ! 258: yyerror("Unknown flag: %c", *--cp); ! 259: cp++; ! 260: break; ! 261: case 'v': ! 262: selfwhat(stdout); ! 263: exit(1); ! 264: case 'd': ! 265: d124 = *cp++ - '0'; ! 266: if ( (d124 != 1) && (d124 != 2) && ! 267: (d124 != 4)){ ! 268: yyerror("-d[124] only"); ! 269: exit(1); ! 270: } ! 271: break; ! 272: case 'a': ! 273: maxalign = atoi(cp+1); ! 274: for (cp++; isdigit(*cp); cp++) ! 275: /*VOID*/; ! 276: if ( (maxalign > 16) || (maxalign < 0)){ ! 277: yyerror("-a: 0<=align<=16"); ! 278: exit(1); ! 279: } ! 280: break; ! 281: case 'o': ! 282: if (argc < 3){ ! 283: yyerror("-o what???"); ! 284: exit(1); ! 285: } ! 286: outfile = argv[2]; ! 287: bumpone: ! 288: argc -= 2; ! 289: argv += 2; ! 290: goto nextarg; ! 291: ! 292: case 't': ! 293: if (argc < 3){ ! 294: yyerror("-t what???"); ! 295: exit(1); ! 296: } ! 297: tmpdirprefix = argv[2]; ! 298: goto bumpone; ! 299: ! 300: case 'V': ! 301: useVM = 1; ! 302: break; ! 303: case 'W': ! 304: silent = 1; ! 305: break; ! 306: case 'L': ! 307: savelabels = 1; ! 308: break; ! 309: case 'J': ! 310: jxxxJUMP = 1; ! 311: break; ! 312: #ifdef DEBUG ! 313: case 'D': ! 314: debug = 1; ! 315: break; ! 316: case 'T': ! 317: toktrace = 1; ! 318: break; ! 319: #endif ! 320: case 'R': ! 321: readonlydata = 1; ! 322: break; ! 323: } /*end of the switch*/ ! 324: } /*end of pulling out all arguments*/ ! 325: } /*end of a flag argument*/ ! 326: --argc; ++argv; ! 327: nextarg:; ! 328: } ! 329: /* innames[ninfiles] = 0; */ ! 330: } ! 331: /* ! 332: * poke through the data space and find all sccs identifiers. ! 333: * We assume: ! 334: * a) that extern char **environ; is the first thing in the bss ! 335: * segment (true, if one is using the new version of cmgt.crt0.c) ! 336: * b) that the sccsid's have not been put into text space. ! 337: */ ! 338: selfwhat(place) ! 339: FILE *place; ! 340: { ! 341: extern char **environ; ! 342: register char *ub; ! 343: register char *cp; ! 344: register char *pat; ! 345: char *sbrk(); ! 346: ! 347: for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){ ! 348: if (cp[0] != '@') continue; ! 349: if (cp[1] != '(') continue; ! 350: if (cp[2] != '#') continue; ! 351: if (cp[3] != ')') continue; ! 352: fputc('\t', place); ! 353: for (cp += 4; cp < ub; cp++){ ! 354: if (*cp == 0) break; ! 355: if (*cp == '>') break; ! 356: if (*cp == '\n') break; ! 357: fputc(*cp, place); ! 358: } ! 359: fputc('\n', place); ! 360: } ! 361: } ! 362: ! 363: initialize() ! 364: { ! 365: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 366: signal(SIGINT, delexit); ! 367: /* ! 368: * Install symbols in the table ! 369: */ ! 370: symtabinit(); ! 371: syminstall(); ! 372: /* ! 373: * Build the expression parser accelerator token sets ! 374: */ ! 375: buildtokensets(); ! 376: } ! 377: ! 378: zeroorigins() ! 379: { ! 380: register int locindex; ! 381: /* ! 382: * Mark usedot: the first NLOC slots are for named text segments, ! 383: * the next for named data segments. ! 384: */ ! 385: for (locindex = 0; locindex < NLOC; locindex++){ ! 386: usedot[locindex].e_xtype = XTEXT; ! 387: usedot[NLOC + locindex].e_xtype = XDATA; ! 388: usedot[locindex].e_xvalue = 0; ! 389: usedot[NLOC + locindex].e_xvalue = 0; ! 390: } ! 391: } ! 392: ! 393: zerolocals() ! 394: { ! 395: register int i; ! 396: ! 397: for (i = 0; i <= 9; i++) { ! 398: lgensym[i] = 1; ! 399: genref[i] = 0; ! 400: } ! 401: } ! 402: ! 403: i_pass1() ! 404: { ! 405: FILE *tempopen(); ! 406: if (useVM == 0) ! 407: tokfile = tempopen(tokfilename, "T"); ! 408: strfile = tempopen(strfilename, "S"); ! 409: /* ! 410: * write out the string length. ! 411: * This will be overwritten when the ! 412: * strings are tacked onto the growing a.out file ! 413: */ ! 414: strfilepos = sizeof(int); ! 415: fwrite(&strfilepos, sizeof(int), 1, strfile); ! 416: ! 417: inittokfile(); ! 418: initijxxx(); ! 419: } ! 420: ! 421: FILE *tempopen(tname, part) ! 422: char *tname; ! 423: char *part; ! 424: { ! 425: FILE *file; ! 426: (void)sprintf(tname, "%s%sas%s%05d", ! 427: tmpdirprefix, ! 428: (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') ? "/" : "", ! 429: part, ! 430: getpid()); ! 431: file = fopen(tname, "w"); ! 432: if (file == NULL) { ! 433: yyerror("Bad pass 1 temporary file for writing %s", tname); ! 434: delexit(); ! 435: } ! 436: return(file); ! 437: } ! 438: ! 439: pass1() ! 440: { ! 441: register int i; ! 442: ! 443: passno = 1; ! 444: dotp = &usedot[0]; ! 445: txtfil = (BFILE *)0; ! 446: relfil = (struct relbufdesc *)0; ! 447: ! 448: if (ninfiles == 0){ /*take the input from stdin directly*/ ! 449: lineno = 1; ! 450: dotsname = "<stdin>"; ! 451: ! 452: yyparse(); ! 453: } else { /*we have the names tanked*/ ! 454: for (i = 0; i < ninfiles; i++){ ! 455: new_dot_s(innames[i]); ! 456: if (freopen(innames[i], "r", stdin) == NULL) { ! 457: yyerror( "Can't open source file %s\n", ! 458: innames[i]); ! 459: exit(2); ! 460: } ! 461: /* stdio is NOT used to read the input characters */ ! 462: /* we use read directly, into our own buffers */ ! 463: yyparse(); ! 464: } ! 465: } ! 466: ! 467: closetokfile(); /*kick out the last buffered intermediate text*/ ! 468: } ! 469: ! 470: testlocals() ! 471: { ! 472: register int i; ! 473: for (i = 0; i <= 9; i++) { ! 474: if (genref[i]) ! 475: yyerror("Reference to undefined local label %df", i); ! 476: lgensym[i] = 1; ! 477: genref[i] = 0; ! 478: } ! 479: } ! 480: ! 481: pass1_5() ! 482: { ! 483: sortsymtab(); ! 484: #ifdef DEBUG ! 485: if (debug) dumpsymtab(); ! 486: #endif ! 487: jxxxfix(); ! 488: #ifdef DEBUG ! 489: if (debug) dumpsymtab(); ! 490: #endif ! 491: } ! 492: ! 493: open_a_out() ! 494: { ! 495: struct stat stb; ! 496: ! 497: /* ! 498: * Open up the a.out file now, and get set to build ! 499: * up offsets into it for all of the various text,data ! 500: * text relocation and data relocation segments. ! 501: */ ! 502: a_out_file = fopen(outfile, "w"); ! 503: if (a_out_file == NULL) { ! 504: yyerror("Cannot create %s", outfile); ! 505: delexit(); ! 506: } ! 507: biofd = a_out_file->_file; ! 508: fstat(biofd, &stb); ! 509: biobufsize = stb.st_blksize; ! 510: a_out_off = 0; ! 511: } ! 512: ! 513: roundsegments() ! 514: { ! 515: register int locindex; ! 516: register long v; ! 517: /* ! 518: * round and assign text segment origins ! 519: * the exec header always goes in usefile[0] ! 520: */ ! 521: tsize = 0; ! 522: for (locindex=0; locindex<NLOC; locindex++) { ! 523: v = round(usedot[locindex].e_xvalue, FW); ! 524: usedot[locindex].e_xvalue = tsize; ! 525: if ((locindex == 0) || (v != 0) ){ ! 526: usefile[locindex] = (BFILE *)Calloc(1, sizeof(BFILE)); ! 527: bopen(usefile[locindex], a_out_off); ! 528: if (locindex == 0) ! 529: a_out_off = sizeof (struct exec); ! 530: } else { ! 531: usefile[locindex] = (BFILE *)-1; ! 532: } ! 533: tsize += v; ! 534: a_out_off += v; ! 535: } ! 536: /* ! 537: * Round and assign data segment origins. ! 538: */ ! 539: datbase = round(tsize, FW); ! 540: for (locindex=0; locindex<NLOC; locindex++) { ! 541: v = round(usedot[NLOC+locindex].e_xvalue, FW); ! 542: usedot[NLOC+locindex].e_xvalue = datbase + dsize; ! 543: if (v != 0){ ! 544: usefile[NLOC + locindex] = (BFILE *)Calloc(1,sizeof(BFILE)); ! 545: bopen(usefile[NLOC + locindex], a_out_off); ! 546: } else { ! 547: usefile[NLOC + locindex] = (BFILE *)-1; ! 548: } ! 549: dsize += v; ! 550: a_out_off += v; ! 551: } ! 552: /* ! 553: * Assign final values to symbols ! 554: */ ! 555: hdr.a_bss = dsize; ! 556: freezesymtab(); /* this touches hdr.a_bss */ ! 557: stabfix(); ! 558: /* ! 559: * Set up the relocation information "files" to ! 560: * be zero; outrel takes care of the rest ! 561: */ ! 562: for (locindex = 0; locindex < NLOC + NLOC; locindex++){ ! 563: rusefile[locindex] = (struct relbufdesc *)0; ! 564: } ! 565: } ! 566: ! 567: build_hdr() ! 568: { ! 569: /* ! 570: * Except for the text and data relocation sizes, ! 571: * calculate the final values for the header ! 572: * ! 573: * Write out the initial copy; we to come ! 574: * back later and patch up a_trsize and a_drsize, ! 575: * and overwrite this first version of the header. ! 576: */ ! 577: hdr.a_magic = MAGIC; ! 578: hdr.a_text = tsize; ! 579: hdr.a_data = dsize; ! 580: hdr.a_bss -= dsize; ! 581: hdr.a_syms = sizesymtab(); /* Does not include string pool length */ ! 582: hdr.a_entry = 0; ! 583: hdr.a_trsize = 0; ! 584: hdr.a_drsize = 0; ! 585: ! 586: bwrite((char *)&hdr, sizeof(hdr), usefile[0]); ! 587: } ! 588: ! 589: i_pass2() ! 590: { ! 591: if (useVM == 0) { ! 592: fclose(tokfile); ! 593: tokfile = fopen(tokfilename, "r"); ! 594: if (tokfile==NULL) { ! 595: yyerror("Bad pass 2 temporary file for reading %s", tokfilename); ! 596: delexit(); ! 597: } ! 598: } ! 599: fclose(strfile); ! 600: strfile = fopen(strfilename, "r"); ! 601: } ! 602: ! 603: pass2() ! 604: { ! 605: #ifdef DEBUG ! 606: if (debug) ! 607: printf("\n\n\n\t\tPASS 2\n\n\n\n"); ! 608: #endif DEBUG ! 609: passno = 2; ! 610: lineno = 1; ! 611: dotp = &usedot[0]; ! 612: txtfil = usefile[0]; /* already opened (always!) */ ! 613: relfil = 0; /* outrel takes care of the rest */ ! 614: initoutrel(); ! 615: ! 616: inittokfile(); ! 617: ! 618: yyparse(); ! 619: ! 620: closetokfile(); ! 621: } ! 622: ! 623: fillsegments() ! 624: { ! 625: int locindex; ! 626: /* ! 627: * Round text and data segments to FW by appending zeros ! 628: */ ! 629: for (locindex = 0; locindex < NLOC + NLOC; locindex++) { ! 630: if (usefile[locindex]) { ! 631: txtfil = usefile[locindex]; ! 632: dotp = &usedot[locindex]; ! 633: while (usedot[locindex].e_xvalue & FW) ! 634: outb(0); ! 635: } ! 636: } ! 637: } ! 638: ! 639: reloc_syms() ! 640: { ! 641: u_long closerelfil(); ! 642: /* ! 643: * Move the relocation information to a.out ! 644: * a_out_off is the offset so far: ! 645: * exec + text segments + data segments ! 646: */ ! 647: relocfile = (BFILE *)Calloc(1,sizeof(BFILE)); ! 648: bopen(relocfile, a_out_off); ! 649: a_out_off += closeoutrel(relocfile); ! 650: ! 651: hdr.a_trsize = trsize; ! 652: hdr.a_drsize = drsize; ! 653: if (readonlydata) { ! 654: hdr.a_text += hdr.a_data; ! 655: hdr.a_data = 0; ! 656: hdr.a_trsize += hdr.a_drsize; ! 657: hdr.a_drsize = 0; ! 658: } ! 659: /* ! 660: * Output the symbol table and the string pool ! 661: * ! 662: * We must first rewind the string pool file to its beginning, ! 663: * in case it was seek'ed into for fetching ascii and asciz ! 664: * strings. ! 665: */ ! 666: fseek(strfile, 0, 0); ! 667: symwrite(relocfile); ! 668: } ! 669: ! 670: fix_a_out() ! 671: { ! 672: if (lseek(a_out_file->_file, 0L, 0) < 0L) ! 673: yyerror("Reposition for header rewrite fails"); ! 674: if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0) ! 675: yyerror("Rewrite of header fails"); ! 676: } ! 677: ! 678: delexit() ! 679: { ! 680: delete(); ! 681: if (passno == 2){ ! 682: unlink(outfile); ! 683: } ! 684: exit(1); ! 685: } ! 686: ! 687: delete() ! 688: { ! 689: if (useVM == 0 || tokfilename[0]) ! 690: unlink(tokfilename); ! 691: if (strfilename[0]) ! 692: unlink(strfilename); ! 693: } ! 694: ! 695: sawabort() ! 696: { ! 697: char *fillinbuffer(); ! 698: while (fillinbuffer() != (char *)0) ! 699: continue; ! 700: delete(); ! 701: exit(1); /*although the previous pass will also exit non zero*/ ! 702: } ! 703: ! 704: panic(fmt, a1, a2, a3, a4) ! 705: char *fmt; ! 706: /*VARARGS 1*/ ! 707: { ! 708: yyerror("Assembler panic: bad internal data structure."); ! 709: yyerror(fmt, a1, a2, a3, a4); ! 710: delete(); ! 711: abort(); ! 712: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.