Annotation of GNUtools/cctools/as/as.c, revision 1.1

1.1     ! root        1: /* as.c - GAS main program.
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GAS, the GNU Assembler.
        !             5: 
        !             6: GAS is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 1, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GAS is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GAS; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: /*
        !            21:  * Main program for AS; a 32-bit assembler of GNU.
        !            22:  * Understands command arguments.
        !            23:  * Has a few routines that don't fit in other modules because they
        !            24:  * are shared.
        !            25:  *
        !            26:  *
        !            27:  *                     bugs
        !            28:  *
        !            29:  * : initialisers
        !            30:  *     Since no-one else says they will support them in future: I
        !            31:  * don't support them now.
        !            32:  *
        !            33:  */
        !            34: 
        !            35: #include <signal.h>
        !            36: #include <string.h>
        !            37: 
        !            38: #include "as.h"
        !            39: #include "input-scrub.h"
        !            40: #include "symbols.h"
        !            41: #include "sections.h"
        !            42: #include "read.h"
        !            43: #include "md.h"
        !            44: #include "messages.h"
        !            45: #include "xmalloc.h"
        !            46: #include "layout.h"
        !            47: #include "write_object.h"
        !            48: 
        !            49: /* ['x'] TRUE if "-x" seen. */
        !            50: char flagseen[128] = { 0 };
        !            51: 
        !            52: /* TRUE if -force_cpusubtype_ALL is specified */
        !            53: int force_cpusubtype_ALL = 0;
        !            54: 
        !            55: /* set to the corresponding cpusubtype if -arch flag is specified */
        !            56: cpu_subtype_t archflag_cpusubtype = -1;
        !            57: 
        !            58: /*
        !            59:  * .include "file" looks in source file dir, then stack.
        !            60:  * -I directories are added to the end, then the defaults are added.
        !            61:  */
        !            62: struct directory_stack include_defaults[] = {
        !            63:     { 0, "/NextDeveloper/Headers/" },
        !            64:     { 0, "/LocalDeveloper/Headers/" },
        !            65:     { 0, NULL }
        !            66: };
        !            67: struct directory_stack *include = NULL;        /* First dir to search */
        !            68: static struct directory_stack *include_tail = NULL;    /* Last in chain */
        !            69: 
        !            70: /* next_version is in next_version.c which is created by the Makefile */
        !            71: extern char next_version[];
        !            72: /* this is only used here, thus defined here (was in version.c in GAS) */
        !            73: static char version_string[] = "GNU assembler version 1.38\n";
        !            74: 
        !            75: /*
        !            76:  * The list of signals to catch if not ignored.
        !            77:  */
        !            78: static int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
        !            79: static void got_sig(
        !            80:     int sig);
        !            81: 
        !            82: static void perform_an_assembly_pass(
        !            83:     int argc,
        !            84:     char **argv);
        !            85: 
        !            86: void
        !            87: main(
        !            88: int argc,
        !            89: char **argv,
        !            90: char **envp)
        !            91: {
        !            92:     char *progname;    /* argv[0] */
        !            93:     int        work_argc;      /* variable copy of argc */
        !            94:     char **work_argv;  /* variable copy of argv */
        !            95:     char *arg;         /* an arg to program */
        !            96:     char a;            /* an arg flag (after -) */
        !            97:     char *out_file_name;/* name of object file, argument to -o if specified */
        !            98:     int i;
        !            99:     char *specific_archflag;
        !           100:     struct directory_stack *dirtmp;
        !           101: 
        !           102:        progname = argv[0];
        !           103: 
        !           104:        /*
        !           105:         * Set up to catch the signals listed in sig[] that are not ignored.
        !           106:         */
        !           107:        for(i = 0; sig[i] != 0; i++)
        !           108:            if(signal(sig[i], SIG_IGN) != SIG_IGN)
        !           109:                signal(sig[i], got_sig);
        !           110:        /*
        !           111:         * Set the default for the flags that will be parsed.
        !           112:         */
        !           113:        memset(flagseen, '\0', sizeof(flagseen)); /* aint seen nothing yet */
        !           114:        specific_archflag = NULL;
        !           115:        out_file_name = "a.out";        /* default .o file */
        !           116: 
        !           117:        /*
        !           118:         * Call the initialization routines.
        !           119:         */
        !           120:        check_for_ProjectBuilder();     /* messages.c */
        !           121:        symbol_begin();                 /* symbols.c */
        !           122:        sections_begin();               /* sections.c */
        !           123:        read_begin();                   /* read.c */
        !           124:        md_begin();                     /* MACHINE.c */
        !           125:        input_scrub_begin();            /* input_scrub.c */
        !           126: 
        !           127:        /*
        !           128:         * Parse arguments, but we are only interested in flags.
        !           129:         * When we find a flag, we process it then make it's argv[] NULL.
        !           130:         * This helps any future argv[] scanners avoid what we processed.
        !           131:         * Since it is easy to do here we interpret the special arg "-"
        !           132:         * to mean "use stdin" and we set that argv[] pointing to "".
        !           133:         * After we have munged argv[], the only things left are source file
        !           134:         * name(s) and ""(s) denoting stdin. These file names are used
        !           135:         * (perhaps more than once) later.
        !           136:         */
        !           137:        work_argc = argc - 1;           /* don't count argv[0] */
        !           138:        work_argv = argv + 1;           /* skip argv[0] */
        !           139:        for( ; work_argc-- ; work_argv++){
        !           140: 
        !           141:            /* work_argv points to this argument */
        !           142:            arg = *work_argv;
        !           143: 
        !           144:            /* Filename. We need it later. */
        !           145:            if(*arg != '-')
        !           146:                continue;
        !           147: 
        !           148:            /* Keep scanning args looking for flags. */
        !           149:            if (arg[1] == '-' && arg[2] == 0) {
        !           150:                /* "--" as an argument means read STDIN */
        !           151:                /* on this scan, we don't want to think about filenames */
        !           152:                *work_argv = "";        /* Code that means 'use stdin'. */
        !           153:                continue;
        !           154:            }
        !           155: 
        !           156:            /* This better be a switch ( -l where l is a letter. */
        !           157:            arg++;              /* -> letter. */
        !           158: 
        !           159:            /* scan all the 1-char flags */
        !           160:            while((a = *arg)){
        !           161:                arg ++; /* arg -> after letter. */
        !           162:                a &= 0x7F;      /* ascii only please */
        !           163:                if(flagseen[(int)a] && (a != 'I') && (a != 'a') && (a != 'f'))
        !           164:                        as_warn("%s: Flag option -%c has already been seen!",
        !           165:                                progname, a);
        !           166:                if(a != 'f')
        !           167:                    flagseen[(int)a] = TRUE;
        !           168:                switch(a){
        !           169:                case 'f':
        !           170:                    if(strcmp(arg-1, "force_cpusubtype_ALL") == 0){
        !           171:                        force_cpusubtype_ALL = 1;
        !           172:                        arg = "";       /* Finished with this arg. */
        !           173:                        break;
        !           174:                    }
        !           175:                    /* -f means fast - no need for "app" preprocessor. */
        !           176:                    flagseen[(int)a] = TRUE;
        !           177:                    break;
        !           178: 
        !           179:                case 'L': /* -L means keep L* symbols */
        !           180:                    break;
        !           181: 
        !           182:                case 'o':
        !           183:                    if(*arg != '\0') /* Rest of argument is object file-name. */
        !           184:                        out_file_name = arg;
        !           185:                    else if(work_argc){ /* Want next arg for a file-name. */
        !           186:                        *work_argv = NULL; /* This is not a file-name. */
        !           187:                        work_argc--;
        !           188:                        out_file_name = *++work_argv;
        !           189:                    }
        !           190:                    else
        !           191:                        as_warn("%s: I expected a filename after -o. \"%s\" "
        !           192:                                "assumed.", progname, out_file_name);
        !           193:                    arg = "";   /* Finished with this arg. */
        !           194:                    break;
        !           195: 
        !           196:                case 'R':
        !           197:                    /* -R means put data into text segment */
        !           198:                    as_warn("%s: -R option not supported (use the "
        !           199:                            ".const directive)", progname);
        !           200:                    flagseen['R'] = FALSE;
        !           201:                    break;
        !           202: 
        !           203:                case 'v':
        !           204:                    fprintf(stderr,"NeXT Computer, Inc. version "
        !           205:                            "%s, ", next_version);
        !           206:                    fprintf(stderr, version_string);
        !           207:                    if(*arg && strcmp(arg,"ersion"))
        !           208:                        as_warn("Unknown -v option ignored");
        !           209:                    while(*arg)
        !           210:                        arg++;  /* Skip the rest */
        !           211:                    break;
        !           212: 
        !           213:                case 'W':
        !           214:                    /* -W means don't warn about things */
        !           215:                    break;
        !           216: 
        !           217:                case 'I':
        !           218:                    /* Add directory to path for includes */
        !           219:                    dirtmp = (struct directory_stack *)
        !           220:                        xmalloc(sizeof(struct directory_stack));
        !           221:                    /* New one goes on the end */
        !           222:                    dirtmp->next = 0;
        !           223:                    if(include == 0)
        !           224:                        include = dirtmp;
        !           225:                    else
        !           226:                        include_tail->next = dirtmp;
        !           227:                    /* Tail follows the last one */
        !           228:                    include_tail = dirtmp;
        !           229:                    /* Rest of argument is include file-name. */
        !           230:                    if(*arg)
        !           231:                        dirtmp->fname = arg;
        !           232:                    else if (work_argc){
        !           233:                        /* Want next arg for a file-name. */
        !           234:                        /* This is not a file-name. */
        !           235:                        *work_argv = NULL;
        !           236:                        work_argc--;
        !           237:                        dirtmp->fname = *++work_argv;
        !           238:                    }
        !           239:                    else
        !           240:                        as_warn("I expected a filename after -I.");
        !           241:                    arg = "";   /* Finished with this arg. */
        !           242:                    break;
        !           243: 
        !           244:                case 'g':
        !           245:                    /* generate stabs for debugging assembly code */
        !           246:                    break;
        !           247: 
        !           248:                case 'n':
        !           249:                    /* no default .text section */
        !           250:                    break;
        !           251: 
        !           252:                case 'd':
        !           253:                    if(strcmp(arg-1, "dynamic") == 0){
        !           254:                        arg = "";       /* Finished with this arg. */
        !           255:                        flagseen[(int)'k'] = TRUE;
        !           256:                        break;
        !           257:                    }
        !           258:                    goto unknown_flag;
        !           259: 
        !           260:                case 's':
        !           261:                    if(strcmp(arg-1, "static") == 0){
        !           262:                        arg = "";       /* Finished with this arg. */
        !           263:                        flagseen[(int)'k'] = FALSE;
        !           264:                        break;
        !           265:                    }
        !           266:                    goto unknown_flag;
        !           267: 
        !           268:                case 'N':
        !           269:                    if(strcmp(arg-1, "NEXTSTEP-deployment-target") == 0){
        !           270:                        arg = "";       /* Finished with this arg. */
        !           271:                        /* Want next arg for a <release_tag> */
        !           272:                        if(work_argc){
        !           273:                            /* This, "-NEXTST..." is not a file-name. */
        !           274:                            *work_argv = NULL;
        !           275:                            work_argc--;
        !           276:                            work_argv++;
        !           277:                            if(strcmp(*work_argv, "3.3") == 0){
        !           278:                                flagseen[(int)'k'] = TRUE;
        !           279:                            }
        !           280:                            else if(strcmp(*work_argv, "3.2") == 0){
        !           281:                                flagseen[(int)'k'] = FALSE;
        !           282:                            }
        !           283:                            else{
        !           284:                                as_fatal("I expected '3.2' or '3.3' after "
        !           285:                                    "-NEXTSTEP-deployment-target.");
        !           286:                            }
        !           287:                        }
        !           288:                        else
        !           289:                            as_fatal("I expected a <release_tag> "
        !           290:                                     "after -NEXTSTEP-deployment-target.");
        !           291:                        break;
        !           292:                    }
        !           293:                    goto unknown_flag;
        !           294: 
        !           295:                case 'k':
        !           296:                    /* use new features incompatible with 3.2 */
        !           297:                    break;
        !           298: 
        !           299:                case 'V':
        !           300:                    /* as driver's -V, verbose, flag */
        !           301:                    break;
        !           302: 
        !           303:                case 'a':
        !           304:                    if(strcmp(arg-1, "arch_multiple") == 0){
        !           305:                        arch_multiple = 1;
        !           306:                        arg = "";       /* Finished with this arg. */
        !           307:                        break;
        !           308:                    }
        !           309:                    else if(strcmp(arg-1, "arch") == 0){
        !           310:                        arg = "";       /* Finished with this arg. */
        !           311:                        /* Want next arg for a <arch_type> */
        !           312:                        if(work_argc){
        !           313:                            /* This, "-arch" is not a file-name. */
        !           314:                            *work_argv = NULL;
        !           315:                            work_argc--;
        !           316:                            work_argv++;
        !           317: #ifdef M68K
        !           318:                            if(strcmp(*work_argv, "m68030") == 0){
        !           319:                                if(archflag_cpusubtype != -1 &&
        !           320:                                   archflag_cpusubtype !=
        !           321:                                    CPU_SUBTYPE_MC68030_ONLY)
        !           322:                                    as_fatal("can't specify both "
        !           323:                                        "-arch m68030 and -arch "
        !           324:                                        "m68040");
        !           325:                                specific_archflag = *work_argv;
        !           326:                                archflag_cpusubtype =
        !           327:                                    CPU_SUBTYPE_MC68030_ONLY;
        !           328:                            }
        !           329:                            else if(strcmp(*work_argv,
        !           330:                                            "m68040") == 0){
        !           331:                                if(archflag_cpusubtype != -1 &&
        !           332:                                   archflag_cpusubtype !=
        !           333:                                    CPU_SUBTYPE_MC68040)
        !           334:                                    as_fatal("can't specify both "
        !           335:                                        "-arch m68030 and -arch "
        !           336:                                        "m68040");
        !           337:                                specific_archflag = *work_argv;
        !           338:                                archflag_cpusubtype =
        !           339:                                    CPU_SUBTYPE_MC68040;
        !           340:                            }
        !           341:                            else if(strcmp(*work_argv, "m68k") != 0)
        !           342:                                as_fatal("I expected 'm68k', "
        !           343:                                    "'m68030' or 'm68040' after "
        !           344:                                    "-arch for this assembler.");
        !           345: #endif
        !           346: #ifdef M88K
        !           347:                            if(strcmp(*work_argv, "m88k") != 0)
        !           348:                                as_fatal("I expected 'm88k' after "
        !           349:                                       "-arch for this assembler.");
        !           350: #endif
        !           351: #ifdef I860
        !           352:                            if(strcmp(*work_argv, "i860") != 0)
        !           353:                                as_fatal("I expected 'i860' after "
        !           354:                                       "-arch for this assembler.");
        !           355: #endif
        !           356: #ifdef I386
        !           357:                            if(strcmp(*work_argv, "i486") == 0){
        !           358:                                if(archflag_cpusubtype != -1 &&
        !           359:                                   archflag_cpusubtype !=
        !           360:                                        CPU_SUBTYPE_486)
        !           361:                                    as_fatal("can't specify more "
        !           362:                                       "than one -arch flag ");
        !           363:                                specific_archflag = *work_argv;
        !           364:                                archflag_cpusubtype =
        !           365:                                    CPU_SUBTYPE_486;
        !           366:                            }
        !           367:                            else if(strcmp(*work_argv,
        !           368:                                           "i486SX") == 0){
        !           369:                                if(archflag_cpusubtype != -1 &&
        !           370:                                   archflag_cpusubtype !=
        !           371:                                        CPU_SUBTYPE_486SX)
        !           372:                                    as_fatal("can't specify more "
        !           373:                                       "than one -arch flag ");
        !           374:                                specific_archflag = *work_argv;
        !           375:                                archflag_cpusubtype =
        !           376:                                    CPU_SUBTYPE_486SX;
        !           377:                            }
        !           378:                            else if(strcmp(*work_argv, "i586") ==0){
        !           379:                                if(archflag_cpusubtype != -1 &&
        !           380:                                   archflag_cpusubtype !=
        !           381:                                        CPU_SUBTYPE_586)
        !           382:                                    as_fatal("can't specify more "
        !           383:                                       "than one -arch flag ");
        !           384:                                specific_archflag = *work_argv;
        !           385:                                archflag_cpusubtype =
        !           386:                                    CPU_SUBTYPE_586;
        !           387:                            }
        !           388:                            else if(strcmp(*work_argv,
        !           389:                                           "i586SX") == 0){
        !           390:                                if(archflag_cpusubtype != -1 &&
        !           391:                                   archflag_cpusubtype !=
        !           392:                                        CPU_SUBTYPE_586SX)
        !           393:                                    as_fatal("can't specify more "
        !           394:                                       "than one -arch flag ");
        !           395:                                specific_archflag = *work_argv;
        !           396:                                archflag_cpusubtype =
        !           397:                                    CPU_SUBTYPE_586SX;
        !           398:                            }
        !           399:                            else if(strcmp(*work_argv, "i386") != 0)
        !           400:                                as_fatal("I expected 'i386', 'i486'"
        !           401:                                   " 'i486SX', 'i586' or 'i586SX' "
        !           402:                                   "after -arch for this "
        !           403:                                   "assembler.");
        !           404: #endif
        !           405: #ifdef HPPA
        !           406:                            if(strcmp(*work_argv, "hppa") != 0)
        !           407:                                as_fatal("I expected 'hppa' after "
        !           408:                                         "-arch for this assembler.");
        !           409: #endif
        !           410: #ifdef SPARC
        !           411:                            if(strcmp(*work_argv, "sparc") != 0)
        !           412:                                as_fatal("I expected 'sparc' after "
        !           413:                                         "-arch for this assembler.");
        !           414: #endif
        !           415:                        }
        !           416:                        else
        !           417:                            as_fatal("I expected an <arch_type> "
        !           418:                                     "after -arch.");
        !           419:                        break;
        !           420:                    }
        !           421:                    /* fall through for non -arch flag */
        !           422:                default:
        !           423: unknown_flag:
        !           424:                    --arg;
        !           425:                    if(md_parse_option(&arg, &work_argc, &work_argv) == 0)
        !           426:                        as_warn("%s: I don't understand '%c' flag!", progname,
        !           427:                                a);
        !           428:                    if(arg && *arg)
        !           429:                        arg++;
        !           430:                    break;
        !           431:                }
        !           432:            }
        !           433:            /*
        !           434:             * We have just processed a "-..." arg, which was not a
        !           435:             * file-name. Smash it so the
        !           436:             * things that look for filenames won't ever see it.
        !           437:             *
        !           438:             * Whatever work_argv points to, it has already been used
        !           439:             * as part of a flag, so DON'T re-use it as a filename.
        !           440:             */
        !           441:            *work_argv = NULL; /* NULL means 'not a file-name' */
        !           442:        }
        !           443:        if(flagseen['g'] == TRUE && flagseen['n'] == TRUE)
        !           444:            as_fatal("-g can't be specified if -n is specified");
        !           445:        /*
        !           446:         * If we haven't seen a -force_cpusubtype_ALL or an -arch flag for a
        !           447:         * specific architecture then let the machine instructions in the
        !           448:         * assembly determine the cpusubtype of the output file.
        !           449:         */
        !           450:        if(force_cpusubtype_ALL && specific_archflag)
        !           451:            archflag_cpusubtype = -1;
        !           452: 
        !           453:        /* Here with flags set up in flagseen[]. */
        !           454:        perform_an_assembly_pass(argc, argv); /* Assemble it. */
        !           455: 
        !           456:        if(seen_at_least_1_file() && bad_error != TRUE){
        !           457:            layout_addresses();
        !           458:            write_object(out_file_name);
        !           459:        }
        !           460: 
        !           461:        input_scrub_end();
        !           462:        md_end();                       /* MACHINE.c */
        !           463: 
        !           464:        exit(bad_error);                /* WIN */
        !           465: }
        !           466:  
        !           467: /*                     perform_an_assembly_pass()
        !           468:  *
        !           469:  * Here to attempt 1 pass over each input file.
        !           470:  * We scan argv[*] looking for filenames or exactly "" which is
        !           471:  * shorthand for stdin. Any argv that is NULL is not a file-name.
        !           472:  * We set need_pass_2 TRUE if, after this, we still have unresolved
        !           473:  * expressions of the form (unknown value)+-(unknown value).
        !           474:  *
        !           475:  * Note the un*x semantics: there is only 1 logical input file, but it
        !           476:  * may be a catenation of many 'physical' input files.
        !           477:  */
        !           478: static
        !           479: void
        !           480: perform_an_assembly_pass(
        !           481: int argc,
        !           482: char **argv)
        !           483: {
        !           484:     char *buffer;              /* Where each bufferful of lines will start. */
        !           485:     int saw_a_file;
        !           486: 
        !           487:        saw_a_file = 0;
        !           488: 
        !           489:        argv++;                 /* skip argv[0] */
        !           490:        argc--;                 /* skip argv[0] */
        !           491:        while(argc--){
        !           492:            if(*argv){          /* Is it a file-name argument? */
        !           493:                /* argv -> "" if stdin desired, else -> filename */
        !           494:                if((buffer = input_scrub_new_file(*argv))){
        !           495:                    saw_a_file++;
        !           496:                    read_a_source_file(buffer);
        !           497:                }
        !           498:            }
        !           499:            argv++;                     /* completed that argv */
        !           500:        }
        !           501:        if(!saw_a_file)
        !           502:            if((buffer = input_scrub_new_file("")))
        !           503:                    read_a_source_file(buffer);
        !           504: }
        !           505: 
        !           506: static
        !           507: void
        !           508: got_sig(
        !           509: int sig)
        !           510: {
        !           511:        static int here_before = 0;
        !           512: 
        !           513:        as_bad("Interrupted by signal %d",sig);
        !           514:        if(here_before++)
        !           515:                exit(1);
        !           516: }

unix.superglobalmegacorp.com

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