15826Srrh /* 218689Sdist * Copyright (c) 1982 Regents of the University of California. 318689Sdist * All rights reserved. The Berkeley software License Agreement 418689Sdist * specifies the terms and conditions for redistribution. 55826Srrh */ 618689Sdist 75826Srrh #ifndef lint 818689Sdist char copyright[] = 918689Sdist "@(#) Copyright (c) 1982 Regents of the University of California.\n\ 1018689Sdist All rights reserved.\n"; 115826Srrh #endif not lint 125826Srrh 1318689Sdist #ifndef lint 14*37786Sbostic static char sccsid[] = "@(#)asmain.c 5.4 (Berkeley) 05/10/89"; 1518689Sdist #endif not lint 1618689Sdist 17596Sbill #include <stdio.h> 18596Sbill #include <ctype.h> 19596Sbill #include <signal.h> 20596Sbill 21596Sbill #include "as.h" 22596Sbill #include "assyms.h" 235826Srrh #include "asscan.h" 24596Sbill #include "asexpr.h" 25*37786Sbostic #include <paths.h> 26596Sbill 2716071Sralph #include <sys/stat.h> 2816071Sralph 29*37786Sbostic #define unix_lang_name "VAX/UNIX Assembler V05/10/89 5.4" 30596Sbill /* 31596Sbill * variables to manage reading the assembly source files 32596Sbill */ 33596Sbill char *dotsname; /*the current file name; managed by the parser*/ 34596Sbill int lineno; /*current line number; managed by the parser*/ 35643Sbill char **innames; /*names of the files being assembled*/ 36596Sbill int ninfiles; /*how many interesting files there are*/ 37596Sbill /* 38596Sbill * Flags settable from the argv process argument list 39596Sbill */ 40596Sbill int silent = 0; /*don't complain about any errors*/ 41596Sbill int savelabels = 0; /*write the labels to the a.out file*/ 42596Sbill int d124 = 4; /*default allocate 4 bytes for unknown pointers*/ 4315560Srrh int maxalign = 2; /*default .align maximum*/ 44596Sbill int anyerrs = 0; /*no errors yet*/ 455826Srrh int anywarnings=0; /*no warnings yet*/ 46596Sbill int orgwarn = 0; /*Bad origins*/ 47596Sbill int passno = 1; /* current pass*/ 48636Shenry int jxxxJUMP = 0; /* in jxxxes that branch too far, use jmp instead of brw */ 49638Sbill int readonlydata = 0; /* initialzed data -> text space */ 50596Sbill 515826Srrh int nGHnumbers = 0; /* GH numbers used */ 525826Srrh int nGHopcodes = 0; /* GH opcodes used */ 535826Srrh int nnewopcodes = 0; /* new opcodes used */ 545826Srrh 55596Sbill #ifdef DEBUG 56596Sbill int debug = 0; 57596Sbill int toktrace = 0; 58596Sbill #endif 59596Sbill 6013518Srrh int useVM = 0; 61596Sbill 62596Sbill char *endcore; /*where to get more symbol space*/ 63596Sbill 64596Sbill /* 65596Sbill * Managers of the a.out file. 66596Sbill */ 67596Sbill struct exec hdr; 68638Sbill #define MAGIC 0407 69596Sbill u_long tsize; /* total text size */ 70596Sbill u_long dsize; /* total data size */ 71596Sbill u_long datbase; /* base of the data segment */ 72596Sbill u_long trsize; /* total text relocation size */ 73596Sbill u_long drsize; /* total data relocation size */ 74596Sbill 75596Sbill /* 76596Sbill * Information about the current segment is accumulated in 77596Sbill * usedot; the most important information stored is the 78596Sbill * accumulated size of each of the text and data segments 79596Sbill * 80596Sbill * dotp points to the correct usedot expression for the current segment 81596Sbill */ 82596Sbill struct exp usedot[NLOC+NLOC]; /* info about all segments */ 83596Sbill struct exp *dotp; /* data/text location pointer */ 84596Sbill /* 8513512Srrh * The inter pass temporary token file is opened and closed by stdio, but 86596Sbill * is written to using direct read/write, as the temporary file 87596Sbill * is composed of buffers exactly BUFSIZ long. 88596Sbill */ 8913512Srrh FILE *tokfile; /* interpass communication file */ 9013512Srrh char tokfilename[TNAMESIZE]; 91596Sbill /* 9213512Srrh * The string file is the string table 9313512Srrh * cat'ed to the end of the built up a.out file 9413512Srrh */ 9513512Srrh FILE *strfile; /* interpass string file */ 9613512Srrh char strfilename[TNAMESIZE]; 9713512Srrh int strfilepos = 0; /* position within the string file */ 9813512Srrh /* 99596Sbill * a.out is created during the second pass. 100596Sbill * It is opened by stdio, but is filled with the parallel 101596Sbill * block I/O library 102596Sbill */ 103596Sbill char *outfile = "a.out"; 104596Sbill FILE *a_out_file; 105596Sbill off_t a_out_off; /* cumulative offsets for segments */ 106596Sbill /* 107596Sbill * The logical files containing the assembled data for each of 108596Sbill * the text and data segments are 109596Sbill * managed by the parallel block I/O library. 110596Sbill * a.out is logically opened in many places at once to 111596Sbill * receive the assembled data from the various segments as 112596Sbill * it all trickles in, but is physically opened only once 113596Sbill * to minimize file overhead. 114596Sbill */ 115596Sbill BFILE *usefile[NLOC+NLOC]; /* text/data files */ 116596Sbill BFILE *txtfil; /* current text/data file */ 117596Sbill /* 118596Sbill * Relocation information is accumulated seperately for each 119596Sbill * segment. This is required by the old loader (from BTL), 120596Sbill * but not by the new loader (Bill Joy). 121596Sbill * 122596Sbill * However, the size of the relocation information can not be computed 123596Sbill * during or after the 1st pass because the ''absoluteness' of values 124596Sbill * is unknown until all locally declared symbols have been seen. 125596Sbill * Thus, the size of the relocation information is only 126596Sbill * known after the second pass is finished. 127596Sbill * This obviates the use of the block I/O 128596Sbill * library, which requires knowing the exact offsets in a.out. 129596Sbill * 130596Sbill * So, we save the relocation information internally (we don't 131596Sbill * go to internal files to minimize overhead). 132596Sbill * 133596Sbill * Empirically, we studied 259 files composing the system, 134596Sbill * two compilers and a compiler generator: (all of which have 135596Sbill * fairly large source files) 136596Sbill * 137596Sbill * Number of files = 259 138596Sbill * Number of non zero text reloc files: 233 139596Sbill * Number of non zero data reloc files: 53 140596Sbill * Average text relocation = 889 141596Sbill * Average data relocation = 346 142596Sbill * Number of files > BUFSIZ text relocation = 71 143596Sbill * Number of files > BUFSIZ data relocation = 6 144596Sbill * 145596Sbill * For compiled C code, there is usually one text segment and two 146596Sbill * data segments; we see that allocating our own buffers and 147596Sbill * doing our internal handling of relocation information will, 148596Sbill * on the average, not use more memory than taken up by the buffers 149596Sbill * allocated for doing file I/O in parallel to a number of file. 150596Sbill * 151596Sbill * If we are assembling with the -V option, we 152596Sbill * use the left over token buffers from the 2nd pass, 153596Sbill * otherwise, we create our own. 154596Sbill * 155596Sbill * When the 2nd pass is complete, closeoutrel flushes the token 156596Sbill * buffers out to a BFILE. 157596Sbill * 158596Sbill * The internals to relbufdesc are known only in assyms.c 159596Sbill * 160596Sbill * outrel constructs the relocation information. 161596Sbill * closeoutrel flushes the relocation information to relfil. 162596Sbill */ 163596Sbill struct relbufdesc *rusefile[NLOC+NLOC]; 164596Sbill struct relbufdesc *relfil; /* un concatnated relocation info */ 165596Sbill BFILE *relocfile; /* concatnated relocation info */ 166596Sbill /* 167596Sbill * Once the relocation information has been written, 168596Sbill * we can write out the symbol table using the Block I/O 169596Sbill * mechanisms, as we once again know the offsets into 170596Sbill * the a.out file. 171596Sbill * 172596Sbill * We use relfil to output the symbol table information. 173596Sbill */ 17413518Srrh char *tmpdirprefix = "/tmp/"; 175596Sbill int delexit(); 176596Sbill 177596Sbill main(argc, argv) 178596Sbill int argc; 179596Sbill char **argv; 180596Sbill { 1815826Srrh char *sbrk(); 182596Sbill 18313512Srrh tokfilename[0] = 0; 18413512Srrh strfilename[0] = 0; 1855826Srrh endcore = sbrk(0); 186596Sbill 187596Sbill argprocess(argc, argv); /* process argument lists */ 188596Sbill if (anyerrs) exit(1); 189596Sbill 190596Sbill initialize(); 191596Sbill zeroorigins(); /* set origins to zero */ 192596Sbill zerolocals(); /* fix local label counters */ 193596Sbill 194596Sbill i_pass1(); /* open temp files, etc */ 195596Sbill pass1(); /* first pass through .s files */ 196596Sbill testlocals(); /* check for undefined locals */ 197596Sbill if (anyerrs) delexit(); 198596Sbill 199596Sbill pass1_5(); /* resolve jxxx */ 200596Sbill if (anyerrs) delexit(); 201596Sbill 202596Sbill open_a_out(); /* open a.out */ 203679Shenry roundsegments(); /* round segments to FW */ 204596Sbill build_hdr(); /* build initial header, and output */ 205596Sbill 206596Sbill i_pass2(); /* reopen temporary file, etc */ 207596Sbill pass2(); /* second pass through the virtual .s */ 208596Sbill if (anyerrs) delexit(); 209596Sbill 210679Shenry fillsegments(); /* fill segments with 0 to FW */ 211596Sbill reloc_syms(); /* dump relocation and symbol table */ 212596Sbill 213596Sbill delete(); /* remove tmp file */ 214596Sbill bflush(); /* close off block I/O view of a.out */ 215596Sbill fix_a_out(); /* add in text and data reloc counts */ 216596Sbill 217596Sbill if (anyerrs == 0 && orgwarn) 218596Sbill yyerror("Caution: absolute origins.\n"); 2195826Srrh 2205826Srrh if (nGHnumbers) 2215826Srrh yywarning("Caution: G or H format floating point numbers"); 2225826Srrh if (nGHopcodes) 2235826Srrh yywarning("Caution: G or H format floating point operators"); 2245826Srrh if (nnewopcodes) 2255826Srrh yywarning("Caution: New Opcodes"); 2265826Srrh if (nGHnumbers || nGHopcodes || nnewopcodes) 2275826Srrh yywarning("These are not defined for all implementations of the VAX architecture.\n"); 2285826Srrh 229596Sbill exit(anyerrs != 0); 23013518Srrh } 231596Sbill 232596Sbill argprocess(argc, argv) 233596Sbill int argc; 234596Sbill char *argv[]; 235596Sbill { 236596Sbill register char *cp; 237596Sbill 238596Sbill ninfiles = 0; 239596Sbill silent = 0; 240596Sbill #ifdef DEBUG 241596Sbill debug = 0; 242596Sbill #endif 243643Sbill innames = (char **)ClearCalloc(argc+1, sizeof (innames[0])); 244596Sbill dotsname = "<argv error>"; 245596Sbill while (argc > 1) { 246643Sbill if (argv[1][0] != '-') 247643Sbill innames[ninfiles++] = argv[1]; 248643Sbill else { 249596Sbill cp = argv[1] + 1; 250596Sbill /* 251596Sbill * We can throw away single minus signs, so 252596Sbill * that make scripts for the PDP 11 assembler work 253596Sbill * on this assembler too 254596Sbill */ 255596Sbill while (*cp){ 256596Sbill switch(*cp++){ 257596Sbill default: 258596Sbill yyerror("Unknown flag: %c", *--cp); 259596Sbill cp++; 260596Sbill break; 2616559Srrh case 'v': 2626559Srrh selfwhat(stdout); 2636559Srrh exit(1); 264596Sbill case 'd': 265596Sbill d124 = *cp++ - '0'; 266596Sbill if ( (d124 != 1) && (d124 != 2) && 267596Sbill (d124 != 4)){ 268596Sbill yyerror("-d[124] only"); 269596Sbill exit(1); 270596Sbill } 271596Sbill break; 27215560Srrh case 'a': 27315560Srrh maxalign = atoi(cp+1); 27415560Srrh for (cp++; isdigit(*cp); cp++) 27515560Srrh /*VOID*/; 27615560Srrh if ( (maxalign > 16) || (maxalign < 0)){ 27715560Srrh yyerror("-a: 0<=align<=16"); 27815560Srrh exit(1); 27915560Srrh } 28015560Srrh break; 281596Sbill case 'o': 282596Sbill if (argc < 3){ 283596Sbill yyerror("-o what???"); 284596Sbill exit(1); 285596Sbill } 286596Sbill outfile = argv[2]; 287596Sbill bumpone: 288596Sbill argc -= 2; 289596Sbill argv += 2; 290596Sbill goto nextarg; 291596Sbill 292596Sbill case 't': 293596Sbill if (argc < 3){ 294596Sbill yyerror("-t what???"); 295596Sbill exit(1); 296596Sbill } 297596Sbill tmpdirprefix = argv[2]; 298596Sbill goto bumpone; 299596Sbill 300596Sbill case 'V': 301596Sbill useVM = 1; 302596Sbill break; 303596Sbill case 'W': 304596Sbill silent = 1; 305596Sbill break; 306596Sbill case 'L': 307596Sbill savelabels = 1; 308596Sbill break; 309636Shenry case 'J': 310636Shenry jxxxJUMP = 1; 311636Shenry break; 312596Sbill #ifdef DEBUG 313596Sbill case 'D': 314596Sbill debug = 1; 315596Sbill break; 316596Sbill case 'T': 317596Sbill toktrace = 1; 318596Sbill break; 319596Sbill #endif 320638Sbill case 'R': 321638Sbill readonlydata = 1; 322638Sbill break; 323596Sbill } /*end of the switch*/ 324596Sbill } /*end of pulling out all arguments*/ 325596Sbill } /*end of a flag argument*/ 326596Sbill --argc; ++argv; 327596Sbill nextarg:; 328596Sbill } 329643Sbill /* innames[ninfiles] = 0; */ 330596Sbill } 3316559Srrh /* 3326559Srrh * poke through the data space and find all sccs identifiers. 3336559Srrh * We assume: 3346559Srrh * a) that extern char **environ; is the first thing in the bss 3356559Srrh * segment (true, if one is using the new version of cmgt.crt0.c) 3366559Srrh * b) that the sccsid's have not been put into text space. 3376559Srrh */ 3386559Srrh selfwhat(place) 3396559Srrh FILE *place; 3406559Srrh { 3416559Srrh extern char **environ; 3426559Srrh register char *ub; 3436559Srrh register char *cp; 3446559Srrh register char *pat; 3456559Srrh char *sbrk(); 346596Sbill 3476559Srrh for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){ 3486559Srrh if (cp[0] != '@') continue; 3496559Srrh if (cp[1] != '(') continue; 3506559Srrh if (cp[2] != '#') continue; 3516559Srrh if (cp[3] != ')') continue; 3526559Srrh fputc('\t', place); 3536559Srrh for (cp += 4; cp < ub; cp++){ 3546559Srrh if (*cp == 0) break; 3556559Srrh if (*cp == '>') break; 3566559Srrh if (*cp == '\n') break; 3576559Srrh fputc(*cp, place); 3586559Srrh } 3596559Srrh fputc('\n', place); 3606559Srrh } 3616559Srrh } 3626559Srrh 363596Sbill initialize() 364596Sbill { 365596Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 366596Sbill signal(SIGINT, delexit); 367596Sbill /* 368596Sbill * Install symbols in the table 369596Sbill */ 370596Sbill symtabinit(); 371596Sbill syminstall(); 372596Sbill /* 373596Sbill * Build the expression parser accelerator token sets 374596Sbill */ 375596Sbill buildtokensets(); 376596Sbill } 377596Sbill 378596Sbill zeroorigins() 379596Sbill { 380596Sbill register int locindex; 381596Sbill /* 382596Sbill * Mark usedot: the first NLOC slots are for named text segments, 383596Sbill * the next for named data segments. 384596Sbill */ 385596Sbill for (locindex = 0; locindex < NLOC; locindex++){ 386631Shenry usedot[locindex].e_xtype = XTEXT; 387631Shenry usedot[NLOC + locindex].e_xtype = XDATA; 388631Shenry usedot[locindex].e_xvalue = 0; 389631Shenry usedot[NLOC + locindex].e_xvalue = 0; 390596Sbill } 391596Sbill } 392596Sbill 393596Sbill zerolocals() 394596Sbill { 395596Sbill register int i; 396596Sbill 397596Sbill for (i = 0; i <= 9; i++) { 398596Sbill lgensym[i] = 1; 399596Sbill genref[i] = 0; 400596Sbill } 401596Sbill } 402596Sbill 403596Sbill i_pass1() 404596Sbill { 40513512Srrh FILE *tempopen(); 40613512Srrh if (useVM == 0) 40713512Srrh tokfile = tempopen(tokfilename, "T"); 40813512Srrh strfile = tempopen(strfilename, "S"); 40913512Srrh /* 41013512Srrh * write out the string length. 41113512Srrh * This will be overwritten when the 41213512Srrh * strings are tacked onto the growing a.out file 41313512Srrh */ 41413512Srrh strfilepos = sizeof(int); 41513512Srrh fwrite(&strfilepos, sizeof(int), 1, strfile); 416596Sbill 41713512Srrh inittokfile(); 418636Shenry initijxxx(); 419596Sbill } 420596Sbill 42113512Srrh FILE *tempopen(tname, part) 42213512Srrh char *tname; 42313512Srrh char *part; 42413512Srrh { 42513512Srrh FILE *file; 42632431Sbostic (void)sprintf(tname, "%s%sas%s%05d", 42713512Srrh tmpdirprefix, 42825246Smckusick (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') ? "/" : "", 42913512Srrh part, 43013512Srrh getpid()); 43113512Srrh file = fopen(tname, "w"); 43213512Srrh if (file == NULL) { 43313512Srrh yyerror("Bad pass 1 temporary file for writing %s", tname); 43413512Srrh delexit(); 43513512Srrh } 43613512Srrh return(file); 43713512Srrh } 43813512Srrh 439596Sbill pass1() 440596Sbill { 441596Sbill register int i; 442596Sbill 443596Sbill passno = 1; 444596Sbill dotp = &usedot[0]; 445596Sbill txtfil = (BFILE *)0; 446596Sbill relfil = (struct relbufdesc *)0; 447596Sbill 448596Sbill if (ninfiles == 0){ /*take the input from stdin directly*/ 449596Sbill lineno = 1; 450596Sbill dotsname = "<stdin>"; 451596Sbill 452596Sbill yyparse(); 453596Sbill } else { /*we have the names tanked*/ 454596Sbill for (i = 0; i < ninfiles; i++){ 455596Sbill new_dot_s(innames[i]); 456596Sbill if (freopen(innames[i], "r", stdin) == NULL) { 457596Sbill yyerror( "Can't open source file %s\n", 458596Sbill innames[i]); 459596Sbill exit(2); 460596Sbill } 461596Sbill /* stdio is NOT used to read the input characters */ 462596Sbill /* we use read directly, into our own buffers */ 463596Sbill yyparse(); 464596Sbill } 465596Sbill } 466596Sbill 46713512Srrh closetokfile(); /*kick out the last buffered intermediate text*/ 468596Sbill } 469596Sbill 470596Sbill testlocals() 471596Sbill { 472596Sbill register int i; 473596Sbill for (i = 0; i <= 9; i++) { 474596Sbill if (genref[i]) 475596Sbill yyerror("Reference to undefined local label %df", i); 476596Sbill lgensym[i] = 1; 477596Sbill genref[i] = 0; 478596Sbill } 479596Sbill } 480596Sbill 481596Sbill pass1_5() 482596Sbill { 483596Sbill sortsymtab(); 484596Sbill #ifdef DEBUG 485596Sbill if (debug) dumpsymtab(); 486596Sbill #endif 487596Sbill jxxxfix(); 488596Sbill #ifdef DEBUG 489596Sbill if (debug) dumpsymtab(); 490596Sbill #endif 491596Sbill } 492596Sbill 493596Sbill open_a_out() 494596Sbill { 49516071Sralph struct stat stb; 49616071Sralph 497596Sbill /* 498596Sbill * Open up the a.out file now, and get set to build 499596Sbill * up offsets into it for all of the various text,data 500596Sbill * text relocation and data relocation segments. 501596Sbill */ 502596Sbill a_out_file = fopen(outfile, "w"); 503596Sbill if (a_out_file == NULL) { 504596Sbill yyerror("Cannot create %s", outfile); 505596Sbill delexit(); 506596Sbill } 507596Sbill biofd = a_out_file->_file; 50816071Sralph fstat(biofd, &stb); 50916071Sralph biobufsize = stb.st_blksize; 510596Sbill a_out_off = 0; 511596Sbill } 512596Sbill 513596Sbill roundsegments() 514596Sbill { 515596Sbill register int locindex; 516596Sbill register long v; 517596Sbill /* 518596Sbill * round and assign text segment origins 519596Sbill * the exec header always goes in usefile[0] 520596Sbill */ 521596Sbill tsize = 0; 522596Sbill for (locindex=0; locindex<NLOC; locindex++) { 523679Shenry v = round(usedot[locindex].e_xvalue, FW); 524631Shenry usedot[locindex].e_xvalue = tsize; 525596Sbill if ((locindex == 0) || (v != 0) ){ 526596Sbill usefile[locindex] = (BFILE *)Calloc(1, sizeof(BFILE)); 527596Sbill bopen(usefile[locindex], a_out_off); 528596Sbill if (locindex == 0) 529596Sbill a_out_off = sizeof (struct exec); 530596Sbill } else { 531596Sbill usefile[locindex] = (BFILE *)-1; 532596Sbill } 533596Sbill tsize += v; 534596Sbill a_out_off += v; 535596Sbill } 536596Sbill /* 537596Sbill * Round and assign data segment origins. 538596Sbill */ 539679Shenry datbase = round(tsize, FW); 540596Sbill for (locindex=0; locindex<NLOC; locindex++) { 541679Shenry v = round(usedot[NLOC+locindex].e_xvalue, FW); 542631Shenry usedot[NLOC+locindex].e_xvalue = datbase + dsize; 543596Sbill if (v != 0){ 544596Sbill usefile[NLOC + locindex] = (BFILE *)Calloc(1,sizeof(BFILE)); 545596Sbill bopen(usefile[NLOC + locindex], a_out_off); 546596Sbill } else { 547596Sbill usefile[NLOC + locindex] = (BFILE *)-1; 548596Sbill } 549596Sbill dsize += v; 550596Sbill a_out_off += v; 551596Sbill } 552596Sbill /* 553596Sbill * Assign final values to symbols 554596Sbill */ 555596Sbill hdr.a_bss = dsize; 556596Sbill freezesymtab(); /* this touches hdr.a_bss */ 557596Sbill stabfix(); 558596Sbill /* 559596Sbill * Set up the relocation information "files" to 560596Sbill * be zero; outrel takes care of the rest 561596Sbill */ 562596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++){ 563596Sbill rusefile[locindex] = (struct relbufdesc *)0; 564596Sbill } 565596Sbill } 566596Sbill 567596Sbill build_hdr() 568596Sbill { 569596Sbill /* 570596Sbill * Except for the text and data relocation sizes, 571596Sbill * calculate the final values for the header 572596Sbill * 573596Sbill * Write out the initial copy; we to come 574596Sbill * back later and patch up a_trsize and a_drsize, 575596Sbill * and overwrite this first version of the header. 576596Sbill */ 577596Sbill hdr.a_magic = MAGIC; 578596Sbill hdr.a_text = tsize; 579596Sbill hdr.a_data = dsize; 580596Sbill hdr.a_bss -= dsize; 581596Sbill hdr.a_syms = sizesymtab(); /* Does not include string pool length */ 582596Sbill hdr.a_entry = 0; 583596Sbill hdr.a_trsize = 0; 584596Sbill hdr.a_drsize = 0; 585596Sbill 586596Sbill bwrite((char *)&hdr, sizeof(hdr), usefile[0]); 587596Sbill } 588596Sbill 589596Sbill i_pass2() 590596Sbill { 591596Sbill if (useVM == 0) { 59213512Srrh fclose(tokfile); 59313512Srrh tokfile = fopen(tokfilename, "r"); 59413512Srrh if (tokfile==NULL) { 59513512Srrh yyerror("Bad pass 2 temporary file for reading %s", tokfilename); 596596Sbill delexit(); 597596Sbill } 598596Sbill } 59913512Srrh fclose(strfile); 60013512Srrh strfile = fopen(strfilename, "r"); 601596Sbill } 602596Sbill 603596Sbill pass2() 604596Sbill { 605596Sbill #ifdef DEBUG 606596Sbill if (debug) 607596Sbill printf("\n\n\n\t\tPASS 2\n\n\n\n"); 608596Sbill #endif DEBUG 609596Sbill passno = 2; 610596Sbill lineno = 1; 611596Sbill dotp = &usedot[0]; 612596Sbill txtfil = usefile[0]; /* already opened (always!) */ 613596Sbill relfil = 0; /* outrel takes care of the rest */ 614596Sbill initoutrel(); 615596Sbill 61613512Srrh inittokfile(); 617596Sbill 618596Sbill yyparse(); 619596Sbill 62013512Srrh closetokfile(); 621596Sbill } 622596Sbill 623596Sbill fillsegments() 624596Sbill { 625596Sbill int locindex; 626596Sbill /* 627679Shenry * Round text and data segments to FW by appending zeros 628596Sbill */ 629596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++) { 630596Sbill if (usefile[locindex]) { 631596Sbill txtfil = usefile[locindex]; 632596Sbill dotp = &usedot[locindex]; 633679Shenry while (usedot[locindex].e_xvalue & FW) 634596Sbill outb(0); 635596Sbill } 636596Sbill } 637596Sbill } 638596Sbill 639596Sbill reloc_syms() 640596Sbill { 641596Sbill u_long closerelfil(); 642596Sbill /* 643596Sbill * Move the relocation information to a.out 644596Sbill * a_out_off is the offset so far: 645596Sbill * exec + text segments + data segments 646596Sbill */ 647596Sbill relocfile = (BFILE *)Calloc(1,sizeof(BFILE)); 648596Sbill bopen(relocfile, a_out_off); 649596Sbill a_out_off += closeoutrel(relocfile); 650596Sbill 651596Sbill hdr.a_trsize = trsize; 652596Sbill hdr.a_drsize = drsize; 653638Sbill if (readonlydata) { 654638Sbill hdr.a_text += hdr.a_data; 655638Sbill hdr.a_data = 0; 656638Sbill hdr.a_trsize += hdr.a_drsize; 657638Sbill hdr.a_drsize = 0; 658638Sbill } 659596Sbill /* 66013521Srrh * Output the symbol table and the string pool 66113512Srrh * 66213512Srrh * We must first rewind the string pool file to its beginning, 66313512Srrh * in case it was seek'ed into for fetching ascii and asciz 66413512Srrh * strings. 665596Sbill */ 66613512Srrh fseek(strfile, 0, 0); 667596Sbill symwrite(relocfile); 668596Sbill } 669596Sbill 670596Sbill fix_a_out() 671596Sbill { 6725826Srrh if (lseek(a_out_file->_file, 0L, 0) < 0L) 673596Sbill yyerror("Reposition for header rewrite fails"); 674596Sbill if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0) 675596Sbill yyerror("Rewrite of header fails"); 676596Sbill } 677596Sbill 678596Sbill delexit() 679596Sbill { 680596Sbill delete(); 681596Sbill if (passno == 2){ 682596Sbill unlink(outfile); 683596Sbill } 684596Sbill exit(1); 685596Sbill } 686596Sbill 687596Sbill delete() 688596Sbill { 68913512Srrh if (useVM == 0 || tokfilename[0]) 69013512Srrh unlink(tokfilename); 69113512Srrh if (strfilename[0]) 69213512Srrh unlink(strfilename); 693596Sbill } 694596Sbill 695596Sbill sawabort() 696596Sbill { 697596Sbill char *fillinbuffer(); 698596Sbill while (fillinbuffer() != (char *)0) 699596Sbill continue; 700596Sbill delete(); 701596Sbill exit(1); /*although the previous pass will also exit non zero*/ 702596Sbill } 703596Sbill 704596Sbill panic(fmt, a1, a2, a3, a4) 705596Sbill char *fmt; 706596Sbill /*VARARGS 1*/ 707596Sbill { 708596Sbill yyerror("Assembler panic: bad internal data structure."); 709596Sbill yyerror(fmt, a1, a2, a3, a4); 710596Sbill delete(); 711596Sbill abort(); 712596Sbill } 713