|
|
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.