Annotation of 3BSD/cmd/as/asmain.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.