as.c revision 130561
133965Sjdp/* as.c - GAS main program.
278828Sobrien   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
389857Sobrien   1999, 2000, 2001, 2002
433965Sjdp   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   This file is part of GAS, the GNU Assembler.
733965Sjdp
833965Sjdp   GAS is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1133965Sjdp   any later version.
1233965Sjdp
1333965Sjdp   GAS is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
2033965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2177298Sobrien   02111-1307, USA.  */
2233965Sjdp
2377298Sobrien/* Main program for AS; a 32-bit assembler of GNU.
24130561Sobrien   Understands command arguments.
25130561Sobrien   Has a few routines that don't fit in other modules because they
26130561Sobrien   are shared.
27130561Sobrien
28130561Sobrien  			bugs
29130561Sobrien
30130561Sobrien   : initialisers
31130561Sobrien  	Since no-one else says they will support them in future: I
32130561Sobrien   don't support them now.  */
3333965Sjdp
3433965Sjdp#include "ansidecl.h"
3533965Sjdp
3633965Sjdp#define COMMON
3733965Sjdp
3833965Sjdp#include "as.h"
3933965Sjdp#include "subsegs.h"
4033965Sjdp#include "output-file.h"
4133965Sjdp#include "sb.h"
4233965Sjdp#include "macro.h"
4377298Sobrien#include "dwarf2dbg.h"
44130561Sobrien#include "dw2gencfi.h"
4560484Sobrien
46130561Sobrien#ifdef BFD_ASSEMBLER
47130561Sobrien#include "bfdver.h"
48130561Sobrien#endif
49130561Sobrien
5060484Sobrien#ifdef HAVE_ITBL_CPU
5160484Sobrien#include "itbl-ops.h"
5260484Sobrien#else
5333965Sjdp#define itbl_parse(itbl_file) 1
5433965Sjdp#define itbl_init()
5533965Sjdp#endif
5633965Sjdp
5733965Sjdp#ifdef HAVE_SBRK
5833965Sjdp#ifdef NEED_DECLARATION_SBRK
5933965Sjdpextern PTR sbrk ();
6033965Sjdp#endif
6133965Sjdp#endif
6233965Sjdp
63130561Sobrien#ifdef USING_CGEN
64130561Sobrien/* Perform any cgen specific initialisation for gas.  */
65130561Sobrienextern void gas_cgen_begin (void);
66130561Sobrien#endif
6733965Sjdp
68130561Sobrien/* Keep a record of the itbl files we read in.  */
69130561Sobrienstruct itbl_file_list
70130561Sobrien{
71130561Sobrien  struct itbl_file_list *next;
72130561Sobrien  char *name;
73130561Sobrien};
74130561Sobrien
75130561Sobrien/* We build a list of defsyms as we read the options, and then define
76130561Sobrien   them after we have initialized everything.  */
77130561Sobrienstruct defsym_list
78130561Sobrien{
79130561Sobrien  struct defsym_list *next;
80130561Sobrien  char *name;
81130561Sobrien  valueT value;
82130561Sobrien};
83130561Sobrien
84130561Sobrien
8577298Sobrien/* True if a listing is wanted.  */
8677298Sobrienint listing;
8733965Sjdp
8838889Sjdp/* Type of debugging to generate.  */
8977298Sobrienenum debug_info_type debug_type = DEBUG_UNSPECIFIED;
90130561Sobrienint use_gnu_debug_info_extensions = 0;
9138889Sjdp
9233965Sjdp/* Maximum level of macro nesting.  */
9333965Sjdpint max_macro_nest = 100;
9433965Sjdp
9577298Sobrien/* argv[0]  */
96130561Sobrienchar * myname;
9733965Sjdp
9838889Sjdp/* The default obstack chunk size.  If we set this to zero, the
9938889Sjdp   obstack code will use whatever will fit in a 4096 byte block.  */
10038889Sjdpint chunksize = 0;
10133965Sjdp
10233965Sjdp/* To monitor memory allocation more effectively, make this non-zero.
10333965Sjdp   Then the chunk sizes for gas and bfd will be reduced.  */
10433965Sjdpint debug_memory = 0;
10533965Sjdp
106130561Sobrien/* Enable verbose mode.  */
107130561Sobrienint verbose = 0;
10833965Sjdp
109130561Sobrien#ifdef BFD_ASSEMBLER
110130561SobriensegT reg_section;
111130561SobriensegT expr_section;
112130561SobriensegT text_section;
113130561SobriensegT data_section;
114130561SobriensegT bss_section;
115130561Sobrien#endif
11633965Sjdp
117130561Sobrien/* Name of listing file.  */
118130561Sobrienstatic char *listing_filename = NULL;
119130561Sobrien
12033965Sjdpstatic struct defsym_list *defsyms;
12133965Sjdp
122130561Sobrienstatic struct itbl_file_list *itbl_files;
12333965Sjdp
124130561Sobrienstatic long start_time;
12533965Sjdp
12633965Sjdp
12733965Sjdp#ifdef USE_EMULATIONS
12833965Sjdp#define EMULATION_ENVIRON "AS_EMULATION"
12933965Sjdp
13033965Sjdpextern struct emulation mipsbelf, mipslelf, mipself;
13133965Sjdpextern struct emulation mipsbecoff, mipslecoff, mipsecoff;
13260484Sobrienextern struct emulation i386coff, i386elf, i386aout;
13377298Sobrienextern struct emulation crisaout, criself;
13433965Sjdp
13533965Sjdpstatic struct emulation *const emulations[] = { EMULATIONS };
13633965Sjdpstatic const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
13733965Sjdp
13833965Sjdpstatic void
139130561Sobrienselect_emulation_mode (int argc, char **argv)
14033965Sjdp{
14133965Sjdp  int i;
14233965Sjdp  char *p, *em = 0;
14333965Sjdp
14433965Sjdp  for (i = 1; i < argc; i++)
14533965Sjdp    if (!strncmp ("--em", argv[i], 4))
14633965Sjdp      break;
14733965Sjdp
14833965Sjdp  if (i == argc)
14933965Sjdp    goto do_default;
15033965Sjdp
15133965Sjdp  p = strchr (argv[i], '=');
15233965Sjdp  if (p)
15333965Sjdp    p++;
15433965Sjdp  else
15577298Sobrien    p = argv[i + 1];
15633965Sjdp
15733965Sjdp  if (!p || !*p)
15860484Sobrien    as_fatal (_("missing emulation mode name"));
15933965Sjdp  em = p;
16033965Sjdp
16133965Sjdp do_default:
16233965Sjdp  if (em == 0)
16333965Sjdp    em = getenv (EMULATION_ENVIRON);
16433965Sjdp  if (em == 0)
16533965Sjdp    em = DEFAULT_EMULATION;
16633965Sjdp
16733965Sjdp  if (em)
16833965Sjdp    {
16933965Sjdp      for (i = 0; i < n_emulations; i++)
17033965Sjdp	if (!strcmp (emulations[i]->name, em))
17133965Sjdp	  break;
17233965Sjdp      if (i == n_emulations)
17360484Sobrien	as_fatal (_("unrecognized emulation name `%s'"), em);
17433965Sjdp      this_emulation = emulations[i];
17533965Sjdp    }
17633965Sjdp  else
17733965Sjdp    this_emulation = emulations[0];
17833965Sjdp
17933965Sjdp  this_emulation->init ();
18033965Sjdp}
18133965Sjdp
18233965Sjdpconst char *
183130561Sobriendefault_emul_bfd_name (void)
18433965Sjdp{
18533965Sjdp  abort ();
18633965Sjdp  return NULL;
18733965Sjdp}
18833965Sjdp
18933965Sjdpvoid
190130561Sobriencommon_emul_init (void)
19133965Sjdp{
19233965Sjdp  this_format = this_emulation->format;
19333965Sjdp
19433965Sjdp  if (this_emulation->leading_underscore == 2)
19533965Sjdp    this_emulation->leading_underscore = this_format->dfl_leading_underscore;
19633965Sjdp
19733965Sjdp  if (this_emulation->default_endian != 2)
19833965Sjdp    target_big_endian = this_emulation->default_endian;
19933965Sjdp
20033965Sjdp  if (this_emulation->fake_label_name == 0)
20133965Sjdp    {
20233965Sjdp      if (this_emulation->leading_underscore)
20333965Sjdp	this_emulation->fake_label_name = "L0\001";
20433965Sjdp      else
20533965Sjdp	/* What other parameters should we test?  */
20633965Sjdp	this_emulation->fake_label_name = ".L0\001";
20733965Sjdp    }
20833965Sjdp}
20933965Sjdp#endif
21033965Sjdp
21160484Sobrienvoid
212130561Sobrienprint_version_id (void)
21360484Sobrien{
21460484Sobrien  static int printed;
215130561Sobrien
21660484Sobrien  if (printed)
21760484Sobrien    return;
21860484Sobrien  printed = 1;
21960484Sobrien
22060484Sobrien#ifdef BFD_ASSEMBLER
22160484Sobrien  fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s"),
22289857Sobrien	   VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
22360484Sobrien#else
22460484Sobrien  fprintf (stderr, _("GNU assembler version %s (%s)"), VERSION, TARGET_ALIAS);
22560484Sobrien#endif
22660484Sobrien  fprintf (stderr, "\n");
22760484Sobrien}
22860484Sobrien
22960484Sobrienstatic void
230130561Sobrienshow_usage (FILE * stream)
23160484Sobrien{
23260484Sobrien  fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname);
23360484Sobrien
23460484Sobrien  fprintf (stream, _("\
23560484SobrienOptions:\n\
23660484Sobrien  -a[sub-option...]	  turn on listings\n\
23760484Sobrien                      	  Sub-options [default hls]:\n\
23860484Sobrien                      	  c      omit false conditionals\n\
23960484Sobrien                      	  d      omit debugging directives\n\
24060484Sobrien                      	  h      include high-level source\n\
24160484Sobrien                      	  l      include assembly\n\
24260484Sobrien                      	  m      include macro expansions\n\
24360484Sobrien                      	  n      omit forms processing\n\
24460484Sobrien                      	  s      include symbols\n\
24560484Sobrien                      	  =FILE  list to FILE (must be last sub-option)\n"));
24660484Sobrien
24760484Sobrien  fprintf (stream, _("\
24860484Sobrien  -D                      produce assembler debugging messages\n"));
24960484Sobrien  fprintf (stream, _("\
25060484Sobrien  --defsym SYM=VAL        define symbol SYM to given value\n"));
25160484Sobrien#ifdef USE_EMULATIONS
25260484Sobrien  {
25360484Sobrien    int i;
25460484Sobrien    char *def_em;
25560484Sobrien
25660484Sobrien    fprintf (stream, "\
25760484Sobrien  --em=[");
25877298Sobrien    for (i = 0; i < n_emulations - 1; i++)
25960484Sobrien      fprintf (stream, "%s | ", emulations[i]->name);
26060484Sobrien    fprintf (stream, "%s]\n", emulations[i]->name);
26160484Sobrien
26260484Sobrien    def_em = getenv (EMULATION_ENVIRON);
26377298Sobrien    if (!def_em)
26460484Sobrien      def_em = DEFAULT_EMULATION;
26560484Sobrien    fprintf (stream, _("\
26660484Sobrien                          emulate output (default %s)\n"), def_em);
26760484Sobrien  }
26860484Sobrien#endif
269130561Sobrien#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
27060484Sobrien  fprintf (stream, _("\
271130561Sobrien  --execstack             require executable stack for this object\n"));
272130561Sobrien  fprintf (stream, _("\
273130561Sobrien  --noexecstack           don't require executable stack for this object\n"));
274130561Sobrien#endif
275130561Sobrien  fprintf (stream, _("\
27660484Sobrien  -f                      skip whitespace and comment preprocessing\n"));
27760484Sobrien  fprintf (stream, _("\
27860484Sobrien  --gstabs                generate stabs debugging information\n"));
27960484Sobrien  fprintf (stream, _("\
280130561Sobrien  --gstabs+               generate stabs debug info with GNU extensions\n"));
281130561Sobrien  fprintf (stream, _("\
28260484Sobrien  --gdwarf2               generate DWARF2 debugging information\n"));
28360484Sobrien  fprintf (stream, _("\
28460484Sobrien  --help                  show this message and exit\n"));
28560484Sobrien  fprintf (stream, _("\
28677298Sobrien  --target-help           show target specific options\n"));
28777298Sobrien  fprintf (stream, _("\
28860484Sobrien  -I DIR                  add DIR to search list for .include directives\n"));
28960484Sobrien  fprintf (stream, _("\
29060484Sobrien  -J                      don't warn about signed overflow\n"));
29160484Sobrien  fprintf (stream, _("\
29260484Sobrien  -K                      warn when differences altered for long displacements\n"));
29360484Sobrien  fprintf (stream, _("\
29460484Sobrien  -L,--keep-locals        keep local symbols (e.g. starting with `L')\n"));
29560484Sobrien  fprintf (stream, _("\
29660484Sobrien  -M,--mri                assemble in MRI compatibility mode\n"));
29760484Sobrien  fprintf (stream, _("\
29860484Sobrien  --MD FILE               write dependency information in FILE (default none)\n"));
29960484Sobrien  fprintf (stream, _("\
30060484Sobrien  -nocpp                  ignored\n"));
30160484Sobrien  fprintf (stream, _("\
30260484Sobrien  -o OBJFILE              name the object-file output OBJFILE (default a.out)\n"));
30360484Sobrien  fprintf (stream, _("\
30460484Sobrien  -R                      fold data section into text section\n"));
30560484Sobrien  fprintf (stream, _("\
30660484Sobrien  --statistics            print various measured statistics from execution\n"));
30760484Sobrien  fprintf (stream, _("\
30860484Sobrien  --strip-local-absolute  strip local absolute symbols\n"));
30960484Sobrien  fprintf (stream, _("\
31060484Sobrien  --traditional-format    Use same format as native assembler when possible\n"));
31160484Sobrien  fprintf (stream, _("\
31260484Sobrien  --version               print assembler version number and exit\n"));
31360484Sobrien  fprintf (stream, _("\
31460484Sobrien  -W  --no-warn           suppress warnings\n"));
31560484Sobrien  fprintf (stream, _("\
31660484Sobrien  --warn                  don't suppress warnings\n"));
31760484Sobrien  fprintf (stream, _("\
31860484Sobrien  --fatal-warnings        treat warnings as errors\n"));
31960484Sobrien  fprintf (stream, _("\
32060484Sobrien  --itbl INSTTBL          extend instruction set to include instructions\n\
32160484Sobrien                          matching the specifications defined in file INSTTBL\n"));
32260484Sobrien  fprintf (stream, _("\
32360484Sobrien  -w                      ignored\n"));
32460484Sobrien  fprintf (stream, _("\
32560484Sobrien  -X                      ignored\n"));
32660484Sobrien  fprintf (stream, _("\
32760484Sobrien  -Z                      generate object file even after errors\n"));
32860484Sobrien  fprintf (stream, _("\
32960484Sobrien  --listing-lhs-width     set the width in words of the output data column of\n\
33060484Sobrien                          the listing\n"));
33160484Sobrien  fprintf (stream, _("\
33260484Sobrien  --listing-lhs-width2    set the width in words of the continuation lines\n\
33360484Sobrien                          of the output data column; ignored if smaller than\n\
33460484Sobrien                          the width of the first line\n"));
33560484Sobrien  fprintf (stream, _("\
33660484Sobrien  --listing-rhs-width     set the max width in characters of the lines from\n\
33760484Sobrien                          the source file\n"));
33860484Sobrien  fprintf (stream, _("\
33960484Sobrien  --listing-cont-lines    set the maximum number of continuation lines used\n\
34060484Sobrien                          for the output data column of the listing\n"));
34160484Sobrien
34260484Sobrien  md_show_usage (stream);
34360484Sobrien
34460484Sobrien  fputc ('\n', stream);
34560484Sobrien  fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
34660484Sobrien}
34760484Sobrien
34877298Sobrien/* Since it is easy to do here we interpret the special arg "-"
34977298Sobrien   to mean "use stdin" and we set that argv[] pointing to "".
35077298Sobrien   After we have munged argv[], the only things left are source file
35177298Sobrien   name(s) and ""(s) denoting stdin. These file names are used
35277298Sobrien   (perhaps more than once) later.
35333965Sjdp
35477298Sobrien   check for new machine-dep cmdline options in
35577298Sobrien   md_parse_option definitions in config/tc-*.c.  */
35677298Sobrien
35733965Sjdpstatic void
358130561Sobrienparse_args (int * pargc, char *** pargv)
35933965Sjdp{
360130561Sobrien  int old_argc;
361130561Sobrien  int new_argc;
362130561Sobrien  char ** old_argv;
363130561Sobrien  char ** new_argv;
36433965Sjdp  /* Starting the short option string with '-' is for programs that
36533965Sjdp     expect options and other ARGV-elements in any order and that care about
36633965Sjdp     the ordering of the two.  We describe each non-option ARGV-element
36733965Sjdp     as if it were the argument of an option with character code 1.  */
36833965Sjdp  char *shortopts;
369104834Sobrien  extern const char *md_shortopts;
370130561Sobrien  static const char std_shortopts[] =
371130561Sobrien  {
37277298Sobrien    '-', 'J',
37333965Sjdp#ifndef WORKING_DOT_WORD
37477298Sobrien    /* -K is not meaningful if .word is not being hacked.  */
37577298Sobrien    'K',
37633965Sjdp#endif
377130561Sobrien    'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'I', ':', 'o', ':',
37833965Sjdp#ifndef VMS
37977298Sobrien    /* -v takes an argument on VMS, so we don't make it a generic
38077298Sobrien       option.  */
38177298Sobrien    'v',
38233965Sjdp#endif
38377298Sobrien    'w', 'X',
384130561Sobrien    /* New option for extending instruction set (see also --itbl below).  */
38577298Sobrien    't', ':',
38677298Sobrien    '\0'
38777298Sobrien  };
38833965Sjdp  struct option *longopts;
38933965Sjdp  extern struct option md_longopts[];
39033965Sjdp  extern size_t md_longopts_size;
391130561Sobrien  /* Codes used for the long options with no short synonyms.  */
392130561Sobrien  enum option_values
393130561Sobrien    {
394130561Sobrien      OPTION_HELP = OPTION_STD_BASE,
395130561Sobrien      OPTION_NOCPP,
396130561Sobrien      OPTION_STATISTICS,
397130561Sobrien      OPTION_VERSION,
398130561Sobrien      OPTION_DUMPCONFIG,
399130561Sobrien      OPTION_VERBOSE,
400130561Sobrien      OPTION_EMULATION,
401130561Sobrien      OPTION_DEFSYM,
402130561Sobrien      OPTION_INSTTBL,
403130561Sobrien      OPTION_LISTING_LHS_WIDTH,
404130561Sobrien      OPTION_LISTING_LHS_WIDTH2,
405130561Sobrien      OPTION_LISTING_RHS_WIDTH,
406130561Sobrien      OPTION_LISTING_CONT_LINES,
407130561Sobrien      OPTION_DEPFILE,
408130561Sobrien      OPTION_GSTABS,
409130561Sobrien      OPTION_GSTABS_PLUS,
410130561Sobrien      OPTION_STRIP_LOCAL_ABSOLUTE,
411130561Sobrien      OPTION_TRADITIONAL_FORMAT,
412130561Sobrien      OPTION_GDWARF2,
413130561Sobrien      OPTION_WARN,
414130561Sobrien      OPTION_TARGET_HELP,
415130561Sobrien      OPTION_EXECSTACK,
416130561Sobrien      OPTION_NOEXECSTACK,
417130561Sobrien      OPTION_WARN_FATAL
418130561Sobrien    };
419130561Sobrien
420130561Sobrien  static const struct option std_longopts[] =
421130561Sobrien  {
42233965Sjdp    {"help", no_argument, NULL, OPTION_HELP},
423130561Sobrien    /* getopt allows abbreviations, so we do this to stop it from
424130561Sobrien       treating -k as an abbreviation for --keep-locals.  Some
425130561Sobrien       ports use -k to enable PIC assembly.  */
42638889Sjdp    {"keep-locals", no_argument, NULL, 'L'},
427130561Sobrien    {"keep-locals", no_argument, NULL, 'L'},
42833965Sjdp    {"mri", no_argument, NULL, 'M'},
42933965Sjdp    {"nocpp", no_argument, NULL, OPTION_NOCPP},
43033965Sjdp    {"statistics", no_argument, NULL, OPTION_STATISTICS},
43133965Sjdp    {"version", no_argument, NULL, OPTION_VERSION},
43233965Sjdp    {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG},
43333965Sjdp    {"verbose", no_argument, NULL, OPTION_VERBOSE},
43433965Sjdp    {"emulation", required_argument, NULL, OPTION_EMULATION},
43533965Sjdp    {"defsym", required_argument, NULL, OPTION_DEFSYM},
43633965Sjdp    /* New option for extending instruction set (see also -t above).
43733965Sjdp       The "-t file" or "--itbl file" option extends the basic set of
43833965Sjdp       valid instructions by reading "file", a text file containing a
43933965Sjdp       list of instruction formats.  The additional opcodes and their
44033965Sjdp       formats are added to the built-in set of instructions, and
44133965Sjdp       mnemonics for new registers may also be defined.  */
44238889Sjdp    {"itbl", required_argument, NULL, OPTION_INSTTBL},
44338889Sjdp    {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH},
44478828Sobrien    {"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2},
44538889Sjdp    {"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH},
44638889Sjdp    {"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES},
44738889Sjdp    {"MD", required_argument, NULL, OPTION_DEPFILE},
44838889Sjdp    {"gstabs", no_argument, NULL, OPTION_GSTABS},
449130561Sobrien    {"gstabs+", no_argument, NULL, OPTION_GSTABS_PLUS},
45038889Sjdp    {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE},
45160484Sobrien    {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
45260484Sobrien    {"gdwarf2", no_argument, NULL, OPTION_GDWARF2},
45360484Sobrien    {"no-warn", no_argument, NULL, 'W'},
45460484Sobrien    {"warn", no_argument, NULL, OPTION_WARN},
45577298Sobrien    {"target-help", no_argument, NULL, OPTION_TARGET_HELP},
456130561Sobrien#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
457130561Sobrien    {"execstack", no_argument, NULL, OPTION_EXECSTACK},
458130561Sobrien    {"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK},
459130561Sobrien#endif
46060484Sobrien    {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
46177298Sobrien    /* When you add options here, check that they do not collide with
46277298Sobrien       OPTION_MD_BASE.  See as.h.  */
46333965Sjdp  };
46433965Sjdp
46577298Sobrien  /* Construct the option lists from the standard list and the target
46677298Sobrien     dependent list.  Include space for an extra NULL option and
46777298Sobrien     always NULL terminate.  */
46833965Sjdp  shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
469130561Sobrien  longopts = xmalloc (sizeof (std_longopts) + md_longopts_size + sizeof (struct option));
47033965Sjdp  memcpy (longopts, std_longopts, sizeof (std_longopts));
471130561Sobrien  memcpy (((char *) longopts) + sizeof (std_longopts), md_longopts, md_longopts_size);
472130561Sobrien  memset (((char *) longopts) + sizeof (std_longopts) + md_longopts_size,
47377298Sobrien	  0, sizeof (struct option));
47433965Sjdp
47533965Sjdp  /* Make a local copy of the old argv.  */
47633965Sjdp  old_argc = *pargc;
47733965Sjdp  old_argv = *pargv;
47833965Sjdp
47933965Sjdp  /* Initialize a new argv that contains no options.  */
480130561Sobrien  new_argv = xmalloc (sizeof (char *) * (old_argc + 1));
48133965Sjdp  new_argv[0] = old_argv[0];
48233965Sjdp  new_argc = 1;
48333965Sjdp  new_argv[new_argc] = NULL;
48433965Sjdp
48533965Sjdp  while (1)
48633965Sjdp    {
48733965Sjdp      /* getopt_long_only is like getopt_long, but '-' as well as '--' can
48833965Sjdp	 indicate a long option.  */
48933965Sjdp      int longind;
49033965Sjdp      int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
49133965Sjdp				   &longind);
49233965Sjdp
49333965Sjdp      if (optc == -1)
49433965Sjdp	break;
49533965Sjdp
49633965Sjdp      switch (optc)
49733965Sjdp	{
49833965Sjdp	default:
49933965Sjdp	  /* md_parse_option should return 1 if it recognizes optc,
50033965Sjdp	     0 if not.  */
50133965Sjdp	  if (md_parse_option (optc, optarg) != 0)
50233965Sjdp	    break;
50333965Sjdp	  /* `-v' isn't included in the general short_opts list, so check for
504130561Sobrien	     it explicitly here before deciding we've gotten a bad argument.  */
50533965Sjdp	  if (optc == 'v')
50633965Sjdp	    {
50733965Sjdp#ifdef VMS
50833965Sjdp	      /* Telling getopt to treat -v's value as optional can result
50933965Sjdp		 in it picking up a following filename argument here.  The
51033965Sjdp		 VMS code in md_parse_option can return 0 in that case,
51133965Sjdp		 but it has no way of pushing the filename argument back.  */
51233965Sjdp	      if (optarg && *optarg)
51377298Sobrien		new_argv[new_argc++] = optarg, new_argv[new_argc] = NULL;
51433965Sjdp	      else
51533965Sjdp#else
51633965Sjdp	      case 'v':
51733965Sjdp#endif
51833965Sjdp	      case OPTION_VERBOSE:
51933965Sjdp		print_version_id ();
520130561Sobrien		verbose = 1;
52133965Sjdp	      break;
52233965Sjdp	    }
52377298Sobrien	  /* Fall through.  */
52433965Sjdp
52533965Sjdp	case '?':
52633965Sjdp	  exit (EXIT_FAILURE);
52733965Sjdp
52833965Sjdp	case 1:			/* File name.  */
52933965Sjdp	  if (!strcmp (optarg, "-"))
53033965Sjdp	    optarg = "";
53133965Sjdp	  new_argv[new_argc++] = optarg;
53233965Sjdp	  new_argv[new_argc] = NULL;
53333965Sjdp	  break;
53433965Sjdp
53577298Sobrien	case OPTION_TARGET_HELP:
536104834Sobrien	  md_show_usage (stdout);
537104834Sobrien	  exit (EXIT_SUCCESS);
53877298Sobrien
53933965Sjdp	case OPTION_HELP:
54033965Sjdp	  show_usage (stdout);
54133965Sjdp	  exit (EXIT_SUCCESS);
54233965Sjdp
54333965Sjdp	case OPTION_NOCPP:
54433965Sjdp	  break;
54533965Sjdp
54633965Sjdp	case OPTION_STATISTICS:
54733965Sjdp	  flag_print_statistics = 1;
54833965Sjdp	  break;
54933965Sjdp
55038889Sjdp	case OPTION_STRIP_LOCAL_ABSOLUTE:
55138889Sjdp	  flag_strip_local_absolute = 1;
55238889Sjdp	  break;
55338889Sjdp
55438889Sjdp	case OPTION_TRADITIONAL_FORMAT:
55538889Sjdp	  flag_traditional_format = 1;
55638889Sjdp	  break;
55738889Sjdp
55833965Sjdp	case OPTION_VERSION:
55933965Sjdp	  /* This output is intended to follow the GNU standards document.  */
56094536Sobrien#ifdef BFD_ASSEMBLER
56189857Sobrien	  printf (_("GNU assembler %s\n"), BFD_VERSION_STRING);
56294536Sobrien#else
56394536Sobrien	  printf (_("GNU assembler %s\n"), VERSION);
56494536Sobrien#endif
56589857Sobrien	  printf (_("Copyright 2002 Free Software Foundation, Inc.\n"));
56660484Sobrien	  printf (_("\
56733965SjdpThis program is free software; you may redistribute it under the terms of\n\
56860484Sobrienthe GNU General Public License.  This program has absolutely no warranty.\n"));
56960484Sobrien	  printf (_("This assembler was configured for a target of `%s'.\n"),
57033965Sjdp		  TARGET_ALIAS);
57133965Sjdp	  exit (EXIT_SUCCESS);
57233965Sjdp
57333965Sjdp	case OPTION_EMULATION:
57433965Sjdp#ifdef USE_EMULATIONS
57533965Sjdp	  if (strcmp (optarg, this_emulation->name))
57660484Sobrien	    as_fatal (_("multiple emulation names specified"));
57733965Sjdp#else
57860484Sobrien	  as_fatal (_("emulations not handled in this configuration"));
57933965Sjdp#endif
58033965Sjdp	  break;
58133965Sjdp
58233965Sjdp	case OPTION_DUMPCONFIG:
58360484Sobrien	  fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS);
58460484Sobrien	  fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL);
58560484Sobrien	  fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU);
58633965Sjdp#ifdef TARGET_OBJ_FORMAT
58760484Sobrien	  fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT);
58833965Sjdp#endif
58933965Sjdp#ifdef TARGET_FORMAT
59060484Sobrien	  fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT);
59133965Sjdp#endif
59233965Sjdp	  exit (EXIT_SUCCESS);
59333965Sjdp
59433965Sjdp	case OPTION_DEFSYM:
59533965Sjdp	  {
59633965Sjdp	    char *s;
59777298Sobrien	    valueT i;
59833965Sjdp	    struct defsym_list *n;
59933965Sjdp
60033965Sjdp	    for (s = optarg; *s != '\0' && *s != '='; s++)
60133965Sjdp	      ;
60233965Sjdp	    if (*s == '\0')
60360484Sobrien	      as_fatal (_("bad defsym; format is --defsym name=value"));
60433965Sjdp	    *s++ = '\0';
60577298Sobrien#ifdef BFD_ASSEMBLER
60677298Sobrien	    i = bfd_scan_vma (s, (const char **) NULL, 0);
60777298Sobrien#else
60833965Sjdp	    i = strtol (s, (char **) NULL, 0);
60977298Sobrien#endif
610130561Sobrien	    n = xmalloc (sizeof *n);
61133965Sjdp	    n->next = defsyms;
61233965Sjdp	    n->name = optarg;
61333965Sjdp	    n->value = i;
61433965Sjdp	    defsyms = n;
61533965Sjdp	  }
61633965Sjdp	  break;
61733965Sjdp
61833965Sjdp	case OPTION_INSTTBL:
61933965Sjdp	case 't':
62033965Sjdp	  {
62177298Sobrien	    /* optarg is the name of the file containing the instruction
62277298Sobrien	       formats, opcodes, register names, etc.  */
62333965Sjdp	    struct itbl_file_list *n;
62433965Sjdp
62538889Sjdp	    if (optarg == NULL)
62638889Sjdp	      {
62789857Sobrien		as_warn (_("no file name following -t option"));
62838889Sjdp		break;
62938889Sjdp	      }
63077298Sobrien
631130561Sobrien	    n = xmalloc (sizeof * n);
63233965Sjdp	    n->next = itbl_files;
63333965Sjdp	    n->name = optarg;
63433965Sjdp	    itbl_files = n;
63533965Sjdp
63633965Sjdp	    /* Parse the file and add the new instructions to our internal
63777298Sobrien	       table.  If multiple instruction tables are specified, the
63877298Sobrien	       information from this table gets appended onto the existing
63977298Sobrien	       internal table.  */
64033965Sjdp	    itbl_files->name = xstrdup (optarg);
64133965Sjdp	    if (itbl_parse (itbl_files->name) != 0)
64289857Sobrien	      as_fatal (_("failed to read instruction table %s\n"),
64389857Sobrien			itbl_files->name);
64433965Sjdp	  }
64533965Sjdp	  break;
64633965Sjdp
64738889Sjdp	case OPTION_DEPFILE:
64838889Sjdp	  start_dependencies (optarg);
64938889Sjdp	  break;
65038889Sjdp
651130561Sobrien	case OPTION_GSTABS_PLUS:
652130561Sobrien	  use_gnu_debug_info_extensions = 1;
653130561Sobrien	  /* Fall through.  */
65438889Sjdp	case OPTION_GSTABS:
65538889Sjdp	  debug_type = DEBUG_STABS;
65638889Sjdp	  break;
65777298Sobrien
65860484Sobrien	case OPTION_GDWARF2:
65960484Sobrien	  debug_type = DEBUG_DWARF2;
66060484Sobrien	  break;
66160484Sobrien
66233965Sjdp	case 'J':
66333965Sjdp	  flag_signed_overflow_ok = 1;
66433965Sjdp	  break;
66533965Sjdp
66633965Sjdp#ifndef WORKING_DOT_WORD
66733965Sjdp	case 'K':
66833965Sjdp	  flag_warn_displacement = 1;
66933965Sjdp	  break;
67033965Sjdp#endif
67133965Sjdp	case 'L':
67233965Sjdp	  flag_keep_locals = 1;
67333965Sjdp	  break;
67433965Sjdp
67538889Sjdp	case OPTION_LISTING_LHS_WIDTH:
67677298Sobrien	  listing_lhs_width = atoi (optarg);
67738889Sjdp	  if (listing_lhs_width_second < listing_lhs_width)
67838889Sjdp	    listing_lhs_width_second = listing_lhs_width;
67938889Sjdp	  break;
68038889Sjdp	case OPTION_LISTING_LHS_WIDTH2:
68138889Sjdp	  {
68277298Sobrien	    int tmp = atoi (optarg);
68338889Sjdp	    if (tmp > listing_lhs_width)
68438889Sjdp	      listing_lhs_width_second = tmp;
68538889Sjdp	  }
68638889Sjdp	  break;
68738889Sjdp	case OPTION_LISTING_RHS_WIDTH:
68877298Sobrien	  listing_rhs_width = atoi (optarg);
68938889Sjdp	  break;
69038889Sjdp	case OPTION_LISTING_CONT_LINES:
69177298Sobrien	  listing_lhs_cont_lines = atoi (optarg);
69238889Sjdp	  break;
69338889Sjdp
69433965Sjdp	case 'M':
69533965Sjdp	  flag_mri = 1;
69633965Sjdp#ifdef TC_M68K
69733965Sjdp	  flag_m68k_mri = 1;
69833965Sjdp#endif
69933965Sjdp	  break;
70033965Sjdp
70133965Sjdp	case 'R':
70233965Sjdp	  flag_readonly_data_in_text = 1;
70333965Sjdp	  break;
70433965Sjdp
70533965Sjdp	case 'W':
70633965Sjdp	  flag_no_warnings = 1;
70733965Sjdp	  break;
70833965Sjdp
70960484Sobrien	case OPTION_WARN:
71060484Sobrien	  flag_no_warnings = 0;
71160484Sobrien	  flag_fatal_warnings = 0;
71260484Sobrien	  break;
71360484Sobrien
71460484Sobrien	case OPTION_WARN_FATAL:
71560484Sobrien	  flag_no_warnings = 0;
71660484Sobrien	  flag_fatal_warnings = 1;
71760484Sobrien	  break;
71860484Sobrien
719130561Sobrien#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
720130561Sobrien	case OPTION_EXECSTACK:
721130561Sobrien	  flag_execstack = 1;
722130561Sobrien	  flag_noexecstack = 0;
723130561Sobrien	  break;
724130561Sobrien
725130561Sobrien	case OPTION_NOEXECSTACK:
726130561Sobrien	  flag_noexecstack = 1;
727130561Sobrien	  flag_execstack = 0;
728130561Sobrien	  break;
729130561Sobrien#endif
73033965Sjdp	case 'Z':
73133965Sjdp	  flag_always_generate_output = 1;
73233965Sjdp	  break;
73333965Sjdp
73433965Sjdp	case 'a':
73533965Sjdp	  if (optarg)
73633965Sjdp	    {
73777298Sobrien	      if (md_parse_option (optc, optarg) != 0)
73877298Sobrien		break;
73977298Sobrien
74033965Sjdp	      while (*optarg)
74133965Sjdp		{
74233965Sjdp		  switch (*optarg)
74333965Sjdp		    {
74433965Sjdp		    case 'c':
74533965Sjdp		      listing |= LISTING_NOCOND;
74633965Sjdp		      break;
74733965Sjdp		    case 'd':
74833965Sjdp		      listing |= LISTING_NODEBUG;
74933965Sjdp		      break;
75033965Sjdp		    case 'h':
75133965Sjdp		      listing |= LISTING_HLL;
75233965Sjdp		      break;
75333965Sjdp		    case 'l':
75433965Sjdp		      listing |= LISTING_LISTING;
75533965Sjdp		      break;
75638889Sjdp		    case 'm':
75738889Sjdp		      listing |= LISTING_MACEXP;
75838889Sjdp		      break;
75933965Sjdp		    case 'n':
76033965Sjdp		      listing |= LISTING_NOFORM;
76133965Sjdp		      break;
76233965Sjdp		    case 's':
76333965Sjdp		      listing |= LISTING_SYMBOLS;
76433965Sjdp		      break;
76533965Sjdp		    case '=':
76633965Sjdp		      listing_filename = xstrdup (optarg + 1);
76733965Sjdp		      optarg += strlen (listing_filename);
76833965Sjdp		      break;
76933965Sjdp		    default:
77060484Sobrien		      as_fatal (_("invalid listing option `%c'"), *optarg);
77133965Sjdp		      break;
77233965Sjdp		    }
77333965Sjdp		  optarg++;
77433965Sjdp		}
77533965Sjdp	    }
77633965Sjdp	  if (!listing)
77733965Sjdp	    listing = LISTING_DEFAULT;
77833965Sjdp	  break;
77933965Sjdp
78033965Sjdp	case 'D':
78177298Sobrien	  /* DEBUG is implemented: it debugs different
78277298Sobrien	     things from other people's assemblers.  */
78333965Sjdp	  flag_debug = 1;
78433965Sjdp	  break;
78533965Sjdp
78633965Sjdp	case 'f':
78733965Sjdp	  flag_no_comments = 1;
78833965Sjdp	  break;
78933965Sjdp
79033965Sjdp	case 'I':
79177298Sobrien	  {			/* Include file directory.  */
79233965Sjdp	    char *temp = xstrdup (optarg);
79333965Sjdp	    add_include_dir (temp);
79433965Sjdp	    break;
79533965Sjdp	  }
79633965Sjdp
79733965Sjdp	case 'o':
79833965Sjdp	  out_file_name = xstrdup (optarg);
79933965Sjdp	  break;
80033965Sjdp
80133965Sjdp	case 'w':
80233965Sjdp	  break;
80333965Sjdp
80433965Sjdp	case 'X':
80577298Sobrien	  /* -X means treat warnings as errors.  */
80633965Sjdp	  break;
80733965Sjdp	}
80833965Sjdp    }
80933965Sjdp
81033965Sjdp  free (shortopts);
81133965Sjdp  free (longopts);
81233965Sjdp
81333965Sjdp  *pargc = new_argc;
81433965Sjdp  *pargv = new_argv;
81589857Sobrien
81689857Sobrien#ifdef md_after_parse_args
81789857Sobrien  md_after_parse_args ();
81889857Sobrien#endif
81933965Sjdp}
82033965Sjdp
821130561Sobrienstatic void
822130561Sobriendump_statistics (void)
823130561Sobrien{
824130561Sobrien#ifdef HAVE_SBRK
825130561Sobrien  char *lim = (char *) sbrk (0);
826130561Sobrien#endif
827130561Sobrien  long run_time = get_run_time () - start_time;
82833965Sjdp
829130561Sobrien  fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"),
830130561Sobrien	   myname, run_time / 1000000, run_time % 1000000);
831130561Sobrien#ifdef HAVE_SBRK
832130561Sobrien  fprintf (stderr, _("%s: data size %ld\n"),
833130561Sobrien	   myname, (long) (lim - (char *) &environ));
834130561Sobrien#endif
83589857Sobrien
836130561Sobrien  subsegs_print_statistics (stderr);
837130561Sobrien  write_print_statistics (stderr);
838130561Sobrien  symbol_print_statistics (stderr);
839130561Sobrien  read_print_statistics (stderr);
840130561Sobrien
841130561Sobrien#ifdef tc_print_statistics
842130561Sobrien  tc_print_statistics (stderr);
843130561Sobrien#endif
844130561Sobrien
845130561Sobrien#ifdef obj_print_statistics
846130561Sobrien  obj_print_statistics (stderr);
847130561Sobrien#endif
848130561Sobrien}
849130561Sobrien
850130561Sobrien/* The interface between the macro code and gas expression handling.  */
851130561Sobrien
852130561Sobrienstatic int
853130561Sobrienmacro_expr (const char *emsg, int idx, sb *in, int *val)
854130561Sobrien{
855130561Sobrien  char *hold;
856130561Sobrien  expressionS ex;
857130561Sobrien
858130561Sobrien  sb_terminate (in);
859130561Sobrien
860130561Sobrien  hold = input_line_pointer;
861130561Sobrien  input_line_pointer = in->ptr + idx;
862130561Sobrien  expression (&ex);
863130561Sobrien  idx = input_line_pointer - in->ptr;
864130561Sobrien  input_line_pointer = hold;
865130561Sobrien
866130561Sobrien  if (ex.X_op != O_constant)
867130561Sobrien    as_bad ("%s", emsg);
868130561Sobrien
869130561Sobrien  *val = (int) ex.X_add_number;
870130561Sobrien
871130561Sobrien  return idx;
872130561Sobrien}
873130561Sobrien
874130561Sobrien/* Here to attempt 1 pass over each input file.
875130561Sobrien   We scan argv[*] looking for filenames or exactly "" which is
876130561Sobrien   shorthand for stdin. Any argv that is NULL is not a file-name.
877130561Sobrien   We set need_pass_2 TRUE if, after this, we still have unresolved
878130561Sobrien   expressions of the form (unknown value)+-(unknown value).
879130561Sobrien
880130561Sobrien   Note the un*x semantics: there is only 1 logical input file, but it
881130561Sobrien   may be a catenation of many 'physical' input files.  */
882130561Sobrien
883130561Sobrienstatic void
884130561Sobrienperform_an_assembly_pass (int argc, char ** argv)
885130561Sobrien{
886130561Sobrien  int saw_a_file = 0;
887130561Sobrien#ifdef BFD_ASSEMBLER
888130561Sobrien  flagword applicable;
889130561Sobrien#endif
890130561Sobrien
891130561Sobrien  need_pass_2 = 0;
892130561Sobrien
893130561Sobrien#ifndef BFD_ASSEMBLER
894130561Sobrien#ifdef MANY_SEGMENTS
895130561Sobrien  {
896130561Sobrien    unsigned int i;
897130561Sobrien    for (i = SEG_E0; i < SEG_UNKNOWN; i++)
898130561Sobrien      segment_info[i].fix_root = 0;
899130561Sobrien  }
900130561Sobrien  /* Create the three fixed ones.  */
901130561Sobrien  {
902130561Sobrien    segT seg;
903130561Sobrien
904130561Sobrien#ifdef TE_APOLLO
905130561Sobrien    seg = subseg_new (".wtext", 0);
906130561Sobrien#else
907130561Sobrien    seg = subseg_new (".text", 0);
908130561Sobrien#endif
909130561Sobrien    assert (seg == SEG_E0);
910130561Sobrien    seg = subseg_new (".data", 0);
911130561Sobrien    assert (seg == SEG_E1);
912130561Sobrien    seg = subseg_new (".bss", 0);
913130561Sobrien    assert (seg == SEG_E2);
914130561Sobrien#ifdef TE_APOLLO
915130561Sobrien    create_target_segments ();
916130561Sobrien#endif
917130561Sobrien  }
918130561Sobrien
919130561Sobrien#else /* not MANY_SEGMENTS.  */
920130561Sobrien  text_fix_root = NULL;
921130561Sobrien  data_fix_root = NULL;
922130561Sobrien  bss_fix_root = NULL;
923130561Sobrien#endif /* not MANY_SEGMENTS.  */
924130561Sobrien#else /* BFD_ASSEMBLER.  */
925130561Sobrien  /* Create the standard sections, and those the assembler uses
926130561Sobrien     internally.  */
927130561Sobrien  text_section = subseg_new (TEXT_SECTION_NAME, 0);
928130561Sobrien  data_section = subseg_new (DATA_SECTION_NAME, 0);
929130561Sobrien  bss_section = subseg_new (BSS_SECTION_NAME, 0);
930130561Sobrien  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
931130561Sobrien     to have relocs, otherwise we don't find out in time.  */
932130561Sobrien  applicable = bfd_applicable_section_flags (stdoutput);
933130561Sobrien  bfd_set_section_flags (stdoutput, text_section,
934130561Sobrien			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
935130561Sobrien				       | SEC_CODE | SEC_READONLY));
936130561Sobrien  bfd_set_section_flags (stdoutput, data_section,
937130561Sobrien			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
938130561Sobrien				       | SEC_DATA));
939130561Sobrien  bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
940130561Sobrien  seg_info (bss_section)->bss = 1;
941130561Sobrien  subseg_new (BFD_ABS_SECTION_NAME, 0);
942130561Sobrien  subseg_new (BFD_UND_SECTION_NAME, 0);
943130561Sobrien  reg_section = subseg_new ("*GAS `reg' section*", 0);
944130561Sobrien  expr_section = subseg_new ("*GAS `expr' section*", 0);
945130561Sobrien
946130561Sobrien#endif /* BFD_ASSEMBLER.  */
947130561Sobrien
948130561Sobrien  subseg_set (text_section, 0);
949130561Sobrien
950130561Sobrien  /* This may add symbol table entries, which requires having an open BFD,
951130561Sobrien     and sections already created, in BFD_ASSEMBLER mode.  */
952130561Sobrien  md_begin ();
953130561Sobrien
954130561Sobrien#ifdef USING_CGEN
955130561Sobrien  gas_cgen_begin ();
956130561Sobrien#endif
957130561Sobrien#ifdef obj_begin
958130561Sobrien  obj_begin ();
959130561Sobrien#endif
960130561Sobrien
961130561Sobrien  /* Skip argv[0].  */
962130561Sobrien  argv++;
963130561Sobrien  argc--;
964130561Sobrien
965130561Sobrien  while (argc--)
966130561Sobrien    {
967130561Sobrien      if (*argv)
968130561Sobrien	{			/* Is it a file-name argument?  */
969130561Sobrien	  PROGRESS (1);
970130561Sobrien	  saw_a_file++;
971130561Sobrien	  /* argv->"" if stdin desired, else->filename.  */
972130561Sobrien	  read_a_source_file (*argv);
973130561Sobrien	}
974130561Sobrien      argv++;			/* Completed that argv.  */
975130561Sobrien    }
976130561Sobrien  if (!saw_a_file)
977130561Sobrien    read_a_source_file ("");
978130561Sobrien}
979130561Sobrien
980130561Sobrien
98177298Sobrienint
982130561Sobrienmain (int argc, char ** argv)
98333965Sjdp{
98433965Sjdp  int macro_alternate;
98533965Sjdp  int macro_strip_at;
98633965Sjdp  int keep_it;
98733965Sjdp
98833965Sjdp  start_time = get_run_time ();
98933965Sjdp
99060484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
99160484Sobrien  setlocale (LC_MESSAGES, "");
99260484Sobrien#endif
99389857Sobrien#if defined (HAVE_SETLOCALE)
99489857Sobrien  setlocale (LC_CTYPE, "");
99589857Sobrien#endif
99660484Sobrien  bindtextdomain (PACKAGE, LOCALEDIR);
99760484Sobrien  textdomain (PACKAGE);
99833965Sjdp
99933965Sjdp  if (debug_memory)
1000104834Sobrien    chunksize = 64;
100133965Sjdp
100233965Sjdp#ifdef HOST_SPECIAL_INIT
100333965Sjdp  HOST_SPECIAL_INIT (argc, argv);
100433965Sjdp#endif
100533965Sjdp
100633965Sjdp  myname = argv[0];
100733965Sjdp  xmalloc_set_program_name (myname);
100833965Sjdp
100933965Sjdp  START_PROGRESS (myname, 0);
101033965Sjdp
101133965Sjdp#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
101233965Sjdp#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
101333965Sjdp#endif
101433965Sjdp
101533965Sjdp  out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
101633965Sjdp
101733965Sjdp  hex_init ();
101833965Sjdp#ifdef BFD_ASSEMBLER
101933965Sjdp  bfd_init ();
102033965Sjdp  bfd_set_error_program_name (myname);
102133965Sjdp#endif
102233965Sjdp
102333965Sjdp#ifdef USE_EMULATIONS
102433965Sjdp  select_emulation_mode (argc, argv);
102533965Sjdp#endif
102633965Sjdp
102733965Sjdp  PROGRESS (1);
102833965Sjdp  symbol_begin ();
102933965Sjdp  frag_init ();
103033965Sjdp  subsegs_begin ();
103177298Sobrien  parse_args (&argc, &argv);
103233965Sjdp  read_begin ();
103333965Sjdp  input_scrub_begin ();
103433965Sjdp  expr_begin ();
103533965Sjdp
103633965Sjdp  if (flag_print_statistics)
103733965Sjdp    xatexit (dump_statistics);
103833965Sjdp
103933965Sjdp  macro_alternate = 0;
104033965Sjdp  macro_strip_at = 0;
104133965Sjdp#ifdef TC_I960
104233965Sjdp  macro_strip_at = flag_mri;
104333965Sjdp#endif
104433965Sjdp#ifdef TC_A29K
104533965Sjdp  /* For compatibility with the AMD 29K family macro assembler
104633965Sjdp     specification.  */
104733965Sjdp  macro_alternate = 1;
104833965Sjdp  macro_strip_at = 1;
104933965Sjdp#endif
105033965Sjdp
105133965Sjdp  macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr);
105233965Sjdp
105333965Sjdp  PROGRESS (1);
105433965Sjdp
105533965Sjdp#ifdef BFD_ASSEMBLER
105633965Sjdp  output_file_create (out_file_name);
105733965Sjdp  assert (stdoutput != 0);
105833965Sjdp#endif
105933965Sjdp
106033965Sjdp#ifdef tc_init_after_args
106133965Sjdp  tc_init_after_args ();
106233965Sjdp#endif
106333965Sjdp
106433965Sjdp  itbl_init ();
106533965Sjdp
106633965Sjdp  /* Now that we have fully initialized, and have created the output
106733965Sjdp     file, define any symbols requested by --defsym command line
106833965Sjdp     arguments.  */
106933965Sjdp  while (defsyms != NULL)
107033965Sjdp    {
107133965Sjdp      symbolS *sym;
107233965Sjdp      struct defsym_list *next;
107333965Sjdp
107433965Sjdp      sym = symbol_new (defsyms->name, absolute_section, defsyms->value,
107533965Sjdp			&zero_address_frag);
107633965Sjdp      symbol_table_insert (sym);
107733965Sjdp      next = defsyms->next;
107833965Sjdp      free (defsyms);
107933965Sjdp      defsyms = next;
108033965Sjdp    }
108133965Sjdp
108233965Sjdp  PROGRESS (1);
108333965Sjdp
108477298Sobrien  /* Assemble it.  */
108577298Sobrien  perform_an_assembly_pass (argc, argv);
108633965Sjdp
108733965Sjdp  cond_finish_check (-1);
108833965Sjdp
108933965Sjdp#ifdef md_end
109033965Sjdp  md_end ();
109133965Sjdp#endif
109233965Sjdp
1093130561Sobrien#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF)
1094130561Sobrien  if ((flag_execstack || flag_noexecstack)
1095130561Sobrien      && OUTPUT_FLAVOR == bfd_target_elf_flavour)
1096130561Sobrien    {
1097130561Sobrien      segT gnustack;
1098130561Sobrien
1099130561Sobrien      gnustack = subseg_new (".note.GNU-stack", 0);
1100130561Sobrien      bfd_set_section_flags (stdoutput, gnustack,
1101130561Sobrien			     SEC_READONLY | (flag_execstack ? SEC_CODE : 0));
1102130561Sobrien
1103130561Sobrien    }
1104130561Sobrien#endif
1105130561Sobrien
110677298Sobrien  /* If we've been collecting dwarf2 .debug_line info, either for
110777298Sobrien     assembly debugging or on behalf of the compiler, emit it now.  */
110877298Sobrien  dwarf2_finish ();
110977298Sobrien
1110130561Sobrien  /* If we constructed dwarf2 .eh_frame info, either via .cfi
1111130561Sobrien     directives from the user or by the backend, emit it now.  */
1112130561Sobrien  cfi_finish ();
1113130561Sobrien
111433965Sjdp  if (seen_at_least_1_file ()
111533965Sjdp      && (flag_always_generate_output || had_errors () == 0))
111633965Sjdp    keep_it = 1;
111733965Sjdp  else
111833965Sjdp    keep_it = 0;
111933965Sjdp
112038889Sjdp#if defined (BFD_ASSEMBLER) || !defined (BFD)
112138889Sjdp  /* This used to be done at the start of write_object_file in
112238889Sjdp     write.c, but that caused problems when doing listings when
112338889Sjdp     keep_it was zero.  This could probably be moved above md_end, but
112438889Sjdp     I didn't want to risk the change.  */
112538889Sjdp  subsegs_finish ();
112638889Sjdp#endif
112738889Sjdp
112833965Sjdp  if (keep_it)
112933965Sjdp    write_object_file ();
113033965Sjdp
113133965Sjdp#ifndef NO_LISTING
113233965Sjdp  listing_print (listing_filename);
113333965Sjdp#endif
113433965Sjdp
1135130561Sobrien#ifndef OBJ_VMS /* Does its own file handling.  */
113633965Sjdp#ifndef BFD_ASSEMBLER
113733965Sjdp  if (keep_it)
113833965Sjdp#endif
113933965Sjdp    output_file_close (out_file_name);
114033965Sjdp#endif
114133965Sjdp
114277298Sobrien  if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0)
114377298Sobrien    as_bad (_("%d warnings, treating warnings as errors"), had_warnings ());
114460484Sobrien
114533965Sjdp  if (had_errors () > 0 && ! flag_always_generate_output)
114633965Sjdp    keep_it = 0;
114733965Sjdp
114833965Sjdp  if (!keep_it)
114933965Sjdp    unlink (out_file_name);
115033965Sjdp
115133965Sjdp  input_scrub_end ();
115233965Sjdp
115333965Sjdp  END_PROGRESS (myname);
115433965Sjdp
115533965Sjdp  /* Use xexit instead of return, because under VMS environments they
115633965Sjdp     may not place the same interpretation on the value given.  */
115733965Sjdp  if (had_errors () > 0)
115833965Sjdp    xexit (EXIT_FAILURE);
115938889Sjdp
116038889Sjdp  /* Only generate dependency file if assembler was successful.  */
116138889Sjdp  print_dependencies ();
116238889Sjdp
116333965Sjdp  xexit (EXIT_SUCCESS);
116433965Sjdp}
116533965Sjdp
1166