15826Srrh /* 25826Srrh * Copyright (c) 1982 Regents of the University of California 35826Srrh */ 45826Srrh #ifndef lint 5*13521Srrh static char sccsid[] = "@(#)asmain.c 4.13 06/30/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*13521Srrh #define unix_lang_name "VAX/UNIX Assembler V06/30/83 4.13" 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*/ 31596Sbill int anyerrs = 0; /*no errors yet*/ 325826Srrh int anywarnings=0; /*no warnings yet*/ 33596Sbill int orgwarn = 0; /*Bad origins*/ 34596Sbill int passno = 1; /* current pass*/ 35636Shenry int jxxxJUMP = 0; /* in jxxxes that branch too far, use jmp instead of brw */ 36638Sbill int readonlydata = 0; /* initialzed data -> text space */ 37596Sbill 385826Srrh int nGHnumbers = 0; /* GH numbers used */ 395826Srrh int nGHopcodes = 0; /* GH opcodes used */ 405826Srrh int nnewopcodes = 0; /* new opcodes used */ 415826Srrh 42596Sbill #ifdef DEBUG 43596Sbill int debug = 0; 44596Sbill int toktrace = 0; 45596Sbill #endif 46596Sbill 4713518Srrh int useVM = 0; 48596Sbill 49596Sbill char *endcore; /*where to get more symbol space*/ 50596Sbill 51596Sbill /* 52596Sbill * Managers of the a.out file. 53596Sbill */ 54596Sbill struct exec hdr; 55638Sbill #define MAGIC 0407 56596Sbill u_long tsize; /* total text size */ 57596Sbill u_long dsize; /* total data size */ 58596Sbill u_long datbase; /* base of the data segment */ 59596Sbill u_long trsize; /* total text relocation size */ 60596Sbill u_long drsize; /* total data relocation size */ 61596Sbill 62596Sbill /* 63596Sbill * Information about the current segment is accumulated in 64596Sbill * usedot; the most important information stored is the 65596Sbill * accumulated size of each of the text and data segments 66596Sbill * 67596Sbill * dotp points to the correct usedot expression for the current segment 68596Sbill */ 69596Sbill struct exp usedot[NLOC+NLOC]; /* info about all segments */ 70596Sbill struct exp *dotp; /* data/text location pointer */ 71596Sbill /* 7213512Srrh * The inter pass temporary token file is opened and closed by stdio, but 73596Sbill * is written to using direct read/write, as the temporary file 74596Sbill * is composed of buffers exactly BUFSIZ long. 75596Sbill */ 7613512Srrh FILE *tokfile; /* interpass communication file */ 7713512Srrh char tokfilename[TNAMESIZE]; 78596Sbill /* 7913512Srrh * The string file is the string table 8013512Srrh * cat'ed to the end of the built up a.out file 8113512Srrh */ 8213512Srrh FILE *strfile; /* interpass string file */ 8313512Srrh char strfilename[TNAMESIZE]; 8413512Srrh int strfilepos = 0; /* position within the string file */ 8513512Srrh /* 86596Sbill * a.out is created during the second pass. 87596Sbill * It is opened by stdio, but is filled with the parallel 88596Sbill * block I/O library 89596Sbill */ 90596Sbill char *outfile = "a.out"; 91596Sbill FILE *a_out_file; 92596Sbill off_t a_out_off; /* cumulative offsets for segments */ 93596Sbill /* 94596Sbill * The logical files containing the assembled data for each of 95596Sbill * the text and data segments are 96596Sbill * managed by the parallel block I/O library. 97596Sbill * a.out is logically opened in many places at once to 98596Sbill * receive the assembled data from the various segments as 99596Sbill * it all trickles in, but is physically opened only once 100596Sbill * to minimize file overhead. 101596Sbill */ 102596Sbill BFILE *usefile[NLOC+NLOC]; /* text/data files */ 103596Sbill BFILE *txtfil; /* current text/data file */ 104596Sbill /* 105596Sbill * Relocation information is accumulated seperately for each 106596Sbill * segment. This is required by the old loader (from BTL), 107596Sbill * but not by the new loader (Bill Joy). 108596Sbill * 109596Sbill * However, the size of the relocation information can not be computed 110596Sbill * during or after the 1st pass because the ''absoluteness' of values 111596Sbill * is unknown until all locally declared symbols have been seen. 112596Sbill * Thus, the size of the relocation information is only 113596Sbill * known after the second pass is finished. 114596Sbill * This obviates the use of the block I/O 115596Sbill * library, which requires knowing the exact offsets in a.out. 116596Sbill * 117596Sbill * So, we save the relocation information internally (we don't 118596Sbill * go to internal files to minimize overhead). 119596Sbill * 120596Sbill * Empirically, we studied 259 files composing the system, 121596Sbill * two compilers and a compiler generator: (all of which have 122596Sbill * fairly large source files) 123596Sbill * 124596Sbill * Number of files = 259 125596Sbill * Number of non zero text reloc files: 233 126596Sbill * Number of non zero data reloc files: 53 127596Sbill * Average text relocation = 889 128596Sbill * Average data relocation = 346 129596Sbill * Number of files > BUFSIZ text relocation = 71 130596Sbill * Number of files > BUFSIZ data relocation = 6 131596Sbill * 132596Sbill * For compiled C code, there is usually one text segment and two 133596Sbill * data segments; we see that allocating our own buffers and 134596Sbill * doing our internal handling of relocation information will, 135596Sbill * on the average, not use more memory than taken up by the buffers 136596Sbill * allocated for doing file I/O in parallel to a number of file. 137596Sbill * 138596Sbill * If we are assembling with the -V option, we 139596Sbill * use the left over token buffers from the 2nd pass, 140596Sbill * otherwise, we create our own. 141596Sbill * 142596Sbill * When the 2nd pass is complete, closeoutrel flushes the token 143596Sbill * buffers out to a BFILE. 144596Sbill * 145596Sbill * The internals to relbufdesc are known only in assyms.c 146596Sbill * 147596Sbill * outrel constructs the relocation information. 148596Sbill * closeoutrel flushes the relocation information to relfil. 149596Sbill */ 150596Sbill struct relbufdesc *rusefile[NLOC+NLOC]; 151596Sbill struct relbufdesc *relfil; /* un concatnated relocation info */ 152596Sbill BFILE *relocfile; /* concatnated relocation info */ 153596Sbill /* 154596Sbill * Once the relocation information has been written, 155596Sbill * we can write out the symbol table using the Block I/O 156596Sbill * mechanisms, as we once again know the offsets into 157596Sbill * the a.out file. 158596Sbill * 159596Sbill * We use relfil to output the symbol table information. 160596Sbill */ 16113518Srrh char *tmpdirprefix = "/tmp/"; 162596Sbill int delexit(); 163596Sbill 164596Sbill main(argc, argv) 165596Sbill int argc; 166596Sbill char **argv; 167596Sbill { 1685826Srrh char *sbrk(); 169596Sbill 17013512Srrh tokfilename[0] = 0; 17113512Srrh strfilename[0] = 0; 1725826Srrh endcore = sbrk(0); 173596Sbill 174596Sbill argprocess(argc, argv); /* process argument lists */ 175596Sbill if (anyerrs) exit(1); 176596Sbill 177596Sbill initialize(); 178596Sbill zeroorigins(); /* set origins to zero */ 179596Sbill zerolocals(); /* fix local label counters */ 180596Sbill 181596Sbill i_pass1(); /* open temp files, etc */ 182596Sbill pass1(); /* first pass through .s files */ 183596Sbill testlocals(); /* check for undefined locals */ 184596Sbill if (anyerrs) delexit(); 185596Sbill 186596Sbill pass1_5(); /* resolve jxxx */ 187596Sbill if (anyerrs) delexit(); 188596Sbill 189596Sbill open_a_out(); /* open a.out */ 190679Shenry roundsegments(); /* round segments to FW */ 191596Sbill build_hdr(); /* build initial header, and output */ 192596Sbill 193596Sbill i_pass2(); /* reopen temporary file, etc */ 194596Sbill pass2(); /* second pass through the virtual .s */ 195596Sbill if (anyerrs) delexit(); 196596Sbill 197679Shenry fillsegments(); /* fill segments with 0 to FW */ 198596Sbill reloc_syms(); /* dump relocation and symbol table */ 199596Sbill 200596Sbill delete(); /* remove tmp file */ 201596Sbill bflush(); /* close off block I/O view of a.out */ 202596Sbill fix_a_out(); /* add in text and data reloc counts */ 203596Sbill 204596Sbill if (anyerrs == 0 && orgwarn) 205596Sbill yyerror("Caution: absolute origins.\n"); 2065826Srrh 2075826Srrh if (nGHnumbers) 2085826Srrh yywarning("Caution: G or H format floating point numbers"); 2095826Srrh if (nGHopcodes) 2105826Srrh yywarning("Caution: G or H format floating point operators"); 2115826Srrh if (nnewopcodes) 2125826Srrh yywarning("Caution: New Opcodes"); 2135826Srrh if (nGHnumbers || nGHopcodes || nnewopcodes) 2145826Srrh yywarning("These are not defined for all implementations of the VAX architecture.\n"); 2155826Srrh 216596Sbill exit(anyerrs != 0); 21713518Srrh } 218596Sbill 219596Sbill argprocess(argc, argv) 220596Sbill int argc; 221596Sbill char *argv[]; 222596Sbill { 223596Sbill register char *cp; 224596Sbill 225596Sbill ninfiles = 0; 226596Sbill silent = 0; 227596Sbill #ifdef DEBUG 228596Sbill debug = 0; 229596Sbill #endif 230643Sbill innames = (char **)ClearCalloc(argc+1, sizeof (innames[0])); 231596Sbill dotsname = "<argv error>"; 232596Sbill while (argc > 1) { 233643Sbill if (argv[1][0] != '-') 234643Sbill innames[ninfiles++] = argv[1]; 235643Sbill else { 236596Sbill cp = argv[1] + 1; 237596Sbill /* 238596Sbill * We can throw away single minus signs, so 239596Sbill * that make scripts for the PDP 11 assembler work 240596Sbill * on this assembler too 241596Sbill */ 242596Sbill while (*cp){ 243596Sbill switch(*cp++){ 244596Sbill default: 245596Sbill yyerror("Unknown flag: %c", *--cp); 246596Sbill cp++; 247596Sbill break; 2486559Srrh case 'v': 2496559Srrh selfwhat(stdout); 2506559Srrh exit(1); 251596Sbill case 'd': 252596Sbill d124 = *cp++ - '0'; 253596Sbill if ( (d124 != 1) && (d124 != 2) && 254596Sbill (d124 != 4)){ 255596Sbill yyerror("-d[124] only"); 256596Sbill exit(1); 257596Sbill } 258596Sbill break; 259596Sbill case 'o': 260596Sbill if (argc < 3){ 261596Sbill yyerror("-o what???"); 262596Sbill exit(1); 263596Sbill } 264596Sbill outfile = argv[2]; 265596Sbill bumpone: 266596Sbill argc -= 2; 267596Sbill argv += 2; 268596Sbill goto nextarg; 269596Sbill 270596Sbill case 't': 271596Sbill if (argc < 3){ 272596Sbill yyerror("-t what???"); 273596Sbill exit(1); 274596Sbill } 275596Sbill tmpdirprefix = argv[2]; 276596Sbill goto bumpone; 277596Sbill 278596Sbill case 'V': 279596Sbill useVM = 1; 280596Sbill break; 281596Sbill case 'W': 282596Sbill silent = 1; 283596Sbill break; 284596Sbill case 'L': 285596Sbill savelabels = 1; 286596Sbill break; 287636Shenry case 'J': 288636Shenry jxxxJUMP = 1; 289636Shenry break; 290596Sbill #ifdef DEBUG 291596Sbill case 'D': 292596Sbill debug = 1; 293596Sbill break; 294596Sbill case 'T': 295596Sbill toktrace = 1; 296596Sbill break; 297596Sbill #endif 298638Sbill case 'R': 299638Sbill readonlydata = 1; 300638Sbill break; 301596Sbill } /*end of the switch*/ 302596Sbill } /*end of pulling out all arguments*/ 303596Sbill } /*end of a flag argument*/ 304596Sbill --argc; ++argv; 305596Sbill nextarg:; 306596Sbill } 307643Sbill /* innames[ninfiles] = 0; */ 308596Sbill } 3096559Srrh /* 3106559Srrh * poke through the data space and find all sccs identifiers. 3116559Srrh * We assume: 3126559Srrh * a) that extern char **environ; is the first thing in the bss 3136559Srrh * segment (true, if one is using the new version of cmgt.crt0.c) 3146559Srrh * b) that the sccsid's have not been put into text space. 3156559Srrh */ 3166559Srrh selfwhat(place) 3176559Srrh FILE *place; 3186559Srrh { 3196559Srrh extern char **environ; 3206559Srrh register char *ub; 3216559Srrh register char *cp; 3226559Srrh register char *pat; 3236559Srrh char *sbrk(); 324596Sbill 3256559Srrh for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){ 3266559Srrh if (cp[0] != '@') continue; 3276559Srrh if (cp[1] != '(') continue; 3286559Srrh if (cp[2] != '#') continue; 3296559Srrh if (cp[3] != ')') continue; 3306559Srrh fputc('\t', place); 3316559Srrh for (cp += 4; cp < ub; cp++){ 3326559Srrh if (*cp == 0) break; 3336559Srrh if (*cp == '>') break; 3346559Srrh if (*cp == '\n') break; 3356559Srrh fputc(*cp, place); 3366559Srrh } 3376559Srrh fputc('\n', place); 3386559Srrh } 3396559Srrh } 3406559Srrh 341596Sbill initialize() 342596Sbill { 343596Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 344596Sbill signal(SIGINT, delexit); 345596Sbill /* 346596Sbill * Install symbols in the table 347596Sbill */ 348596Sbill symtabinit(); 349596Sbill syminstall(); 350596Sbill /* 351596Sbill * Build the expression parser accelerator token sets 352596Sbill */ 353596Sbill buildtokensets(); 354596Sbill } 355596Sbill 356596Sbill zeroorigins() 357596Sbill { 358596Sbill register int locindex; 359596Sbill /* 360596Sbill * Mark usedot: the first NLOC slots are for named text segments, 361596Sbill * the next for named data segments. 362596Sbill */ 363596Sbill for (locindex = 0; locindex < NLOC; locindex++){ 364631Shenry usedot[locindex].e_xtype = XTEXT; 365631Shenry usedot[NLOC + locindex].e_xtype = XDATA; 366631Shenry usedot[locindex].e_xvalue = 0; 367631Shenry usedot[NLOC + locindex].e_xvalue = 0; 368596Sbill } 369596Sbill } 370596Sbill 371596Sbill zerolocals() 372596Sbill { 373596Sbill register int i; 374596Sbill 375596Sbill for (i = 0; i <= 9; i++) { 376596Sbill lgensym[i] = 1; 377596Sbill genref[i] = 0; 378596Sbill } 379596Sbill } 380596Sbill 381596Sbill i_pass1() 382596Sbill { 38313512Srrh FILE *tempopen(); 38413512Srrh if (useVM == 0) 38513512Srrh tokfile = tempopen(tokfilename, "T"); 38613512Srrh strfile = tempopen(strfilename, "S"); 38713512Srrh /* 38813512Srrh * write out the string length. 38913512Srrh * This will be overwritten when the 39013512Srrh * strings are tacked onto the growing a.out file 39113512Srrh */ 39213512Srrh strfilepos = sizeof(int); 39313512Srrh fwrite(&strfilepos, sizeof(int), 1, strfile); 394596Sbill 39513512Srrh inittokfile(); 396636Shenry initijxxx(); 397596Sbill } 398596Sbill 39913512Srrh FILE *tempopen(tname, part) 40013512Srrh char *tname; 40113512Srrh char *part; 40213512Srrh { 40313512Srrh FILE *file; 40413512Srrh sprintf(tname, "%s%sas%s%05d", 40513512Srrh tmpdirprefix, 40613512Srrh (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') ? "/" : 0, 40713512Srrh part, 40813512Srrh getpid()); 40913512Srrh file = fopen(tname, "w"); 41013512Srrh if (file == NULL) { 41113512Srrh yyerror("Bad pass 1 temporary file for writing %s", tname); 41213512Srrh delexit(); 41313512Srrh } 41413512Srrh return(file); 41513512Srrh } 41613512Srrh 417596Sbill pass1() 418596Sbill { 419596Sbill register int i; 420596Sbill 421596Sbill passno = 1; 422596Sbill dotp = &usedot[0]; 423596Sbill txtfil = (BFILE *)0; 424596Sbill relfil = (struct relbufdesc *)0; 425596Sbill 426596Sbill if (ninfiles == 0){ /*take the input from stdin directly*/ 427596Sbill lineno = 1; 428596Sbill dotsname = "<stdin>"; 429596Sbill 430596Sbill yyparse(); 431596Sbill } else { /*we have the names tanked*/ 432596Sbill for (i = 0; i < ninfiles; i++){ 433596Sbill new_dot_s(innames[i]); 434596Sbill if (freopen(innames[i], "r", stdin) == NULL) { 435596Sbill yyerror( "Can't open source file %s\n", 436596Sbill innames[i]); 437596Sbill exit(2); 438596Sbill } 439596Sbill /* stdio is NOT used to read the input characters */ 440596Sbill /* we use read directly, into our own buffers */ 441596Sbill yyparse(); 442596Sbill } 443596Sbill } 444596Sbill 44513512Srrh closetokfile(); /*kick out the last buffered intermediate text*/ 446596Sbill } 447596Sbill 448596Sbill testlocals() 449596Sbill { 450596Sbill register int i; 451596Sbill for (i = 0; i <= 9; i++) { 452596Sbill if (genref[i]) 453596Sbill yyerror("Reference to undefined local label %df", i); 454596Sbill lgensym[i] = 1; 455596Sbill genref[i] = 0; 456596Sbill } 457596Sbill } 458596Sbill 459596Sbill pass1_5() 460596Sbill { 461596Sbill sortsymtab(); 462596Sbill #ifdef DEBUG 463596Sbill if (debug) dumpsymtab(); 464596Sbill #endif 465596Sbill jxxxfix(); 466596Sbill #ifdef DEBUG 467596Sbill if (debug) dumpsymtab(); 468596Sbill #endif 469596Sbill } 470596Sbill 471596Sbill open_a_out() 472596Sbill { 473596Sbill /* 474596Sbill * Open up the a.out file now, and get set to build 475596Sbill * up offsets into it for all of the various text,data 476596Sbill * text relocation and data relocation segments. 477596Sbill */ 478596Sbill a_out_file = fopen(outfile, "w"); 479596Sbill if (a_out_file == NULL) { 480596Sbill yyerror("Cannot create %s", outfile); 481596Sbill delexit(); 482596Sbill } 483596Sbill biofd = a_out_file->_file; 484596Sbill a_out_off = 0; 485596Sbill } 486596Sbill 487596Sbill roundsegments() 488596Sbill { 489596Sbill register int locindex; 490596Sbill register long v; 491596Sbill /* 492596Sbill * round and assign text segment origins 493596Sbill * the exec header always goes in usefile[0] 494596Sbill */ 495596Sbill tsize = 0; 496596Sbill for (locindex=0; locindex<NLOC; locindex++) { 497679Shenry v = round(usedot[locindex].e_xvalue, FW); 498631Shenry usedot[locindex].e_xvalue = tsize; 499596Sbill if ((locindex == 0) || (v != 0) ){ 500596Sbill usefile[locindex] = (BFILE *)Calloc(1, sizeof(BFILE)); 501596Sbill bopen(usefile[locindex], a_out_off); 502596Sbill if (locindex == 0) 503596Sbill a_out_off = sizeof (struct exec); 504596Sbill } else { 505596Sbill usefile[locindex] = (BFILE *)-1; 506596Sbill } 507596Sbill tsize += v; 508596Sbill a_out_off += v; 509596Sbill } 510596Sbill /* 511596Sbill * Round and assign data segment origins. 512596Sbill */ 513679Shenry datbase = round(tsize, FW); 514596Sbill for (locindex=0; locindex<NLOC; locindex++) { 515679Shenry v = round(usedot[NLOC+locindex].e_xvalue, FW); 516631Shenry usedot[NLOC+locindex].e_xvalue = datbase + dsize; 517596Sbill if (v != 0){ 518596Sbill usefile[NLOC + locindex] = (BFILE *)Calloc(1,sizeof(BFILE)); 519596Sbill bopen(usefile[NLOC + locindex], a_out_off); 520596Sbill } else { 521596Sbill usefile[NLOC + locindex] = (BFILE *)-1; 522596Sbill } 523596Sbill dsize += v; 524596Sbill a_out_off += v; 525596Sbill } 526596Sbill /* 527596Sbill * Assign final values to symbols 528596Sbill */ 529596Sbill hdr.a_bss = dsize; 530596Sbill freezesymtab(); /* this touches hdr.a_bss */ 531596Sbill stabfix(); 532596Sbill /* 533596Sbill * Set up the relocation information "files" to 534596Sbill * be zero; outrel takes care of the rest 535596Sbill */ 536596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++){ 537596Sbill rusefile[locindex] = (struct relbufdesc *)0; 538596Sbill } 539596Sbill } 540596Sbill 541596Sbill build_hdr() 542596Sbill { 543596Sbill /* 544596Sbill * Except for the text and data relocation sizes, 545596Sbill * calculate the final values for the header 546596Sbill * 547596Sbill * Write out the initial copy; we to come 548596Sbill * back later and patch up a_trsize and a_drsize, 549596Sbill * and overwrite this first version of the header. 550596Sbill */ 551596Sbill hdr.a_magic = MAGIC; 552596Sbill hdr.a_text = tsize; 553596Sbill hdr.a_data = dsize; 554596Sbill hdr.a_bss -= dsize; 555596Sbill hdr.a_syms = sizesymtab(); /* Does not include string pool length */ 556596Sbill hdr.a_entry = 0; 557596Sbill hdr.a_trsize = 0; 558596Sbill hdr.a_drsize = 0; 559596Sbill 560596Sbill bwrite((char *)&hdr, sizeof(hdr), usefile[0]); 561596Sbill } 562596Sbill 563596Sbill i_pass2() 564596Sbill { 565596Sbill if (useVM == 0) { 56613512Srrh fclose(tokfile); 56713512Srrh tokfile = fopen(tokfilename, "r"); 56813512Srrh if (tokfile==NULL) { 56913512Srrh yyerror("Bad pass 2 temporary file for reading %s", tokfilename); 570596Sbill delexit(); 571596Sbill } 572596Sbill } 57313512Srrh fclose(strfile); 57413512Srrh strfile = fopen(strfilename, "r"); 575596Sbill } 576596Sbill 577596Sbill pass2() 578596Sbill { 579596Sbill #ifdef DEBUG 580596Sbill if (debug) 581596Sbill printf("\n\n\n\t\tPASS 2\n\n\n\n"); 582596Sbill #endif DEBUG 583596Sbill passno = 2; 584596Sbill lineno = 1; 585596Sbill dotp = &usedot[0]; 586596Sbill txtfil = usefile[0]; /* already opened (always!) */ 587596Sbill relfil = 0; /* outrel takes care of the rest */ 588596Sbill initoutrel(); 589596Sbill 59013512Srrh inittokfile(); 591596Sbill 592596Sbill yyparse(); 593596Sbill 59413512Srrh closetokfile(); 595596Sbill } 596596Sbill 597596Sbill fillsegments() 598596Sbill { 599596Sbill int locindex; 600596Sbill /* 601679Shenry * Round text and data segments to FW by appending zeros 602596Sbill */ 603596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++) { 604596Sbill if (usefile[locindex]) { 605596Sbill txtfil = usefile[locindex]; 606596Sbill dotp = &usedot[locindex]; 607679Shenry while (usedot[locindex].e_xvalue & FW) 608596Sbill outb(0); 609596Sbill } 610596Sbill } 611596Sbill } 612596Sbill 613596Sbill reloc_syms() 614596Sbill { 615596Sbill u_long closerelfil(); 616596Sbill /* 617596Sbill * Move the relocation information to a.out 618596Sbill * a_out_off is the offset so far: 619596Sbill * exec + text segments + data segments 620596Sbill */ 621596Sbill relocfile = (BFILE *)Calloc(1,sizeof(BFILE)); 622596Sbill bopen(relocfile, a_out_off); 623596Sbill a_out_off += closeoutrel(relocfile); 624596Sbill 625596Sbill hdr.a_trsize = trsize; 626596Sbill hdr.a_drsize = drsize; 627638Sbill if (readonlydata) { 628638Sbill hdr.a_text += hdr.a_data; 629638Sbill hdr.a_data = 0; 630638Sbill hdr.a_trsize += hdr.a_drsize; 631638Sbill hdr.a_drsize = 0; 632638Sbill } 633596Sbill /* 634*13521Srrh * Output the symbol table and the string pool 63513512Srrh * 63613512Srrh * We must first rewind the string pool file to its beginning, 63713512Srrh * in case it was seek'ed into for fetching ascii and asciz 63813512Srrh * strings. 639596Sbill */ 64013512Srrh fseek(strfile, 0, 0); 641596Sbill symwrite(relocfile); 642596Sbill } 643596Sbill 644596Sbill fix_a_out() 645596Sbill { 6465826Srrh if (lseek(a_out_file->_file, 0L, 0) < 0L) 647596Sbill yyerror("Reposition for header rewrite fails"); 648596Sbill if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0) 649596Sbill yyerror("Rewrite of header fails"); 650596Sbill } 651596Sbill 652596Sbill delexit() 653596Sbill { 654596Sbill delete(); 655596Sbill if (passno == 2){ 656596Sbill unlink(outfile); 657596Sbill } 658596Sbill exit(1); 659596Sbill } 660596Sbill 661596Sbill delete() 662596Sbill { 66313512Srrh if (useVM == 0 || tokfilename[0]) 66413512Srrh unlink(tokfilename); 66513512Srrh if (strfilename[0]) 66613512Srrh unlink(strfilename); 667596Sbill } 668596Sbill 669596Sbill sawabort() 670596Sbill { 671596Sbill char *fillinbuffer(); 672596Sbill while (fillinbuffer() != (char *)0) 673596Sbill continue; 674596Sbill delete(); 675596Sbill exit(1); /*although the previous pass will also exit non zero*/ 676596Sbill } 677596Sbill 678596Sbill panic(fmt, a1, a2, a3, a4) 679596Sbill char *fmt; 680596Sbill /*VARARGS 1*/ 681596Sbill { 682596Sbill yyerror("Assembler panic: bad internal data structure."); 683596Sbill yyerror(fmt, a1, a2, a3, a4); 684596Sbill delete(); 685596Sbill abort(); 686596Sbill } 687