15826Srrh /* 25826Srrh * Copyright (c) 1982 Regents of the University of California 35826Srrh */ 45826Srrh #ifndef lint 5*15560Srrh static char sccsid[] = "@(#)asmain.c 4.14 11/21/83"; 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*15560Srrh #define unix_lang_name "VAX/UNIX Assembler V11/21/83 4.14" 18596Sbill /* 19596Sbill * variables to manage reading the assembly source files 20596Sbill */ 21596Sbill char *dotsname; /*the current file name; managed by the parser*/ 22596Sbill int lineno; /*current line number; managed by the parser*/ 23643Sbill char **innames; /*names of the files being assembled*/ 24596Sbill int ninfiles; /*how many interesting files there are*/ 25596Sbill /* 26596Sbill * Flags settable from the argv process argument list 27596Sbill */ 28596Sbill int silent = 0; /*don't complain about any errors*/ 29596Sbill int savelabels = 0; /*write the labels to the a.out file*/ 30596Sbill int d124 = 4; /*default allocate 4 bytes for unknown pointers*/ 31*15560Srrh int maxalign = 2; /*default .align maximum*/ 32596Sbill int anyerrs = 0; /*no errors yet*/ 335826Srrh int anywarnings=0; /*no warnings yet*/ 34596Sbill int orgwarn = 0; /*Bad origins*/ 35596Sbill int passno = 1; /* current pass*/ 36636Shenry int jxxxJUMP = 0; /* in jxxxes that branch too far, use jmp instead of brw */ 37638Sbill int readonlydata = 0; /* initialzed data -> text space */ 38596Sbill 395826Srrh int nGHnumbers = 0; /* GH numbers used */ 405826Srrh int nGHopcodes = 0; /* GH opcodes used */ 415826Srrh int nnewopcodes = 0; /* new opcodes used */ 425826Srrh 43596Sbill #ifdef DEBUG 44596Sbill int debug = 0; 45596Sbill int toktrace = 0; 46596Sbill #endif 47596Sbill 4813518Srrh int useVM = 0; 49596Sbill 50596Sbill char *endcore; /*where to get more symbol space*/ 51596Sbill 52596Sbill /* 53596Sbill * Managers of the a.out file. 54596Sbill */ 55596Sbill struct exec hdr; 56638Sbill #define MAGIC 0407 57596Sbill u_long tsize; /* total text size */ 58596Sbill u_long dsize; /* total data size */ 59596Sbill u_long datbase; /* base of the data segment */ 60596Sbill u_long trsize; /* total text relocation size */ 61596Sbill u_long drsize; /* total data relocation size */ 62596Sbill 63596Sbill /* 64596Sbill * Information about the current segment is accumulated in 65596Sbill * usedot; the most important information stored is the 66596Sbill * accumulated size of each of the text and data segments 67596Sbill * 68596Sbill * dotp points to the correct usedot expression for the current segment 69596Sbill */ 70596Sbill struct exp usedot[NLOC+NLOC]; /* info about all segments */ 71596Sbill struct exp *dotp; /* data/text location pointer */ 72596Sbill /* 7313512Srrh * The inter pass temporary token file is opened and closed by stdio, but 74596Sbill * is written to using direct read/write, as the temporary file 75596Sbill * is composed of buffers exactly BUFSIZ long. 76596Sbill */ 7713512Srrh FILE *tokfile; /* interpass communication file */ 7813512Srrh char tokfilename[TNAMESIZE]; 79596Sbill /* 8013512Srrh * The string file is the string table 8113512Srrh * cat'ed to the end of the built up a.out file 8213512Srrh */ 8313512Srrh FILE *strfile; /* interpass string file */ 8413512Srrh char strfilename[TNAMESIZE]; 8513512Srrh int strfilepos = 0; /* position within the string file */ 8613512Srrh /* 87596Sbill * a.out is created during the second pass. 88596Sbill * It is opened by stdio, but is filled with the parallel 89596Sbill * block I/O library 90596Sbill */ 91596Sbill char *outfile = "a.out"; 92596Sbill FILE *a_out_file; 93596Sbill off_t a_out_off; /* cumulative offsets for segments */ 94596Sbill /* 95596Sbill * The logical files containing the assembled data for each of 96596Sbill * the text and data segments are 97596Sbill * managed by the parallel block I/O library. 98596Sbill * a.out is logically opened in many places at once to 99596Sbill * receive the assembled data from the various segments as 100596Sbill * it all trickles in, but is physically opened only once 101596Sbill * to minimize file overhead. 102596Sbill */ 103596Sbill BFILE *usefile[NLOC+NLOC]; /* text/data files */ 104596Sbill BFILE *txtfil; /* current text/data file */ 105596Sbill /* 106596Sbill * Relocation information is accumulated seperately for each 107596Sbill * segment. This is required by the old loader (from BTL), 108596Sbill * but not by the new loader (Bill Joy). 109596Sbill * 110596Sbill * However, the size of the relocation information can not be computed 111596Sbill * during or after the 1st pass because the ''absoluteness' of values 112596Sbill * is unknown until all locally declared symbols have been seen. 113596Sbill * Thus, the size of the relocation information is only 114596Sbill * known after the second pass is finished. 115596Sbill * This obviates the use of the block I/O 116596Sbill * library, which requires knowing the exact offsets in a.out. 117596Sbill * 118596Sbill * So, we save the relocation information internally (we don't 119596Sbill * go to internal files to minimize overhead). 120596Sbill * 121596Sbill * Empirically, we studied 259 files composing the system, 122596Sbill * two compilers and a compiler generator: (all of which have 123596Sbill * fairly large source files) 124596Sbill * 125596Sbill * Number of files = 259 126596Sbill * Number of non zero text reloc files: 233 127596Sbill * Number of non zero data reloc files: 53 128596Sbill * Average text relocation = 889 129596Sbill * Average data relocation = 346 130596Sbill * Number of files > BUFSIZ text relocation = 71 131596Sbill * Number of files > BUFSIZ data relocation = 6 132596Sbill * 133596Sbill * For compiled C code, there is usually one text segment and two 134596Sbill * data segments; we see that allocating our own buffers and 135596Sbill * doing our internal handling of relocation information will, 136596Sbill * on the average, not use more memory than taken up by the buffers 137596Sbill * allocated for doing file I/O in parallel to a number of file. 138596Sbill * 139596Sbill * If we are assembling with the -V option, we 140596Sbill * use the left over token buffers from the 2nd pass, 141596Sbill * otherwise, we create our own. 142596Sbill * 143596Sbill * When the 2nd pass is complete, closeoutrel flushes the token 144596Sbill * buffers out to a BFILE. 145596Sbill * 146596Sbill * The internals to relbufdesc are known only in assyms.c 147596Sbill * 148596Sbill * outrel constructs the relocation information. 149596Sbill * closeoutrel flushes the relocation information to relfil. 150596Sbill */ 151596Sbill struct relbufdesc *rusefile[NLOC+NLOC]; 152596Sbill struct relbufdesc *relfil; /* un concatnated relocation info */ 153596Sbill BFILE *relocfile; /* concatnated relocation info */ 154596Sbill /* 155596Sbill * Once the relocation information has been written, 156596Sbill * we can write out the symbol table using the Block I/O 157596Sbill * mechanisms, as we once again know the offsets into 158596Sbill * the a.out file. 159596Sbill * 160596Sbill * We use relfil to output the symbol table information. 161596Sbill */ 16213518Srrh char *tmpdirprefix = "/tmp/"; 163596Sbill int delexit(); 164596Sbill 165596Sbill main(argc, argv) 166596Sbill int argc; 167596Sbill char **argv; 168596Sbill { 1695826Srrh char *sbrk(); 170596Sbill 17113512Srrh tokfilename[0] = 0; 17213512Srrh strfilename[0] = 0; 1735826Srrh endcore = sbrk(0); 174596Sbill 175596Sbill argprocess(argc, argv); /* process argument lists */ 176596Sbill if (anyerrs) exit(1); 177596Sbill 178596Sbill initialize(); 179596Sbill zeroorigins(); /* set origins to zero */ 180596Sbill zerolocals(); /* fix local label counters */ 181596Sbill 182596Sbill i_pass1(); /* open temp files, etc */ 183596Sbill pass1(); /* first pass through .s files */ 184596Sbill testlocals(); /* check for undefined locals */ 185596Sbill if (anyerrs) delexit(); 186596Sbill 187596Sbill pass1_5(); /* resolve jxxx */ 188596Sbill if (anyerrs) delexit(); 189596Sbill 190596Sbill open_a_out(); /* open a.out */ 191679Shenry roundsegments(); /* round segments to FW */ 192596Sbill build_hdr(); /* build initial header, and output */ 193596Sbill 194596Sbill i_pass2(); /* reopen temporary file, etc */ 195596Sbill pass2(); /* second pass through the virtual .s */ 196596Sbill if (anyerrs) delexit(); 197596Sbill 198679Shenry fillsegments(); /* fill segments with 0 to FW */ 199596Sbill reloc_syms(); /* dump relocation and symbol table */ 200596Sbill 201596Sbill delete(); /* remove tmp file */ 202596Sbill bflush(); /* close off block I/O view of a.out */ 203596Sbill fix_a_out(); /* add in text and data reloc counts */ 204596Sbill 205596Sbill if (anyerrs == 0 && orgwarn) 206596Sbill yyerror("Caution: absolute origins.\n"); 2075826Srrh 2085826Srrh if (nGHnumbers) 2095826Srrh yywarning("Caution: G or H format floating point numbers"); 2105826Srrh if (nGHopcodes) 2115826Srrh yywarning("Caution: G or H format floating point operators"); 2125826Srrh if (nnewopcodes) 2135826Srrh yywarning("Caution: New Opcodes"); 2145826Srrh if (nGHnumbers || nGHopcodes || nnewopcodes) 2155826Srrh yywarning("These are not defined for all implementations of the VAX architecture.\n"); 2165826Srrh 217596Sbill exit(anyerrs != 0); 21813518Srrh } 219596Sbill 220596Sbill argprocess(argc, argv) 221596Sbill int argc; 222596Sbill char *argv[]; 223596Sbill { 224596Sbill register char *cp; 225596Sbill 226596Sbill ninfiles = 0; 227596Sbill silent = 0; 228596Sbill #ifdef DEBUG 229596Sbill debug = 0; 230596Sbill #endif 231643Sbill innames = (char **)ClearCalloc(argc+1, sizeof (innames[0])); 232596Sbill dotsname = "<argv error>"; 233596Sbill while (argc > 1) { 234643Sbill if (argv[1][0] != '-') 235643Sbill innames[ninfiles++] = argv[1]; 236643Sbill else { 237596Sbill cp = argv[1] + 1; 238596Sbill /* 239596Sbill * We can throw away single minus signs, so 240596Sbill * that make scripts for the PDP 11 assembler work 241596Sbill * on this assembler too 242596Sbill */ 243596Sbill while (*cp){ 244596Sbill switch(*cp++){ 245596Sbill default: 246596Sbill yyerror("Unknown flag: %c", *--cp); 247596Sbill cp++; 248596Sbill break; 2496559Srrh case 'v': 2506559Srrh selfwhat(stdout); 2516559Srrh exit(1); 252596Sbill case 'd': 253596Sbill d124 = *cp++ - '0'; 254596Sbill if ( (d124 != 1) && (d124 != 2) && 255596Sbill (d124 != 4)){ 256596Sbill yyerror("-d[124] only"); 257596Sbill exit(1); 258596Sbill } 259596Sbill break; 260*15560Srrh case 'a': 261*15560Srrh maxalign = atoi(cp+1); 262*15560Srrh for (cp++; isdigit(*cp); cp++) 263*15560Srrh /*VOID*/; 264*15560Srrh if ( (maxalign > 16) || (maxalign < 0)){ 265*15560Srrh yyerror("-a: 0<=align<=16"); 266*15560Srrh exit(1); 267*15560Srrh } 268*15560Srrh break; 269596Sbill case 'o': 270596Sbill if (argc < 3){ 271596Sbill yyerror("-o what???"); 272596Sbill exit(1); 273596Sbill } 274596Sbill outfile = argv[2]; 275596Sbill bumpone: 276596Sbill argc -= 2; 277596Sbill argv += 2; 278596Sbill goto nextarg; 279596Sbill 280596Sbill case 't': 281596Sbill if (argc < 3){ 282596Sbill yyerror("-t what???"); 283596Sbill exit(1); 284596Sbill } 285596Sbill tmpdirprefix = argv[2]; 286596Sbill goto bumpone; 287596Sbill 288596Sbill case 'V': 289596Sbill useVM = 1; 290596Sbill break; 291596Sbill case 'W': 292596Sbill silent = 1; 293596Sbill break; 294596Sbill case 'L': 295596Sbill savelabels = 1; 296596Sbill break; 297636Shenry case 'J': 298636Shenry jxxxJUMP = 1; 299636Shenry break; 300596Sbill #ifdef DEBUG 301596Sbill case 'D': 302596Sbill debug = 1; 303596Sbill break; 304596Sbill case 'T': 305596Sbill toktrace = 1; 306596Sbill break; 307596Sbill #endif 308638Sbill case 'R': 309638Sbill readonlydata = 1; 310638Sbill break; 311596Sbill } /*end of the switch*/ 312596Sbill } /*end of pulling out all arguments*/ 313596Sbill } /*end of a flag argument*/ 314596Sbill --argc; ++argv; 315596Sbill nextarg:; 316596Sbill } 317643Sbill /* innames[ninfiles] = 0; */ 318596Sbill } 3196559Srrh /* 3206559Srrh * poke through the data space and find all sccs identifiers. 3216559Srrh * We assume: 3226559Srrh * a) that extern char **environ; is the first thing in the bss 3236559Srrh * segment (true, if one is using the new version of cmgt.crt0.c) 3246559Srrh * b) that the sccsid's have not been put into text space. 3256559Srrh */ 3266559Srrh selfwhat(place) 3276559Srrh FILE *place; 3286559Srrh { 3296559Srrh extern char **environ; 3306559Srrh register char *ub; 3316559Srrh register char *cp; 3326559Srrh register char *pat; 3336559Srrh char *sbrk(); 334596Sbill 3356559Srrh for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){ 3366559Srrh if (cp[0] != '@') continue; 3376559Srrh if (cp[1] != '(') continue; 3386559Srrh if (cp[2] != '#') continue; 3396559Srrh if (cp[3] != ')') continue; 3406559Srrh fputc('\t', place); 3416559Srrh for (cp += 4; cp < ub; cp++){ 3426559Srrh if (*cp == 0) break; 3436559Srrh if (*cp == '>') break; 3446559Srrh if (*cp == '\n') break; 3456559Srrh fputc(*cp, place); 3466559Srrh } 3476559Srrh fputc('\n', place); 3486559Srrh } 3496559Srrh } 3506559Srrh 351596Sbill initialize() 352596Sbill { 353596Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 354596Sbill signal(SIGINT, delexit); 355596Sbill /* 356596Sbill * Install symbols in the table 357596Sbill */ 358596Sbill symtabinit(); 359596Sbill syminstall(); 360596Sbill /* 361596Sbill * Build the expression parser accelerator token sets 362596Sbill */ 363596Sbill buildtokensets(); 364596Sbill } 365596Sbill 366596Sbill zeroorigins() 367596Sbill { 368596Sbill register int locindex; 369596Sbill /* 370596Sbill * Mark usedot: the first NLOC slots are for named text segments, 371596Sbill * the next for named data segments. 372596Sbill */ 373596Sbill for (locindex = 0; locindex < NLOC; locindex++){ 374631Shenry usedot[locindex].e_xtype = XTEXT; 375631Shenry usedot[NLOC + locindex].e_xtype = XDATA; 376631Shenry usedot[locindex].e_xvalue = 0; 377631Shenry usedot[NLOC + locindex].e_xvalue = 0; 378596Sbill } 379596Sbill } 380596Sbill 381596Sbill zerolocals() 382596Sbill { 383596Sbill register int i; 384596Sbill 385596Sbill for (i = 0; i <= 9; i++) { 386596Sbill lgensym[i] = 1; 387596Sbill genref[i] = 0; 388596Sbill } 389596Sbill } 390596Sbill 391596Sbill i_pass1() 392596Sbill { 39313512Srrh FILE *tempopen(); 39413512Srrh if (useVM == 0) 39513512Srrh tokfile = tempopen(tokfilename, "T"); 39613512Srrh strfile = tempopen(strfilename, "S"); 39713512Srrh /* 39813512Srrh * write out the string length. 39913512Srrh * This will be overwritten when the 40013512Srrh * strings are tacked onto the growing a.out file 40113512Srrh */ 40213512Srrh strfilepos = sizeof(int); 40313512Srrh fwrite(&strfilepos, sizeof(int), 1, strfile); 404596Sbill 40513512Srrh inittokfile(); 406636Shenry initijxxx(); 407596Sbill } 408596Sbill 40913512Srrh FILE *tempopen(tname, part) 41013512Srrh char *tname; 41113512Srrh char *part; 41213512Srrh { 41313512Srrh FILE *file; 41413512Srrh sprintf(tname, "%s%sas%s%05d", 41513512Srrh tmpdirprefix, 41613512Srrh (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') ? "/" : 0, 41713512Srrh part, 41813512Srrh getpid()); 41913512Srrh file = fopen(tname, "w"); 42013512Srrh if (file == NULL) { 42113512Srrh yyerror("Bad pass 1 temporary file for writing %s", tname); 42213512Srrh delexit(); 42313512Srrh } 42413512Srrh return(file); 42513512Srrh } 42613512Srrh 427596Sbill pass1() 428596Sbill { 429596Sbill register int i; 430596Sbill 431596Sbill passno = 1; 432596Sbill dotp = &usedot[0]; 433596Sbill txtfil = (BFILE *)0; 434596Sbill relfil = (struct relbufdesc *)0; 435596Sbill 436596Sbill if (ninfiles == 0){ /*take the input from stdin directly*/ 437596Sbill lineno = 1; 438596Sbill dotsname = "<stdin>"; 439596Sbill 440596Sbill yyparse(); 441596Sbill } else { /*we have the names tanked*/ 442596Sbill for (i = 0; i < ninfiles; i++){ 443596Sbill new_dot_s(innames[i]); 444596Sbill if (freopen(innames[i], "r", stdin) == NULL) { 445596Sbill yyerror( "Can't open source file %s\n", 446596Sbill innames[i]); 447596Sbill exit(2); 448596Sbill } 449596Sbill /* stdio is NOT used to read the input characters */ 450596Sbill /* we use read directly, into our own buffers */ 451596Sbill yyparse(); 452596Sbill } 453596Sbill } 454596Sbill 45513512Srrh closetokfile(); /*kick out the last buffered intermediate text*/ 456596Sbill } 457596Sbill 458596Sbill testlocals() 459596Sbill { 460596Sbill register int i; 461596Sbill for (i = 0; i <= 9; i++) { 462596Sbill if (genref[i]) 463596Sbill yyerror("Reference to undefined local label %df", i); 464596Sbill lgensym[i] = 1; 465596Sbill genref[i] = 0; 466596Sbill } 467596Sbill } 468596Sbill 469596Sbill pass1_5() 470596Sbill { 471596Sbill sortsymtab(); 472596Sbill #ifdef DEBUG 473596Sbill if (debug) dumpsymtab(); 474596Sbill #endif 475596Sbill jxxxfix(); 476596Sbill #ifdef DEBUG 477596Sbill if (debug) dumpsymtab(); 478596Sbill #endif 479596Sbill } 480596Sbill 481596Sbill open_a_out() 482596Sbill { 483596Sbill /* 484596Sbill * Open up the a.out file now, and get set to build 485596Sbill * up offsets into it for all of the various text,data 486596Sbill * text relocation and data relocation segments. 487596Sbill */ 488596Sbill a_out_file = fopen(outfile, "w"); 489596Sbill if (a_out_file == NULL) { 490596Sbill yyerror("Cannot create %s", outfile); 491596Sbill delexit(); 492596Sbill } 493596Sbill biofd = a_out_file->_file; 494596Sbill a_out_off = 0; 495596Sbill } 496596Sbill 497596Sbill roundsegments() 498596Sbill { 499596Sbill register int locindex; 500596Sbill register long v; 501596Sbill /* 502596Sbill * round and assign text segment origins 503596Sbill * the exec header always goes in usefile[0] 504596Sbill */ 505596Sbill tsize = 0; 506596Sbill for (locindex=0; locindex<NLOC; locindex++) { 507679Shenry v = round(usedot[locindex].e_xvalue, FW); 508631Shenry usedot[locindex].e_xvalue = tsize; 509596Sbill if ((locindex == 0) || (v != 0) ){ 510596Sbill usefile[locindex] = (BFILE *)Calloc(1, sizeof(BFILE)); 511596Sbill bopen(usefile[locindex], a_out_off); 512596Sbill if (locindex == 0) 513596Sbill a_out_off = sizeof (struct exec); 514596Sbill } else { 515596Sbill usefile[locindex] = (BFILE *)-1; 516596Sbill } 517596Sbill tsize += v; 518596Sbill a_out_off += v; 519596Sbill } 520596Sbill /* 521596Sbill * Round and assign data segment origins. 522596Sbill */ 523679Shenry datbase = round(tsize, FW); 524596Sbill for (locindex=0; locindex<NLOC; locindex++) { 525679Shenry v = round(usedot[NLOC+locindex].e_xvalue, FW); 526631Shenry usedot[NLOC+locindex].e_xvalue = datbase + dsize; 527596Sbill if (v != 0){ 528596Sbill usefile[NLOC + locindex] = (BFILE *)Calloc(1,sizeof(BFILE)); 529596Sbill bopen(usefile[NLOC + locindex], a_out_off); 530596Sbill } else { 531596Sbill usefile[NLOC + locindex] = (BFILE *)-1; 532596Sbill } 533596Sbill dsize += v; 534596Sbill a_out_off += v; 535596Sbill } 536596Sbill /* 537596Sbill * Assign final values to symbols 538596Sbill */ 539596Sbill hdr.a_bss = dsize; 540596Sbill freezesymtab(); /* this touches hdr.a_bss */ 541596Sbill stabfix(); 542596Sbill /* 543596Sbill * Set up the relocation information "files" to 544596Sbill * be zero; outrel takes care of the rest 545596Sbill */ 546596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++){ 547596Sbill rusefile[locindex] = (struct relbufdesc *)0; 548596Sbill } 549596Sbill } 550596Sbill 551596Sbill build_hdr() 552596Sbill { 553596Sbill /* 554596Sbill * Except for the text and data relocation sizes, 555596Sbill * calculate the final values for the header 556596Sbill * 557596Sbill * Write out the initial copy; we to come 558596Sbill * back later and patch up a_trsize and a_drsize, 559596Sbill * and overwrite this first version of the header. 560596Sbill */ 561596Sbill hdr.a_magic = MAGIC; 562596Sbill hdr.a_text = tsize; 563596Sbill hdr.a_data = dsize; 564596Sbill hdr.a_bss -= dsize; 565596Sbill hdr.a_syms = sizesymtab(); /* Does not include string pool length */ 566596Sbill hdr.a_entry = 0; 567596Sbill hdr.a_trsize = 0; 568596Sbill hdr.a_drsize = 0; 569596Sbill 570596Sbill bwrite((char *)&hdr, sizeof(hdr), usefile[0]); 571596Sbill } 572596Sbill 573596Sbill i_pass2() 574596Sbill { 575596Sbill if (useVM == 0) { 57613512Srrh fclose(tokfile); 57713512Srrh tokfile = fopen(tokfilename, "r"); 57813512Srrh if (tokfile==NULL) { 57913512Srrh yyerror("Bad pass 2 temporary file for reading %s", tokfilename); 580596Sbill delexit(); 581596Sbill } 582596Sbill } 58313512Srrh fclose(strfile); 58413512Srrh strfile = fopen(strfilename, "r"); 585596Sbill } 586596Sbill 587596Sbill pass2() 588596Sbill { 589596Sbill #ifdef DEBUG 590596Sbill if (debug) 591596Sbill printf("\n\n\n\t\tPASS 2\n\n\n\n"); 592596Sbill #endif DEBUG 593596Sbill passno = 2; 594596Sbill lineno = 1; 595596Sbill dotp = &usedot[0]; 596596Sbill txtfil = usefile[0]; /* already opened (always!) */ 597596Sbill relfil = 0; /* outrel takes care of the rest */ 598596Sbill initoutrel(); 599596Sbill 60013512Srrh inittokfile(); 601596Sbill 602596Sbill yyparse(); 603596Sbill 60413512Srrh closetokfile(); 605596Sbill } 606596Sbill 607596Sbill fillsegments() 608596Sbill { 609596Sbill int locindex; 610596Sbill /* 611679Shenry * Round text and data segments to FW by appending zeros 612596Sbill */ 613596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++) { 614596Sbill if (usefile[locindex]) { 615596Sbill txtfil = usefile[locindex]; 616596Sbill dotp = &usedot[locindex]; 617679Shenry while (usedot[locindex].e_xvalue & FW) 618596Sbill outb(0); 619596Sbill } 620596Sbill } 621596Sbill } 622596Sbill 623596Sbill reloc_syms() 624596Sbill { 625596Sbill u_long closerelfil(); 626596Sbill /* 627596Sbill * Move the relocation information to a.out 628596Sbill * a_out_off is the offset so far: 629596Sbill * exec + text segments + data segments 630596Sbill */ 631596Sbill relocfile = (BFILE *)Calloc(1,sizeof(BFILE)); 632596Sbill bopen(relocfile, a_out_off); 633596Sbill a_out_off += closeoutrel(relocfile); 634596Sbill 635596Sbill hdr.a_trsize = trsize; 636596Sbill hdr.a_drsize = drsize; 637638Sbill if (readonlydata) { 638638Sbill hdr.a_text += hdr.a_data; 639638Sbill hdr.a_data = 0; 640638Sbill hdr.a_trsize += hdr.a_drsize; 641638Sbill hdr.a_drsize = 0; 642638Sbill } 643596Sbill /* 64413521Srrh * Output the symbol table and the string pool 64513512Srrh * 64613512Srrh * We must first rewind the string pool file to its beginning, 64713512Srrh * in case it was seek'ed into for fetching ascii and asciz 64813512Srrh * strings. 649596Sbill */ 65013512Srrh fseek(strfile, 0, 0); 651596Sbill symwrite(relocfile); 652596Sbill } 653596Sbill 654596Sbill fix_a_out() 655596Sbill { 6565826Srrh if (lseek(a_out_file->_file, 0L, 0) < 0L) 657596Sbill yyerror("Reposition for header rewrite fails"); 658596Sbill if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0) 659596Sbill yyerror("Rewrite of header fails"); 660596Sbill } 661596Sbill 662596Sbill delexit() 663596Sbill { 664596Sbill delete(); 665596Sbill if (passno == 2){ 666596Sbill unlink(outfile); 667596Sbill } 668596Sbill exit(1); 669596Sbill } 670596Sbill 671596Sbill delete() 672596Sbill { 67313512Srrh if (useVM == 0 || tokfilename[0]) 67413512Srrh unlink(tokfilename); 67513512Srrh if (strfilename[0]) 67613512Srrh unlink(strfilename); 677596Sbill } 678596Sbill 679596Sbill sawabort() 680596Sbill { 681596Sbill char *fillinbuffer(); 682596Sbill while (fillinbuffer() != (char *)0) 683596Sbill continue; 684596Sbill delete(); 685596Sbill exit(1); /*although the previous pass will also exit non zero*/ 686596Sbill } 687596Sbill 688596Sbill panic(fmt, a1, a2, a3, a4) 689596Sbill char *fmt; 690596Sbill /*VARARGS 1*/ 691596Sbill { 692596Sbill yyerror("Assembler panic: bad internal data structure."); 693596Sbill yyerror(fmt, a1, a2, a3, a4); 694596Sbill delete(); 695596Sbill abort(); 696596Sbill } 697