133965Sjdp/* as.c - GAS main program.
278828Sobrien   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3218822Sdim   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
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
20218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, 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#define COMMON
3533965Sjdp
3633965Sjdp#include "as.h"
3733965Sjdp#include "subsegs.h"
3833965Sjdp#include "output-file.h"
3933965Sjdp#include "sb.h"
4033965Sjdp#include "macro.h"
4177298Sobrien#include "dwarf2dbg.h"
42130561Sobrien#include "dw2gencfi.h"
43130561Sobrien#include "bfdver.h"
44130561Sobrien
4560484Sobrien#ifdef HAVE_ITBL_CPU
4660484Sobrien#include "itbl-ops.h"
4760484Sobrien#else
4833965Sjdp#define itbl_parse(itbl_file) 1
4933965Sjdp#define itbl_init()
5033965Sjdp#endif
5133965Sjdp
5233965Sjdp#ifdef HAVE_SBRK
5333965Sjdp#ifdef NEED_DECLARATION_SBRK
5433965Sjdpextern PTR sbrk ();
5533965Sjdp#endif
5633965Sjdp#endif
5733965Sjdp
58130561Sobrien#ifdef USING_CGEN
59130561Sobrien/* Perform any cgen specific initialisation for gas.  */
60130561Sobrienextern void gas_cgen_begin (void);
61130561Sobrien#endif
6233965Sjdp
63130561Sobrien/* Keep a record of the itbl files we read in.  */
64130561Sobrienstruct itbl_file_list
65130561Sobrien{
66130561Sobrien  struct itbl_file_list *next;
67130561Sobrien  char *name;
68130561Sobrien};
69130561Sobrien
70130561Sobrien/* We build a list of defsyms as we read the options, and then define
71130561Sobrien   them after we have initialized everything.  */
72130561Sobrienstruct defsym_list
73130561Sobrien{
74130561Sobrien  struct defsym_list *next;
75130561Sobrien  char *name;
76130561Sobrien  valueT value;
77130561Sobrien};
78130561Sobrien
79130561Sobrien
8077298Sobrien/* True if a listing is wanted.  */
8177298Sobrienint listing;
8233965Sjdp
8338889Sjdp/* Type of debugging to generate.  */
8477298Sobrienenum debug_info_type debug_type = DEBUG_UNSPECIFIED;
85130561Sobrienint use_gnu_debug_info_extensions = 0;
8638889Sjdp
87218822Sdim#ifndef MD_DEBUG_FORMAT_SELECTOR
88218822Sdim#define MD_DEBUG_FORMAT_SELECTOR NULL
89218822Sdim#endif
90218822Sdimstatic enum debug_info_type (*md_debug_format_selector) (int *) = MD_DEBUG_FORMAT_SELECTOR;
91218822Sdim
9233965Sjdp/* Maximum level of macro nesting.  */
9333965Sjdpint max_macro_nest = 100;
9433965Sjdp
9577298Sobrien/* argv[0]  */
96218822Sdimstatic char * 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
109130561SobriensegT reg_section;
110130561SobriensegT expr_section;
111130561SobriensegT text_section;
112130561SobriensegT data_section;
113130561SobriensegT bss_section;
11433965Sjdp
115130561Sobrien/* Name of listing file.  */
116130561Sobrienstatic char *listing_filename = NULL;
117130561Sobrien
11833965Sjdpstatic struct defsym_list *defsyms;
11933965Sjdp
120130561Sobrienstatic struct itbl_file_list *itbl_files;
12133965Sjdp
122130561Sobrienstatic long start_time;
12333965Sjdp
124218822Sdimstatic int flag_macro_alternate;
125218822Sdim
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
220218822Sdim  fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s\n"),
22189857Sobrien	   VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
22260484Sobrien}
22360484Sobrien
22460484Sobrienstatic void
225130561Sobrienshow_usage (FILE * stream)
22660484Sobrien{
22760484Sobrien  fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname);
22860484Sobrien
22960484Sobrien  fprintf (stream, _("\
23060484SobrienOptions:\n\
23160484Sobrien  -a[sub-option...]	  turn on listings\n\
23260484Sobrien                      	  Sub-options [default hls]:\n\
23360484Sobrien                      	  c      omit false conditionals\n\
23460484Sobrien                      	  d      omit debugging directives\n\
23560484Sobrien                      	  h      include high-level source\n\
23660484Sobrien                      	  l      include assembly\n\
23760484Sobrien                      	  m      include macro expansions\n\
23860484Sobrien                      	  n      omit forms processing\n\
23960484Sobrien                      	  s      include symbols\n\
24060484Sobrien                      	  =FILE  list to FILE (must be last sub-option)\n"));
24160484Sobrien
24260484Sobrien  fprintf (stream, _("\
243218822Sdim  --alternate             initially turn on alternate macro syntax\n"));
244218822Sdim  fprintf (stream, _("\
24560484Sobrien  -D                      produce assembler debugging messages\n"));
24660484Sobrien  fprintf (stream, _("\
24760484Sobrien  --defsym SYM=VAL        define symbol SYM to given value\n"));
24860484Sobrien#ifdef USE_EMULATIONS
24960484Sobrien  {
25060484Sobrien    int i;
25160484Sobrien    char *def_em;
25260484Sobrien
25360484Sobrien    fprintf (stream, "\
25460484Sobrien  --em=[");
25577298Sobrien    for (i = 0; i < n_emulations - 1; i++)
25660484Sobrien      fprintf (stream, "%s | ", emulations[i]->name);
25760484Sobrien    fprintf (stream, "%s]\n", emulations[i]->name);
25860484Sobrien
25960484Sobrien    def_em = getenv (EMULATION_ENVIRON);
26077298Sobrien    if (!def_em)
26160484Sobrien      def_em = DEFAULT_EMULATION;
26260484Sobrien    fprintf (stream, _("\
26360484Sobrien                          emulate output (default %s)\n"), def_em);
26460484Sobrien  }
26560484Sobrien#endif
266218822Sdim#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
26760484Sobrien  fprintf (stream, _("\
268130561Sobrien  --execstack             require executable stack for this object\n"));
269130561Sobrien  fprintf (stream, _("\
270130561Sobrien  --noexecstack           don't require executable stack for this object\n"));
271130561Sobrien#endif
272130561Sobrien  fprintf (stream, _("\
27360484Sobrien  -f                      skip whitespace and comment preprocessing\n"));
27460484Sobrien  fprintf (stream, _("\
275218822Sdim  -g --gen-debug          generate debugging information\n"));
27660484Sobrien  fprintf (stream, _("\
277218822Sdim  --gstabs                generate STABS debugging information\n"));
278130561Sobrien  fprintf (stream, _("\
279218822Sdim  --gstabs+               generate STABS debug info with GNU extensions\n"));
28060484Sobrien  fprintf (stream, _("\
281218822Sdim  --gdwarf-2              generate DWARF2 debugging information\n"));
282218822Sdim  fprintf (stream, _("\
283218822Sdim  --hash-size=<value>     set the hash table size close to <value>\n"));
284218822Sdim  fprintf (stream, _("\
28560484Sobrien  --help                  show this message and exit\n"));
28660484Sobrien  fprintf (stream, _("\
28777298Sobrien  --target-help           show target specific options\n"));
28877298Sobrien  fprintf (stream, _("\
28960484Sobrien  -I DIR                  add DIR to search list for .include directives\n"));
29060484Sobrien  fprintf (stream, _("\
29160484Sobrien  -J                      don't warn about signed overflow\n"));
29260484Sobrien  fprintf (stream, _("\
29360484Sobrien  -K                      warn when differences altered for long displacements\n"));
29460484Sobrien  fprintf (stream, _("\
29560484Sobrien  -L,--keep-locals        keep local symbols (e.g. starting with `L')\n"));
29660484Sobrien  fprintf (stream, _("\
29760484Sobrien  -M,--mri                assemble in MRI compatibility mode\n"));
29860484Sobrien  fprintf (stream, _("\
29960484Sobrien  --MD FILE               write dependency information in FILE (default none)\n"));
30060484Sobrien  fprintf (stream, _("\
30160484Sobrien  -nocpp                  ignored\n"));
30260484Sobrien  fprintf (stream, _("\
30360484Sobrien  -o OBJFILE              name the object-file output OBJFILE (default a.out)\n"));
30460484Sobrien  fprintf (stream, _("\
30560484Sobrien  -R                      fold data section into text section\n"));
30660484Sobrien  fprintf (stream, _("\
307218822Sdim  --reduce-memory-overheads \n\
308218822Sdim                          prefer smaller memory use at the cost of longer\n\
309218822Sdim                          assembly times\n"));
310218822Sdim  fprintf (stream, _("\
31160484Sobrien  --statistics            print various measured statistics from execution\n"));
31260484Sobrien  fprintf (stream, _("\
31360484Sobrien  --strip-local-absolute  strip local absolute symbols\n"));
31460484Sobrien  fprintf (stream, _("\
31560484Sobrien  --traditional-format    Use same format as native assembler when possible\n"));
31660484Sobrien  fprintf (stream, _("\
31760484Sobrien  --version               print assembler version number and exit\n"));
31860484Sobrien  fprintf (stream, _("\
31960484Sobrien  -W  --no-warn           suppress warnings\n"));
32060484Sobrien  fprintf (stream, _("\
32160484Sobrien  --warn                  don't suppress warnings\n"));
32260484Sobrien  fprintf (stream, _("\
32360484Sobrien  --fatal-warnings        treat warnings as errors\n"));
32460484Sobrien  fprintf (stream, _("\
32560484Sobrien  --itbl INSTTBL          extend instruction set to include instructions\n\
32660484Sobrien                          matching the specifications defined in file INSTTBL\n"));
32760484Sobrien  fprintf (stream, _("\
32860484Sobrien  -w                      ignored\n"));
32960484Sobrien  fprintf (stream, _("\
33060484Sobrien  -X                      ignored\n"));
33160484Sobrien  fprintf (stream, _("\
33260484Sobrien  -Z                      generate object file even after errors\n"));
33360484Sobrien  fprintf (stream, _("\
33460484Sobrien  --listing-lhs-width     set the width in words of the output data column of\n\
33560484Sobrien                          the listing\n"));
33660484Sobrien  fprintf (stream, _("\
33760484Sobrien  --listing-lhs-width2    set the width in words of the continuation lines\n\
33860484Sobrien                          of the output data column; ignored if smaller than\n\
33960484Sobrien                          the width of the first line\n"));
34060484Sobrien  fprintf (stream, _("\
34160484Sobrien  --listing-rhs-width     set the max width in characters of the lines from\n\
34260484Sobrien                          the source file\n"));
34360484Sobrien  fprintf (stream, _("\
34460484Sobrien  --listing-cont-lines    set the maximum number of continuation lines used\n\
34560484Sobrien                          for the output data column of the listing\n"));
346218822Sdim  fprintf (stream, _("\
347218822Sdim  @FILE                   read options from FILE\n"));
34860484Sobrien
34960484Sobrien  md_show_usage (stream);
35060484Sobrien
35160484Sobrien  fputc ('\n', stream);
352218822Sdim
353218822Sdim  if (REPORT_BUGS_TO[0] && stream == stdout)
354218822Sdim    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
35560484Sobrien}
35660484Sobrien
35777298Sobrien/* Since it is easy to do here we interpret the special arg "-"
35877298Sobrien   to mean "use stdin" and we set that argv[] pointing to "".
35977298Sobrien   After we have munged argv[], the only things left are source file
36077298Sobrien   name(s) and ""(s) denoting stdin. These file names are used
36177298Sobrien   (perhaps more than once) later.
36233965Sjdp
36377298Sobrien   check for new machine-dep cmdline options in
36477298Sobrien   md_parse_option definitions in config/tc-*.c.  */
36577298Sobrien
36633965Sjdpstatic void
367130561Sobrienparse_args (int * pargc, char *** pargv)
36833965Sjdp{
369130561Sobrien  int old_argc;
370130561Sobrien  int new_argc;
371130561Sobrien  char ** old_argv;
372130561Sobrien  char ** new_argv;
37333965Sjdp  /* Starting the short option string with '-' is for programs that
37433965Sjdp     expect options and other ARGV-elements in any order and that care about
37533965Sjdp     the ordering of the two.  We describe each non-option ARGV-element
37633965Sjdp     as if it were the argument of an option with character code 1.  */
37733965Sjdp  char *shortopts;
378104834Sobrien  extern const char *md_shortopts;
379130561Sobrien  static const char std_shortopts[] =
380130561Sobrien  {
38177298Sobrien    '-', 'J',
38233965Sjdp#ifndef WORKING_DOT_WORD
38377298Sobrien    /* -K is not meaningful if .word is not being hacked.  */
38477298Sobrien    'K',
38533965Sjdp#endif
386218822Sdim    'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'g', ':',':', 'I', ':', 'o', ':',
38733965Sjdp#ifndef VMS
38877298Sobrien    /* -v takes an argument on VMS, so we don't make it a generic
38977298Sobrien       option.  */
39077298Sobrien    'v',
39133965Sjdp#endif
39277298Sobrien    'w', 'X',
393130561Sobrien    /* New option for extending instruction set (see also --itbl below).  */
39477298Sobrien    't', ':',
39577298Sobrien    '\0'
39677298Sobrien  };
39733965Sjdp  struct option *longopts;
39833965Sjdp  extern struct option md_longopts[];
39933965Sjdp  extern size_t md_longopts_size;
400130561Sobrien  /* Codes used for the long options with no short synonyms.  */
401130561Sobrien  enum option_values
402130561Sobrien    {
403130561Sobrien      OPTION_HELP = OPTION_STD_BASE,
404130561Sobrien      OPTION_NOCPP,
405130561Sobrien      OPTION_STATISTICS,
406130561Sobrien      OPTION_VERSION,
407130561Sobrien      OPTION_DUMPCONFIG,
408130561Sobrien      OPTION_VERBOSE,
409130561Sobrien      OPTION_EMULATION,
410130561Sobrien      OPTION_DEFSYM,
411130561Sobrien      OPTION_INSTTBL,
412130561Sobrien      OPTION_LISTING_LHS_WIDTH,
413130561Sobrien      OPTION_LISTING_LHS_WIDTH2,
414130561Sobrien      OPTION_LISTING_RHS_WIDTH,
415130561Sobrien      OPTION_LISTING_CONT_LINES,
416130561Sobrien      OPTION_DEPFILE,
417130561Sobrien      OPTION_GSTABS,
418130561Sobrien      OPTION_GSTABS_PLUS,
419218822Sdim      OPTION_GDWARF2,
420130561Sobrien      OPTION_STRIP_LOCAL_ABSOLUTE,
421130561Sobrien      OPTION_TRADITIONAL_FORMAT,
422130561Sobrien      OPTION_WARN,
423130561Sobrien      OPTION_TARGET_HELP,
424130561Sobrien      OPTION_EXECSTACK,
425130561Sobrien      OPTION_NOEXECSTACK,
426218822Sdim      OPTION_ALTERNATE,
427218822Sdim      OPTION_AL,
428218822Sdim      OPTION_HASH_TABLE_SIZE,
429218822Sdim      OPTION_REDUCE_MEMORY_OVERHEADS,
430130561Sobrien      OPTION_WARN_FATAL
431218822Sdim    /* When you add options here, check that they do
432218822Sdim       not collide with OPTION_MD_BASE.  See as.h.  */
433130561Sobrien    };
434130561Sobrien
435130561Sobrien  static const struct option std_longopts[] =
436130561Sobrien  {
437218822Sdim    /* Note: commas are placed at the start of the line rather than
438218822Sdim       the end of the preceeding line so that it is simpler to
439218822Sdim       selectively add and remove lines from this list.  */
440218822Sdim    {"alternate", no_argument, NULL, OPTION_ALTERNATE}
441218822Sdim    /* The entry for "a" is here to prevent getopt_long_only() from
442218822Sdim       considering that -a is an abbreviation for --alternate.  This is
443218822Sdim       necessary because -a=<FILE> is a valid switch but getopt would
444218822Sdim       normally reject it since --alternate does not take an argument.  */
445218822Sdim    ,{"a", optional_argument, NULL, 'a'}
446218822Sdim    /* Handle -al=<FILE>.  */
447218822Sdim    ,{"al", optional_argument, NULL, OPTION_AL}
448218822Sdim    ,{"defsym", required_argument, NULL, OPTION_DEFSYM}
449218822Sdim    ,{"dump-config", no_argument, NULL, OPTION_DUMPCONFIG}
450218822Sdim    ,{"emulation", required_argument, NULL, OPTION_EMULATION}
451218822Sdim#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
452218822Sdim    ,{"execstack", no_argument, NULL, OPTION_EXECSTACK}
453218822Sdim    ,{"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK}
454218822Sdim#endif
455218822Sdim    ,{"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
456218822Sdim    ,{"gdwarf-2", no_argument, NULL, OPTION_GDWARF2}
457218822Sdim    /* GCC uses --gdwarf-2 but GAS uses to use --gdwarf2,
458218822Sdim       so we keep it here for backwards compatibility.  */
459218822Sdim    ,{"gdwarf2", no_argument, NULL, OPTION_GDWARF2}
460218822Sdim    ,{"gen-debug", no_argument, NULL, 'g'}
461218822Sdim    ,{"gstabs", no_argument, NULL, OPTION_GSTABS}
462218822Sdim    ,{"gstabs+", no_argument, NULL, OPTION_GSTABS_PLUS}
463218822Sdim    ,{"hash-size", required_argument, NULL, OPTION_HASH_TABLE_SIZE}
464218822Sdim    ,{"help", no_argument, NULL, OPTION_HELP}
46533965Sjdp    /* New option for extending instruction set (see also -t above).
46633965Sjdp       The "-t file" or "--itbl file" option extends the basic set of
46733965Sjdp       valid instructions by reading "file", a text file containing a
46833965Sjdp       list of instruction formats.  The additional opcodes and their
46933965Sjdp       formats are added to the built-in set of instructions, and
47033965Sjdp       mnemonics for new registers may also be defined.  */
471218822Sdim    ,{"itbl", required_argument, NULL, OPTION_INSTTBL}
472218822Sdim    /* getopt allows abbreviations, so we do this to stop it from
473218822Sdim       treating -k as an abbreviation for --keep-locals.  Some
474218822Sdim       ports use -k to enable PIC assembly.  */
475218822Sdim    ,{"keep-locals", no_argument, NULL, 'L'}
476218822Sdim    ,{"keep-locals", no_argument, NULL, 'L'}
477218822Sdim    ,{"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH}
478218822Sdim    ,{"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2}
479218822Sdim    ,{"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH}
480218822Sdim    ,{"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES}
481218822Sdim    ,{"MD", required_argument, NULL, OPTION_DEPFILE}
482218822Sdim    ,{"mri", no_argument, NULL, 'M'}
483218822Sdim    ,{"nocpp", no_argument, NULL, OPTION_NOCPP}
484218822Sdim    ,{"no-warn", no_argument, NULL, 'W'}
485218822Sdim    ,{"reduce-memory-overheads", no_argument, NULL, OPTION_REDUCE_MEMORY_OVERHEADS}
486218822Sdim    ,{"statistics", no_argument, NULL, OPTION_STATISTICS}
487218822Sdim    ,{"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE}
488218822Sdim    ,{"version", no_argument, NULL, OPTION_VERSION}
489218822Sdim    ,{"verbose", no_argument, NULL, OPTION_VERBOSE}
490218822Sdim    ,{"target-help", no_argument, NULL, OPTION_TARGET_HELP}
491218822Sdim    ,{"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT}
492218822Sdim    ,{"warn", no_argument, NULL, OPTION_WARN}
49333965Sjdp  };
49433965Sjdp
49577298Sobrien  /* Construct the option lists from the standard list and the target
49677298Sobrien     dependent list.  Include space for an extra NULL option and
49777298Sobrien     always NULL terminate.  */
49833965Sjdp  shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
499130561Sobrien  longopts = xmalloc (sizeof (std_longopts) + md_longopts_size + sizeof (struct option));
50033965Sjdp  memcpy (longopts, std_longopts, sizeof (std_longopts));
501130561Sobrien  memcpy (((char *) longopts) + sizeof (std_longopts), md_longopts, md_longopts_size);
502130561Sobrien  memset (((char *) longopts) + sizeof (std_longopts) + md_longopts_size,
50377298Sobrien	  0, sizeof (struct option));
50433965Sjdp
50533965Sjdp  /* Make a local copy of the old argv.  */
50633965Sjdp  old_argc = *pargc;
50733965Sjdp  old_argv = *pargv;
50833965Sjdp
50933965Sjdp  /* Initialize a new argv that contains no options.  */
510130561Sobrien  new_argv = xmalloc (sizeof (char *) * (old_argc + 1));
51133965Sjdp  new_argv[0] = old_argv[0];
51233965Sjdp  new_argc = 1;
51333965Sjdp  new_argv[new_argc] = NULL;
51433965Sjdp
51533965Sjdp  while (1)
51633965Sjdp    {
51733965Sjdp      /* getopt_long_only is like getopt_long, but '-' as well as '--' can
51833965Sjdp	 indicate a long option.  */
51933965Sjdp      int longind;
52033965Sjdp      int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
52133965Sjdp				   &longind);
52233965Sjdp
52333965Sjdp      if (optc == -1)
52433965Sjdp	break;
52533965Sjdp
52633965Sjdp      switch (optc)
52733965Sjdp	{
52833965Sjdp	default:
52933965Sjdp	  /* md_parse_option should return 1 if it recognizes optc,
53033965Sjdp	     0 if not.  */
53133965Sjdp	  if (md_parse_option (optc, optarg) != 0)
53233965Sjdp	    break;
53333965Sjdp	  /* `-v' isn't included in the general short_opts list, so check for
534130561Sobrien	     it explicitly here before deciding we've gotten a bad argument.  */
53533965Sjdp	  if (optc == 'v')
53633965Sjdp	    {
53733965Sjdp#ifdef VMS
53833965Sjdp	      /* Telling getopt to treat -v's value as optional can result
53933965Sjdp		 in it picking up a following filename argument here.  The
54033965Sjdp		 VMS code in md_parse_option can return 0 in that case,
54133965Sjdp		 but it has no way of pushing the filename argument back.  */
54233965Sjdp	      if (optarg && *optarg)
54377298Sobrien		new_argv[new_argc++] = optarg, new_argv[new_argc] = NULL;
54433965Sjdp	      else
54533965Sjdp#else
54633965Sjdp	      case 'v':
54733965Sjdp#endif
54833965Sjdp	      case OPTION_VERBOSE:
54933965Sjdp		print_version_id ();
550130561Sobrien		verbose = 1;
55133965Sjdp	      break;
55233965Sjdp	    }
553218822Sdim	  else
554218822Sdim	    as_bad (_("unrecognized option -%c%s"), optc, optarg ? optarg : "");
55577298Sobrien	  /* Fall through.  */
55633965Sjdp
55733965Sjdp	case '?':
55833965Sjdp	  exit (EXIT_FAILURE);
55933965Sjdp
56033965Sjdp	case 1:			/* File name.  */
56133965Sjdp	  if (!strcmp (optarg, "-"))
56233965Sjdp	    optarg = "";
56333965Sjdp	  new_argv[new_argc++] = optarg;
56433965Sjdp	  new_argv[new_argc] = NULL;
56533965Sjdp	  break;
56633965Sjdp
56777298Sobrien	case OPTION_TARGET_HELP:
568104834Sobrien	  md_show_usage (stdout);
569104834Sobrien	  exit (EXIT_SUCCESS);
57077298Sobrien
57133965Sjdp	case OPTION_HELP:
57233965Sjdp	  show_usage (stdout);
57333965Sjdp	  exit (EXIT_SUCCESS);
57433965Sjdp
57533965Sjdp	case OPTION_NOCPP:
57633965Sjdp	  break;
57733965Sjdp
57833965Sjdp	case OPTION_STATISTICS:
57933965Sjdp	  flag_print_statistics = 1;
58033965Sjdp	  break;
58133965Sjdp
58238889Sjdp	case OPTION_STRIP_LOCAL_ABSOLUTE:
58338889Sjdp	  flag_strip_local_absolute = 1;
58438889Sjdp	  break;
58538889Sjdp
58638889Sjdp	case OPTION_TRADITIONAL_FORMAT:
58738889Sjdp	  flag_traditional_format = 1;
58838889Sjdp	  break;
58938889Sjdp
59033965Sjdp	case OPTION_VERSION:
59133965Sjdp	  /* This output is intended to follow the GNU standards document.  */
59289857Sobrien	  printf (_("GNU assembler %s\n"), BFD_VERSION_STRING);
593218822Sdim	  printf (_("Copyright 2007 Free Software Foundation, Inc.\n"));
59460484Sobrien	  printf (_("\
59533965SjdpThis program is free software; you may redistribute it under the terms of\n\
59660484Sobrienthe GNU General Public License.  This program has absolutely no warranty.\n"));
59760484Sobrien	  printf (_("This assembler was configured for a target of `%s'.\n"),
59833965Sjdp		  TARGET_ALIAS);
59933965Sjdp	  exit (EXIT_SUCCESS);
60033965Sjdp
60133965Sjdp	case OPTION_EMULATION:
60233965Sjdp#ifdef USE_EMULATIONS
60333965Sjdp	  if (strcmp (optarg, this_emulation->name))
60460484Sobrien	    as_fatal (_("multiple emulation names specified"));
60533965Sjdp#else
60660484Sobrien	  as_fatal (_("emulations not handled in this configuration"));
60733965Sjdp#endif
60833965Sjdp	  break;
60933965Sjdp
61033965Sjdp	case OPTION_DUMPCONFIG:
61160484Sobrien	  fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS);
61260484Sobrien	  fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL);
61360484Sobrien	  fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU);
61433965Sjdp#ifdef TARGET_OBJ_FORMAT
61560484Sobrien	  fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT);
61633965Sjdp#endif
61733965Sjdp#ifdef TARGET_FORMAT
61860484Sobrien	  fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT);
61933965Sjdp#endif
62033965Sjdp	  exit (EXIT_SUCCESS);
62133965Sjdp
62233965Sjdp	case OPTION_DEFSYM:
62333965Sjdp	  {
62433965Sjdp	    char *s;
62577298Sobrien	    valueT i;
62633965Sjdp	    struct defsym_list *n;
62733965Sjdp
62833965Sjdp	    for (s = optarg; *s != '\0' && *s != '='; s++)
62933965Sjdp	      ;
63033965Sjdp	    if (*s == '\0')
63160484Sobrien	      as_fatal (_("bad defsym; format is --defsym name=value"));
63233965Sjdp	    *s++ = '\0';
63377298Sobrien	    i = bfd_scan_vma (s, (const char **) NULL, 0);
634130561Sobrien	    n = xmalloc (sizeof *n);
63533965Sjdp	    n->next = defsyms;
63633965Sjdp	    n->name = optarg;
63733965Sjdp	    n->value = i;
63833965Sjdp	    defsyms = n;
63933965Sjdp	  }
64033965Sjdp	  break;
64133965Sjdp
64233965Sjdp	case OPTION_INSTTBL:
64333965Sjdp	case 't':
64433965Sjdp	  {
64577298Sobrien	    /* optarg is the name of the file containing the instruction
64677298Sobrien	       formats, opcodes, register names, etc.  */
64733965Sjdp	    struct itbl_file_list *n;
64833965Sjdp
64938889Sjdp	    if (optarg == NULL)
65038889Sjdp	      {
65189857Sobrien		as_warn (_("no file name following -t option"));
65238889Sjdp		break;
65338889Sjdp	      }
65477298Sobrien
655130561Sobrien	    n = xmalloc (sizeof * n);
65633965Sjdp	    n->next = itbl_files;
65733965Sjdp	    n->name = optarg;
65833965Sjdp	    itbl_files = n;
65933965Sjdp
66033965Sjdp	    /* Parse the file and add the new instructions to our internal
66177298Sobrien	       table.  If multiple instruction tables are specified, the
66277298Sobrien	       information from this table gets appended onto the existing
66377298Sobrien	       internal table.  */
66433965Sjdp	    itbl_files->name = xstrdup (optarg);
66533965Sjdp	    if (itbl_parse (itbl_files->name) != 0)
66689857Sobrien	      as_fatal (_("failed to read instruction table %s\n"),
66789857Sobrien			itbl_files->name);
66833965Sjdp	  }
66933965Sjdp	  break;
67033965Sjdp
67138889Sjdp	case OPTION_DEPFILE:
67238889Sjdp	  start_dependencies (optarg);
67338889Sjdp	  break;
67438889Sjdp
675218822Sdim	case 'g':
676218822Sdim	  /* Some backends, eg Alpha and Mips, use the -g switch for their
677218822Sdim	     own purposes.  So we check here for an explicit -g and allow
678218822Sdim	     the backend to decide if it wants to process it.  */
679218822Sdim	  if (   old_argv[optind - 1][1] == 'g'
680218822Sdim	      && md_parse_option (optc, optarg))
681218822Sdim	    continue;
682218822Sdim
683218822Sdim	  if (md_debug_format_selector)
684218822Sdim	    debug_type = md_debug_format_selector (& use_gnu_debug_info_extensions);
685218822Sdim	  else if (IS_ELF)
686218822Sdim	    debug_type = DEBUG_DWARF2;
687218822Sdim	  else
688218822Sdim	    debug_type = DEBUG_STABS;
689218822Sdim	  break;
690218822Sdim
691130561Sobrien	case OPTION_GSTABS_PLUS:
692130561Sobrien	  use_gnu_debug_info_extensions = 1;
693130561Sobrien	  /* Fall through.  */
69438889Sjdp	case OPTION_GSTABS:
69538889Sjdp	  debug_type = DEBUG_STABS;
69638889Sjdp	  break;
69777298Sobrien
69860484Sobrien	case OPTION_GDWARF2:
69960484Sobrien	  debug_type = DEBUG_DWARF2;
70060484Sobrien	  break;
70160484Sobrien
70233965Sjdp	case 'J':
70333965Sjdp	  flag_signed_overflow_ok = 1;
70433965Sjdp	  break;
70533965Sjdp
70633965Sjdp#ifndef WORKING_DOT_WORD
70733965Sjdp	case 'K':
70833965Sjdp	  flag_warn_displacement = 1;
70933965Sjdp	  break;
71033965Sjdp#endif
71133965Sjdp	case 'L':
71233965Sjdp	  flag_keep_locals = 1;
71333965Sjdp	  break;
71433965Sjdp
71538889Sjdp	case OPTION_LISTING_LHS_WIDTH:
71677298Sobrien	  listing_lhs_width = atoi (optarg);
71738889Sjdp	  if (listing_lhs_width_second < listing_lhs_width)
71838889Sjdp	    listing_lhs_width_second = listing_lhs_width;
71938889Sjdp	  break;
72038889Sjdp	case OPTION_LISTING_LHS_WIDTH2:
72138889Sjdp	  {
72277298Sobrien	    int tmp = atoi (optarg);
723218822Sdim
72438889Sjdp	    if (tmp > listing_lhs_width)
72538889Sjdp	      listing_lhs_width_second = tmp;
72638889Sjdp	  }
72738889Sjdp	  break;
72838889Sjdp	case OPTION_LISTING_RHS_WIDTH:
72977298Sobrien	  listing_rhs_width = atoi (optarg);
73038889Sjdp	  break;
73138889Sjdp	case OPTION_LISTING_CONT_LINES:
73277298Sobrien	  listing_lhs_cont_lines = atoi (optarg);
73338889Sjdp	  break;
73438889Sjdp
73533965Sjdp	case 'M':
73633965Sjdp	  flag_mri = 1;
73733965Sjdp#ifdef TC_M68K
73833965Sjdp	  flag_m68k_mri = 1;
73933965Sjdp#endif
74033965Sjdp	  break;
74133965Sjdp
74233965Sjdp	case 'R':
74333965Sjdp	  flag_readonly_data_in_text = 1;
74433965Sjdp	  break;
74533965Sjdp
74633965Sjdp	case 'W':
74733965Sjdp	  flag_no_warnings = 1;
74833965Sjdp	  break;
74933965Sjdp
75060484Sobrien	case OPTION_WARN:
75160484Sobrien	  flag_no_warnings = 0;
75260484Sobrien	  flag_fatal_warnings = 0;
75360484Sobrien	  break;
75460484Sobrien
75560484Sobrien	case OPTION_WARN_FATAL:
75660484Sobrien	  flag_no_warnings = 0;
75760484Sobrien	  flag_fatal_warnings = 1;
75860484Sobrien	  break;
75960484Sobrien
760218822Sdim#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
761130561Sobrien	case OPTION_EXECSTACK:
762130561Sobrien	  flag_execstack = 1;
763130561Sobrien	  flag_noexecstack = 0;
764130561Sobrien	  break;
765130561Sobrien
766130561Sobrien	case OPTION_NOEXECSTACK:
767130561Sobrien	  flag_noexecstack = 1;
768130561Sobrien	  flag_execstack = 0;
769130561Sobrien	  break;
770130561Sobrien#endif
77133965Sjdp	case 'Z':
77233965Sjdp	  flag_always_generate_output = 1;
77333965Sjdp	  break;
77433965Sjdp
775218822Sdim 	case OPTION_AL:
776218822Sdim	  listing |= LISTING_LISTING;
777218822Sdim	  if (optarg)
778218822Sdim	    listing_filename = xstrdup (optarg);
779218822Sdim	  break;
780218822Sdim
781218822Sdim 	case OPTION_ALTERNATE:
782218822Sdim 	  optarg = old_argv [optind - 1];
783218822Sdim 	  while (* optarg == '-')
784218822Sdim 	    optarg ++;
785218822Sdim
786218822Sdim 	  if (strcmp (optarg, "alternate") == 0)
787218822Sdim 	    {
788218822Sdim 	      flag_macro_alternate = 1;
789218822Sdim 	      break;
790218822Sdim 	    }
791218822Sdim 	  optarg ++;
792218822Sdim 	  /* Fall through.  */
793218822Sdim
79433965Sjdp	case 'a':
79533965Sjdp	  if (optarg)
79633965Sjdp	    {
797218822Sdim	      if (optarg != old_argv[optind] && optarg[-1] == '=')
798218822Sdim		--optarg;
799218822Sdim
80077298Sobrien	      if (md_parse_option (optc, optarg) != 0)
80177298Sobrien		break;
80277298Sobrien
80333965Sjdp	      while (*optarg)
80433965Sjdp		{
80533965Sjdp		  switch (*optarg)
80633965Sjdp		    {
80733965Sjdp		    case 'c':
80833965Sjdp		      listing |= LISTING_NOCOND;
80933965Sjdp		      break;
81033965Sjdp		    case 'd':
81133965Sjdp		      listing |= LISTING_NODEBUG;
81233965Sjdp		      break;
81333965Sjdp		    case 'h':
81433965Sjdp		      listing |= LISTING_HLL;
81533965Sjdp		      break;
81633965Sjdp		    case 'l':
81733965Sjdp		      listing |= LISTING_LISTING;
81833965Sjdp		      break;
81938889Sjdp		    case 'm':
82038889Sjdp		      listing |= LISTING_MACEXP;
82138889Sjdp		      break;
82233965Sjdp		    case 'n':
82333965Sjdp		      listing |= LISTING_NOFORM;
82433965Sjdp		      break;
82533965Sjdp		    case 's':
82633965Sjdp		      listing |= LISTING_SYMBOLS;
82733965Sjdp		      break;
82833965Sjdp		    case '=':
82933965Sjdp		      listing_filename = xstrdup (optarg + 1);
83033965Sjdp		      optarg += strlen (listing_filename);
83133965Sjdp		      break;
83233965Sjdp		    default:
83360484Sobrien		      as_fatal (_("invalid listing option `%c'"), *optarg);
83433965Sjdp		      break;
83533965Sjdp		    }
83633965Sjdp		  optarg++;
83733965Sjdp		}
83833965Sjdp	    }
83933965Sjdp	  if (!listing)
84033965Sjdp	    listing = LISTING_DEFAULT;
84133965Sjdp	  break;
84233965Sjdp
84333965Sjdp	case 'D':
84477298Sobrien	  /* DEBUG is implemented: it debugs different
84577298Sobrien	     things from other people's assemblers.  */
84633965Sjdp	  flag_debug = 1;
84733965Sjdp	  break;
84833965Sjdp
84933965Sjdp	case 'f':
85033965Sjdp	  flag_no_comments = 1;
85133965Sjdp	  break;
85233965Sjdp
85333965Sjdp	case 'I':
85477298Sobrien	  {			/* Include file directory.  */
85533965Sjdp	    char *temp = xstrdup (optarg);
856218822Sdim
85733965Sjdp	    add_include_dir (temp);
85833965Sjdp	    break;
85933965Sjdp	  }
86033965Sjdp
86133965Sjdp	case 'o':
86233965Sjdp	  out_file_name = xstrdup (optarg);
86333965Sjdp	  break;
86433965Sjdp
86533965Sjdp	case 'w':
86633965Sjdp	  break;
86733965Sjdp
86833965Sjdp	case 'X':
86977298Sobrien	  /* -X means treat warnings as errors.  */
87033965Sjdp	  break;
871218822Sdim
872218822Sdim	case OPTION_REDUCE_MEMORY_OVERHEADS:
873218822Sdim	  /* The only change we make at the moment is to reduce
874218822Sdim	     the size of the hash tables that we use.  */
875218822Sdim	  set_gas_hash_table_size (4051);
876218822Sdim	  break;
877218822Sdim
878218822Sdim	case OPTION_HASH_TABLE_SIZE:
879218822Sdim	  {
880218822Sdim	    unsigned long new_size;
881218822Sdim
882218822Sdim            new_size = strtoul (optarg, NULL, 0);
883218822Sdim            if (new_size)
884218822Sdim              set_gas_hash_table_size (new_size);
885218822Sdim            else
886218822Sdim              as_fatal (_("--hash-size needs a numeric argument"));
887218822Sdim	    break;
888218822Sdim	  }
88933965Sjdp	}
89033965Sjdp    }
89133965Sjdp
89233965Sjdp  free (shortopts);
89333965Sjdp  free (longopts);
89433965Sjdp
89533965Sjdp  *pargc = new_argc;
89633965Sjdp  *pargv = new_argv;
89789857Sobrien
89889857Sobrien#ifdef md_after_parse_args
89989857Sobrien  md_after_parse_args ();
90089857Sobrien#endif
90133965Sjdp}
90233965Sjdp
903130561Sobrienstatic void
904130561Sobriendump_statistics (void)
905130561Sobrien{
906130561Sobrien#ifdef HAVE_SBRK
907130561Sobrien  char *lim = (char *) sbrk (0);
908130561Sobrien#endif
909130561Sobrien  long run_time = get_run_time () - start_time;
91033965Sjdp
911130561Sobrien  fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"),
912130561Sobrien	   myname, run_time / 1000000, run_time % 1000000);
913130561Sobrien#ifdef HAVE_SBRK
914130561Sobrien  fprintf (stderr, _("%s: data size %ld\n"),
915130561Sobrien	   myname, (long) (lim - (char *) &environ));
916130561Sobrien#endif
91789857Sobrien
918130561Sobrien  subsegs_print_statistics (stderr);
919130561Sobrien  write_print_statistics (stderr);
920130561Sobrien  symbol_print_statistics (stderr);
921130561Sobrien  read_print_statistics (stderr);
922130561Sobrien
923130561Sobrien#ifdef tc_print_statistics
924130561Sobrien  tc_print_statistics (stderr);
925130561Sobrien#endif
926130561Sobrien
927130561Sobrien#ifdef obj_print_statistics
928130561Sobrien  obj_print_statistics (stderr);
929130561Sobrien#endif
930130561Sobrien}
931130561Sobrien
932218822Sdim#ifndef OBJ_VMS
933218822Sdimstatic void
934218822Sdimclose_output_file (void)
935218822Sdim{
936218822Sdim  output_file_close (out_file_name);
937218822Sdim}
938218822Sdim#endif
939218822Sdim
940130561Sobrien/* The interface between the macro code and gas expression handling.  */
941130561Sobrien
942130561Sobrienstatic int
943130561Sobrienmacro_expr (const char *emsg, int idx, sb *in, int *val)
944130561Sobrien{
945130561Sobrien  char *hold;
946130561Sobrien  expressionS ex;
947130561Sobrien
948130561Sobrien  sb_terminate (in);
949130561Sobrien
950130561Sobrien  hold = input_line_pointer;
951130561Sobrien  input_line_pointer = in->ptr + idx;
952218822Sdim  expression_and_evaluate (&ex);
953130561Sobrien  idx = input_line_pointer - in->ptr;
954130561Sobrien  input_line_pointer = hold;
955130561Sobrien
956130561Sobrien  if (ex.X_op != O_constant)
957130561Sobrien    as_bad ("%s", emsg);
958130561Sobrien
959130561Sobrien  *val = (int) ex.X_add_number;
960130561Sobrien
961130561Sobrien  return idx;
962130561Sobrien}
963130561Sobrien
964130561Sobrien/* Here to attempt 1 pass over each input file.
965130561Sobrien   We scan argv[*] looking for filenames or exactly "" which is
966130561Sobrien   shorthand for stdin. Any argv that is NULL is not a file-name.
967130561Sobrien   We set need_pass_2 TRUE if, after this, we still have unresolved
968130561Sobrien   expressions of the form (unknown value)+-(unknown value).
969130561Sobrien
970130561Sobrien   Note the un*x semantics: there is only 1 logical input file, but it
971130561Sobrien   may be a catenation of many 'physical' input files.  */
972130561Sobrien
973130561Sobrienstatic void
974130561Sobrienperform_an_assembly_pass (int argc, char ** argv)
975130561Sobrien{
976130561Sobrien  int saw_a_file = 0;
977130561Sobrien  flagword applicable;
978130561Sobrien
979130561Sobrien  need_pass_2 = 0;
980130561Sobrien
981130561Sobrien  /* Create the standard sections, and those the assembler uses
982130561Sobrien     internally.  */
983130561Sobrien  text_section = subseg_new (TEXT_SECTION_NAME, 0);
984130561Sobrien  data_section = subseg_new (DATA_SECTION_NAME, 0);
985130561Sobrien  bss_section = subseg_new (BSS_SECTION_NAME, 0);
986130561Sobrien  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
987130561Sobrien     to have relocs, otherwise we don't find out in time.  */
988130561Sobrien  applicable = bfd_applicable_section_flags (stdoutput);
989130561Sobrien  bfd_set_section_flags (stdoutput, text_section,
990130561Sobrien			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
991130561Sobrien				       | SEC_CODE | SEC_READONLY));
992130561Sobrien  bfd_set_section_flags (stdoutput, data_section,
993130561Sobrien			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
994130561Sobrien				       | SEC_DATA));
995130561Sobrien  bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
996130561Sobrien  seg_info (bss_section)->bss = 1;
997130561Sobrien  subseg_new (BFD_ABS_SECTION_NAME, 0);
998130561Sobrien  subseg_new (BFD_UND_SECTION_NAME, 0);
999130561Sobrien  reg_section = subseg_new ("*GAS `reg' section*", 0);
1000130561Sobrien  expr_section = subseg_new ("*GAS `expr' section*", 0);
1001130561Sobrien
1002130561Sobrien  subseg_set (text_section, 0);
1003130561Sobrien
1004130561Sobrien  /* This may add symbol table entries, which requires having an open BFD,
1005218822Sdim     and sections already created.  */
1006130561Sobrien  md_begin ();
1007130561Sobrien
1008130561Sobrien#ifdef USING_CGEN
1009130561Sobrien  gas_cgen_begin ();
1010130561Sobrien#endif
1011130561Sobrien#ifdef obj_begin
1012130561Sobrien  obj_begin ();
1013130561Sobrien#endif
1014130561Sobrien
1015130561Sobrien  /* Skip argv[0].  */
1016130561Sobrien  argv++;
1017130561Sobrien  argc--;
1018130561Sobrien
1019130561Sobrien  while (argc--)
1020130561Sobrien    {
1021130561Sobrien      if (*argv)
1022130561Sobrien	{			/* Is it a file-name argument?  */
1023130561Sobrien	  PROGRESS (1);
1024130561Sobrien	  saw_a_file++;
1025130561Sobrien	  /* argv->"" if stdin desired, else->filename.  */
1026130561Sobrien	  read_a_source_file (*argv);
1027130561Sobrien	}
1028130561Sobrien      argv++;			/* Completed that argv.  */
1029130561Sobrien    }
1030130561Sobrien  if (!saw_a_file)
1031130561Sobrien    read_a_source_file ("");
1032130561Sobrien}
1033130561Sobrien
1034218822Sdim#ifdef OBJ_ELF
1035218822Sdimstatic void
1036218822Sdimcreate_obj_attrs_section (void)
1037218822Sdim{
1038218822Sdim  segT s;
1039218822Sdim  char *p;
1040218822Sdim  addressT addr;
1041218822Sdim  offsetT size;
1042218822Sdim  const char *name;
1043130561Sobrien
1044218822Sdim  size = bfd_elf_obj_attr_size (stdoutput);
1045218822Sdim  if (size)
1046218822Sdim    {
1047218822Sdim      name = get_elf_backend_data (stdoutput)->obj_attrs_section;
1048218822Sdim      if (!name)
1049218822Sdim	name = ".gnu.attributes";
1050218822Sdim      s = subseg_new (name, 0);
1051218822Sdim      elf_section_type (s)
1052218822Sdim	= get_elf_backend_data (stdoutput)->obj_attrs_section_type;
1053218822Sdim      bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
1054218822Sdim      addr = frag_now_fix ();
1055218822Sdim      p = frag_more (size);
1056218822Sdim      bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size);
1057218822Sdim    }
1058218822Sdim}
1059218822Sdim#endif
1060218822Sdim
1061218822Sdim
106277298Sobrienint
1063130561Sobrienmain (int argc, char ** argv)
106433965Sjdp{
106533965Sjdp  int macro_strip_at;
106633965Sjdp  int keep_it;
106733965Sjdp
106833965Sjdp  start_time = get_run_time ();
106933965Sjdp
107060484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
107160484Sobrien  setlocale (LC_MESSAGES, "");
107260484Sobrien#endif
107389857Sobrien#if defined (HAVE_SETLOCALE)
107489857Sobrien  setlocale (LC_CTYPE, "");
107589857Sobrien#endif
107660484Sobrien  bindtextdomain (PACKAGE, LOCALEDIR);
107760484Sobrien  textdomain (PACKAGE);
107833965Sjdp
107933965Sjdp  if (debug_memory)
1080104834Sobrien    chunksize = 64;
108133965Sjdp
108233965Sjdp#ifdef HOST_SPECIAL_INIT
108333965Sjdp  HOST_SPECIAL_INIT (argc, argv);
108433965Sjdp#endif
108533965Sjdp
108633965Sjdp  myname = argv[0];
108733965Sjdp  xmalloc_set_program_name (myname);
108833965Sjdp
1089218822Sdim  expandargv (&argc, &argv);
1090218822Sdim
109133965Sjdp  START_PROGRESS (myname, 0);
109233965Sjdp
109333965Sjdp#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
109433965Sjdp#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
109533965Sjdp#endif
109633965Sjdp
109733965Sjdp  out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
109833965Sjdp
109933965Sjdp  hex_init ();
110033965Sjdp  bfd_init ();
110133965Sjdp  bfd_set_error_program_name (myname);
110233965Sjdp
110333965Sjdp#ifdef USE_EMULATIONS
110433965Sjdp  select_emulation_mode (argc, argv);
110533965Sjdp#endif
110633965Sjdp
110733965Sjdp  PROGRESS (1);
1108218822Sdim  /* Call parse_args before any of the init/begin functions
1109218822Sdim     so that switches like --hash-size can be honored.  */
1110218822Sdim  parse_args (&argc, &argv);
111133965Sjdp  symbol_begin ();
111233965Sjdp  frag_init ();
111333965Sjdp  subsegs_begin ();
111433965Sjdp  read_begin ();
111533965Sjdp  input_scrub_begin ();
111633965Sjdp  expr_begin ();
111733965Sjdp
1118218822Sdim#ifndef OBJ_VMS /* Does its own file handling.  */
1119218822Sdim  /* It has to be called after dump_statistics ().  */
1120218822Sdim  xatexit (close_output_file);
1121218822Sdim#endif
1122218822Sdim
112333965Sjdp  if (flag_print_statistics)
112433965Sjdp    xatexit (dump_statistics);
112533965Sjdp
112633965Sjdp  macro_strip_at = 0;
112733965Sjdp#ifdef TC_I960
112833965Sjdp  macro_strip_at = flag_mri;
112933965Sjdp#endif
113033965Sjdp
1131218822Sdim  macro_init (flag_macro_alternate, flag_mri, macro_strip_at, macro_expr);
113233965Sjdp
113333965Sjdp  PROGRESS (1);
113433965Sjdp
113533965Sjdp  output_file_create (out_file_name);
113633965Sjdp  assert (stdoutput != 0);
113733965Sjdp
113833965Sjdp#ifdef tc_init_after_args
113933965Sjdp  tc_init_after_args ();
114033965Sjdp#endif
114133965Sjdp
114233965Sjdp  itbl_init ();
114333965Sjdp
114433965Sjdp  /* Now that we have fully initialized, and have created the output
114533965Sjdp     file, define any symbols requested by --defsym command line
114633965Sjdp     arguments.  */
114733965Sjdp  while (defsyms != NULL)
114833965Sjdp    {
114933965Sjdp      symbolS *sym;
115033965Sjdp      struct defsym_list *next;
115133965Sjdp
115233965Sjdp      sym = symbol_new (defsyms->name, absolute_section, defsyms->value,
115333965Sjdp			&zero_address_frag);
1154218822Sdim      /* Make symbols defined on the command line volatile, so that they
1155218822Sdim	 can be redefined inside a source file.  This makes this assembler's
1156218822Sdim	 behaviour compatible with earlier versions, but it may not be
1157218822Sdim	 completely intuitive.  */
1158218822Sdim      S_SET_VOLATILE (sym);
115933965Sjdp      symbol_table_insert (sym);
116033965Sjdp      next = defsyms->next;
116133965Sjdp      free (defsyms);
116233965Sjdp      defsyms = next;
116333965Sjdp    }
116433965Sjdp
116533965Sjdp  PROGRESS (1);
116633965Sjdp
116777298Sobrien  /* Assemble it.  */
116877298Sobrien  perform_an_assembly_pass (argc, argv);
116933965Sjdp
117033965Sjdp  cond_finish_check (-1);
117133965Sjdp
117233965Sjdp#ifdef md_end
117333965Sjdp  md_end ();
117433965Sjdp#endif
117533965Sjdp
1176218822Sdim#ifdef OBJ_ELF
1177218822Sdim  if (IS_ELF)
1178218822Sdim    create_obj_attrs_section ();
1179218822Sdim#endif
1180218822Sdim
1181218822Sdim#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
1182130561Sobrien  if ((flag_execstack || flag_noexecstack)
1183130561Sobrien      && OUTPUT_FLAVOR == bfd_target_elf_flavour)
1184130561Sobrien    {
1185130561Sobrien      segT gnustack;
1186130561Sobrien
1187130561Sobrien      gnustack = subseg_new (".note.GNU-stack", 0);
1188130561Sobrien      bfd_set_section_flags (stdoutput, gnustack,
1189130561Sobrien			     SEC_READONLY | (flag_execstack ? SEC_CODE : 0));
1190130561Sobrien
1191130561Sobrien    }
1192130561Sobrien#endif
1193130561Sobrien
119477298Sobrien  /* If we've been collecting dwarf2 .debug_line info, either for
119577298Sobrien     assembly debugging or on behalf of the compiler, emit it now.  */
119677298Sobrien  dwarf2_finish ();
119777298Sobrien
1198130561Sobrien  /* If we constructed dwarf2 .eh_frame info, either via .cfi
1199130561Sobrien     directives from the user or by the backend, emit it now.  */
1200130561Sobrien  cfi_finish ();
1201130561Sobrien
120233965Sjdp  if (seen_at_least_1_file ()
120333965Sjdp      && (flag_always_generate_output || had_errors () == 0))
120433965Sjdp    keep_it = 1;
120533965Sjdp  else
120633965Sjdp    keep_it = 0;
120733965Sjdp
120838889Sjdp  /* This used to be done at the start of write_object_file in
120938889Sjdp     write.c, but that caused problems when doing listings when
121038889Sjdp     keep_it was zero.  This could probably be moved above md_end, but
121138889Sjdp     I didn't want to risk the change.  */
121238889Sjdp  subsegs_finish ();
121338889Sjdp
121433965Sjdp  if (keep_it)
121533965Sjdp    write_object_file ();
121633965Sjdp
121733965Sjdp#ifndef NO_LISTING
121833965Sjdp  listing_print (listing_filename);
121933965Sjdp#endif
122033965Sjdp
122177298Sobrien  if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0)
122277298Sobrien    as_bad (_("%d warnings, treating warnings as errors"), had_warnings ());
122360484Sobrien
122433965Sjdp  if (had_errors () > 0 && ! flag_always_generate_output)
122533965Sjdp    keep_it = 0;
122633965Sjdp
122733965Sjdp  if (!keep_it)
1228218822Sdim    unlink_if_ordinary (out_file_name);
122933965Sjdp
123033965Sjdp  input_scrub_end ();
123133965Sjdp
123233965Sjdp  END_PROGRESS (myname);
123333965Sjdp
123433965Sjdp  /* Use xexit instead of return, because under VMS environments they
123533965Sjdp     may not place the same interpretation on the value given.  */
123633965Sjdp  if (had_errors () > 0)
123733965Sjdp    xexit (EXIT_FAILURE);
123838889Sjdp
123938889Sjdp  /* Only generate dependency file if assembler was successful.  */
124038889Sjdp  print_dependencies ();
124138889Sjdp
124233965Sjdp  xexit (EXIT_SUCCESS);
124333965Sjdp}
1244