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*44770Sbostic static char sccsid[] = "@(#)asmain.c 5.6 (Berkeley) 06/30/90";
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"
2537786Sbostic #include <paths.h>
26596Sbill
2716071Sralph #include <sys/stat.h>
2816071Sralph
29*44770Sbostic #define unix_lang_name "VAX/UNIX Assembler V06/30/90 5.6"
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 */
103*44770Sbostic 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
main(argc,argv)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
argprocess(argc,argv)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 }
286*44770Sbostic 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 */
selfwhat(place)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
initialize()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
zeroorigins()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
zerolocals()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
i_pass1()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
tempopen(tname,part)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
pass1()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
testlocals()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
pass1_5()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
open_a_out()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
roundsegments()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
build_hdr()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
i_pass2()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
pass2()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
fillsegments()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
reloc_syms()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
fix_a_out()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
delexit()678596Sbill delexit()
679596Sbill {
680596Sbill delete();
681596Sbill if (passno == 2){
682596Sbill unlink(outfile);
683596Sbill }
684596Sbill exit(1);
685596Sbill }
686596Sbill
delete()687596Sbill delete()
688596Sbill {
68913512Srrh if (useVM == 0 || tokfilename[0])
69013512Srrh unlink(tokfilename);
69113512Srrh if (strfilename[0])
69213512Srrh unlink(strfilename);
693596Sbill }
694596Sbill
sawabort()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
panic(fmt,a1,a2,a3,a4)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