|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include <stdio.h>
3: #include <signal.h>
4:
5: #include "as.h"
6: #include "assyms.h"
7: #include "asexpr.h"
8: #include "asscan.h"
9:
10: int curlen;
11: /*
12: * variables to manage the assembly input
13: */
14: char *dotsname; /*the current file name; managed by the parser*/
15: int lineno; /*current line number; managed by the parser*/
16: int silent; /*don't complain about any errors*/
17: int savelabels; /*write the labels to the a.out file*/
18:
19: #ifdef DEBUG
20: int debug;
21: int toktrace;
22: #endif
23:
24: long datbase;
25:
26: char *endcore; /*where to get more symbol space*/
27:
28: struct hdr hdr = {
29: 0410, 0, 0, 0, 0, 0, 0, 0,
30: };
31:
32: #ifndef vax
33: struct {short hiword; short loword;}; /* stupid fp-11 */
34: #else
35: #define writel(p,n,f) fwrite( (long) p, sizeof (long), n, f)
36: #endif
37:
38: char *tmpn1;
39: char *tmpn2;
40: char *tmpn3;
41:
42: struct exp usedot[NLOC+NLOC];
43:
44: FILE *usefile[NLOC+NLOC];
45: FILE *rusefile[NLOC+NLOC];
46: char sibuf[TOKBUFLG]; /*buffer used for all input*/
47: char sobuf[TOKBUFLG]; /*buffer used for all output*/
48: /*except stdout and relfil*/
49: char stdoutbuf[BUFSIZ]; /*stdout buffer*/
50:
51: extern int njxxx; /*number of jumpxxx instructs*/
52: extern int d124; /*allocate 1,2 or 4 bytes for unknowns*/
53:
54: int delexit();
55:
56: char *innames[32]; /*names of the files being assembled*/
57: int ninfiles; /*how many interesting files there are*/
58:
59: main(argc, argv)
60: int argc;
61: char **argv;
62: {
63: int locindex;
64: long v;
65: char *outfile = "a.out";
66: int filestep;
67: char *cp;
68:
69: setbuf(stdout, stdoutbuf);
70: ninfiles = 0;
71: silent = 0;
72: useVM = 0;
73: #ifdef DEBUG
74: debug = 0;
75: #endif
76: /*
77: * Give the error processor something to complain about
78: * if there is an error processing an argument
79: */
80: dotsname = "<argv error>";
81: while (argc > 1) {
82: if (argv[1][0] == '-'){
83: cp = argv[1] + 1;
84: /*
85: * We can throw away single minus signs, so
86: * that make scripts for the PDP 11 assembler work
87: * on this assembler too
88: */
89: while (*cp){
90: switch(*cp++){
91: default:
92: yyerror("Unknown flag: %c", *--cp);
93: cp++;
94: break;
95: case 'd':
96: d124 = *cp++ - '0';
97: if ( (d124 != 1) && (d124 != 2) &&
98: (d124 != 4)){
99: yyerror("-d[124] only");
100: exit(1);
101: }
102: break;
103: case 'o':
104: if (argc < 3){
105: yyerror("-o what???");
106: exit(1);
107: }
108: outfile = argv[2];
109: argc -= 2;
110: argv += 2;
111: goto nextarg;
112:
113: case 'V':
114: useVM = 1;
115: break;
116: #ifdef fooiearg
117: case 'M':
118: if (argc < 3){
119: yyerror("Mode what?");
120: exit(1);
121: }
122: hdr.magic = 0;
123: cp = argv[2];
124: while (*cp && ('0' <= *cp) && (*cp <= '7'))
125: hdr.magic = hdr.magic<<3 + *cp++ - '0';
126: argc -= 2;
127: argv += 2;
128: goto nextarg;
129: case 'W': silent = 1;
130: break;
131: #endif
132:
133: #ifdef DEBUG
134: case 'D': debug = 1;
135: break;
136: case 'T': toktrace = 1;
137: break;
138: #endif
139: #ifdef METRIC
140: case 'C': outcounters = 1;
141: break;
142: #endif
143: case 'L': savelabels = 1;
144: break;
145: } /*end of the switch*/
146: } /*end of pulling out all arguments*/
147: } /*end of a flag argument*/
148: else { /*file name*/
149: if (ninfiles > 32){
150: yyerror("More than 32 file names");
151: exit(3);
152: }
153: innames[ninfiles++] = argv[1];
154: }
155: --argc; ++argv;
156: nextarg:;
157: } /*end of looking at all of the arguments*/
158:
159: if (anyerrs)
160: exit(1);
161:
162: endcore = (char *)sbrk(0);
163:
164: /*
165: * Install symbols in the table
166: */
167: symtabinit();
168: syminstall();
169: /*
170: * mark usedot: first NLOC slots for named text segments,
171: * the next for named data segments.
172: */
173: for (locindex=0; locindex<NLOC; locindex++) {
174: usedot[locindex].xtype = XTEXT;
175: usedot[locindex+NLOC].xtype = XDATA;
176: }
177:
178: if (signal(SIGINT, SIG_IGN) != SIG_IGN)
179: signal(SIGINT, delexit);
180:
181: tmpn1 = (char *)mktemp("/tmp/asXXXXX");
182: tmpfil = fopen(tmpn1, "w");
183: if (tmpfil==NULL) {
184: yyerror("Bad pass 1 temporary file for writing %s", tmpn1);
185: delexit();
186: }
187: setbuf(tmpfil,sobuf);
188:
189: inittmpfile();
190: buildtokensets(); /*sets to implement expression lookahead*/
191:
192: if (ninfiles == 0){ /*take the input from stdin directly*/
193: setbuf(stdin, sibuf);
194: lineno = 1;
195: dotsname = "<stdin>";
196:
197: yyparse();
198: } else { /*we have the names tanked*/
199: for (filestep = 0; filestep < ninfiles; filestep++){
200: new_dot_s(innames[filestep]);
201: if (freopen(innames[filestep], "r", stdin) == NULL) {
202: yyerror( "Can't open source file %s\n",
203: innames[filestep]);
204: exit(2);
205: }
206: setbuf(stdin,sibuf);
207:
208: yyparse();
209: }
210: }
211:
212: closetmpfile(); /*kick out the last buffered intermediate text*/
213:
214: if (anyerrs)
215: delexit();
216:
217: /*
218: * Pass 1.5
219: */
220: sortsymtab();
221:
222: #ifdef DEBUG
223: if (debug)
224: dumpsymtab();
225: #endif
226:
227: jxxxfix();
228:
229: #ifdef DEBUG
230: if (debug)
231: dumpsymtab();
232: #endif
233:
234: #ifdef METRIC
235: lgtmpfile = ftell(tmpfil);
236: #endif
237:
238: fclose(tmpfil);
239: tmpfil = fopen(tmpn1, "r");
240: if (tmpfil==NULL) {
241: yyerror("Bad pass 2 temporary file for reading %s", tmpn1);
242: delexit();
243: }
244: setbuf(tmpfil,sibuf);
245:
246: /*
247: * round and assign text segment origins
248: */
249: tsize = 0;
250: for (locindex=0; locindex<NLOC; locindex++) {
251: v = round(usedot[locindex].xvalue, FW);
252: usedot[locindex].xvalue = tsize;
253: tsize += v;
254: }
255: /*
256: * round and assign data segment origins
257: */
258: datbase = round(tsize, PAGRND);
259: for (locindex=0; locindex<NLOC; locindex++) {
260: v = round(usedot[NLOC+locindex].xvalue, FW);
261: usedot[NLOC+locindex].xvalue = datbase+dsize;
262: dsize += v;
263: }
264:
265: hdr.bsize = dsize;
266:
267: /*
268: * Assign final values to symbols
269: */
270: freezesymtab();
271: stabfix();
272:
273: hdr.bsize -= dsize;
274:
275: txtfil = fopen(outfile, "w");
276: if (txtfil==NULL) {
277: yyerror("Cannot create %s", outfile);
278: delexit();
279: }
280: setbuf(txtfil,sobuf);
281:
282: usefile[0] = txtfil;
283:
284: tmpn2 = (char *)mktemp("/tmp/aaatXXXXX");
285: tmpn3 = (char *)mktemp("/tmp/abatXXXXX");
286:
287: relfil = fopen(tmpn3, "w");
288: if (relfil==NULL) {
289: yyerror("Bad temp file for writing extra text segments %s", tmpn3);
290: delexit();
291: }
292: rusefile[0] = relfil;
293:
294: hdr.tsize = tsize;
295: hdr.dsize = dsize;
296: hdr.ssize = sizesymtab();
297: /*
298: * hdr.trsize, hdr.drsize set by outrel
299: */
300:
301: /* *************** PASS 2 **************** */
302:
303: writel(&hdr,8,txtfil);
304: tsize = 0;
305: dsize = 0;
306: lineno = 1;
307: dotp = &usedot[0];
308: #ifdef DEBUG
309: if (debug)
310: printf("\n\n\n\t\tPASS 2\n\n\n\n");
311: #endif
312: passno = 2;
313: inittmpfile();
314:
315: yyparse();
316:
317: closetmpfile();
318:
319: /*
320: * round csects to FW
321: */
322: for (locindex=0; locindex<NLOC; locindex++) {
323: if (usefile[locindex]) {
324: txtfil=usefile[locindex];
325: dotp= &usedot[locindex];
326: while (usedot[locindex].xvalue & FW)
327: outb(0);
328: if (locindex>0)
329: fclose(usefile[locindex]);
330: fclose(rusefile[locindex]);
331: }
332: if (usefile[NLOC+locindex]) {
333: txtfil = usefile[NLOC+locindex];
334: dotp= &usedot[locindex+NLOC];
335: relfil = rusefile[NLOC+locindex];
336: while (usedot[locindex+NLOC].xvalue & FW)
337: outb(0);
338: fclose(txtfil);
339: fclose(relfil);
340: }
341: }
342:
343: txtfil = usefile[0];
344: /*
345: * append csect text onto text for csect 0
346: */
347: for (locindex=1; locindex<NLOC+NLOC; locindex++) {
348: char buffer[BUFSIZ];
349: if (usefile[locindex]) {
350: tmpn2[TMPC] = locindex+'a';
351: relfil = fopen(tmpn2, "r");
352: if (relfil==NULL) {
353: yyerror("cannot reopen temp");
354: continue;
355: }
356: while (!feof(relfil))
357: fwrite(buffer, 1,
358: fread(buffer, 1, BUFSIZ, relfil),
359: txtfil);
360: fclose(relfil);
361: }
362: }
363: /*
364: * append relocation info onto text
365: */
366: for (locindex=0; locindex<NLOC+NLOC; locindex++) {
367: char buffer[BUFSIZ];
368: if (rusefile[locindex]) {
369: tmpn3[TMPC] = locindex+'a';
370: relfil = fopen(tmpn3, "r");
371: if (relfil==NULL) {
372: yyerror("cannot reopen temp");
373: continue;
374: }
375: while (!feof(relfil))
376: fwrite(buffer, 1,
377: fread(buffer, 1, BUFSIZ, relfil),
378: txtfil);
379: fclose(relfil);
380: }
381: }
382:
383: symwrite(txtfil);
384: /*
385: * Go back and patch up rsize
386: */
387: fseek(txtfil,0L,0);
388: writel(&hdr,8,txtfil);
389:
390: delete();
391:
392: if (anyerrs==0 && orgwarn)
393: yyerror("Caution: absolute origins.\n");
394: #ifdef METRIC
395: pcounters();
396: #endif
397: exit(anyerrs!=0);
398: } /*end of main*/
399:
400:
401: delexit()
402: {
403: delete();
404: #ifdef METRIC
405: pcounters();
406: #endif
407: exit(1);
408: }
409:
410: sawabort()
411: {
412: char buffer[BUFSIZ];
413: #ifdef METRIC
414: pcounters();
415: #endif
416: while (!feof(stdin))
417: fread(buffer, 1, BUFSIZ, stdin);
418: delete();
419: exit(1); /*although the previous pass will also exit non zero*/
420: }
421:
422: delete()
423: {
424: register locindex;
425:
426: if (tmpn1)
427: unlink(tmpn1);
428: for (locindex=0; locindex<NLOC+NLOC; locindex++) {
429: if (tmpn2) {
430: tmpn2[TMPC] = locindex+'a';
431: unlink(tmpn2);
432: }
433: if (tmpn3) {
434: tmpn3[TMPC] = locindex+'a';
435: unlink(tmpn3);
436: }
437: }
438: }
439: #ifdef METRIC
440: pcounters()
441: {
442: int i;
443: struct {
444: long p_user;
445: long p_sys;
446: long c_user;
447: long c_sys;
448: } tbuffer;
449:
450: if (!outcounters) return;
451: printf("Assembly of files: ");
452: if (innames[0] == 0)
453: printf("<Standard Input.>\n");
454: else {
455: for (i = 0; i<ninfiles; i++)
456: printf("%s ", innames[i]);
457: printf("\n");
458: }
459: if (useVM)
460: printf("Using ");
461: else
462: printf("NOT using ");
463: printf("Virtual Memory for the interpass temporary file.\n");
464: printf("%d hashing collsions\n", nhcollisions);
465: printf("%d hash table accesses\n", nhashed);
466: printf("%d values entered in the hash table\n", nentered);
467: printf("%d byte length of the temporary file\n", lgtmpfile);
468: printf("%d symbols in the symbol table\n", nsyms);
469: printf("%d labels in the symbol table\n", nlabels);
470: printf("%d forgotten symbols\n", nforgotten);
471: printf("%d iterations through all symbols to remove jxxxes\n",
472: jxxxiterate);
473: printf("%d jumps resolved via tunnelling\n", jxxxtunnel);
474: if (jxdeadlock)
475: printf("%d DEADLOCKED JXXXentries: Resolved by %s jumping\n",
476: jxdeadlock, nbadjxsegs == 0 ? "short" : "long");
477: if (nbadjxsegs)
478: printf("%d Segments with jxxx over aligns.\n",
479: nbadjxsegs);
480: times(&tbuffer);
481: printf("%1.2fu 1.2fs\n",
482: ((float)tbuffer.p_user)/60.0,
483: ((float)tbuffer.p_sys)/60.0);
484: }
485: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.