15826Srrh /* 25826Srrh * Copyright (c) 1982 Regents of the University of California 35826Srrh */ 45826Srrh #ifndef lint 5*6559Srrh static char sccsid[] = "@(#)asmain.c 4.10 04/17/82"; 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 17596Sbill #ifdef UNIX 18*6559Srrh #define unix_lang_name "VAX/UNIX Assembler V04/17/82 4.10" 19596Sbill #endif 20596Sbill 21596Sbill #ifdef VMS 22631Shenry #define vms_lang_name "VAX/VMS C Assembler V1.00" 23596Sbill #endif VMS 24596Sbill 25596Sbill /* 26596Sbill * variables to manage reading the assembly source files 27596Sbill */ 28596Sbill char *dotsname; /*the current file name; managed by the parser*/ 29596Sbill int lineno; /*current line number; managed by the parser*/ 30643Sbill char **innames; /*names of the files being assembled*/ 31596Sbill int ninfiles; /*how many interesting files there are*/ 32596Sbill /* 33596Sbill * Flags settable from the argv process argument list 34596Sbill */ 35596Sbill int silent = 0; /*don't complain about any errors*/ 36596Sbill int savelabels = 0; /*write the labels to the a.out file*/ 37596Sbill int d124 = 4; /*default allocate 4 bytes for unknown pointers*/ 38596Sbill int anyerrs = 0; /*no errors yet*/ 395826Srrh int anywarnings=0; /*no warnings yet*/ 40596Sbill int orgwarn = 0; /*Bad origins*/ 41596Sbill int passno = 1; /* current pass*/ 42636Shenry int jxxxJUMP = 0; /* in jxxxes that branch too far, use jmp instead of brw */ 43638Sbill int readonlydata = 0; /* initialzed data -> text space */ 44596Sbill 455826Srrh int nGHnumbers = 0; /* GH numbers used */ 465826Srrh int nGHopcodes = 0; /* GH opcodes used */ 475826Srrh int nnewopcodes = 0; /* new opcodes used */ 485826Srrh 49596Sbill #ifdef DEBUG 50596Sbill int debug = 0; 51596Sbill int toktrace = 0; 52596Sbill #endif 53596Sbill 54596Sbill int useVM = /*put the temp file in virtual memory*/ 55596Sbill #ifdef VMS 56596Sbill 1; /*VMS has virtual memory (duh)*/ 57596Sbill #endif VMS 58596Sbill #ifdef UNIX 59596Sbill 0; 60596Sbill #endif 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 /* 85596Sbill * The inter pass temporary 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 */ 89596Sbill FILE *tmpfil; /* interpass communication file */ 90596Sbill /* 91596Sbill * a.out is created during the second pass. 92596Sbill * It is opened by stdio, but is filled with the parallel 93596Sbill * block I/O library 94596Sbill */ 95596Sbill char *outfile = "a.out"; 96596Sbill FILE *a_out_file; 97596Sbill off_t a_out_off; /* cumulative offsets for segments */ 98596Sbill /* 99596Sbill * The logical files containing the assembled data for each of 100596Sbill * the text and data segments are 101596Sbill * managed by the parallel block I/O library. 102596Sbill * a.out is logically opened in many places at once to 103596Sbill * receive the assembled data from the various segments as 104596Sbill * it all trickles in, but is physically opened only once 105596Sbill * to minimize file overhead. 106596Sbill */ 107596Sbill BFILE *usefile[NLOC+NLOC]; /* text/data files */ 108596Sbill BFILE *txtfil; /* current text/data file */ 109596Sbill /* 110596Sbill * Relocation information is accumulated seperately for each 111596Sbill * segment. This is required by the old loader (from BTL), 112596Sbill * but not by the new loader (Bill Joy). 113596Sbill * 114596Sbill * However, the size of the relocation information can not be computed 115596Sbill * during or after the 1st pass because the ''absoluteness' of values 116596Sbill * is unknown until all locally declared symbols have been seen. 117596Sbill * Thus, the size of the relocation information is only 118596Sbill * known after the second pass is finished. 119596Sbill * This obviates the use of the block I/O 120596Sbill * library, which requires knowing the exact offsets in a.out. 121596Sbill * 122596Sbill * So, we save the relocation information internally (we don't 123596Sbill * go to internal files to minimize overhead). 124596Sbill * 125596Sbill * Empirically, we studied 259 files composing the system, 126596Sbill * two compilers and a compiler generator: (all of which have 127596Sbill * fairly large source files) 128596Sbill * 129596Sbill * Number of files = 259 130596Sbill * Number of non zero text reloc files: 233 131596Sbill * Number of non zero data reloc files: 53 132596Sbill * Average text relocation = 889 133596Sbill * Average data relocation = 346 134596Sbill * Number of files > BUFSIZ text relocation = 71 135596Sbill * Number of files > BUFSIZ data relocation = 6 136596Sbill * 137596Sbill * For compiled C code, there is usually one text segment and two 138596Sbill * data segments; we see that allocating our own buffers and 139596Sbill * doing our internal handling of relocation information will, 140596Sbill * on the average, not use more memory than taken up by the buffers 141596Sbill * allocated for doing file I/O in parallel to a number of file. 142596Sbill * 143596Sbill * If we are assembling with the -V option, we 144596Sbill * use the left over token buffers from the 2nd pass, 145596Sbill * otherwise, we create our own. 146596Sbill * 147596Sbill * When the 2nd pass is complete, closeoutrel flushes the token 148596Sbill * buffers out to a BFILE. 149596Sbill * 150596Sbill * The internals to relbufdesc are known only in assyms.c 151596Sbill * 152596Sbill * outrel constructs the relocation information. 153596Sbill * closeoutrel flushes the relocation information to relfil. 154596Sbill */ 155596Sbill struct relbufdesc *rusefile[NLOC+NLOC]; 156596Sbill struct relbufdesc *relfil; /* un concatnated relocation info */ 157596Sbill BFILE *relocfile; /* concatnated relocation info */ 158596Sbill /* 159596Sbill * Once the relocation information has been written, 160596Sbill * we can write out the symbol table using the Block I/O 161596Sbill * mechanisms, as we once again know the offsets into 162596Sbill * the a.out file. 163596Sbill * 164596Sbill * We use relfil to output the symbol table information. 165596Sbill */ 166596Sbill 167596Sbill char *tmpdirprefix = 168596Sbill #ifdef UNIX 169596Sbill "/tmp/"; 170596Sbill #else VMS 171596Sbill "/usr/tmp/"; 172596Sbill #endif 173596Sbill 174596Sbill #define TMP_SUFFIX "asXXXXXX" 175596Sbill char tmpn1[TNAMESIZE]; 176596Sbill 177596Sbill int delexit(); 178596Sbill 179596Sbill main(argc, argv) 180596Sbill int argc; 181596Sbill char **argv; 182596Sbill { 1835826Srrh char *sbrk(); 184596Sbill 185596Sbill tmpn1[0] = 0; 1865826Srrh endcore = sbrk(0); 187596Sbill 188596Sbill argprocess(argc, argv); /* process argument lists */ 189596Sbill if (anyerrs) exit(1); 190596Sbill 191596Sbill initialize(); 192596Sbill zeroorigins(); /* set origins to zero */ 193596Sbill zerolocals(); /* fix local label counters */ 194596Sbill 195596Sbill i_pass1(); /* open temp files, etc */ 196596Sbill pass1(); /* first pass through .s files */ 197596Sbill testlocals(); /* check for undefined locals */ 198596Sbill if (anyerrs) delexit(); 199596Sbill 200596Sbill pass1_5(); /* resolve jxxx */ 201596Sbill if (anyerrs) delexit(); 202596Sbill 203596Sbill open_a_out(); /* open a.out */ 204679Shenry roundsegments(); /* round segments to FW */ 205596Sbill build_hdr(); /* build initial header, and output */ 206596Sbill 207596Sbill i_pass2(); /* reopen temporary file, etc */ 208596Sbill pass2(); /* second pass through the virtual .s */ 209596Sbill if (anyerrs) delexit(); 210596Sbill 211679Shenry fillsegments(); /* fill segments with 0 to FW */ 212596Sbill reloc_syms(); /* dump relocation and symbol table */ 213596Sbill 214596Sbill delete(); /* remove tmp file */ 215596Sbill bflush(); /* close off block I/O view of a.out */ 216596Sbill fix_a_out(); /* add in text and data reloc counts */ 217596Sbill 218596Sbill if (anyerrs == 0 && orgwarn) 219596Sbill yyerror("Caution: absolute origins.\n"); 2205826Srrh 2215826Srrh if (nGHnumbers) 2225826Srrh yywarning("Caution: G or H format floating point numbers"); 2235826Srrh if (nGHopcodes) 2245826Srrh yywarning("Caution: G or H format floating point operators"); 2255826Srrh if (nnewopcodes) 2265826Srrh yywarning("Caution: New Opcodes"); 2275826Srrh if (nGHnumbers || nGHopcodes || nnewopcodes) 2285826Srrh yywarning("These are not defined for all implementations of the VAX architecture.\n"); 2295826Srrh 230596Sbill exit(anyerrs != 0); 231596Sbill } /*end of UNIX main*/ 232596Sbill 233596Sbill argprocess(argc, argv) 234596Sbill int argc; 235596Sbill char *argv[]; 236596Sbill { 237596Sbill register char *cp; 238596Sbill 239596Sbill ninfiles = 0; 240596Sbill silent = 0; 241596Sbill #ifdef DEBUG 242596Sbill debug = 0; 243596Sbill #endif 244643Sbill innames = (char **)ClearCalloc(argc+1, sizeof (innames[0])); 245596Sbill dotsname = "<argv error>"; 246596Sbill while (argc > 1) { 247643Sbill if (argv[1][0] != '-') 248643Sbill innames[ninfiles++] = argv[1]; 249643Sbill else { 250596Sbill cp = argv[1] + 1; 251596Sbill /* 252596Sbill * We can throw away single minus signs, so 253596Sbill * that make scripts for the PDP 11 assembler work 254596Sbill * on this assembler too 255596Sbill */ 256596Sbill while (*cp){ 257596Sbill switch(*cp++){ 258596Sbill default: 259596Sbill yyerror("Unknown flag: %c", *--cp); 260596Sbill cp++; 261596Sbill break; 262*6559Srrh case 'v': 263*6559Srrh selfwhat(stdout); 264*6559Srrh exit(1); 265596Sbill case 'd': 266596Sbill d124 = *cp++ - '0'; 267596Sbill if ( (d124 != 1) && (d124 != 2) && 268596Sbill (d124 != 4)){ 269596Sbill yyerror("-d[124] only"); 270596Sbill exit(1); 271596Sbill } 272596Sbill break; 273596Sbill case 'o': 274596Sbill if (argc < 3){ 275596Sbill yyerror("-o what???"); 276596Sbill exit(1); 277596Sbill } 278596Sbill outfile = argv[2]; 279596Sbill bumpone: 280596Sbill argc -= 2; 281596Sbill argv += 2; 282596Sbill goto nextarg; 283596Sbill 284596Sbill case 't': 285596Sbill if (argc < 3){ 286596Sbill yyerror("-t what???"); 287596Sbill exit(1); 288596Sbill } 289596Sbill tmpdirprefix = argv[2]; 290596Sbill goto bumpone; 291596Sbill 292596Sbill case 'V': 293596Sbill useVM = 1; 294596Sbill break; 295596Sbill case 'W': 296596Sbill silent = 1; 297596Sbill break; 298596Sbill case 'L': 299596Sbill savelabels = 1; 300596Sbill break; 301636Shenry case 'J': 302636Shenry jxxxJUMP = 1; 303636Shenry break; 304596Sbill #ifdef DEBUG 305596Sbill case 'D': 306596Sbill debug = 1; 307596Sbill break; 308596Sbill case 'T': 309596Sbill toktrace = 1; 310596Sbill break; 311596Sbill #endif 312638Sbill case 'R': 313638Sbill readonlydata = 1; 314638Sbill break; 315596Sbill } /*end of the switch*/ 316596Sbill } /*end of pulling out all arguments*/ 317596Sbill } /*end of a flag argument*/ 318596Sbill --argc; ++argv; 319596Sbill nextarg:; 320596Sbill } 321643Sbill /* innames[ninfiles] = 0; */ 322596Sbill } 323*6559Srrh /* 324*6559Srrh * poke through the data space and find all sccs identifiers. 325*6559Srrh * We assume: 326*6559Srrh * a) that extern char **environ; is the first thing in the bss 327*6559Srrh * segment (true, if one is using the new version of cmgt.crt0.c) 328*6559Srrh * b) that the sccsid's have not been put into text space. 329*6559Srrh */ 330*6559Srrh selfwhat(place) 331*6559Srrh FILE *place; 332*6559Srrh { 333*6559Srrh extern char **environ; 334*6559Srrh register char *ub; 335*6559Srrh register char *cp; 336*6559Srrh register char *pat; 337*6559Srrh char *sbrk(); 338596Sbill 339*6559Srrh for (cp = (char *)&environ, ub = sbrk(0); cp < ub; cp++){ 340*6559Srrh if (cp[0] != '@') continue; 341*6559Srrh if (cp[1] != '(') continue; 342*6559Srrh if (cp[2] != '#') continue; 343*6559Srrh if (cp[3] != ')') continue; 344*6559Srrh fputc('\t', place); 345*6559Srrh for (cp += 4; cp < ub; cp++){ 346*6559Srrh if (*cp == 0) break; 347*6559Srrh if (*cp == '>') break; 348*6559Srrh if (*cp == '\n') break; 349*6559Srrh fputc(*cp, place); 350*6559Srrh } 351*6559Srrh fputc('\n', place); 352*6559Srrh } 353*6559Srrh } 354*6559Srrh 355596Sbill initialize() 356596Sbill { 357596Sbill if (signal(SIGINT, SIG_IGN) != SIG_IGN) 358596Sbill signal(SIGINT, delexit); 359596Sbill /* 360596Sbill * Install symbols in the table 361596Sbill */ 362596Sbill symtabinit(); 363596Sbill syminstall(); 364596Sbill /* 365596Sbill * Build the expression parser accelerator token sets 366596Sbill */ 367596Sbill buildtokensets(); 368596Sbill } 369596Sbill 370596Sbill zeroorigins() 371596Sbill { 372596Sbill register int locindex; 373596Sbill /* 374596Sbill * Mark usedot: the first NLOC slots are for named text segments, 375596Sbill * the next for named data segments. 376596Sbill */ 377596Sbill for (locindex = 0; locindex < NLOC; locindex++){ 378631Shenry usedot[locindex].e_xtype = XTEXT; 379631Shenry usedot[NLOC + locindex].e_xtype = XDATA; 380631Shenry usedot[locindex].e_xvalue = 0; 381631Shenry usedot[NLOC + locindex].e_xvalue = 0; 382596Sbill } 383596Sbill } 384596Sbill 385596Sbill zerolocals() 386596Sbill { 387596Sbill register int i; 388596Sbill 389596Sbill for (i = 0; i <= 9; i++) { 390596Sbill lgensym[i] = 1; 391596Sbill genref[i] = 0; 392596Sbill } 393596Sbill } 394596Sbill 395596Sbill i_pass1() 396596Sbill { 397596Sbill if (useVM == 0){ 398596Sbill strcat(tmpn1, tmpdirprefix); 399644Shenry if (tmpdirprefix[strlen(tmpdirprefix)-1] != '/') 400644Shenry strcat(tmpn1, "/"); 4015826Srrh (void)strcat(tmpn1, TMP_SUFFIX); 4025826Srrh (void)mktemp(tmpn1); 403596Sbill tmpfil = fopen(tmpn1, "w"); 404596Sbill if (tmpfil==NULL) { 405596Sbill yyerror("Bad pass 1 temporary file for writing %s", tmpn1); 406596Sbill delexit(); 407596Sbill } 408596Sbill } 409596Sbill 410596Sbill inittmpfile(); 411636Shenry initijxxx(); 412596Sbill } 413596Sbill 414596Sbill pass1() 415596Sbill { 416596Sbill register int i; 417596Sbill 418596Sbill passno = 1; 419596Sbill dotp = &usedot[0]; 420596Sbill txtfil = (BFILE *)0; 421596Sbill relfil = (struct relbufdesc *)0; 422596Sbill 423596Sbill if (ninfiles == 0){ /*take the input from stdin directly*/ 424596Sbill lineno = 1; 425596Sbill dotsname = "<stdin>"; 426596Sbill 427596Sbill yyparse(); 428596Sbill } else { /*we have the names tanked*/ 429596Sbill for (i = 0; i < ninfiles; i++){ 430596Sbill new_dot_s(innames[i]); 431596Sbill if (freopen(innames[i], "r", stdin) == NULL) { 432596Sbill yyerror( "Can't open source file %s\n", 433596Sbill innames[i]); 434596Sbill exit(2); 435596Sbill } 436596Sbill /* stdio is NOT used to read the input characters */ 437596Sbill /* we use read directly, into our own buffers */ 438596Sbill yyparse(); 439596Sbill } 440596Sbill } 441596Sbill 442596Sbill closetmpfile(); /*kick out the last buffered intermediate text*/ 443596Sbill } 444596Sbill 445596Sbill testlocals() 446596Sbill { 447596Sbill register int i; 448596Sbill for (i = 0; i <= 9; i++) { 449596Sbill if (genref[i]) 450596Sbill yyerror("Reference to undefined local label %df", i); 451596Sbill lgensym[i] = 1; 452596Sbill genref[i] = 0; 453596Sbill } 454596Sbill } 455596Sbill 456596Sbill pass1_5() 457596Sbill { 458596Sbill sortsymtab(); 459596Sbill #ifdef DEBUG 460596Sbill if (debug) dumpsymtab(); 461596Sbill #endif 462596Sbill jxxxfix(); 463596Sbill #ifdef DEBUG 464596Sbill if (debug) dumpsymtab(); 465596Sbill #endif 466596Sbill } 467596Sbill 468596Sbill open_a_out() 469596Sbill { 470596Sbill /* 471596Sbill * Open up the a.out file now, and get set to build 472596Sbill * up offsets into it for all of the various text,data 473596Sbill * text relocation and data relocation segments. 474596Sbill */ 475596Sbill a_out_file = fopen(outfile, "w"); 476596Sbill if (a_out_file == NULL) { 477596Sbill yyerror("Cannot create %s", outfile); 478596Sbill delexit(); 479596Sbill } 480596Sbill biofd = a_out_file->_file; 481596Sbill a_out_off = 0; 482596Sbill } 483596Sbill 484596Sbill roundsegments() 485596Sbill { 486596Sbill register int locindex; 487596Sbill register long v; 488596Sbill /* 489596Sbill * round and assign text segment origins 490596Sbill * the exec header always goes in usefile[0] 491596Sbill */ 492596Sbill tsize = 0; 493596Sbill for (locindex=0; locindex<NLOC; locindex++) { 494679Shenry v = round(usedot[locindex].e_xvalue, FW); 495631Shenry usedot[locindex].e_xvalue = tsize; 496596Sbill if ((locindex == 0) || (v != 0) ){ 497596Sbill usefile[locindex] = (BFILE *)Calloc(1, sizeof(BFILE)); 498596Sbill bopen(usefile[locindex], a_out_off); 499596Sbill if (locindex == 0) 500596Sbill a_out_off = sizeof (struct exec); 501596Sbill } else { 502596Sbill usefile[locindex] = (BFILE *)-1; 503596Sbill } 504596Sbill tsize += v; 505596Sbill a_out_off += v; 506596Sbill } 507596Sbill /* 508596Sbill * Round and assign data segment origins. 509596Sbill */ 510679Shenry datbase = round(tsize, FW); 511596Sbill for (locindex=0; locindex<NLOC; locindex++) { 512679Shenry v = round(usedot[NLOC+locindex].e_xvalue, FW); 513631Shenry usedot[NLOC+locindex].e_xvalue = datbase + dsize; 514596Sbill if (v != 0){ 515596Sbill usefile[NLOC + locindex] = (BFILE *)Calloc(1,sizeof(BFILE)); 516596Sbill bopen(usefile[NLOC + locindex], a_out_off); 517596Sbill } else { 518596Sbill usefile[NLOC + locindex] = (BFILE *)-1; 519596Sbill } 520596Sbill dsize += v; 521596Sbill a_out_off += v; 522596Sbill } 523596Sbill /* 524596Sbill * Assign final values to symbols 525596Sbill */ 526596Sbill hdr.a_bss = dsize; 527596Sbill freezesymtab(); /* this touches hdr.a_bss */ 528596Sbill stabfix(); 529596Sbill /* 530596Sbill * Set up the relocation information "files" to 531596Sbill * be zero; outrel takes care of the rest 532596Sbill */ 533596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++){ 534596Sbill rusefile[locindex] = (struct relbufdesc *)0; 535596Sbill } 536596Sbill } 537596Sbill 538596Sbill build_hdr() 539596Sbill { 540596Sbill /* 541596Sbill * Except for the text and data relocation sizes, 542596Sbill * calculate the final values for the header 543596Sbill * 544596Sbill * Write out the initial copy; we to come 545596Sbill * back later and patch up a_trsize and a_drsize, 546596Sbill * and overwrite this first version of the header. 547596Sbill */ 548596Sbill hdr.a_magic = MAGIC; 549596Sbill hdr.a_text = tsize; 550596Sbill hdr.a_data = dsize; 551596Sbill hdr.a_bss -= dsize; 552596Sbill hdr.a_syms = sizesymtab(); /* Does not include string pool length */ 553596Sbill hdr.a_entry = 0; 554596Sbill hdr.a_trsize = 0; 555596Sbill hdr.a_drsize = 0; 556596Sbill 557596Sbill bwrite((char *)&hdr, sizeof(hdr), usefile[0]); 558596Sbill } 559596Sbill 560596Sbill i_pass2() 561596Sbill { 562596Sbill if (useVM == 0) { 563596Sbill fclose(tmpfil); 564596Sbill tmpfil = fopen(tmpn1, "r"); 565596Sbill if (tmpfil==NULL) { 566596Sbill yyerror("Bad pass 2 temporary file for reading %s", tmpn1); 567596Sbill delexit(); 568596Sbill } 569596Sbill } 570596Sbill } 571596Sbill 572596Sbill pass2() 573596Sbill { 574596Sbill #ifdef DEBUG 575596Sbill if (debug) 576596Sbill printf("\n\n\n\t\tPASS 2\n\n\n\n"); 577596Sbill #endif DEBUG 578596Sbill passno = 2; 579596Sbill lineno = 1; 580596Sbill dotp = &usedot[0]; 581596Sbill txtfil = usefile[0]; /* already opened (always!) */ 582596Sbill relfil = 0; /* outrel takes care of the rest */ 583596Sbill initoutrel(); 584596Sbill 585596Sbill inittmpfile(); 586596Sbill 587596Sbill yyparse(); 588596Sbill 589596Sbill closetmpfile(); 590596Sbill } 591596Sbill 592596Sbill fillsegments() 593596Sbill { 594596Sbill int locindex; 595596Sbill /* 596679Shenry * Round text and data segments to FW by appending zeros 597596Sbill */ 598596Sbill for (locindex = 0; locindex < NLOC + NLOC; locindex++) { 599596Sbill if (usefile[locindex]) { 600596Sbill txtfil = usefile[locindex]; 601596Sbill dotp = &usedot[locindex]; 602679Shenry while (usedot[locindex].e_xvalue & FW) 603596Sbill outb(0); 604596Sbill } 605596Sbill } 606596Sbill } 607596Sbill 608596Sbill reloc_syms() 609596Sbill { 610596Sbill u_long closerelfil(); 611596Sbill /* 612596Sbill * Move the relocation information to a.out 613596Sbill * a_out_off is the offset so far: 614596Sbill * exec + text segments + data segments 615596Sbill */ 616596Sbill relocfile = (BFILE *)Calloc(1,sizeof(BFILE)); 617596Sbill bopen(relocfile, a_out_off); 618596Sbill a_out_off += closeoutrel(relocfile); 619596Sbill 620596Sbill hdr.a_trsize = trsize; 621596Sbill hdr.a_drsize = drsize; 622638Sbill if (readonlydata) { 623638Sbill hdr.a_text += hdr.a_data; 624638Sbill hdr.a_data = 0; 625638Sbill hdr.a_trsize += hdr.a_drsize; 626638Sbill hdr.a_drsize = 0; 627638Sbill } 628596Sbill /* 629596Sbill * Output the symbol table 630596Sbill * and if FLEXNAMES is set, the string pool 631596Sbill */ 632596Sbill symwrite(relocfile); 633596Sbill } 634596Sbill 635596Sbill fix_a_out() 636596Sbill { 6375826Srrh if (lseek(a_out_file->_file, 0L, 0) < 0L) 638596Sbill yyerror("Reposition for header rewrite fails"); 639596Sbill if (write(a_out_file->_file, (char *)&hdr, sizeof (struct exec)) < 0) 640596Sbill yyerror("Rewrite of header fails"); 641596Sbill } 642596Sbill 643596Sbill delexit() 644596Sbill { 645596Sbill delete(); 646596Sbill if (passno == 2){ 647596Sbill unlink(outfile); 648596Sbill } 649596Sbill exit(1); 650596Sbill } 651596Sbill 652596Sbill delete() 653596Sbill { 654596Sbill if (useVM == 0 || tmpn1[0]) 655596Sbill unlink(tmpn1); 656596Sbill } 657596Sbill 658596Sbill sawabort() 659596Sbill { 660596Sbill char *fillinbuffer(); 661596Sbill while (fillinbuffer() != (char *)0) 662596Sbill continue; 663596Sbill delete(); 664596Sbill exit(1); /*although the previous pass will also exit non zero*/ 665596Sbill } 666596Sbill 667596Sbill panic(fmt, a1, a2, a3, a4) 668596Sbill char *fmt; 669596Sbill /*VARARGS 1*/ 670596Sbill { 671596Sbill yyerror("Assembler panic: bad internal data structure."); 672596Sbill yyerror(fmt, a1, a2, a3, a4); 673596Sbill delete(); 674596Sbill abort(); 675596Sbill } 676