home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.2 (Developer) / NS_dev_3.2.iso / NextDeveloper / Source / GNU / cctools / as / as.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-13  |  14.2 KB  |  531 lines

  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.  
  37. #define COMMON
  38. #include "as.h"
  39. #include "struc-symbol.h"
  40. #include "write.h"
  41.         /* Warning!  This may have some slightly strange side effects
  42.            if you try to compile two or more assemblers in the same
  43.            directory!
  44.          */
  45.  
  46. #ifndef SIGTY
  47. #define SIGTY int
  48. #endif
  49.  
  50. SIGTY got_sig();
  51.  
  52. #ifdef DONTDEF
  53. static char * gdb_symbol_file_name;
  54. long int gdb_begin();
  55. #endif
  56.  
  57. char *myname;        /* argv[0] */
  58. extern char version_string[];
  59. #ifdef NeXT
  60. extern char next_version[];
  61. extern int arch_multiple;
  62. #endif NeXT
  63.  
  64. #ifdef NeXT    /* .include feature */
  65. /* DJA
  66.  * .include "file" looks in source file dir, then stack.
  67.  * -I directories are added to the end, then the defaults are added.
  68.  */
  69. struct directory_stack include_defaults[] =
  70.   {
  71.     { 0, "/NextDeveloper/Headers/" },
  72.     { 0, "/LocalDeveloper/Headers/" },
  73.     { 0, NULL }
  74.   };
  75.  
  76. struct directory_stack *include = 0;        /* First dir to search */
  77. struct directory_stack *include_tail = 0;    /* Last in chain */
  78. #endif NeXT    /* .include feature */
  79.  
  80. #ifdef NeXT
  81. int force_cpusubtype_ALL = 0;
  82. cpu_subtype_t archflag_cpusubtype = -1;
  83. cpu_subtype_t cpusubtype = 
  84. #ifdef M68K
  85.         CPU_SUBTYPE_MC680x0_ALL;
  86. #endif
  87. #ifdef I860
  88.         CPU_SUBTYPE_I860_ALL;
  89. #endif
  90. #ifdef M88K
  91.         CPU_SUBTYPE_MC88000_ALL;
  92. #endif
  93. #ifdef I386
  94.         CPU_SUBTYPE_I386_ALL;
  95. #endif
  96. #ifdef M98K
  97.         CPU_SUBTYPE_MC98000_ALL;
  98. #endif
  99. #endif /* NeXT */
  100.  
  101.  
  102. main(argc,argv)
  103. int    argc;
  104. char    **argv;
  105. {
  106.     int    work_argc;    /* variable copy of argc */
  107.     char    **work_argv;    /* variable copy of argv */
  108.     char    *arg;        /* an arg to program */
  109.     char    a;        /* an arg flag (after -) */
  110.     static int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
  111.  
  112.     extern int bad_error;    /* Did we hit a bad error ? */
  113.  
  114.     char    *stralloc();    /* Make a (safe) copy of a string. */
  115.     void    symbol_begin();
  116.     void    read_begin();
  117.     void    write_object_file();
  118. #ifdef NeXT
  119.     char *specific_archflag = NULL;
  120. #endif
  121.  
  122.     for(a=0;sig[a]!=0;a++)
  123.         if(signal(sig[a], SIG_IGN) != SIG_IGN)
  124.             signal(sig[a], got_sig);
  125.  
  126.     myname=argv[0];
  127.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  128.     out_file_name    = "a.out";    /* default .o file */
  129.     symbol_begin();        /* symbols.c */
  130.     subsegs_begin();        /* subsegs.c */
  131.     read_begin();            /* read.c */
  132.     md_begin();            /* MACHINE.c */
  133.     input_scrub_begin();        /* input_scrub.c */
  134. #ifdef DONTDEF
  135.     gdb_symbol_file_name = 0;
  136. #endif
  137.     /*
  138.      * Parse arguments, but we are only interested in flags.
  139.      * When we find a flag, we process it then make it's argv[] NULL.
  140.      * This helps any future argv[] scanners avoid what we processed.
  141.      * Since it is easy to do here we interpret the special arg "-"
  142.      * to mean "use stdin" and we set that argv[] pointing to "".
  143.      * After we have munged argv[], the only things left are source file
  144.      * name(s) and ""(s) denoting stdin. These file names are used
  145.      * (perhaps more than once) later.
  146.      */
  147.     work_argc = argc-1;        /* don't count argv[0] */
  148.     work_argv = argv+1;        /* skip argv[0] */
  149.     for (;work_argc--;work_argv++) {
  150.         arg = * work_argv;    /* work_argv points to this argument */
  151.  
  152.         if (*arg!='-')        /* Filename. We need it later. */
  153.             continue;    /* Keep scanning args looking for flags. */
  154.         if (arg[1] == '-' && arg[2] == 0) {
  155.             /* "--" as an argument means read STDIN */
  156.             /* on this scan, we don't want to think about filenames */
  157.             * work_argv = "";    /* Code that means 'use stdin'. */
  158.             continue;
  159.         }
  160.                 /* This better be a switch. */
  161.         arg ++;        /* -> letter. */
  162.  
  163.         while (a = * arg)  {/* scan all the 1-char flags */
  164.             arg ++;    /* arg -> after letter. */
  165.             a &= 0x7F;    /* ascii only please */
  166. #ifdef NeXT
  167.             if (flagseen[a] && (a!='I') && (a!='a') && (a!='f'))
  168. #else
  169.             if (flagseen[a])
  170. #endif
  171.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  172. #ifdef NeXT
  173.             if(a != 'f')
  174. #endif
  175.                 flagseen[a] = TRUE;
  176.             switch (a) {
  177.             case 'f':
  178. #ifdef NeXT
  179.                 if(strcmp(arg-1, "force_cpusubtype_ALL") == 0){
  180.                     force_cpusubtype_ALL = 1;
  181.                     arg = "";    /* Finished with this arg. */
  182.                     break;
  183.                 }
  184.                 flagseen[a] = TRUE;
  185. #endif /* NeXT */
  186.                 break;    /* -f means fast - no need for "app" preprocessor. */
  187.  
  188. #ifndef NeXT
  189.             /* NeXT, since this does nothing anywhere in the code
  190.                that is used by NeXT this flag is not recognized */
  191.             case 'D':
  192.                 /* DEBUG is implemented: it debugs different */
  193.                 /* things to other people's assemblers. */
  194.                 break;
  195. #endif NeXT
  196.  
  197. #ifdef DONTDEF
  198.             case 'G':    /* GNU AS switch: include gdbsyms. */
  199.                 if (*arg)    /* Rest of argument is file-name. */
  200.                     gdb_symbol_file_name = stralloc (arg);
  201.                 else if (work_argc) {    /* Next argument is file-name. */
  202.                     work_argc --;
  203.                     * work_argv = NULL; /* Not a source file-name. */
  204.                     gdb_symbol_file_name = * ++ work_argv;
  205.                 } else
  206.                     as_warn( "%s: I expected a filename after -G",myname);
  207.                 arg = "";    /* Finished with this arg. */
  208.                 break;
  209. #endif
  210.  
  211. #ifndef WORKING_DOT_WORD
  212.             case 'k':
  213.                 break;
  214. #endif
  215.  
  216.             case 'L': /* -L means keep L* symbols */
  217.                 break;
  218.  
  219.             case 'o':
  220.                 if (*arg)    /* Rest of argument is object file-name. */
  221.                     out_file_name = stralloc (arg);
  222.                 else if (work_argc) {    /* Want next arg for a file-name. */
  223.                     * work_argv = NULL; /* This is not a file-name. */
  224.                     work_argc--;
  225.                     out_file_name = * ++ work_argv;
  226.                 } else
  227.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  228.                 arg = "";    /* Finished with this arg. */
  229.                 break;
  230.  
  231.             case 'R':
  232.                 /* -R means put data into text segment */
  233. #ifdef NeXT
  234.                 as_warn("%s: -R option not supported (used the "
  235.                     ".const directive)", myname);
  236.                 flagseen['R'] = FALSE;
  237. #endif NeXT
  238.                 break;
  239.  
  240.             case 'v':
  241. #ifdef    VMS
  242.                 {
  243.                 extern char *compiler_version_string;
  244.                 compiler_version_string = arg;
  245.                 }
  246. #else /* not VMS */
  247. #ifdef NeXT
  248.                 fprintf(stderr,"NeXT Computer, Inc. version "
  249.                     "%s, ", next_version);
  250. #endif NeXT
  251.                 fprintf(stderr,version_string);
  252.                 if(*arg && strcmp(arg,"ersion"))
  253.                     as_warn("Unknown -v option ignored");
  254. #endif
  255.                 while(*arg) arg++;    /* Skip the rest */
  256.                 break;
  257.  
  258.             case 'W':
  259.                 /* -W means don't warn about things */
  260.                 break;
  261.  
  262. #ifdef NeXT    /* .include feature */
  263.             case 'I': /* DJA -- Add directory to path for includes*/
  264.                 {
  265.                   struct directory_stack *dirtmp;
  266.  
  267.                   dirtmp = (struct directory_stack *)
  268.                     xmalloc (sizeof (struct directory_stack));
  269.                   /* New one goes on the end */
  270.                   dirtmp->next = 0;
  271.                   if (include == 0)
  272.                     include = dirtmp;
  273.                   else
  274.                     include_tail->next = dirtmp;
  275.                   /* Tail follows the last one */
  276.                   include_tail = dirtmp;
  277.                   /* Rest of argument is include file-name. */
  278.                   if (*arg)
  279.                     dirtmp->fname = stralloc (arg);
  280.                   else if (work_argc)
  281.                     {    /* Want next arg for a file-name. */
  282.                       /* This is not a file-name. */
  283.                       * work_argv = NULL;
  284.                       work_argc--;
  285.                       dirtmp->fname = * ++ work_argv;
  286.                     }
  287.                   else
  288.                     as_warn("I expected a filename after -I.");
  289.                   arg = "";    /* Finished with this arg. */
  290.                 }
  291.                 break;
  292. #endif NeXT    /* .include feature */
  293.  
  294. #ifdef NeXT    /* generate stabs for debugging assembly code */
  295.             case 'g':
  296.                 break;
  297. #endif NeXT    /* generate stabs for debugging assembly code */
  298.  
  299. #ifdef NeXT    /* mutiple arch stuff, see driver.c */
  300.             case 'V':
  301.                 /* as driver's -V, verbose, flag */
  302.                 break;
  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.                     }
  406.                     else
  407.                     as_fatal("I expected an <arch_type> "
  408.                          "after -arch.");
  409.                     break;
  410.                 }
  411.                 /* fall through for non -arch flag */
  412. #endif NeXT    /* mutiple arch stuff, see driver.c */
  413.             default:
  414.                 --arg;
  415.                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  416.                     as_warn("%s: I don't understand '%c' flag!",myname,a);
  417.                 if(arg && *arg)
  418.                     arg++;
  419.                 break;
  420.             }
  421.         }
  422.         /*
  423.          * We have just processed a "-..." arg, which was not a
  424.          * file-name. Smash it so the
  425.          * things that look for filenames won't ever see it.
  426.          *
  427.          * Whatever work_argv points to, it has already been used
  428.          * as part of a flag, so DON'T re-use it as a filename.
  429.          */
  430.         *work_argv = NULL; /* NULL means 'not a file-name' */
  431.     }
  432. #ifdef NeXT
  433.     if(force_cpusubtype_ALL && specific_archflag)
  434.         archflag_cpusubtype = -1;
  435. #endif
  436. #ifdef DONTDEF
  437.     if (gdb_begin(gdb_symbol_file_name) == 0)
  438.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  439. #endif
  440.     /* Here with flags set up in flagseen[]. */
  441.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  442.     if (seen_at_least_1_file() && !bad_error)
  443.         write_object_file();/* relax() addresses then emit object file */
  444.     input_scrub_end();
  445.     md_end();            /* MACHINE.c */
  446. #ifndef    VMS
  447.     exit(bad_error);            /* WIN */
  448. #else    /* VMS */
  449.     exit(!bad_error);            /* WIN */
  450. #endif    /* VMS */
  451. }
  452.  
  453.  
  454. /*            perform_an_assembly_pass()
  455.  *
  456.  * Here to attempt 1 pass over each input file.
  457.  * We scan argv[*] looking for filenames or exactly "" which is
  458.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  459.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  460.  * expressions of the form (unknown value)+-(unknown value).
  461.  *
  462.  * Note the un*x semantics: there is only 1 logical input file, but it
  463.  * may be a catenation of many 'physical' input files.
  464.  */
  465. perform_an_assembly_pass (argc, argv)
  466. int    argc;
  467. char **    argv;
  468. {
  469.     char *    buffer;        /* Where each bufferful of lines will start. */
  470.     void    read_a_source_file();
  471.     int saw_a_file = 0;
  472.  
  473.     text_fix_root        = NULL;
  474.     data_fix_root        = NULL;
  475.     need_pass_2        = FALSE;
  476.  
  477.     argv++;            /* skip argv[0] */
  478.     argc--;            /* skip argv[0] */
  479.     while (argc--) {
  480.         if (*argv) {        /* Is it a file-name argument? */
  481.             /* argv -> "" if stdin desired, else -> filename */
  482.             if (buffer = input_scrub_new_file (*argv) ) {
  483.                 saw_a_file++;
  484.                 read_a_source_file(buffer);
  485.             }
  486.         }
  487.         argv++;            /* completed that argv */
  488.     }
  489.     if(!saw_a_file)
  490.         if(buffer = input_scrub_new_file("") )
  491.             read_a_source_file(buffer);
  492. }
  493.  
  494. /*
  495.  *            stralloc()
  496.  *
  497.  * Allocate memory for a new copy of a string. Copy the string.
  498.  * Return the address of the new string. Die if there is any error.
  499.  */
  500.  
  501. char *
  502. stralloc (str)
  503. char *    str;
  504. {
  505.     register char *    retval;
  506.     register long int    len;
  507.  
  508.     len = strlen (str) + 1;
  509.     retval = xmalloc (len);
  510.     (void)strcpy (retval, str);
  511.     return (retval);
  512. }
  513.  
  514. lose()
  515. {
  516.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  517. }
  518.  
  519. SIGTY
  520. got_sig(sig)
  521. int sig;
  522. {
  523.     static here_before = 0;
  524.  
  525.     as_bad("Interrupted by signal %d",sig);
  526.     if(here_before++)
  527.         exit(1);
  528. }
  529.  
  530. /* end: as.c */
  531.