as.c revision 60484
133965Sjdp/* as.c - GAS main program.
260484Sobrien   Copyright (C) 1987, 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
333965Sjdp   Free Software Foundation, Inc.
433965Sjdp
533965Sjdp   This file is part of GAS, the GNU Assembler.
633965Sjdp
733965Sjdp   GAS is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1033965Sjdp   any later version.
1133965Sjdp
1233965Sjdp   GAS is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1833965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
1933965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2033965Sjdp   02111-1307, USA. */
2133965Sjdp
2233965Sjdp/*
2333965Sjdp * Main program for AS; a 32-bit assembler of GNU.
2433965Sjdp * Understands command arguments.
2533965Sjdp * Has a few routines that don't fit in other modules because they
2633965Sjdp * are shared.
2733965Sjdp *
2833965Sjdp *
2933965Sjdp *			bugs
3033965Sjdp *
3133965Sjdp * : initialisers
3233965Sjdp *	Since no-one else says they will support them in future: I
3333965Sjdp * don't support them now.
3433965Sjdp *
3533965Sjdp */
3633965Sjdp
3733965Sjdp#include "ansidecl.h"
3833965Sjdp
3933965Sjdp#define COMMON
4033965Sjdp
4133965Sjdp#include "as.h"
4233965Sjdp#include "subsegs.h"
4333965Sjdp#include "output-file.h"
4433965Sjdp#include "sb.h"
4533965Sjdp#include "macro.h"
4660484Sobrien
4760484Sobrien#ifdef HAVE_ITBL_CPU
4860484Sobrien#include "itbl-ops.h"
4960484Sobrien#else
5033965Sjdp#define itbl_parse(itbl_file) 1
5133965Sjdp#define itbl_init()
5233965Sjdp#endif
5333965Sjdp
5433965Sjdp#ifdef HAVE_SBRK
5533965Sjdp#ifdef NEED_DECLARATION_SBRK
5633965Sjdpextern PTR sbrk ();
5733965Sjdp#endif
5833965Sjdp#endif
5933965Sjdp
6033965Sjdpstatic void show_usage PARAMS ((FILE *));
6133965Sjdpstatic void parse_args PARAMS ((int *, char ***));
6233965Sjdpstatic void dump_statistics PARAMS ((void));
6333965Sjdpstatic void perform_an_assembly_pass PARAMS ((int argc, char **argv));
6433965Sjdpstatic int macro_expr PARAMS ((const char *, int, sb *, int *));
6533965Sjdp
6633965Sjdpint listing;			/* true if a listing is wanted */
6733965Sjdp
6833965Sjdpstatic char *listing_filename = NULL;	/* Name of listing file.  */
6933965Sjdp
7038889Sjdp/* Type of debugging to generate.  */
7138889Sjdp
7238889Sjdpenum debug_info_type debug_type = DEBUG_NONE;
7338889Sjdp
7433965Sjdp/* Maximum level of macro nesting.  */
7533965Sjdp
7633965Sjdpint max_macro_nest = 100;
7733965Sjdp
7833965Sjdpchar *myname;			/* argv[0] */
7933965Sjdp#ifdef BFD_ASSEMBLER
8033965SjdpsegT reg_section, expr_section;
8133965SjdpsegT text_section, data_section, bss_section;
8233965Sjdp#endif
8333965Sjdp
8438889Sjdp/* The default obstack chunk size.  If we set this to zero, the
8538889Sjdp   obstack code will use whatever will fit in a 4096 byte block.  */
8638889Sjdpint chunksize = 0;
8733965Sjdp
8833965Sjdp/* To monitor memory allocation more effectively, make this non-zero.
8933965Sjdp   Then the chunk sizes for gas and bfd will be reduced.  */
9033965Sjdpint debug_memory = 0;
9133965Sjdp
9233965Sjdp/* We build a list of defsyms as we read the options, and then define
9333965Sjdp   them after we have initialized everything.  */
9433965Sjdp
9533965Sjdpstruct defsym_list
9633965Sjdp{
9733965Sjdp  struct defsym_list *next;
9833965Sjdp  char *name;
9933965Sjdp  valueT value;
10033965Sjdp};
10133965Sjdp
10233965Sjdpstatic struct defsym_list *defsyms;
10333965Sjdp
10433965Sjdp/* Keep a record of the itbl files we read in. */
10533965Sjdp
10633965Sjdpstruct itbl_file_list
10733965Sjdp{
10833965Sjdp  struct itbl_file_list *next;
10933965Sjdp  char *name;
11033965Sjdp};
11133965Sjdp
11233965Sjdpstatic struct itbl_file_list *itbl_files;
11333965Sjdp
11433965Sjdp#ifdef USE_EMULATIONS
11533965Sjdp#define EMULATION_ENVIRON "AS_EMULATION"
11633965Sjdp
11733965Sjdpextern struct emulation mipsbelf, mipslelf, mipself;
11833965Sjdpextern struct emulation mipsbecoff, mipslecoff, mipsecoff;
11960484Sobrienextern struct emulation i386coff, i386elf, i386aout;
12033965Sjdp
12133965Sjdpstatic struct emulation *const emulations[] = { EMULATIONS };
12233965Sjdpstatic const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
12333965Sjdp
12433965Sjdpstatic void select_emulation_mode PARAMS ((int, char **));
12533965Sjdp
12633965Sjdpstatic void
12733965Sjdpselect_emulation_mode (argc, argv)
12833965Sjdp     int argc;
12933965Sjdp     char **argv;
13033965Sjdp{
13133965Sjdp  int i;
13233965Sjdp  char *p, *em = 0;
13333965Sjdp
13433965Sjdp  for (i = 1; i < argc; i++)
13533965Sjdp    if (!strncmp ("--em", argv[i], 4))
13633965Sjdp      break;
13733965Sjdp
13833965Sjdp  if (i == argc)
13933965Sjdp    goto do_default;
14033965Sjdp
14133965Sjdp  p = strchr (argv[i], '=');
14233965Sjdp  if (p)
14333965Sjdp    p++;
14433965Sjdp  else
14533965Sjdp    p = argv[i+1];
14633965Sjdp
14733965Sjdp  if (!p || !*p)
14860484Sobrien    as_fatal (_("missing emulation mode name"));
14933965Sjdp  em = p;
15033965Sjdp
15133965Sjdp do_default:
15233965Sjdp  if (em == 0)
15333965Sjdp    em = getenv (EMULATION_ENVIRON);
15433965Sjdp  if (em == 0)
15533965Sjdp    em = DEFAULT_EMULATION;
15633965Sjdp
15733965Sjdp  if (em)
15833965Sjdp    {
15933965Sjdp      for (i = 0; i < n_emulations; i++)
16033965Sjdp	if (!strcmp (emulations[i]->name, em))
16133965Sjdp	  break;
16233965Sjdp      if (i == n_emulations)
16360484Sobrien	as_fatal (_("unrecognized emulation name `%s'"), em);
16433965Sjdp      this_emulation = emulations[i];
16533965Sjdp    }
16633965Sjdp  else
16733965Sjdp    this_emulation = emulations[0];
16833965Sjdp
16933965Sjdp  this_emulation->init ();
17033965Sjdp}
17133965Sjdp
17233965Sjdpconst char *
17333965Sjdpdefault_emul_bfd_name ()
17433965Sjdp{
17533965Sjdp  abort ();
17633965Sjdp  return NULL;
17733965Sjdp}
17833965Sjdp
17933965Sjdpvoid
18033965Sjdpcommon_emul_init ()
18133965Sjdp{
18233965Sjdp  this_format = this_emulation->format;
18333965Sjdp
18433965Sjdp  if (this_emulation->leading_underscore == 2)
18533965Sjdp    this_emulation->leading_underscore = this_format->dfl_leading_underscore;
18633965Sjdp
18733965Sjdp  if (this_emulation->default_endian != 2)
18833965Sjdp    target_big_endian = this_emulation->default_endian;
18933965Sjdp
19033965Sjdp  if (this_emulation->fake_label_name == 0)
19133965Sjdp    {
19233965Sjdp      if (this_emulation->leading_underscore)
19333965Sjdp	this_emulation->fake_label_name = "L0\001";
19433965Sjdp      else
19533965Sjdp	/* What other parameters should we test?  */
19633965Sjdp	this_emulation->fake_label_name = ".L0\001";
19733965Sjdp    }
19833965Sjdp}
19933965Sjdp#endif
20033965Sjdp
20160484Sobrienvoid
20260484Sobrienprint_version_id ()
20360484Sobrien{
20460484Sobrien  static int printed;
20560484Sobrien  if (printed)
20660484Sobrien    return;
20760484Sobrien  printed = 1;
20860484Sobrien
20960484Sobrien#ifdef BFD_ASSEMBLER
21060484Sobrien  fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s"),
21160484Sobrien	   VERSION, TARGET_ALIAS, BFD_VERSION);
21260484Sobrien#else
21360484Sobrien  fprintf (stderr, _("GNU assembler version %s (%s)"), VERSION, TARGET_ALIAS);
21460484Sobrien#endif
21560484Sobrien  fprintf (stderr, "\n");
21660484Sobrien}
21760484Sobrien
21860484Sobrienstatic void
21960484Sobrienshow_usage (stream)
22060484Sobrien     FILE *stream;
22160484Sobrien{
22260484Sobrien  fprintf (stream, _("Usage: %s [option...] [asmfile...]\n"), myname);
22360484Sobrien
22460484Sobrien  fprintf (stream, _("\
22560484SobrienOptions:\n\
22660484Sobrien  -a[sub-option...]	  turn on listings\n\
22760484Sobrien                      	  Sub-options [default hls]:\n\
22860484Sobrien                      	  c      omit false conditionals\n\
22960484Sobrien                      	  d      omit debugging directives\n\
23060484Sobrien                      	  h      include high-level source\n\
23160484Sobrien                      	  l      include assembly\n\
23260484Sobrien                      	  m      include macro expansions\n\
23360484Sobrien                      	  n      omit forms processing\n\
23460484Sobrien                      	  s      include symbols\n\
23560484Sobrien                      	  L      include line debug statistics (if applicable)\n\
23660484Sobrien                      	  =FILE  list to FILE (must be last sub-option)\n"));
23760484Sobrien
23860484Sobrien  fprintf (stream, _("\
23960484Sobrien  -D                      produce assembler debugging messages\n"));
24060484Sobrien  fprintf (stream, _("\
24160484Sobrien  --defsym SYM=VAL        define symbol SYM to given value\n"));
24260484Sobrien#ifdef USE_EMULATIONS
24360484Sobrien  {
24460484Sobrien    int i;
24560484Sobrien    char *def_em;
24660484Sobrien
24760484Sobrien    fprintf (stream, "\
24860484Sobrien  --em=[");
24960484Sobrien    for (i = 0; i < n_emulations-1; i++)
25060484Sobrien      fprintf (stream, "%s | ", emulations[i]->name);
25160484Sobrien    fprintf (stream, "%s]\n", emulations[i]->name);
25260484Sobrien
25360484Sobrien    def_em = getenv (EMULATION_ENVIRON);
25460484Sobrien    if (!def_em)
25560484Sobrien      def_em = DEFAULT_EMULATION;
25660484Sobrien    fprintf (stream, _("\
25760484Sobrien                          emulate output (default %s)\n"), def_em);
25860484Sobrien  }
25960484Sobrien#endif
26060484Sobrien  fprintf (stream, _("\
26160484Sobrien  -f                      skip whitespace and comment preprocessing\n"));
26260484Sobrien  fprintf (stream, _("\
26360484Sobrien  --gstabs                generate stabs debugging information\n"));
26460484Sobrien  fprintf (stream, _("\
26560484Sobrien  --gdwarf2               generate DWARF2 debugging information\n"));
26660484Sobrien  fprintf (stream, _("\
26760484Sobrien  --help                  show this message and exit\n"));
26860484Sobrien  fprintf (stream, _("\
26960484Sobrien  -I DIR                  add DIR to search list for .include directives\n"));
27060484Sobrien  fprintf (stream, _("\
27160484Sobrien  -J                      don't warn about signed overflow\n"));
27260484Sobrien  fprintf (stream, _("\
27360484Sobrien  -K                      warn when differences altered for long displacements\n"));
27460484Sobrien  fprintf (stream, _("\
27560484Sobrien  -L,--keep-locals        keep local symbols (e.g. starting with `L')\n"));
27660484Sobrien  fprintf (stream, _("\
27760484Sobrien  -M,--mri                assemble in MRI compatibility mode\n"));
27860484Sobrien  fprintf (stream, _("\
27960484Sobrien  --MD FILE               write dependency information in FILE (default none)\n"));
28060484Sobrien  fprintf (stream, _("\
28160484Sobrien  -nocpp                  ignored\n"));
28260484Sobrien  fprintf (stream, _("\
28360484Sobrien  -o OBJFILE              name the object-file output OBJFILE (default a.out)\n"));
28460484Sobrien  fprintf (stream, _("\
28560484Sobrien  -R                      fold data section into text section\n"));
28660484Sobrien  fprintf (stream, _("\
28760484Sobrien  --statistics            print various measured statistics from execution\n"));
28860484Sobrien  fprintf (stream, _("\
28960484Sobrien  --strip-local-absolute  strip local absolute symbols\n"));
29060484Sobrien  fprintf (stream, _("\
29160484Sobrien  --traditional-format    Use same format as native assembler when possible\n"));
29260484Sobrien  fprintf (stream, _("\
29360484Sobrien  --version               print assembler version number and exit\n"));
29460484Sobrien  fprintf (stream, _("\
29560484Sobrien  -W  --no-warn           suppress warnings\n"));
29660484Sobrien  fprintf (stream, _("\
29760484Sobrien  --warn                  don't suppress warnings\n"));
29860484Sobrien  fprintf (stream, _("\
29960484Sobrien  --fatal-warnings        treat warnings as errors\n"));
30060484Sobrien  fprintf (stream, _("\
30160484Sobrien  --itbl INSTTBL          extend instruction set to include instructions\n\
30260484Sobrien                          matching the specifications defined in file INSTTBL\n"));
30360484Sobrien  fprintf (stream, _("\
30460484Sobrien  -w                      ignored\n"));
30560484Sobrien  fprintf (stream, _("\
30660484Sobrien  -X                      ignored\n"));
30760484Sobrien  fprintf (stream, _("\
30860484Sobrien  -Z                      generate object file even after errors\n"));
30960484Sobrien  fprintf (stream, _("\
31060484Sobrien  --listing-lhs-width     set the width in words of the output data column of\n\
31160484Sobrien                          the listing\n"));
31260484Sobrien  fprintf (stream, _("\
31360484Sobrien  --listing-lhs-width2    set the width in words of the continuation lines\n\
31460484Sobrien                          of the output data column; ignored if smaller than\n\
31560484Sobrien                          the width of the first line\n"));
31660484Sobrien  fprintf (stream, _("\
31760484Sobrien  --listing-rhs-width     set the max width in characters of the lines from\n\
31860484Sobrien                          the source file\n"));
31960484Sobrien  fprintf (stream, _("\
32060484Sobrien  --listing-cont-lines    set the maximum number of continuation lines used\n\
32160484Sobrien                          for the output data column of the listing\n"));
32260484Sobrien
32360484Sobrien  md_show_usage (stream);
32460484Sobrien
32560484Sobrien  fputc ('\n', stream);
32660484Sobrien  fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
32760484Sobrien}
32860484Sobrien
32933965Sjdp/*
33033965Sjdp * Since it is easy to do here we interpret the special arg "-"
33133965Sjdp * to mean "use stdin" and we set that argv[] pointing to "".
33233965Sjdp * After we have munged argv[], the only things left are source file
33333965Sjdp * name(s) and ""(s) denoting stdin. These file names are used
33433965Sjdp * (perhaps more than once) later.
33533965Sjdp *
33633965Sjdp * check for new machine-dep cmdline options in
33733965Sjdp * md_parse_option definitions in config/tc-*.c
33833965Sjdp */
33933965Sjdp
34033965Sjdpstatic void
34133965Sjdpparse_args (pargc, pargv)
34233965Sjdp     int *pargc;
34333965Sjdp     char ***pargv;
34433965Sjdp{
34533965Sjdp  int old_argc, new_argc;
34633965Sjdp  char **old_argv, **new_argv;
34733965Sjdp
34833965Sjdp  /* Starting the short option string with '-' is for programs that
34933965Sjdp     expect options and other ARGV-elements in any order and that care about
35033965Sjdp     the ordering of the two.  We describe each non-option ARGV-element
35133965Sjdp     as if it were the argument of an option with character code 1.  */
35233965Sjdp
35333965Sjdp  char *shortopts;
35433965Sjdp  extern CONST char *md_shortopts;
35533965Sjdp  static const char std_shortopts[] =
35633965Sjdp    {
35733965Sjdp      '-', 'J',
35833965Sjdp#ifndef WORKING_DOT_WORD
35933965Sjdp      /* -K is not meaningful if .word is not being hacked.  */
36033965Sjdp      'K',
36133965Sjdp#endif
36233965Sjdp      'L', 'M', 'R', 'W', 'Z', 'f', 'a', ':', ':', 'D', 'I', ':', 'o', ':',
36333965Sjdp#ifndef VMS
36433965Sjdp      /* -v takes an argument on VMS, so we don't make it a generic
36533965Sjdp         option.  */
36633965Sjdp      'v',
36733965Sjdp#endif
36833965Sjdp      'w', 'X',
36933965Sjdp      /* New option for extending instruction set (see also --itbl below) */
37038889Sjdp      't', ':',
37133965Sjdp      '\0'
37233965Sjdp    };
37333965Sjdp  struct option *longopts;
37433965Sjdp  extern struct option md_longopts[];
37533965Sjdp  extern size_t md_longopts_size;
37633965Sjdp  static const struct option std_longopts[] = {
37733965Sjdp#define OPTION_HELP (OPTION_STD_BASE)
37833965Sjdp    {"help", no_argument, NULL, OPTION_HELP},
37938889Sjdp    {"keep-locals", no_argument, NULL, 'L'},
38033965Sjdp    {"mri", no_argument, NULL, 'M'},
38133965Sjdp#define OPTION_NOCPP (OPTION_STD_BASE + 1)
38233965Sjdp    {"nocpp", no_argument, NULL, OPTION_NOCPP},
38333965Sjdp#define OPTION_STATISTICS (OPTION_STD_BASE + 2)
38433965Sjdp    {"statistics", no_argument, NULL, OPTION_STATISTICS},
38533965Sjdp#define OPTION_VERSION (OPTION_STD_BASE + 3)
38633965Sjdp    {"version", no_argument, NULL, OPTION_VERSION},
38733965Sjdp#define OPTION_DUMPCONFIG (OPTION_STD_BASE + 4)
38833965Sjdp    {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG},
38933965Sjdp#define OPTION_VERBOSE (OPTION_STD_BASE + 5)
39033965Sjdp    {"verbose", no_argument, NULL, OPTION_VERBOSE},
39133965Sjdp#define OPTION_EMULATION (OPTION_STD_BASE + 6)
39233965Sjdp    {"emulation", required_argument, NULL, OPTION_EMULATION},
39333965Sjdp#define OPTION_DEFSYM (OPTION_STD_BASE + 7)
39433965Sjdp    {"defsym", required_argument, NULL, OPTION_DEFSYM},
39533965Sjdp#define OPTION_INSTTBL (OPTION_STD_BASE + 8)
39633965Sjdp    /* New option for extending instruction set (see also -t above).
39733965Sjdp       The "-t file" or "--itbl file" option extends the basic set of
39833965Sjdp       valid instructions by reading "file", a text file containing a
39933965Sjdp       list of instruction formats.  The additional opcodes and their
40033965Sjdp       formats are added to the built-in set of instructions, and
40133965Sjdp       mnemonics for new registers may also be defined.  */
40238889Sjdp    {"itbl", required_argument, NULL, OPTION_INSTTBL},
40338889Sjdp#define OPTION_LISTING_LHS_WIDTH (OPTION_STD_BASE + 9)
40438889Sjdp    {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH},
40538889Sjdp#define OPTION_LISTING_LHS_WIDTH2 (OPTION_STD_BASE + 10)
40638889Sjdp    {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2},
40738889Sjdp#define OPTION_LISTING_RHS_WIDTH (OPTION_STD_BASE + 11)
40838889Sjdp    {"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH},
40938889Sjdp#define OPTION_LISTING_CONT_LINES (OPTION_STD_BASE + 12)
41038889Sjdp    {"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES},
41138889Sjdp#define OPTION_DEPFILE (OPTION_STD_BASE + 13)
41238889Sjdp    {"MD", required_argument, NULL, OPTION_DEPFILE},
41338889Sjdp#define OPTION_GSTABS (OPTION_STD_BASE + 14)
41438889Sjdp    {"gstabs", no_argument, NULL, OPTION_GSTABS},
41538889Sjdp#define OPTION_STRIP_LOCAL_ABSOLUTE (OPTION_STD_BASE + 15)
41638889Sjdp    {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE},
41738889Sjdp#define OPTION_TRADITIONAL_FORMAT (OPTION_STD_BASE + 16)
41860484Sobrien    {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT},
41960484Sobrien#define OPTION_GDWARF2 (OPTION_STD_BASE + 17)
42060484Sobrien    {"gdwarf2", no_argument, NULL, OPTION_GDWARF2},
42160484Sobrien    {"no-warn", no_argument, NULL, 'W'},
42260484Sobrien#define OPTION_WARN (OPTION_STD_BASE + 18)
42360484Sobrien    {"warn", no_argument, NULL, OPTION_WARN},
42460484Sobrien#define OPTION_WARN_FATAL (OPTION_STD_BASE + 19)
42560484Sobrien    {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}
42633965Sjdp  };
42733965Sjdp
42833965Sjdp  /* Construct the option lists from the standard list and the
42933965Sjdp     target dependent list.  */
43033965Sjdp  shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
43133965Sjdp  longopts = (struct option *) xmalloc (sizeof (std_longopts) + md_longopts_size);
43233965Sjdp  memcpy (longopts, std_longopts, sizeof (std_longopts));
43333965Sjdp  memcpy ((char *) longopts + sizeof (std_longopts),
43433965Sjdp	  md_longopts, md_longopts_size);
43533965Sjdp
43633965Sjdp  /* Make a local copy of the old argv.  */
43733965Sjdp  old_argc = *pargc;
43833965Sjdp  old_argv = *pargv;
43933965Sjdp
44033965Sjdp  /* Initialize a new argv that contains no options.  */
44133965Sjdp  new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1));
44233965Sjdp  new_argv[0] = old_argv[0];
44333965Sjdp  new_argc = 1;
44433965Sjdp  new_argv[new_argc] = NULL;
44533965Sjdp
44633965Sjdp  while (1)
44733965Sjdp    {
44833965Sjdp      /* getopt_long_only is like getopt_long, but '-' as well as '--' can
44933965Sjdp	 indicate a long option.  */
45033965Sjdp      int longind;
45133965Sjdp      int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
45233965Sjdp				   &longind);
45333965Sjdp
45433965Sjdp      if (optc == -1)
45533965Sjdp	break;
45633965Sjdp
45733965Sjdp      switch (optc)
45833965Sjdp	{
45933965Sjdp	default:
46033965Sjdp	  /* md_parse_option should return 1 if it recognizes optc,
46133965Sjdp	     0 if not.  */
46233965Sjdp	  if (md_parse_option (optc, optarg) != 0)
46333965Sjdp	    break;
46433965Sjdp	  /* `-v' isn't included in the general short_opts list, so check for
46533965Sjdp	     it explicity here before deciding we've gotten a bad argument.  */
46633965Sjdp	  if (optc == 'v')
46733965Sjdp	    {
46833965Sjdp#ifdef VMS
46933965Sjdp	      /* Telling getopt to treat -v's value as optional can result
47033965Sjdp		 in it picking up a following filename argument here.  The
47133965Sjdp		 VMS code in md_parse_option can return 0 in that case,
47233965Sjdp		 but it has no way of pushing the filename argument back.  */
47333965Sjdp	      if (optarg && *optarg)
47433965Sjdp		new_argv[new_argc++] = optarg,  new_argv[new_argc] = NULL;
47533965Sjdp	      else
47633965Sjdp#else
47733965Sjdp	      case 'v':
47833965Sjdp#endif
47933965Sjdp	      case OPTION_VERBOSE:
48033965Sjdp		print_version_id ();
48133965Sjdp	      break;
48233965Sjdp	    }
48333965Sjdp	  /*FALLTHRU*/
48433965Sjdp
48533965Sjdp	case '?':
48633965Sjdp	  exit (EXIT_FAILURE);
48733965Sjdp
48833965Sjdp	case 1:			/* File name.  */
48933965Sjdp	  if (!strcmp (optarg, "-"))
49033965Sjdp	    optarg = "";
49133965Sjdp	  new_argv[new_argc++] = optarg;
49233965Sjdp	  new_argv[new_argc] = NULL;
49333965Sjdp	  break;
49433965Sjdp
49533965Sjdp	case OPTION_HELP:
49633965Sjdp	  show_usage (stdout);
49733965Sjdp	  exit (EXIT_SUCCESS);
49833965Sjdp
49933965Sjdp	case OPTION_NOCPP:
50033965Sjdp	  break;
50133965Sjdp
50233965Sjdp	case OPTION_STATISTICS:
50333965Sjdp	  flag_print_statistics = 1;
50433965Sjdp	  break;
50533965Sjdp
50638889Sjdp	case OPTION_STRIP_LOCAL_ABSOLUTE:
50738889Sjdp	  flag_strip_local_absolute = 1;
50838889Sjdp	  break;
50938889Sjdp
51038889Sjdp	case OPTION_TRADITIONAL_FORMAT:
51138889Sjdp	  flag_traditional_format = 1;
51238889Sjdp	  break;
51338889Sjdp
51433965Sjdp	case OPTION_VERSION:
51533965Sjdp	  /* This output is intended to follow the GNU standards document.  */
51660484Sobrien	  printf (_("GNU assembler %s\n"), VERSION);
51760484Sobrien	  printf (_("Copyright 2000 Free Software Foundation, Inc.\n"));
51860484Sobrien	  printf (_("\
51933965SjdpThis program is free software; you may redistribute it under the terms of\n\
52060484Sobrienthe GNU General Public License.  This program has absolutely no warranty.\n"));
52160484Sobrien	  printf (_("This assembler was configured for a target of `%s'.\n"),
52233965Sjdp		  TARGET_ALIAS);
52333965Sjdp	  exit (EXIT_SUCCESS);
52433965Sjdp
52533965Sjdp	case OPTION_EMULATION:
52633965Sjdp#ifdef USE_EMULATIONS
52733965Sjdp	  if (strcmp (optarg, this_emulation->name))
52860484Sobrien	    as_fatal (_("multiple emulation names specified"));
52933965Sjdp#else
53060484Sobrien	  as_fatal (_("emulations not handled in this configuration"));
53133965Sjdp#endif
53233965Sjdp	  break;
53333965Sjdp
53433965Sjdp	case OPTION_DUMPCONFIG:
53560484Sobrien	  fprintf (stderr, _("alias = %s\n"), TARGET_ALIAS);
53660484Sobrien	  fprintf (stderr, _("canonical = %s\n"), TARGET_CANONICAL);
53760484Sobrien	  fprintf (stderr, _("cpu-type = %s\n"), TARGET_CPU);
53833965Sjdp#ifdef TARGET_OBJ_FORMAT
53960484Sobrien	  fprintf (stderr, _("format = %s\n"), TARGET_OBJ_FORMAT);
54033965Sjdp#endif
54133965Sjdp#ifdef TARGET_FORMAT
54260484Sobrien	  fprintf (stderr, _("bfd-target = %s\n"), TARGET_FORMAT);
54333965Sjdp#endif
54433965Sjdp	  exit (EXIT_SUCCESS);
54533965Sjdp
54633965Sjdp	case OPTION_DEFSYM:
54733965Sjdp	  {
54833965Sjdp	    char *s;
54933965Sjdp	    long i;
55033965Sjdp	    struct defsym_list *n;
55133965Sjdp
55233965Sjdp	    for (s = optarg; *s != '\0' && *s != '='; s++)
55333965Sjdp	      ;
55433965Sjdp	    if (*s == '\0')
55560484Sobrien	      as_fatal (_("bad defsym; format is --defsym name=value"));
55633965Sjdp	    *s++ = '\0';
55733965Sjdp	    i = strtol (s, (char **) NULL, 0);
55833965Sjdp	    n = (struct defsym_list *) xmalloc (sizeof *n);
55933965Sjdp	    n->next = defsyms;
56033965Sjdp	    n->name = optarg;
56133965Sjdp	    n->value = i;
56233965Sjdp	    defsyms = n;
56333965Sjdp	  }
56433965Sjdp	  break;
56533965Sjdp
56633965Sjdp	case OPTION_INSTTBL:
56733965Sjdp	case 't':
56833965Sjdp	  {
56933965Sjdp	    /* optarg is the name of the file containing the instruction
57033965Sjdp	       formats, opcodes, register names, etc. */
57133965Sjdp	    struct itbl_file_list *n;
57233965Sjdp
57338889Sjdp	    if (optarg == NULL)
57438889Sjdp	      {
57560484Sobrien		as_warn ( _("No file name following -t option\n") );
57638889Sjdp		break;
57738889Sjdp	      }
57838889Sjdp
57933965Sjdp	    n = (struct itbl_file_list *) xmalloc (sizeof *n);
58033965Sjdp	    n->next = itbl_files;
58133965Sjdp	    n->name = optarg;
58233965Sjdp	    itbl_files = n;
58333965Sjdp
58433965Sjdp	    /* Parse the file and add the new instructions to our internal
58533965Sjdp	       table.  If multiple instruction tables are specified, the
58633965Sjdp	       information from this table gets appended onto the existing
58733965Sjdp	       internal table. */
58833965Sjdp	    itbl_files->name = xstrdup (optarg);
58933965Sjdp	    if (itbl_parse (itbl_files->name) != 0)
59033965Sjdp	      {
59160484Sobrien		fprintf (stderr, _("Failed to read instruction table %s\n"),
59233965Sjdp			 itbl_files->name);
59333965Sjdp		exit (EXIT_SUCCESS);
59433965Sjdp	      }
59533965Sjdp	  }
59633965Sjdp	  break;
59733965Sjdp
59838889Sjdp	case OPTION_DEPFILE:
59938889Sjdp	  start_dependencies (optarg);
60038889Sjdp	  break;
60138889Sjdp
60238889Sjdp	case OPTION_GSTABS:
60338889Sjdp	  debug_type = DEBUG_STABS;
60438889Sjdp	  break;
60538889Sjdp
60660484Sobrien	case OPTION_GDWARF2:
60760484Sobrien	  debug_type = DEBUG_DWARF2;
60860484Sobrien	  break;
60960484Sobrien
61033965Sjdp	case 'J':
61133965Sjdp	  flag_signed_overflow_ok = 1;
61233965Sjdp	  break;
61333965Sjdp
61433965Sjdp#ifndef WORKING_DOT_WORD
61533965Sjdp	case 'K':
61633965Sjdp	  flag_warn_displacement = 1;
61733965Sjdp	  break;
61833965Sjdp#endif
61933965Sjdp
62033965Sjdp	case 'L':
62133965Sjdp	  flag_keep_locals = 1;
62233965Sjdp	  break;
62333965Sjdp
62438889Sjdp	case OPTION_LISTING_LHS_WIDTH:
62538889Sjdp	  listing_lhs_width = atoi(optarg);
62638889Sjdp	  if (listing_lhs_width_second < listing_lhs_width)
62738889Sjdp	    listing_lhs_width_second = listing_lhs_width;
62838889Sjdp	  break;
62938889Sjdp	case OPTION_LISTING_LHS_WIDTH2:
63038889Sjdp	  {
63138889Sjdp	    int tmp = atoi(optarg);
63238889Sjdp	    if (tmp > listing_lhs_width)
63338889Sjdp	      listing_lhs_width_second = tmp;
63438889Sjdp	  }
63538889Sjdp	  break;
63638889Sjdp	case OPTION_LISTING_RHS_WIDTH:
63738889Sjdp	  listing_rhs_width = atoi(optarg);
63838889Sjdp	  break;
63938889Sjdp	case OPTION_LISTING_CONT_LINES:
64038889Sjdp	  listing_lhs_cont_lines = atoi(optarg);
64138889Sjdp	  break;
64238889Sjdp
64333965Sjdp	case 'M':
64433965Sjdp	  flag_mri = 1;
64533965Sjdp#ifdef TC_M68K
64633965Sjdp	  flag_m68k_mri = 1;
64733965Sjdp#endif
64833965Sjdp	  break;
64933965Sjdp
65033965Sjdp	case 'R':
65133965Sjdp	  flag_readonly_data_in_text = 1;
65233965Sjdp	  break;
65333965Sjdp
65433965Sjdp	case 'W':
65533965Sjdp	  flag_no_warnings = 1;
65633965Sjdp	  break;
65733965Sjdp
65860484Sobrien	case OPTION_WARN:
65960484Sobrien	  flag_no_warnings = 0;
66060484Sobrien	  flag_fatal_warnings = 0;
66160484Sobrien	  break;
66260484Sobrien
66360484Sobrien	case OPTION_WARN_FATAL:
66460484Sobrien	  flag_no_warnings = 0;
66560484Sobrien	  flag_fatal_warnings = 1;
66660484Sobrien	  break;
66760484Sobrien
66833965Sjdp	case 'Z':
66933965Sjdp	  flag_always_generate_output = 1;
67033965Sjdp	  break;
67133965Sjdp
67233965Sjdp	case 'a':
67333965Sjdp	  if (optarg)
67433965Sjdp	    {
67533965Sjdp	      while (*optarg)
67633965Sjdp		{
67733965Sjdp		  switch (*optarg)
67833965Sjdp		    {
67933965Sjdp		    case 'c':
68033965Sjdp		      listing |= LISTING_NOCOND;
68133965Sjdp		      break;
68233965Sjdp		    case 'd':
68333965Sjdp		      listing |= LISTING_NODEBUG;
68433965Sjdp		      break;
68533965Sjdp		    case 'h':
68633965Sjdp		      listing |= LISTING_HLL;
68733965Sjdp		      break;
68833965Sjdp		    case 'l':
68933965Sjdp		      listing |= LISTING_LISTING;
69033965Sjdp		      break;
69138889Sjdp		    case 'm':
69238889Sjdp		      listing |= LISTING_MACEXP;
69338889Sjdp		      break;
69433965Sjdp		    case 'n':
69533965Sjdp		      listing |= LISTING_NOFORM;
69633965Sjdp		      break;
69733965Sjdp		    case 's':
69833965Sjdp		      listing |= LISTING_SYMBOLS;
69933965Sjdp		      break;
70033965Sjdp		    case '=':
70133965Sjdp		      listing_filename = xstrdup (optarg + 1);
70233965Sjdp		      optarg += strlen (listing_filename);
70333965Sjdp		      break;
70433965Sjdp		    default:
70560484Sobrien		      as_fatal (_("invalid listing option `%c'"), *optarg);
70633965Sjdp		      break;
70733965Sjdp		    }
70833965Sjdp		  optarg++;
70933965Sjdp		}
71033965Sjdp	    }
71133965Sjdp	  if (!listing)
71233965Sjdp	    listing = LISTING_DEFAULT;
71333965Sjdp	  break;
71433965Sjdp
71533965Sjdp	case 'D':
71633965Sjdp	  /* DEBUG is implemented: it debugs different */
71733965Sjdp	  /* things from other people's assemblers. */
71833965Sjdp	  flag_debug = 1;
71933965Sjdp	  break;
72033965Sjdp
72133965Sjdp	case 'f':
72233965Sjdp	  flag_no_comments = 1;
72333965Sjdp	  break;
72433965Sjdp
72533965Sjdp	case 'I':
72633965Sjdp	  {			/* Include file directory */
72733965Sjdp	    char *temp = xstrdup (optarg);
72833965Sjdp	    add_include_dir (temp);
72933965Sjdp	    break;
73033965Sjdp	  }
73133965Sjdp
73233965Sjdp	case 'o':
73333965Sjdp	  out_file_name = xstrdup (optarg);
73433965Sjdp	  break;
73533965Sjdp
73633965Sjdp	case 'w':
73733965Sjdp	  break;
73833965Sjdp
73933965Sjdp	case 'X':
74033965Sjdp	  /* -X means treat warnings as errors */
74133965Sjdp	  break;
74233965Sjdp	}
74333965Sjdp    }
74433965Sjdp
74533965Sjdp  free (shortopts);
74633965Sjdp  free (longopts);
74733965Sjdp
74833965Sjdp  *pargc = new_argc;
74933965Sjdp  *pargv = new_argv;
75033965Sjdp}
75133965Sjdp
75233965Sjdpstatic long start_time;
75333965Sjdp
75433965Sjdpint
75533965Sjdpmain (argc, argv)
75633965Sjdp     int argc;
75733965Sjdp     char **argv;
75833965Sjdp{
75933965Sjdp  int macro_alternate;
76033965Sjdp  int macro_strip_at;
76133965Sjdp  int keep_it;
76233965Sjdp
76333965Sjdp  start_time = get_run_time ();
76433965Sjdp
76560484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
76660484Sobrien  setlocale (LC_MESSAGES, "");
76760484Sobrien#endif
76860484Sobrien  bindtextdomain (PACKAGE, LOCALEDIR);
76960484Sobrien  textdomain (PACKAGE);
77033965Sjdp
77133965Sjdp  if (debug_memory)
77233965Sjdp    {
77333965Sjdp#ifdef BFD_ASSEMBLER
77433965Sjdp      extern long _bfd_chunksize;
77533965Sjdp      _bfd_chunksize = 64;
77633965Sjdp#endif
77733965Sjdp      chunksize = 64;
77833965Sjdp    }
77933965Sjdp
78033965Sjdp#ifdef HOST_SPECIAL_INIT
78133965Sjdp  HOST_SPECIAL_INIT (argc, argv);
78233965Sjdp#endif
78333965Sjdp
78433965Sjdp  myname = argv[0];
78533965Sjdp  xmalloc_set_program_name (myname);
78633965Sjdp
78733965Sjdp  START_PROGRESS (myname, 0);
78833965Sjdp
78933965Sjdp#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
79033965Sjdp#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
79133965Sjdp#endif
79233965Sjdp
79333965Sjdp  out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
79433965Sjdp
79533965Sjdp  hex_init ();
79633965Sjdp#ifdef BFD_ASSEMBLER
79733965Sjdp  bfd_init ();
79833965Sjdp  bfd_set_error_program_name (myname);
79933965Sjdp#endif
80033965Sjdp
80133965Sjdp#ifdef USE_EMULATIONS
80233965Sjdp  select_emulation_mode (argc, argv);
80333965Sjdp#endif
80433965Sjdp
80533965Sjdp  PROGRESS (1);
80633965Sjdp  symbol_begin ();
80733965Sjdp  frag_init ();
80833965Sjdp  subsegs_begin ();
80933965Sjdp  parse_args (&argc, &argv);
81033965Sjdp  read_begin ();
81133965Sjdp  input_scrub_begin ();
81233965Sjdp  expr_begin ();
81333965Sjdp
81433965Sjdp  if (flag_print_statistics)
81533965Sjdp    xatexit (dump_statistics);
81633965Sjdp
81733965Sjdp  macro_alternate = 0;
81833965Sjdp  macro_strip_at = 0;
81933965Sjdp#ifdef TC_I960
82033965Sjdp  macro_strip_at = flag_mri;
82133965Sjdp#endif
82233965Sjdp#ifdef TC_A29K
82333965Sjdp  /* For compatibility with the AMD 29K family macro assembler
82433965Sjdp     specification.  */
82533965Sjdp  macro_alternate = 1;
82633965Sjdp  macro_strip_at = 1;
82733965Sjdp#endif
82833965Sjdp
82933965Sjdp  macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr);
83033965Sjdp
83133965Sjdp  PROGRESS (1);
83233965Sjdp
83333965Sjdp#ifdef BFD_ASSEMBLER
83433965Sjdp  output_file_create (out_file_name);
83533965Sjdp  assert (stdoutput != 0);
83633965Sjdp#endif
83733965Sjdp
83833965Sjdp#ifdef tc_init_after_args
83933965Sjdp  tc_init_after_args ();
84033965Sjdp#endif
84133965Sjdp
84233965Sjdp  itbl_init ();
84333965Sjdp
84433965Sjdp  /* Now that we have fully initialized, and have created the output
84533965Sjdp     file, define any symbols requested by --defsym command line
84633965Sjdp     arguments.  */
84733965Sjdp  while (defsyms != NULL)
84833965Sjdp    {
84933965Sjdp      symbolS *sym;
85033965Sjdp      struct defsym_list *next;
85133965Sjdp
85233965Sjdp      sym = symbol_new (defsyms->name, absolute_section, defsyms->value,
85333965Sjdp			&zero_address_frag);
85433965Sjdp      symbol_table_insert (sym);
85533965Sjdp      next = defsyms->next;
85633965Sjdp      free (defsyms);
85733965Sjdp      defsyms = next;
85833965Sjdp    }
85933965Sjdp
86033965Sjdp  PROGRESS (1);
86133965Sjdp
86233965Sjdp  perform_an_assembly_pass (argc, argv);	/* Assemble it. */
86333965Sjdp
86433965Sjdp  cond_finish_check (-1);
86533965Sjdp
86633965Sjdp#ifdef md_end
86733965Sjdp  md_end ();
86833965Sjdp#endif
86933965Sjdp
87033965Sjdp  if (seen_at_least_1_file ()
87133965Sjdp      && (flag_always_generate_output || had_errors () == 0))
87233965Sjdp    keep_it = 1;
87333965Sjdp  else
87433965Sjdp    keep_it = 0;
87533965Sjdp
87638889Sjdp#if defined (BFD_ASSEMBLER) || !defined (BFD)
87738889Sjdp  /* This used to be done at the start of write_object_file in
87838889Sjdp     write.c, but that caused problems when doing listings when
87938889Sjdp     keep_it was zero.  This could probably be moved above md_end, but
88038889Sjdp     I didn't want to risk the change.  */
88138889Sjdp  subsegs_finish ();
88238889Sjdp#endif
88338889Sjdp
88433965Sjdp  if (keep_it)
88533965Sjdp    write_object_file ();
88633965Sjdp
88733965Sjdp#ifndef NO_LISTING
88833965Sjdp  listing_print (listing_filename);
88933965Sjdp#endif
89033965Sjdp
89133965Sjdp#ifndef OBJ_VMS /* does its own file handling */
89233965Sjdp#ifndef BFD_ASSEMBLER
89333965Sjdp  if (keep_it)
89433965Sjdp#endif
89533965Sjdp    output_file_close (out_file_name);
89633965Sjdp#endif
89733965Sjdp
89860484Sobrien  if (flag_fatal_warnings && had_warnings() > 0 && had_errors () == 0)
89960484Sobrien    as_bad (_("%d warnings, treating warnings as errors"), had_warnings());
90060484Sobrien
90133965Sjdp  if (had_errors () > 0 && ! flag_always_generate_output)
90233965Sjdp    keep_it = 0;
90333965Sjdp
90433965Sjdp  if (!keep_it)
90533965Sjdp    unlink (out_file_name);
90633965Sjdp
90733965Sjdp  input_scrub_end ();
90833965Sjdp
90933965Sjdp  END_PROGRESS (myname);
91033965Sjdp
91133965Sjdp  /* Use xexit instead of return, because under VMS environments they
91233965Sjdp     may not place the same interpretation on the value given.  */
91333965Sjdp  if (had_errors () > 0)
91433965Sjdp    xexit (EXIT_FAILURE);
91538889Sjdp
91638889Sjdp  /* Only generate dependency file if assembler was successful.  */
91738889Sjdp  print_dependencies ();
91838889Sjdp
91933965Sjdp  xexit (EXIT_SUCCESS);
92033965Sjdp}
92133965Sjdp
92233965Sjdpstatic void
92333965Sjdpdump_statistics ()
92433965Sjdp{
92533965Sjdp#ifdef HAVE_SBRK
92633965Sjdp  char *lim = (char *) sbrk (0);
92733965Sjdp#endif
92833965Sjdp  long run_time = get_run_time () - start_time;
92933965Sjdp
93060484Sobrien  fprintf (stderr, _("%s: total time in assembly: %ld.%06ld\n"),
93133965Sjdp	   myname, run_time / 1000000, run_time % 1000000);
93233965Sjdp#ifdef HAVE_SBRK
93360484Sobrien  fprintf (stderr, _("%s: data size %ld\n"),
93433965Sjdp	   myname, (long) (lim - (char *) &environ));
93533965Sjdp#endif
93633965Sjdp
93733965Sjdp  subsegs_print_statistics (stderr);
93833965Sjdp  write_print_statistics (stderr);
93933965Sjdp  symbol_print_statistics (stderr);
94033965Sjdp  read_print_statistics (stderr);
94133965Sjdp
94233965Sjdp#ifdef tc_print_statistics
94333965Sjdp  tc_print_statistics (stderr);
94433965Sjdp#endif
94533965Sjdp#ifdef obj_print_statistics
94633965Sjdp  obj_print_statistics (stderr);
94733965Sjdp#endif
94833965Sjdp}
94933965Sjdp
95033965Sjdp
95133965Sjdp/*			perform_an_assembly_pass()
95233965Sjdp *
95333965Sjdp * Here to attempt 1 pass over each input file.
95433965Sjdp * We scan argv[*] looking for filenames or exactly "" which is
95533965Sjdp * shorthand for stdin. Any argv that is NULL is not a file-name.
95633965Sjdp * We set need_pass_2 TRUE if, after this, we still have unresolved
95733965Sjdp * expressions of the form (unknown value)+-(unknown value).
95833965Sjdp *
95933965Sjdp * Note the un*x semantics: there is only 1 logical input file, but it
96033965Sjdp * may be a catenation of many 'physical' input files.
96133965Sjdp */
96233965Sjdpstatic void
96333965Sjdpperform_an_assembly_pass (argc, argv)
96433965Sjdp     int argc;
96533965Sjdp     char **argv;
96633965Sjdp{
96733965Sjdp  int saw_a_file = 0;
96833965Sjdp#ifdef BFD_ASSEMBLER
96933965Sjdp  flagword applicable;
97033965Sjdp#endif
97133965Sjdp
97233965Sjdp  need_pass_2 = 0;
97333965Sjdp
97433965Sjdp#ifndef BFD_ASSEMBLER
97533965Sjdp#ifdef MANY_SEGMENTS
97633965Sjdp  {
97733965Sjdp    unsigned int i;
97833965Sjdp    for (i = SEG_E0; i < SEG_UNKNOWN; i++)
97933965Sjdp      segment_info[i].fix_root = 0;
98033965Sjdp  }
98133965Sjdp  /* Create the three fixed ones */
98233965Sjdp  {
98333965Sjdp    segT seg;
98433965Sjdp
98533965Sjdp#ifdef TE_APOLLO
98633965Sjdp    seg = subseg_new (".wtext", 0);
98733965Sjdp#else
98833965Sjdp    seg = subseg_new (".text", 0);
98933965Sjdp#endif
99033965Sjdp    assert (seg == SEG_E0);
99133965Sjdp    seg = subseg_new (".data", 0);
99233965Sjdp    assert (seg == SEG_E1);
99333965Sjdp    seg = subseg_new (".bss", 0);
99433965Sjdp    assert (seg == SEG_E2);
99533965Sjdp#ifdef TE_APOLLO
99633965Sjdp    create_target_segments ();
99733965Sjdp#endif
99833965Sjdp  }
99933965Sjdp
100033965Sjdp#else /* not MANY_SEGMENTS */
100133965Sjdp  text_fix_root = NULL;
100233965Sjdp  data_fix_root = NULL;
100333965Sjdp  bss_fix_root = NULL;
100433965Sjdp#endif /* not MANY_SEGMENTS */
100533965Sjdp#else /* BFD_ASSEMBLER */
100633965Sjdp  /* Create the standard sections, and those the assembler uses
100733965Sjdp     internally.  */
100838889Sjdp  text_section = subseg_new (TEXT_SECTION_NAME, 0);
100938889Sjdp  data_section = subseg_new (DATA_SECTION_NAME, 0);
101038889Sjdp  bss_section = subseg_new (BSS_SECTION_NAME, 0);
101133965Sjdp  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
101233965Sjdp     to have relocs, otherwise we don't find out in time. */
101333965Sjdp  applicable = bfd_applicable_section_flags (stdoutput);
101433965Sjdp  bfd_set_section_flags (stdoutput, text_section,
101533965Sjdp			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
101633965Sjdp				       | SEC_CODE | SEC_READONLY));
101733965Sjdp  bfd_set_section_flags (stdoutput, data_section,
101860484Sobrien			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
101960484Sobrien				       | SEC_DATA));
102033965Sjdp  bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
102133965Sjdp  seg_info (bss_section)->bss = 1;
102233965Sjdp  subseg_new (BFD_ABS_SECTION_NAME, 0);
102333965Sjdp  subseg_new (BFD_UND_SECTION_NAME, 0);
102433965Sjdp  reg_section = subseg_new ("*GAS `reg' section*", 0);
102533965Sjdp  expr_section = subseg_new ("*GAS `expr' section*", 0);
102633965Sjdp
102733965Sjdp#endif /* BFD_ASSEMBLER */
102833965Sjdp
102933965Sjdp  subseg_set (text_section, 0);
103033965Sjdp
103133965Sjdp  /* This may add symbol table entries, which requires having an open BFD,
103233965Sjdp     and sections already created, in BFD_ASSEMBLER mode.  */
103333965Sjdp  md_begin ();
103433965Sjdp
103533965Sjdp#ifdef obj_begin
103633965Sjdp  obj_begin ();
103733965Sjdp#endif
103833965Sjdp
103933965Sjdp  argv++;			/* skip argv[0] */
104033965Sjdp  argc--;			/* skip argv[0] */
104133965Sjdp  while (argc--)
104233965Sjdp    {
104333965Sjdp      if (*argv)
104433965Sjdp	{			/* Is it a file-name argument? */
104533965Sjdp	  PROGRESS (1);
104633965Sjdp	  saw_a_file++;
104733965Sjdp	  /* argv->"" if stdin desired, else->filename */
104833965Sjdp	  read_a_source_file (*argv);
104933965Sjdp	}
105033965Sjdp      argv++;			/* completed that argv */
105133965Sjdp    }
105233965Sjdp  if (!saw_a_file)
105333965Sjdp    read_a_source_file ("");
105433965Sjdp}				/* perform_an_assembly_pass() */
105533965Sjdp
105633965Sjdp/* The interface between the macro code and gas expression handling.  */
105733965Sjdp
105833965Sjdpstatic int
105933965Sjdpmacro_expr (emsg, idx, in, val)
106033965Sjdp     const char *emsg;
106133965Sjdp     int idx;
106233965Sjdp     sb *in;
106333965Sjdp     int *val;
106433965Sjdp{
106533965Sjdp  char *hold;
106633965Sjdp  expressionS ex;
106733965Sjdp
106833965Sjdp  sb_terminate (in);
106933965Sjdp
107033965Sjdp  hold = input_line_pointer;
107133965Sjdp  input_line_pointer = in->ptr + idx;
107233965Sjdp  expression (&ex);
107333965Sjdp  idx = input_line_pointer - in->ptr;
107433965Sjdp  input_line_pointer = hold;
107533965Sjdp
107633965Sjdp  if (ex.X_op != O_constant)
107733965Sjdp    as_bad ("%s", emsg);
107833965Sjdp
107933965Sjdp  *val = (int) ex.X_add_number;
108033965Sjdp
108133965Sjdp  return idx;
108233965Sjdp}
108333965Sjdp
108433965Sjdp/* end of as.c */
1085