Annotation of GNUtools/cctools/as/as.c, revision 1.1.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.