|
|
1.1 root 1: static char *ID_pass1 = "@(#) pass1.c: 1.9 12/10/83";
2:
3: #include <stdio.h>
4: #include <ctype.h>
5: #include <signal.h>
6: #include <paths.h>
7: #include "systems.h"
8: #include "symbols.h"
9: #include "gendefs.h"
10:
11: /*
12: *
13: * "pass1.c" is a file containing the main routine for the first
14: * pass of the assembler. It is invoked with the command:
15: *
16: * as1 [flags] ifile ofile t1 t2 t3 t4 t5 t6 t7
17: *
18: * where {flags] are optional flags passed from pass 0,
19: * "ifile" is the name of the assembly language input file,
20: * "t1" through "t7" are the names of temporary files to be used
21: * by the assembler, and "ofile" is the file where the object code
22: * is to be written. Pass 1 of the assembler reads "ifile" and
23: * writes the temporary text section to "t1", the temporary data
24: * section to "t2", and the symbol table to "t3".
25: *
26: * The following things are done by this function:
27: *
28: * 1. Initialization. This consists of calling signal to catch
29: * interrupt signals for hang-up, break, and terminate. Then
30: * the argument list is processed by "getargs" followed by the
31: * initialization of the symbol table with mnemonics for
32: * instructions and pseudos-ops.
33: *
34: * 2. "yyparse" is called to do the actual first pass processing.
35: * This is followed by a call to "cgsect". Normally this
36: * function is used to change the section into which code
37: * is generated. In this case, it is only called to make
38: * sure that "dottxt", "dotdat", and "dotbss" contain the
39: * proper values for the program counters for the respective
40: * sections. The following symbols are then defined:
41: *
42: * .text This has a type of text and a value of zero.
43: * It is used to label the beginning of the text
44: * section, and later as a reference for relocation
45: * entries that are relative to the text section.
46: *
47: * .data This has a type of data and a value of zero.
48: * It is used to label the beginning of the data
49: * section, and later as a reference for relocation
50: * entries that are relative to the data section.
51: *
52: * .bss This has a type of bss and a value of zero. It
53: * is used to label the beginning of the bss
54: * section, and later as a reference for relocation
55: * entries that are relative to the bss section.
56: *
57: * (text) This is a totally internal symbol used to
58: * remember the size of the text section. It has
59: * characters in it that cannot legally be used in
60: * a symbol, and hence cannot be referenced or
61: * redefined by a user.
62: *
63: * (data) This is an internal symbol used to remember the
64: * size of the data section.
65: *
66: * (bss) This is an internal symbol used to remember the
67: * size of the bss section.
68: *
69: * (sdicnt) This is the internal symbol used to remember
70: * the number of span dependent instructions
71: * on which optimizations were performed.
72: *
73: * 3. The function "dmpstb" is called to dump the symbol
74: * table out to a temporary file to be used by pass 2 of
75: * the assembler.
76: *
77: * 4. The temporary files are closed and the next pass (if any)
78: * is called.
79: *
80: */
81:
82: #if ONEPROC
83: extern short passnbr;
84: #endif
85:
86: extern char file[];
87:
88: extern char *filenames[];
89:
90: extern unsigned short
91: line,
92: sdicnt;
93:
94:
95: #if DEBUG
96: extern unsigned
97: numcalls,
98: numids,
99: numcoll;
100: #endif
101:
102: extern short
103: anyerrs;
104:
105: extern int
106: aerror(),
107: delexit(),
108: #if !ONEPROC
109: dmpstb(),
110: #endif
111: fixsyms(),
112: flags(),
113: flushbuf(),
114: onintr();
115:
116: extern FILE
117: *fderr;
118:
119: #if !ONEPROC
120: extern FILE
121: *fdstab;
122: #endif
123:
124: extern upsymins
125: *lookup();
126:
127: extern long
128: #if MULTSECT
129: dottxt[4],
130: dotdat[4],
131: #else
132: dottxt,
133: dotdat,
134: #endif
135: dotbss;
136:
137: #if !ONEPROC
138: char *xargp[15];
139: #endif
140:
141: short opt = YES,
142: workaround = YES,
143: Oflag = NO;
144:
145: #if M4ON
146: extern short rflag;
147: #endif
148:
149: #if M32RSTFIX
150: short rstflag = YES;
151: #endif /* M32RSTFIX */
152: #if ONEPROC
153: extern short
154: transvec;
155: #else
156: short
157: transvec = NO,
158: argindex = 1;
159: #endif
160:
161: #if ONEPROC
162: extern long newdot;
163: extern symbol *dot;
164: #else
165: long newdot;
166: symbol *dot;
167: #endif
168:
169: FILE *fdin,
170: #if !ONEPROC
171: *fdstring,
172: *fdlong,
173: #endif
174: *fdtext,
175: #if MULTSECT
176: *fdtxt1,
177: *fdtxt2,
178: *fdtxt3,
179: *fddat1,
180: *fddat2,
181: *fddat3,
182: #endif
183: #if DEBUG
184: *perfile, /* performance data file descriptor */
185: #endif
186: *fddata,
187: *fdcomment;
188:
189: #if MULTSECT
190: add1text(ptr)
191: symbol *ptr;
192: {
193: addsect(ptr,TXT,1);
194: } /* add1text() */
195:
196:
197: add2text(ptr)
198: symbol *ptr;
199: {
200: addsect(ptr,TXT,2);
201: } /* add2text() */
202:
203:
204: add3text(ptr)
205: symbol *ptr;
206: {
207: addsect(ptr,TXT,3);
208: } /* add3text() */
209:
210:
211: add1data(ptr)
212: symbol *ptr;
213: {
214: addsect(ptr,DAT,1);
215: } /* add1data() */
216:
217:
218: add2data(ptr)
219: symbol *ptr;
220: {
221: addsect(ptr,DAT,2);
222: } /* add2data() */
223:
224:
225: add3data(ptr)
226: symbol *ptr;
227: {
228: addsect(ptr,DAT,3);
229: } /* add3data() */
230:
231: addsect(ptr,sectclass,sectnum)
232: symbol *ptr;
233: short sectclass,
234: sectnum;
235: {
236: if (((ptr->styp & TYPE) == sectclass) && (ptr->sectnum == sectnum))
237: ptr->value += (sectclass == TXT) ? dottxt[0] : dotdat[0];
238: } /* addsect() */
239:
240: #endif
241:
242: #if !ONEPROC
243: static char
244: nextpass[80];
245:
246: static char
247: teststr[4] = {'-','t','\0'};
248: #endif
249:
250: short tstlookup = NO;
251:
252: static short
253: #if !ONEPROC
254: filecnt = 0,
255: #endif
256: testas = TESTVAL;
257:
258: #if DEBUG
259: /*
260: * Performance data structure
261: */
262: long ttime;
263: struct tbuffer {
264: long proc_user_time;
265: long proc_system_time;
266: long child_user_time;
267: long child_system_time;
268: } ptimes;
269: extern long times();
270:
271: #endif
272: #if !ONEPROC
273: /*
274: *
275: * "getargs" is a general purpose argument parsing routine.
276: * It locates flags (identified by a preceding minus sign ('-'))
277: * and initializes any associated flags for the assembler.
278: * If there are any file names in the argument list, then a
279: * pointer to the name is stored in the array "filenames" for
280: * later use.
281: *
282: */
283:
284: getargs(xargc,xargv)
285: register int xargc;
286: register char **xargv;
287: {
288: register char ch;
289:
290: while (xargc-- > 0) {
291: if (**xargv == '-') {
292: while ((ch = *++*xargv) != '\0')
293: switch (ch) {
294: case 'n':
295: if( *++*xargv == 'f' ) {
296: /* -nf option; disable work arounds */
297: workaround = NO;
298: #if M32RSTFIX
299: rstflag = NO;
300: #endif /* M32RSTFIX */
301: } else { /* -n option */
302: opt = NO;
303: *--*xargv;
304: }
305: break;
306: #if DEBUG
307: case 'O':
308: Oflag = YES;
309: break;
310: #endif
311: #if M4ON
312: case 'R':
313: rflag = YES;
314: xargp[argindex++] = "-R";
315: break;
316: #endif
317: case 'd':
318: if (*++*xargv == 'l')
319: xargp[argindex++] = "-dl";
320: break;
321: case 't': {
322: ++*xargv;
323: #if TRANVEC
324: if (**xargv == 'v'){
325: transvec = YES;
326: xargp[argindex++]="-tv";
327: break;
328: }
329: #endif
330: if (isdigit(**xargv)) {
331: testas = **xargv - '0' -1;
332: if (testas > TESTVAL + 1) {
333: teststr[2] = (char)(testas + '0');
334: }
335: }
336: else {
337: --*xargv;
338: testas += 2;
339: }
340: xargp[argindex++] = teststr;
341: break;
342: }
343: #if DEBUG
344: case 'T': {
345: switch (*++*xargv) {
346: case 'L': {
347: tstlookup = YES;
348: break;
349: }
350: }
351: break;
352: }
353: #endif
354: #if M32RSTFIX
355: case 'r':
356: rstflag = NO;
357: break;
358: #endif /* M32RSTFIX */
359: default: {
360: /* installation dependent flag? */
361: flags(ch);
362: break;
363: }
364: }
365: xargv++;
366: }
367: else {
368: filenames[filecnt++] = *xargv++;
369: }
370: }
371: }
372:
373: main(argc,argv)
374: int argc;
375: char **argv;
376: #else
377:
378: aspass1()
379:
380: #endif
381: {
382: register short i;
383: register symbol *ptr;
384:
385: #if ONEPROC
386: passnbr = 1;
387: #endif
388: if (signal(SIGHUP,SIG_IGN) == SIG_DFL)
389: signal(SIGHUP,onintr);
390: if (signal(SIGINT,SIG_IGN) == SIG_DFL)
391: signal(SIGINT,onintr);
392: if (signal(SIGTERM,SIG_IGN) == SIG_DFL)
393: signal(SIGTERM,onintr);
394: fderr = stderr;
395:
396: #if DEBUG
397: /* Performance data collected */
398: ttime = times(&ptimes);
399: #endif
400:
401: #if !ONEPROC
402: strcpy(nextpass,argv[0]);
403: argv++;
404: argc--;
405: getargs(argc,argv);
406: if (filecnt < NFILES)
407: aerror("Illegal number of temporary files");
408: strcpy(file,filenames[0]);
409: #endif
410: if ((fdin = fopen(file, "r")) == NULL)
411: aerror("Unable to open input file");
412: if ((fdtext = fopen(filenames[2], "w")) == NULL)
413: aerror("Unable to open temporary (text) file");
414: #if MULTSECT
415: if ((fdtxt1 = fopen(filenames[9],"w")) == NULL)
416: aerror("Unable to open temporary (text 1) file");
417: if ((fdtxt2 = fopen(filenames[10],"w")) == NULL)
418: aerror("Unable to open temporary (text 2) file");
419: if ((fdtxt3 = fopen(filenames[11],"w")) == NULL)
420: aerror("Unable to open temporary (text 3) file");
421: if ((fddat1 = fopen(filenames[12],"w")) == NULL)
422: aerror("Unable to open temporary (data 1) file");
423: if ((fddat2 = fopen(filenames[13],"w")) == NULL)
424: aerror("Unable to open temporary (data 2) file");
425: if ((fddat3 = fopen(filenames[14],"w")) == NULL)
426: aerror("Unable to open temporary (data 3) file");
427: #endif
428: if ((fddata = fopen(filenames[3], "w")) == NULL)
429: aerror("Unable to open temporary (data) file");
430: if ((fdcomment = fopen(filenames[8], "w")) == NULL)
431: aerror("Unable to open temporary (comment) file");
432: #if !ONEPROC
433: if ((fdstring = fopen(filenames[6], "w")) == NULL)
434: aerror("Unable to open temporary (string) file");
435: #endif
436: #if FLEXNAMES
437: strtabinit();
438: #endif
439: creasyms();
440: dot = (*lookup(".",INSTALL, USRNAME)).stp;
441: dot->styp = TXT;
442: dot->value = newdot = 0L;
443: #if MULTSECT
444: dot->sectnum = 0;
445: #endif
446: yyparse(); /* pass 1 */
447: fclose(fdin);
448: #if !ONEPROC
449: fflush(fdstring);
450: if (ferror(fdstring))
451: aerror("trouble writing; probably out of temp-file space");
452: fclose(fdstring);
453: #endif
454: #if MULTSECT
455: cgsect(TXT,0);
456: #else
457: cgsect(TXT);
458: #endif
459: flushbuf();
460: #if MULTSECT
461: fclose(fdtxt1);
462: fclose(fdtxt2);
463: fclose(fdtxt3);
464: fclose(fddat1);
465: fclose(fddat2);
466: fclose(fddat3);
467:
468: traverse(add1text);
469: dottxt[0] += dottxt[1];
470: traverse(add2text);
471: dottxt[0] += dottxt[2];
472: traverse(add3text);
473: dottxt[0] += dottxt[3];
474:
475: traverse(add1data);
476: dotdat[0] += dotdat[1];
477: traverse(add2data);
478: dotdat[0] += dotdat[2];
479: traverse(add3data);
480: dotdat[0] += dotdat[3];
481: #endif
482: fflush(fdtext);
483: if (ferror(fdtext))
484: aerror("trouble writing; probably out of temp-file space");
485: fclose(fdtext);
486: fflush(fddata);
487: if (ferror(fddata))
488: aerror("trouble writing; probably out of temp-file space");
489: fclose(fddata);
490: fflush(fdcomment);
491: if (ferror(fdcomment))
492: aerror("trouble writing; probably out of temp-file space");
493: fclose(fdcomment);
494:
495: #if !ONEPROC
496: if ((fdlong = fopen(filenames[5], "w")) == NULL)
497: aerror("Unable to open temporary (sdi) file");
498: #endif
499: fixsyms();
500: #if MULTSECT
501: cgsect(TXT,0);
502: #else
503: cgsect(TXT); /* update "dottxt" */
504: #endif
505: #if !ONEPROC
506: fflush(fdlong);
507: if (ferror(fdlong))
508: aerror("trouble writing; probably out of temp-file space");
509: fclose(fdlong);
510: #endif
511:
512: ptr = (*lookup(".text", INSTALL, USRNAME)).stp;
513: ptr->styp = TXT;
514: ptr->value = 0L;
515: ptr = (*lookup("(text)", INSTALL, USRNAME)).stp;
516: ptr->styp = TXT;
517: #if MULTSECT
518: ptr->value = dottxt[0];
519: #else
520: ptr->value = dottxt;
521: #endif
522: ptr = (*lookup(".data", INSTALL, USRNAME)).stp;
523: ptr->styp = DAT;
524: ptr->value = 0L;
525: ptr = (*lookup("(data)", INSTALL, USRNAME)).stp;
526: ptr->styp = DAT;
527: #if MULTSECT
528: ptr->value = dotdat[0];
529: #else
530: ptr->value = dotdat;
531: #endif
532: ptr = (*lookup(".bss", INSTALL, USRNAME)).stp;
533: ptr->styp = BSS;
534: ptr->value = 0L;
535: ptr = (*lookup("(bss)", INSTALL, USRNAME)).stp;
536: ptr->styp = BSS;
537: ptr->value = dotbss;
538:
539: #if !ONEPROC
540: ptr = (*lookup("(sdicnt)",INSTALL,USRNAME)).stp;
541: ptr->value = (long)sdicnt; /* has to be set after fixsyms is called */
542: ptr->styp = ABS;
543:
544: if ((fdstab = fopen(filenames[4], "w")) == NULL)
545: aerror("Unable to open temporary (symtab) file");
546: dmpstb(); /* dump the symbol table for the next pass */
547: fflush(fdstab);
548: if (ferror(fdstab))
549: aerror("trouble writing; probably out of temp-file space");
550: fclose(fdstab);
551: #endif
552:
553: #if DEBUG
554: if (tstlookup) {
555: printf("Number of calls to lookup: %u\n",numcalls);
556: printf("Number of identifiers: %u\n",numids);
557: printf("Number of identifier collisions: %u\n",numcoll);
558: fflush(stdout);
559: }
560: /*
561: * Performance data collected and written out here
562: */
563:
564: ttime = times(&ptimes) - ttime;
565: if ((perfile = fopen("as.info", "r")) != NULL ) {
566: fclose(perfile);
567: if ((perfile = fopen("as.info", "a")) != NULL ) {
568: fprintf(perfile,
569: "as1\t%07ld\t%07ld\t%07ld\t%07ld\t%07ld\tpass 1\n",
570: ttime, ptimes);
571: fclose(perfile);
572: }
573: }
574:
575: #endif
576:
577: if (!anyerrs) {
578: #if ONEPROC
579: return(aspass2());
580: #else
581: nextpass[strlen(nextpass) - 1] = '2';
582: xargp[0] = nextpass;
583: for (i=0; i < filecnt; ++i)
584: xargp[argindex++] = filenames[i];
585: if (testas != TESTVAL + 1) {
586: if (testas > TESTVAL + 1){
587: execv(NAS2,xargp);
588: }
589: else
590: execv(AS2,xargp);
591: aerror("Unable to exec pass 2");
592: }
593: #endif
594: }
595: else {
596: delexit();
597: }
598: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.