15826Srrh /* 25826Srrh * Copyright (c) 1982 Regents of the University of California 35826Srrh */ 45826Srrh #ifndef lint 5*16071Sralph static char sccsid[] = "@(#)asmain.c 4.15 02/17/84"; 65826Srrh #endif not lint 75826Srrh 8596Sbill #include <stdio.h> 9596Sbill #include <ctype.h> 10596Sbill #include <signal.h> 11596Sbill 12596Sbill #include "as.h" 13596Sbill #include "assyms.h" 145826Srrh #include "asscan.h" 15596Sbill #include "asexpr.h" 16596Sbill 17*16071Sralph #include <sys/stat.h> 18*16071Sralph 19*16071Sralph #define unix_lang_name "VAX/UNIX Assembler V02/17/84 4.15" 20596Sbill /* 21596Sbill * variables to manage reading the assembly source files 22596Sbill */ 23596Sbill char *dotsname; /*the current file name; managed by the parser*/ 24596Sbill int lineno; /*current line number; managed by the parser*/ 25643Sbill char **innames; /*names of the files being assembled*/ 26596Sbill int ninfiles; /*how many interesting files there are*/ 27596Sbill /* 28596Sbill * Flags settable from the argv process argument list 29596Sbill */ 30596Sbill int silent = 0; /*don't complain about any errors*/ 31596Sbill int savelabels = 0; /*write the labels to the a.out file*/ 32596Sbill int d124 = 4; /*default allocate 4 bytes for unknown pointers*/ 3315560Srrh int maxalign = 2; /*default .align maximum*/ 34596Sbill int anyerrs = 0; /*no errors yet*/ 355826Srrh int anywarnings=0; /*no warnings yet*/ 36596Sbill int orgwarn = 0; /*Bad origins*/ 37596Sbill int passno = 1; /* current pass*/ 38636Shenry int jxxxJUMP = 0; /* in jxxxes that branch too far, use jmp instead of brw */ 39638Sbill int readonlydata = 0; /* initialzed data -> text space */ 40596Sbill 415826Srrh int nGHnumbers = 0; /* GH numbers used */ 425826Srrh int nGHopcodes = 0; /* GH opcodes used */ 435826Srrh int nnewopcodes = 0; /* new opcodes used */ 445826Srrh 45596Sbill #ifdef DEBUG 46596Sbill int debug = 0; 47596Sbill int toktrace = 0; 48596Sbill #endif 49596Sbill 5013518Srrh int useVM = 0; 51596Sbill 52596Sbill char *endcore; /*where to get more symbol space*/ 53596Sbill 54596Sbill /* 55596Sbill * Managers of the a.out file. 56596Sbill */ 57596Sbill struct exec hdr; 58638Sbill #define MAGIC 0407 59596Sbill u_long tsize; /* total text size */ 60596Sbill u_long dsize; /* total data size */ 61596Sbill u_long datbase; /* base of the data segment */ 62596Sbill u_long trsize; /* total text relocation size */ 63596Sbill u_long drsize; /* total data relocation size */ 64596Sbill 65596Sbill /* 66596Sbill * Information about the current segment is accumulated in 67596Sbill * usedot; the most important information stored is the 68596Sbill * accumulated size of each of the text and data segments 69596Sbill * 70596Sbill * dotp points to the correct usedot expression for the current segment 71596Sbill */ 72596Sbill struct exp usedot[NLOC+NLOC]; /* info about all segments */ 73596Sbill struct exp *dotp; /* data/text location pointer */ 74596Sbill /* 7513512Srrh * The inter pass temporary token file is opened and closed by stdio, but 76596Sbill * is written to using direct read/write, as the temporary file 77596Sbill * is composed of buffers exactly BUFSIZ long. 78596Sbill */ 7913512Srrh FILE *tokfile; /* interpass communication file */ 8013512Srrh char tokfilename[TNAMESIZE]; 81596Sbill /* 8213512Srrh * The string file is the string table 8313512Srrh * cat'ed to the end of the built up a.out file 8413512Srrh */ 8513512Srrh FILE *strfile; /* interpass string file */ 8613512Srrh char strfilename[TNAMESIZE]; 8713512Srrh int strfilepos = 0; /* position within the string file */ 8813512Srrh /* 89596Sbill * a.out is created during the second pass. 90596Sbill * It is opened by stdio, but is filled with the parallel 91596Sbill * block I/O library 92596Sbill */ 93596Sbill char *outfile = "a.out"; 94596Sbill FILE *a_out_file; 95596Sbill off_t a_out_off; /* cumulative offsets for segments */ 96596Sbill /* 97596Sbill * The logical files containing the assembled data for each of 98596Sbill * the text and data segments are 99596Sbill * managed by the parallel block I/O library. 100596Sbill * a.out is logically opened in many places at once to 101596Sbill * receive the assembled data from the various segments as 102596Sbill * it all trickles in, but is physically opened only once 103596Sbill * to minimize file overhead. 104596Sbill */ 105596Sbill BFILE *usefile[NLOC+NLOC]; /* text/data files */ 106596Sbill BFILE *txtfil; /* current text/data file */ 107596Sbill /* 108596Sbill * Relocation information is accumulated seperately for each 109596Sbill * segment. This is required by the old loader (from BTL), 110596Sbill * but not by the new loader (Bill Joy). 111596Sbill * 112596Sbill * However, the size of the relocation information can not be computed 113596Sbill * during or after the 1st pass because the ''absoluteness' of values 114596Sbill * is unknown until all locally declared symbols have been seen. 115596Sbill * Thus, the size of the relocation information is only 116596Sbill * known after the second pass is finished. 117596Sbill * This obviates the use of the block I/O 118596Sbill * library, which requires knowing the exact offsets in a.out. 119596Sbill * 120596Sbill * So, we save the relocation information internally (we don't 121596Sbill * go to internal files to minimize overhead). 122596Sbill * 123596Sbill * Empirically, we studied 259 files composing the system, 124596Sbill * two compilers and a compiler generator: (all of which have 125596Sbill * fairly large source files) 126596Sbill * 127596Sbill * Number of files = 259 128596Sbill * Number of non zero text reloc files: 233 129596Sbill * Number of non zero data reloc files: 53 130596Sbill * Average text relocation = 889 131596Sbill * Average data relocation = 346 132596Sbill * Number of files > BUFSIZ text relocation = 71 133596Sbill * Number of files > BUFSIZ data relocation = 6 134596Sbill * 135596Sbill * For compiled C code, there is usually one text segment and two 136596Sbill * data segments; we see that allocating our own buffers and 137596Sbill * doing our internal handling of relocation information will, 138596Sbill * on the average, not use more memory than taken up by the buffers 139596Sbill * allocated for doing file I/O in parallel to a number of file. 140596Sbill * 141596Sbill * If we are assembling with the -V option, we 142596Sbill * use the left over token buffers from the 2nd pass, 143596Sbill * otherwise, we create our own. 144596Sbill * 145596Sbill * When the 2nd pass is complete, closeoutrel flushes the token 146596Sbill * buffers out to a BFILE. 147596Sbill * 148596Sbill * The internals to relbufdesc are known only in assyms.c 149596Sbill * 150596Sbill * outrel constructs the relocation information. 151596Sbill * closeoutrel flushes the relocation information to relfil. 152596Sbill */ 153596Sbill struct relbufdesc *rusefile[NLOC+NLOC]; 154596Sbill struct relbufdesc *relfil; /* un concatnated relocation info */ 155596Sbill BFILE *relocfile; /* concatnated relocation info */ 156596Sbill /* 157596Sbill * Once the relocation information has been written, 158596Sbill * we can write out the symbol table using the Block I/O 159596Sbill * mechanisms, as we once again know the offsets into 160596Sbill * the a.out file. 161596Sbill * 162596Sbill * We use relfil to output the symbol table information. 163596Sbill */ 16413518Srrh char *tmpdirprefix = "/tmp/"; 165596Sbill int delexit(); 166596Sbill 167596Sbill main(argc, argv) 168596Sbill int argc; 169596Sbill char **argv; 170596Sbill { 1715826Srrh char *sbrk(); 172596Sbill 17313512Srrh tokfilename[0] = 0; 17413512Srrh strfilename[0] = 0; 1755826Srrh endcore = sbrk(0); 176596Sbill 177596Sbill argprocess(argc, argv); /* process argument lists */ 178596Sbill if (anyerrs) exit(1); 179596Sbill 180596Sbill initialize(); 181596Sbill zeroorigins(); /* set origins to zero */ 182596Sbill zerolocals(); /* fix local label counters */ 183596Sbill 184596Sbill i_pass1(); /* open temp files, etc */ 185596Sbill pass1(); /* first pass through .s files */ 186596Sbill testlocals(); /* check for undefined locals */ 187596Sbill if (anyerrs) delexit(); 188596Sbill 189596Sbill pass1_5(); /* resolve jxxx */ 190596Sbill if (anyerrs) delexit(); 191596Sbill 192596Sbill open_a_out(); /* open a.out */ 193679Shenry roundsegments(); /* round segments to FW */ 194596Sbill build_hdr(); /* build initial header, and output */ 195596Sbill 196596Sbill i_pass2(); /* reopen temporary file, etc */ 197596Sbill pass2(); /* second pass through the virtual .s */ 198596Sbill if (anyerrs) delexit(); 199596Sbill 200679Shenry fillsegments(); /* fill segments with 0 to FW */ 201596Sbill reloc_syms(); /* dump relocation and symbol table */ 202596Sbill 203596Sbill delete(); /* remove tmp file */ 204596Sbill bflush(); /* close off block I/O view of a.out */ 205596Sbill fix_a_out(); /* add in text and data reloc counts */ 206596Sbill 207596Sbill if (anyerrs == 0 && orgwarn) 208596Sbill yyerror("Caution: absolute origins.\n"); 2095826Srrh 2105826Srrh if (nGHnumbers) 2115826Srrh yywarning("Caution: G or H format floating point numbers"); 2125826Srrh if (nGHopcodes) 2135826Srrh yywarning("Caution: G or H format floating point operators"); 2145826Srrh if (nnewopcodes) 2155826Srrh yywarning("Caution: New Opcodes"); 2165826Srrh if (nGHnumbers || nGHopcodes || nnewopcodes) 2175826Srrh yywarning("These are not defined for all implementations of the VAX architecture.\n"); 2185826Srrh 219596Sbill exit(anyerrs != 0); 22013518Srrh } 221596Sbill 222596Sbill argprocess(argc, argv) 223596Sbill int argc; 224596Sbill char *argv[]; 225596Sbill { 226596Sbill register char *cp; 227596Sbill 228596Sbill ninfiles = 0; 229596Sbill silent = 0; 230596Sbill #ifdef DEBUG 231596Sbill debug = 0; 232596Sbill #endif 233643Sbill innames = (char **)ClearCalloc(argc+1, sizeof (innames[0])); 234596Sbill dotsname = "<argv error>"; 235596Sbill while (argc > 1) { 236643Sbill if (argv[1][0] != '-') 237643Sbill innames[ninfiles++] = argv[1]; 238643Sbill else { 239596Sbill cp = argv[1] + 1; 240596Sbill /* 241596Sbill * We can throw away single minus signs, so 242596Sbill * that make scripts for the PDP 11 assembler work 243596Sbill * on this assembler too 244596Sbill */ 245596Sbill while (*cp){ 246596Sbill switch(*cp++){ 247596Sbill default: 248596Sbill yyerror("Unknown flag: %c", *--cp); 249596Sbill cp++; 250596Sbill break; 2516559Srrh case 'v': 2526559Srrh selfwhat(stdout); 2536559Srrh exit(1); 254596Sbill case 'd': 255596Sbill d124 = *cp++ - '0'; 256596Sbill if ( (d124 != 1) && (d124 != 2) && 257596Sbill (d124 != 4)){ 258596Sbill yyerror("-d[124] only"); 259596Sbill exit(1); 260596Sbill } 261596Sbill break; 26215560Srrh case 'a': 26315560Srrh maxalign = atoi(cp+1); 26415560Srrh for (cp++; isdigit(*cp); cp++) 26515560Srrh /*VOID*/; 26615560Srrh if ( (maxalign > 16) || (maxalign < 0)){ 26715560Srrh yyerror("-a: 0<=align<=16"); 26815560Srrh exit(1); 26915560Srrh } 27015560Srrh break; 271596Sbill case 'o': 272596Sbill if (argc < 3){ 273596Sbill yyerror("-o what???"); 274596Sbill exit(1); 275596Sbill } 276596Sbill outfile = argv[2]; 277596Sbill bumpone: 278596Sbill argc -= 2; 279596Sbill argv += 2; 280596Sbill goto nextarg; 281596Sbill 282596Sbill case 't': 283596Sbill if (argc < 3){ 284596Sbill yyerror("-t what???"); 285596Sbill exit(1); 286596Sbill } 287596Sbill tmpdirprefix = argv[2]; 288596Sbill goto bumpone; 289596Sbill 290596Sbill case 'V': 291596Sbill useVM = 1; 292596Sbill break; 293596Sbill case 'W': 294596Sbill silent = 1; 295596Sbill break; 296596Sbill case 'L': 297596Sbill savelabels = 1; 298596Sbill break; 299636Shenry case 'J': 300636Shenry jxxxJUMP = 1; 301636Shenry break; 302596Sbill #ifdef DEBUG 303596Sbill case 'D': 304596Sbill debug = 1; 305596Sbill break; 306596Sbill case 'T': 307596Sbill toktrace = 1; 308596Sbill break; 309596Sbill #endif 310638Sbill case 'R': 311638Sbill readonlydata = 1; 312638Sbill break; 313596Sbill } /*end of the switch*/ 314596Sbill } /*end of pulling out all arguments*/ 315596Sbill } /*end of a flag argument*/ 316596Sbill --argc; ++argv; 317596Sbill nextarg:; 318596Sbill } 319643Sbill /* innames[ninfiles] = 0; */ 320596Sbill } 3216559Srrh /* 3226559Srrh * poke through the data space and find all sccs identifiers. 3236559Srrh * We assume: 3246559Srrh * a) that extern char **environ; is the first thing in the bss 3256559Srrh * segment (true, if one is using the new version of cmgt.crt0.c) 3266559Srrh * b) that the sccsid's have not been put into text space. 3276559Srrh */ 3286559Srrh selfwhat(place) 3296559Srrh FILE *place; 3306559Srrh { 3316559Srrh extern char **environ; 3326559Srrh register char *ub; 3336559Srrh register char *cp; 3346559Srrh register char *pat; 3356559Srrh char *sbrk(); 336596Sbill 3376559Srrh for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){ 3386559Srrh if (cp[0] != '@') continue; 3396559Srrh if (cp[1] != '(') continue; 3406559Srrh if (cp[2] != '#') continue; 3416559Srrh if (cp[3] != ')') continue; 3426559Srrh fputc('\t', place); 3436559Srrh for (cp += 4; cp < ub; cp++){ 3446559Srrh if (*cp == 0) break; 3456559Srrh if (*cp == '>') break; 3466559Srrh if (*cp == '\n') break; 3476559Srrh fputc(*cp, place); 3486559Srrh } 3496559Srrh fputc('\n', place); 3506559Srrh } 3516559Srrh } 3526559Srrh 353596Sbill initialize() 354596Sbill { 355596Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 356596Sbill signal(SIGINT, delexit); 357596Sbill /* 358596Sbill * Install symbols in the table 359596Sbill */ 360596Sbill symtabinit(); 361596Sbill syminstall(); 362596Sbill /* 363596Sbill * Build the expression parser accelerator token sets 364596Sbill */ 365596Sbill buildtokensets(); 366596Sbill } 367596Sbill 368596Sbill zeroorigins() 369596Sbill { 370596Sbill register int locindex; 371596Sbill /* 372596Sbill * Mark usedot: the first NLOC slots are for named text segments, 373596Sbill * the next for named data segments. 374596Sbill */ 375596Sbill for (locindex = 0; locindex < NLOC; locindex++){ 376631Shenry usedot[locindex].e_xtype = XTEXT; 377631Shenry usedot[NLOC + locindex].e_xtype = XDATA; 378631Shenry usedot[locindex].e_xvalue = 0; 379631Shenry usedot[NLOC + locindex].e_xvalue = 0; 380596Sbill } 381596Sbill } 382596Sbill 383596Sbill zerolocals() 384596Sbill { 385596Sbill register int i; 386596Sbill 387596Sbill for (i = 0; i <= 9; i++) { 388596Sbill lgensym[i] = 1; 389596Sbill genref[i] = 0; 390596Sbill } 391596Sbill } 392596Sbill 393596Sbill i_pass1() 394596Sbill { 39513512Srrh FILE *tempopen(); 39613512Srrh if (useVM == 0) 39713512Srrh tokfile = tempopen(tokfilename, "T"); 39813512Srrh strfile = tempopen(strfilename, "S"); 39913512Srrh /* 40013512Srrh * write out the string length. 40113512Srrh * This will be overwritten when the 40213512Srrh * strings are tacked onto the growing a.out file 40313512Srrh */ 40413512Srrh strfilepos = sizeof(int); 40513512Srrh fwrite(&strfilepos, sizeof(int), 1, strfile); 406596Sbill 40713512Srrh inittokfile(); 408636Shenry initijxxx(); 409596Sbill } 410596Sbill 41113512Srrh FILE *tempopen(tname, part) 41213512Srrh char *tname; 41313512Srrh char *part; 41413512Srrh { 41513512Srrh FILE *file; 41613512Srrh sprintf(tname, "%s%sas%s%05d", 41713512Srrh tmpdirprefix, 41813512Srrh (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') ? "/" : 0, 41913512Srrh part, 42013512Srrh getpid()); 42113512Srrh file = fopen(tname, "w"); 42213512Srrh if (file == NULL) { 42313512Srrh yyerror("Bad pass 1 temporary file for writing %s", tname); 42413512Srrh delexit(); 42513512Srrh } 42613512Srrh return(file); 42713512Srrh } 42813512Srrh 429596Sbill pass1() 430596Sbill { 431596Sbill register int i; 432596Sbill 433596Sbill passno = 1; 434596Sbill dotp = &usedot[0]; 435596Sbill txtfil = (BFILE *)0; 436596Sbill relfil = (struct relbufdesc *)0; 437596Sbill 438596Sbill if (ninfiles == 0){ /*take the input from stdin directly*/ 439596Sbill lineno = 1; 440596Sbill dotsname = "<stdin>"; 441596Sbill 442596Sbill yyparse(); 443596Sbill } else { /*we have the names tanked*/ 444596Sbill for (i = 0; i < ninfiles; i++){ 445596Sbill new_dot_s(innames[i]); 446596Sbill if (freopen(innames[i], "r", stdin) == NULL) { 447596Sbill yyerror( "Can't open source file %s\n", 448596Sbill innames[i]); 449596Sbill exit(2); 450596Sbill } 451596Sbill /* stdio is NOT used to read the input characters */ 452596Sbill /* we use read directly, into our own buffers */ 453596Sbill yyparse(); 454596Sbill } 455596Sbill } 456596Sbill 45713512Srrh closetokfile(); /*kick out the last buffered intermediate text*/ 458596Sbill } 459596Sbill 460596Sbill testlocals() 461596Sbill { 462596Sbill register int i; 463596Sbill for (i = 0; i <= 9; i++) { 464596Sbill if (genref[i]) 465596Sbill yyerror("Reference to undefined local label %df", i); 466596Sbill lgensym[i] = 1; 467596Sbill genref[i] = 0; 468596Sbill } 469596Sbill } 470596Sbill 471596Sbill pass1_5() 472596Sbill { 473596Sbill sortsymtab(); 474596Sbill #ifdef DEBUG 475596Sbill if (debug) dumpsymtab(); 476596Sbill #endif 477596Sbill jxxxfix(); 478596Sbill #ifdef DEBUG 479596Sbill if (debug) dumpsymtab(); 480596Sbill #endif 481596Sbill } 482596Sbill 483596Sbill open_a_out() 484596Sbill { 485*16071Sralph struct stat stb; 486*16071Sralph 487596Sbill /* 488596Sbill * Open up the a.out file now, and get set to build 489596Sbill * up offsets into it for all of the various text,data 490596Sbill * text relocation and data relocation segments. 491596Sbill */ 492596Sbill a_out_file = fopen(outfile, "w"); 493596Sbill if (a_out_file == NULL) { 494596Sbill yyerror("Cannot create %s", outfile); 495596Sbill delexit(); 496596Sbill } 497596Sbill biofd = a_out_file->_file; 498*16071Sralph fstat(biofd, &stb); 499*16071Sralph biobufsize = stb.st_blksize; 500596Sbill a_out_off = 0; 501596Sbill } 502596Sbill 503596Sbill roundsegments() 504596Sbill { 505596Sbill register int locindex; 506596Sbill register long v; 507596Sbill /* 508596Sbill * round and assign text segment origins 509596Sbill * the exec header always goes in usefile[0] 510596Sbill */ 511596Sbill tsize = 0; 512596Sbill for (locindex=0; locindex<NLOC; locindex++) { 513679Shenry v = round(usedot[locindex].e_xvalue, FW); 514631Shenry usedot[locindex].e_xvalue = tsize; 515596Sbill if ((locindex == 0) || (v != 0) ){ 516596Sbill usefile[locindex] = (BFILE *)Calloc(1, sizeof(BFILE)); 517596Sbill bopen(usefile[locindex], a_out_off); 518596Sbill if (locindex == 0) 519596Sbill a_out_off = sizeof (struct exec); 520596Sbill } else { 521596Sbill usefile[locindex] = (BFILE *)-1; 522596Sbill } 523596Sbill tsize += v; 524596Sbill a_out_off += v; 525596Sbill } 526596Sbill /* 527596Sbill * Round and assign data segment origins. 528596Sbill */ 529679Shenry datbase = round(tsize, FW); 530596Sbill for (locindex=0; locindex<NLOC; locindex++) { 531679Shenry v = round(usedot[NLOC+locindex].e_xvalue, FW); 532631Shenry usedot[NLOC+locindex].e_xvalue = datbase + dsize; 533596Sbill if (v != 0){ 534596Sbill usefile[NLOC + locindex] = (BFILE *)Calloc(1,sizeof(BFILE)); 535596Sbill bopen(usefile[NLOC + locindex], a_out_off); 536596Sbill } else { 537596Sbill usefile[NLOC + locindex] = (BFILE *)-1; 538596Sbill } 539596Sbill dsize += v; 540596Sbill a_out_off += v; 541596Sbill } 542596Sbill /* 543596Sbill * Assign final values to symbols 544596Sbill */ 545596Sbill hdr.a_bss = dsize; 546596Sbill freezesymtab(); /* this touches hdr.a_bss */ 547596Sbill stabfix(); 548596Sbill /* 549596Sbill * Set up the relocation information "files" to 550596Sbill * be zero; outrel takes care of the rest 551596Sbill */ 552596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++){ 553596Sbill rusefile[locindex] = (struct relbufdesc *)0; 554596Sbill } 555596Sbill } 556596Sbill 557596Sbill build_hdr() 558596Sbill { 559596Sbill /* 560596Sbill * Except for the text and data relocation sizes, 561596Sbill * calculate the final values for the header 562596Sbill * 563596Sbill * Write out the initial copy; we to come 564596Sbill * back later and patch up a_trsize and a_drsize, 565596Sbill * and overwrite this first version of the header. 566596Sbill */ 567596Sbill hdr.a_magic = MAGIC; 568596Sbill hdr.a_text = tsize; 569596Sbill hdr.a_data = dsize; 570596Sbill hdr.a_bss -= dsize; 571596Sbill hdr.a_syms = sizesymtab(); /* Does not include string pool length */ 572596Sbill hdr.a_entry = 0; 573596Sbill hdr.a_trsize = 0; 574596Sbill hdr.a_drsize = 0; 575596Sbill 576596Sbill bwrite((char *)&hdr, sizeof(hdr), usefile[0]); 577596Sbill } 578596Sbill 579596Sbill i_pass2() 580596Sbill { 581596Sbill if (useVM == 0) { 58213512Srrh fclose(tokfile); 58313512Srrh tokfile = fopen(tokfilename, "r"); 58413512Srrh if (tokfile==NULL) { 58513512Srrh yyerror("Bad pass 2 temporary file for reading %s", tokfilename); 586596Sbill delexit(); 587596Sbill } 588596Sbill } 58913512Srrh fclose(strfile); 59013512Srrh strfile = fopen(strfilename, "r"); 591596Sbill } 592596Sbill 593596Sbill pass2() 594596Sbill { 595596Sbill #ifdef DEBUG 596596Sbill if (debug) 597596Sbill printf("\n\n\n\t\tPASS 2\n\n\n\n"); 598596Sbill #endif DEBUG 599596Sbill passno = 2; 600596Sbill lineno = 1; 601596Sbill dotp = &usedot[0]; 602596Sbill txtfil = usefile[0]; /* already opened (always!) */ 603596Sbill relfil = 0; /* outrel takes care of the rest */ 604596Sbill initoutrel(); 605596Sbill 60613512Srrh inittokfile(); 607596Sbill 608596Sbill yyparse(); 609596Sbill 61013512Srrh closetokfile(); 611596Sbill } 612596Sbill 613596Sbill fillsegments() 614596Sbill { 615596Sbill int locindex; 616596Sbill /* 617679Shenry * Round text and data segments to FW by appending zeros 618596Sbill */ 619596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++) { 620596Sbill if (usefile[locindex]) { 621596Sbill txtfil = usefile[locindex]; 622596Sbill dotp = &usedot[locindex]; 623679Shenry while (usedot[locindex].e_xvalue & FW) 624596Sbill outb(0); 625596Sbill } 626596Sbill } 627596Sbill } 628596Sbill 629596Sbill reloc_syms() 630596Sbill { 631596Sbill u_long closerelfil(); 632596Sbill /* 633596Sbill * Move the relocation information to a.out 634596Sbill * a_out_off is the offset so far: 635596Sbill * exec + text segments + data segments 636596Sbill */ 637596Sbill relocfile = (BFILE *)Calloc(1,sizeof(BFILE)); 638596Sbill bopen(relocfile, a_out_off); 639596Sbill a_out_off += closeoutrel(relocfile); 640596Sbill 641596Sbill hdr.a_trsize = trsize; 642596Sbill hdr.a_drsize = drsize; 643638Sbill if (readonlydata) { 644638Sbill hdr.a_text += hdr.a_data; 645638Sbill hdr.a_data = 0; 646638Sbill hdr.a_trsize += hdr.a_drsize; 647638Sbill hdr.a_drsize = 0; 648638Sbill } 649596Sbill /* 65013521Srrh * Output the symbol table and the string pool 65113512Srrh * 65213512Srrh * We must first rewind the string pool file to its beginning, 65313512Srrh * in case it was seek'ed into for fetching ascii and asciz 65413512Srrh * strings. 655596Sbill */ 65613512Srrh fseek(strfile, 0, 0); 657596Sbill symwrite(relocfile); 658596Sbill } 659596Sbill 660596Sbill fix_a_out() 661596Sbill { 6625826Srrh if (lseek(a_out_file->_file, 0L, 0) < 0L) 663596Sbill yyerror("Reposition for header rewrite fails"); 664596Sbill if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0) 665596Sbill yyerror("Rewrite of header fails"); 666596Sbill } 667596Sbill 668596Sbill delexit() 669596Sbill { 670596Sbill delete(); 671596Sbill if (passno == 2){ 672596Sbill unlink(outfile); 673596Sbill } 674596Sbill exit(1); 675596Sbill } 676596Sbill 677596Sbill delete() 678596Sbill { 67913512Srrh if (useVM == 0 || tokfilename[0]) 68013512Srrh unlink(tokfilename); 68113512Srrh if (strfilename[0]) 68213512Srrh unlink(strfilename); 683596Sbill } 684596Sbill 685596Sbill sawabort() 686596Sbill { 687596Sbill char *fillinbuffer(); 688596Sbill while (fillinbuffer() != (char *)0) 689596Sbill continue; 690596Sbill delete(); 691596Sbill exit(1); /*although the previous pass will also exit non zero*/ 692596Sbill } 693596Sbill 694596Sbill panic(fmt, a1, a2, a3, a4) 695596Sbill char *fmt; 696596Sbill /*VARARGS 1*/ 697596Sbill { 698596Sbill yyerror("Assembler panic: bad internal data structure."); 699596Sbill yyerror(fmt, a1, a2, a3, a4); 700596Sbill delete(); 701596Sbill abort(); 702596Sbill } 703