as.c revision 33965
1/* as.c - GAS main program.
2   Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
3   Free Software Foundation, Inc.
4
5   This file is part of GAS, the GNU Assembler.
6
7   GAS is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
12   GAS is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with GAS; see the file COPYING.  If not, write to the Free
19   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20   02111-1307, USA. */
21
22/*
23 * Main program for AS; a 32-bit assembler of GNU.
24 * Understands command arguments.
25 * Has a few routines that don't fit in other modules because they
26 * are shared.
27 *
28 *
29 *			bugs
30 *
31 * : initialisers
32 *	Since no-one else says they will support them in future: I
33 * don't support them now.
34 *
35 */
36
37#include "ansidecl.h"
38
39#define COMMON
40
41#include "as.h"
42#include "subsegs.h"
43#include "output-file.h"
44#include "sb.h"
45#include "macro.h"
46#ifndef HAVE_ITBL_CPU
47#define itbl_parse(itbl_file) 1
48#define itbl_init()
49#endif
50
51#ifdef HAVE_SBRK
52#ifdef NEED_DECLARATION_SBRK
53extern PTR sbrk ();
54#endif
55#endif
56
57static void show_usage PARAMS ((FILE *));
58static void parse_args PARAMS ((int *, char ***));
59static void dump_statistics PARAMS ((void));
60static void perform_an_assembly_pass PARAMS ((int argc, char **argv));
61static int macro_expr PARAMS ((const char *, int, sb *, int *));
62
63int listing;			/* true if a listing is wanted */
64
65static char *listing_filename = NULL;	/* Name of listing file.  */
66
67/* Maximum level of macro nesting.  */
68
69int max_macro_nest = 100;
70
71char *myname;			/* argv[0] */
72#ifdef BFD_ASSEMBLER
73segT reg_section, expr_section;
74segT text_section, data_section, bss_section;
75#endif
76
77int chunksize = 5000;
78
79/* To monitor memory allocation more effectively, make this non-zero.
80   Then the chunk sizes for gas and bfd will be reduced.  */
81int debug_memory = 0;
82
83/* We build a list of defsyms as we read the options, and then define
84   them after we have initialized everything.  */
85
86struct defsym_list
87{
88  struct defsym_list *next;
89  char *name;
90  valueT value;
91};
92
93static struct defsym_list *defsyms;
94
95/* Keep a record of the itbl files we read in. */
96
97struct itbl_file_list
98{
99  struct itbl_file_list *next;
100  char *name;
101};
102
103static struct itbl_file_list *itbl_files;
104
105void
106print_version_id ()
107{
108  static int printed;
109  if (printed)
110    return;
111  printed = 1;
112
113  fprintf (stderr, "GNU assembler version %s (%s)", GAS_VERSION, TARGET_ALIAS);
114#ifdef BFD_ASSEMBLER
115  fprintf (stderr, ", using BFD version %s", BFD_VERSION);
116#endif
117  fprintf (stderr, "\n");
118}
119
120static void
121show_usage (stream)
122     FILE *stream;
123{
124  fprintf (stream, "Usage: %s [option...] [asmfile...]\n", myname);
125
126  fprintf (stream, "\
127Options:\n\
128-a[sub-option...]	turn on listings\n\
129  Sub-options [default hls]:\n\
130  c	omit false conditionals\n\
131  d	omit debugging directives\n\
132  h	include high-level source\n\
133  l	include assembly\n\
134  n	omit forms processing\n\
135  s	include symbols\n\
136  =file set listing file name (must be last sub-option)\n");
137  fprintf (stream, "\
138-D			produce assembler debugging messages\n\
139--defsym SYM=VAL	define symbol SYM to given value\n\
140-f			skip whitespace and comment preprocessing\n\
141--help			show this message and exit\n\
142-I DIR			add DIR to search list for .include directives\n\
143-J			don't warn about signed overflow\n\
144-K			warn when differences altered for long displacements\n\
145-L			keep local symbols (starting with `L')\n");
146  fprintf (stream, "\
147-M,--mri		assemble in MRI compatibility mode\n\
148-nocpp			ignored\n\
149-o OBJFILE		name the object-file output OBJFILE (default a.out)\n\
150-R			fold data section into text section\n\
151--statistics		print various measured statistics from execution\n\
152--version		print assembler version number and exit\n\
153-W			suppress warnings\n\
154--itbl INSTTBL		extend instruction set to include instructions\n\
155			matching the specifications defined in file INSTTBL\n\
156-w			ignored\n\
157-X			ignored\n\
158-Z			generate object file even after errors\n");
159
160  md_show_usage (stream);
161
162  fprintf (stream, "\nReport bugs to bug-gnu-utils@prep.ai.mit.edu\n");
163}
164
165#ifdef USE_EMULATIONS
166#define EMULATION_ENVIRON "AS_EMULATION"
167
168extern struct emulation mipsbelf, mipslelf, mipself;
169extern struct emulation mipsbecoff, mipslecoff, mipsecoff;
170extern struct emulation i386coff, i386elf;
171
172static struct emulation *const emulations[] = { EMULATIONS };
173static const int n_emulations = sizeof (emulations) / sizeof (emulations[0]);
174
175static void select_emulation_mode PARAMS ((int, char **));
176
177static void
178select_emulation_mode (argc, argv)
179     int argc;
180     char **argv;
181{
182  int i;
183  char *p, *em = 0;
184
185  for (i = 1; i < argc; i++)
186    if (!strncmp ("--em", argv[i], 4))
187      break;
188
189  if (i == argc)
190    goto do_default;
191
192  p = strchr (argv[i], '=');
193  if (p)
194    p++;
195  else
196    p = argv[i+1];
197
198  if (!p || !*p)
199    as_fatal ("missing emulation mode name");
200  em = p;
201
202 do_default:
203  if (em == 0)
204    em = getenv (EMULATION_ENVIRON);
205  if (em == 0)
206    em = DEFAULT_EMULATION;
207
208  if (em)
209    {
210      for (i = 0; i < n_emulations; i++)
211	if (!strcmp (emulations[i]->name, em))
212	  break;
213      if (i == n_emulations)
214	as_fatal ("unrecognized emulation name `%s'", em);
215      this_emulation = emulations[i];
216    }
217  else
218    this_emulation = emulations[0];
219
220  this_emulation->init ();
221}
222
223const char *
224default_emul_bfd_name ()
225{
226  abort ();
227  return NULL;
228}
229
230void
231common_emul_init ()
232{
233  this_format = this_emulation->format;
234
235  if (this_emulation->leading_underscore == 2)
236    this_emulation->leading_underscore = this_format->dfl_leading_underscore;
237
238  if (this_emulation->default_endian != 2)
239    target_big_endian = this_emulation->default_endian;
240
241  if (this_emulation->fake_label_name == 0)
242    {
243      if (this_emulation->leading_underscore)
244	this_emulation->fake_label_name = "L0\001";
245      else
246	/* What other parameters should we test?  */
247	this_emulation->fake_label_name = ".L0\001";
248    }
249}
250#endif
251
252/*
253 * Since it is easy to do here we interpret the special arg "-"
254 * to mean "use stdin" and we set that argv[] pointing to "".
255 * After we have munged argv[], the only things left are source file
256 * name(s) and ""(s) denoting stdin. These file names are used
257 * (perhaps more than once) later.
258 *
259 * check for new machine-dep cmdline options in
260 * md_parse_option definitions in config/tc-*.c
261 */
262
263static void
264parse_args (pargc, pargv)
265     int *pargc;
266     char ***pargv;
267{
268  int old_argc, new_argc;
269  char **old_argv, **new_argv;
270
271  /* Starting the short option string with '-' is for programs that
272     expect options and other ARGV-elements in any order and that care about
273     the ordering of the two.  We describe each non-option ARGV-element
274     as if it were the argument of an option with character code 1.  */
275
276  char *shortopts;
277  extern CONST char *md_shortopts;
278  static const char std_shortopts[] =
279    {
280      '-', 'J',
281#ifndef WORKING_DOT_WORD
282      /* -K is not meaningful if .word is not being hacked.  */
283      'K',
284#endif
285      'L', 'M', 'R', 'W', 'Z', 'f', 'a', ':', ':', 'D', 'I', ':', 'o', ':',
286#ifndef VMS
287      /* -v takes an argument on VMS, so we don't make it a generic
288         option.  */
289      'v',
290#endif
291      'w', 'X',
292      /* New option for extending instruction set (see also --itbl below) */
293      't',
294      '\0'
295    };
296  struct option *longopts;
297  extern struct option md_longopts[];
298  extern size_t md_longopts_size;
299  static const struct option std_longopts[] = {
300#define OPTION_HELP (OPTION_STD_BASE)
301    {"help", no_argument, NULL, OPTION_HELP},
302    {"mri", no_argument, NULL, 'M'},
303#define OPTION_NOCPP (OPTION_STD_BASE + 1)
304    {"nocpp", no_argument, NULL, OPTION_NOCPP},
305#define OPTION_STATISTICS (OPTION_STD_BASE + 2)
306    {"statistics", no_argument, NULL, OPTION_STATISTICS},
307#define OPTION_VERSION (OPTION_STD_BASE + 3)
308    {"version", no_argument, NULL, OPTION_VERSION},
309#define OPTION_DUMPCONFIG (OPTION_STD_BASE + 4)
310    {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG},
311#define OPTION_VERBOSE (OPTION_STD_BASE + 5)
312    {"verbose", no_argument, NULL, OPTION_VERBOSE},
313#define OPTION_EMULATION (OPTION_STD_BASE + 6)
314    {"emulation", required_argument, NULL, OPTION_EMULATION},
315#define OPTION_DEFSYM (OPTION_STD_BASE + 7)
316    {"defsym", required_argument, NULL, OPTION_DEFSYM},
317#define OPTION_INSTTBL (OPTION_STD_BASE + 8)
318    /* New option for extending instruction set (see also -t above).
319       The "-t file" or "--itbl file" option extends the basic set of
320       valid instructions by reading "file", a text file containing a
321       list of instruction formats.  The additional opcodes and their
322       formats are added to the built-in set of instructions, and
323       mnemonics for new registers may also be defined.  */
324    {"itbl", required_argument, NULL, OPTION_INSTTBL}
325  };
326
327  /* Construct the option lists from the standard list and the
328     target dependent list.  */
329  shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
330  longopts = (struct option *) xmalloc (sizeof (std_longopts) + md_longopts_size);
331  memcpy (longopts, std_longopts, sizeof (std_longopts));
332  memcpy ((char *) longopts + sizeof (std_longopts),
333	  md_longopts, md_longopts_size);
334
335  /* Make a local copy of the old argv.  */
336  old_argc = *pargc;
337  old_argv = *pargv;
338
339  /* Initialize a new argv that contains no options.  */
340  new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1));
341  new_argv[0] = old_argv[0];
342  new_argc = 1;
343  new_argv[new_argc] = NULL;
344
345  while (1)
346    {
347      /* getopt_long_only is like getopt_long, but '-' as well as '--' can
348	 indicate a long option.  */
349      int longind;
350      int optc = getopt_long_only (old_argc, old_argv, shortopts, longopts,
351				   &longind);
352
353      if (optc == -1)
354	break;
355
356      switch (optc)
357	{
358	default:
359	  /* md_parse_option should return 1 if it recognizes optc,
360	     0 if not.  */
361	  if (md_parse_option (optc, optarg) != 0)
362	    break;
363	  /* `-v' isn't included in the general short_opts list, so check for
364	     it explicity here before deciding we've gotten a bad argument.  */
365	  if (optc == 'v')
366	    {
367#ifdef VMS
368	      /* Telling getopt to treat -v's value as optional can result
369		 in it picking up a following filename argument here.  The
370		 VMS code in md_parse_option can return 0 in that case,
371		 but it has no way of pushing the filename argument back.  */
372	      if (optarg && *optarg)
373		new_argv[new_argc++] = optarg,  new_argv[new_argc] = NULL;
374	      else
375#else
376	      case 'v':
377#endif
378	      case OPTION_VERBOSE:
379		print_version_id ();
380	      break;
381	    }
382	  /*FALLTHRU*/
383
384	case '?':
385	  exit (EXIT_FAILURE);
386
387	case 1:			/* File name.  */
388	  if (!strcmp (optarg, "-"))
389	    optarg = "";
390	  new_argv[new_argc++] = optarg;
391	  new_argv[new_argc] = NULL;
392	  break;
393
394	case OPTION_HELP:
395	  show_usage (stdout);
396	  exit (EXIT_SUCCESS);
397
398	case OPTION_NOCPP:
399	  break;
400
401	case OPTION_STATISTICS:
402	  flag_print_statistics = 1;
403	  break;
404
405	case OPTION_VERSION:
406	  /* This output is intended to follow the GNU standards document.  */
407	  printf ("GNU assembler %s\n", GAS_VERSION);
408	  printf ("Copyright 1997 Free Software Foundation, Inc.\n");
409	  printf ("\
410This program is free software; you may redistribute it under the terms of\n\
411the GNU General Public License.  This program has absolutely no warranty.\n");
412	  printf ("This assembler was configured for a target of `%s'.\n",
413		  TARGET_ALIAS);
414	  exit (EXIT_SUCCESS);
415
416	case OPTION_EMULATION:
417#ifdef USE_EMULATIONS
418	  if (strcmp (optarg, this_emulation->name))
419	    as_fatal ("multiple emulation names specified");
420#else
421	  as_fatal ("emulations not handled in this configuration");
422#endif
423	  break;
424
425	case OPTION_DUMPCONFIG:
426	  fprintf (stderr, "alias = %s\n", TARGET_ALIAS);
427	  fprintf (stderr, "canonical = %s\n", TARGET_CANONICAL);
428	  fprintf (stderr, "cpu-type = %s\n", TARGET_CPU);
429#ifdef TARGET_OBJ_FORMAT
430	  fprintf (stderr, "format = %s\n", TARGET_OBJ_FORMAT);
431#endif
432#ifdef TARGET_FORMAT
433	  fprintf (stderr, "bfd-target = %s\n", TARGET_FORMAT);
434#endif
435	  exit (EXIT_SUCCESS);
436
437	case OPTION_DEFSYM:
438	  {
439	    char *s;
440	    long i;
441	    struct defsym_list *n;
442
443	    for (s = optarg; *s != '\0' && *s != '='; s++)
444	      ;
445	    if (*s == '\0')
446	      as_fatal ("bad defsym; format is --defsym name=value");
447	    *s++ = '\0';
448	    i = strtol (s, (char **) NULL, 0);
449	    n = (struct defsym_list *) xmalloc (sizeof *n);
450	    n->next = defsyms;
451	    n->name = optarg;
452	    n->value = i;
453	    defsyms = n;
454	  }
455	  break;
456
457	case OPTION_INSTTBL:
458	case 't':
459	  {
460	    /* optarg is the name of the file containing the instruction
461	       formats, opcodes, register names, etc. */
462	    struct itbl_file_list *n;
463
464	    n = (struct itbl_file_list *) xmalloc (sizeof *n);
465	    n->next = itbl_files;
466	    n->name = optarg;
467	    itbl_files = n;
468
469	    /* Parse the file and add the new instructions to our internal
470	       table.  If multiple instruction tables are specified, the
471	       information from this table gets appended onto the existing
472	       internal table. */
473	    itbl_files->name = xstrdup (optarg);
474	    if (itbl_parse (itbl_files->name) != 0)
475	      {
476		fprintf (stderr, "Failed to read instruction table %s\n",
477			 itbl_files->name);
478		exit (EXIT_SUCCESS);
479	      }
480	  }
481	  break;
482
483	case 'J':
484	  flag_signed_overflow_ok = 1;
485	  break;
486
487#ifndef WORKING_DOT_WORD
488	case 'K':
489	  flag_warn_displacement = 1;
490	  break;
491#endif
492
493	case 'L':
494	  flag_keep_locals = 1;
495	  break;
496
497	case 'M':
498	  flag_mri = 1;
499#ifdef TC_M68K
500	  flag_m68k_mri = 1;
501#endif
502	  break;
503
504	case 'R':
505	  flag_readonly_data_in_text = 1;
506	  break;
507
508	case 'W':
509	  flag_no_warnings = 1;
510	  break;
511
512	case 'Z':
513	  flag_always_generate_output = 1;
514	  break;
515
516	case 'a':
517	  if (optarg)
518	    {
519	      while (*optarg)
520		{
521		  switch (*optarg)
522		    {
523		    case 'c':
524		      listing |= LISTING_NOCOND;
525		      break;
526		    case 'd':
527		      listing |= LISTING_NODEBUG;
528		      break;
529		    case 'h':
530		      listing |= LISTING_HLL;
531		      break;
532		    case 'l':
533		      listing |= LISTING_LISTING;
534		      break;
535		    case 'n':
536		      listing |= LISTING_NOFORM;
537		      break;
538		    case 's':
539		      listing |= LISTING_SYMBOLS;
540		      break;
541		    case '=':
542		      listing_filename = xstrdup (optarg + 1);
543		      optarg += strlen (listing_filename);
544		      break;
545		    default:
546		      as_fatal ("invalid listing option `%c'", *optarg);
547		      break;
548		    }
549		  optarg++;
550		}
551	    }
552	  if (!listing)
553	    listing = LISTING_DEFAULT;
554	  break;
555
556	case 'D':
557	  /* DEBUG is implemented: it debugs different */
558	  /* things from other people's assemblers. */
559	  flag_debug = 1;
560	  break;
561
562	case 'f':
563	  flag_no_comments = 1;
564	  break;
565
566	case 'I':
567	  {			/* Include file directory */
568	    char *temp = xstrdup (optarg);
569	    add_include_dir (temp);
570	    break;
571	  }
572
573	case 'o':
574	  out_file_name = xstrdup (optarg);
575	  break;
576
577	case 'w':
578	  break;
579
580	case 'X':
581	  /* -X means treat warnings as errors */
582	  break;
583	}
584    }
585
586  free (shortopts);
587  free (longopts);
588
589  *pargc = new_argc;
590  *pargv = new_argv;
591}
592
593static long start_time;
594
595int
596main (argc, argv)
597     int argc;
598     char **argv;
599{
600  int macro_alternate;
601  int macro_strip_at;
602  int keep_it;
603
604  start_time = get_run_time ();
605
606
607  if (debug_memory)
608    {
609#ifdef BFD_ASSEMBLER
610      extern long _bfd_chunksize;
611      _bfd_chunksize = 64;
612#endif
613      chunksize = 64;
614    }
615
616#ifdef HOST_SPECIAL_INIT
617  HOST_SPECIAL_INIT (argc, argv);
618#endif
619
620  myname = argv[0];
621  xmalloc_set_program_name (myname);
622
623  START_PROGRESS (myname, 0);
624
625#ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
626#define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
627#endif
628
629  out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
630
631  hex_init ();
632#ifdef BFD_ASSEMBLER
633  bfd_init ();
634  bfd_set_error_program_name (myname);
635#endif
636
637#ifdef USE_EMULATIONS
638  select_emulation_mode (argc, argv);
639#endif
640
641  PROGRESS (1);
642  symbol_begin ();
643  frag_init ();
644  subsegs_begin ();
645  parse_args (&argc, &argv);
646  read_begin ();
647  input_scrub_begin ();
648  expr_begin ();
649
650  if (flag_print_statistics)
651    xatexit (dump_statistics);
652
653  macro_alternate = 0;
654  macro_strip_at = 0;
655#ifdef TC_I960
656  macro_strip_at = flag_mri;
657#endif
658#ifdef TC_A29K
659  /* For compatibility with the AMD 29K family macro assembler
660     specification.  */
661  macro_alternate = 1;
662  macro_strip_at = 1;
663#endif
664
665  macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr);
666
667  PROGRESS (1);
668
669#ifdef BFD_ASSEMBLER
670  output_file_create (out_file_name);
671  assert (stdoutput != 0);
672#endif
673
674#ifdef tc_init_after_args
675  tc_init_after_args ();
676#endif
677
678  itbl_init ();
679
680  /* Now that we have fully initialized, and have created the output
681     file, define any symbols requested by --defsym command line
682     arguments.  */
683  while (defsyms != NULL)
684    {
685      symbolS *sym;
686      struct defsym_list *next;
687
688      sym = symbol_new (defsyms->name, absolute_section, defsyms->value,
689			&zero_address_frag);
690      symbol_table_insert (sym);
691      next = defsyms->next;
692      free (defsyms);
693      defsyms = next;
694    }
695
696  PROGRESS (1);
697
698  perform_an_assembly_pass (argc, argv);	/* Assemble it. */
699
700  cond_finish_check (-1);
701
702#ifdef md_end
703  md_end ();
704#endif
705
706  if (seen_at_least_1_file ()
707      && (flag_always_generate_output || had_errors () == 0))
708    keep_it = 1;
709  else
710    keep_it = 0;
711
712  if (keep_it)
713    write_object_file ();
714
715#ifndef NO_LISTING
716  listing_print (listing_filename);
717#endif
718
719#ifndef OBJ_VMS /* does its own file handling */
720#ifndef BFD_ASSEMBLER
721  if (keep_it)
722#endif
723    output_file_close (out_file_name);
724#endif
725
726  if (had_errors () > 0 && ! flag_always_generate_output)
727    keep_it = 0;
728
729  if (!keep_it)
730    unlink (out_file_name);
731
732  input_scrub_end ();
733
734  END_PROGRESS (myname);
735
736  /* Use xexit instead of return, because under VMS environments they
737     may not place the same interpretation on the value given.  */
738  if (had_errors () > 0)
739    xexit (EXIT_FAILURE);
740  xexit (EXIT_SUCCESS);
741}
742
743static void
744dump_statistics ()
745{
746  extern char **environ;
747#ifdef HAVE_SBRK
748  char *lim = (char *) sbrk (0);
749#endif
750  long run_time = get_run_time () - start_time;
751
752  fprintf (stderr, "%s: total time in assembly: %ld.%06ld\n",
753	   myname, run_time / 1000000, run_time % 1000000);
754#ifdef HAVE_SBRK
755  fprintf (stderr, "%s: data size %ld\n",
756	   myname, (long) (lim - (char *) &environ));
757#endif
758
759  subsegs_print_statistics (stderr);
760  write_print_statistics (stderr);
761  symbol_print_statistics (stderr);
762  read_print_statistics (stderr);
763
764#ifdef tc_print_statistics
765  tc_print_statistics (stderr);
766#endif
767#ifdef obj_print_statistics
768  obj_print_statistics (stderr);
769#endif
770}
771
772
773/*			perform_an_assembly_pass()
774 *
775 * Here to attempt 1 pass over each input file.
776 * We scan argv[*] looking for filenames or exactly "" which is
777 * shorthand for stdin. Any argv that is NULL is not a file-name.
778 * We set need_pass_2 TRUE if, after this, we still have unresolved
779 * expressions of the form (unknown value)+-(unknown value).
780 *
781 * Note the un*x semantics: there is only 1 logical input file, but it
782 * may be a catenation of many 'physical' input files.
783 */
784static void
785perform_an_assembly_pass (argc, argv)
786     int argc;
787     char **argv;
788{
789  int saw_a_file = 0;
790#ifdef BFD_ASSEMBLER
791  flagword applicable;
792#endif
793
794  need_pass_2 = 0;
795
796#ifndef BFD_ASSEMBLER
797#ifdef MANY_SEGMENTS
798  {
799    unsigned int i;
800    for (i = SEG_E0; i < SEG_UNKNOWN; i++)
801      segment_info[i].fix_root = 0;
802  }
803  /* Create the three fixed ones */
804  {
805    segT seg;
806
807#ifdef TE_APOLLO
808    seg = subseg_new (".wtext", 0);
809#else
810    seg = subseg_new (".text", 0);
811#endif
812    assert (seg == SEG_E0);
813    seg = subseg_new (".data", 0);
814    assert (seg == SEG_E1);
815    seg = subseg_new (".bss", 0);
816    assert (seg == SEG_E2);
817#ifdef TE_APOLLO
818    create_target_segments ();
819#endif
820  }
821
822#else /* not MANY_SEGMENTS */
823  text_fix_root = NULL;
824  data_fix_root = NULL;
825  bss_fix_root = NULL;
826#endif /* not MANY_SEGMENTS */
827#else /* BFD_ASSEMBLER */
828  /* Create the standard sections, and those the assembler uses
829     internally.  */
830  text_section = subseg_new (".text", 0);
831  data_section = subseg_new (".data", 0);
832  bss_section = subseg_new (".bss", 0);
833  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
834     to have relocs, otherwise we don't find out in time. */
835  applicable = bfd_applicable_section_flags (stdoutput);
836  bfd_set_section_flags (stdoutput, text_section,
837			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
838				       | SEC_CODE | SEC_READONLY));
839  /* @@ FIXME -- SEC_CODE seems to mean code only, rather than code possibly.*/
840  bfd_set_section_flags (stdoutput, data_section,
841			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC));
842  bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
843  seg_info (bss_section)->bss = 1;
844  subseg_new (BFD_ABS_SECTION_NAME, 0);
845  subseg_new (BFD_UND_SECTION_NAME, 0);
846  reg_section = subseg_new ("*GAS `reg' section*", 0);
847  expr_section = subseg_new ("*GAS `expr' section*", 0);
848
849#endif /* BFD_ASSEMBLER */
850
851  subseg_set (text_section, 0);
852
853  /* This may add symbol table entries, which requires having an open BFD,
854     and sections already created, in BFD_ASSEMBLER mode.  */
855  md_begin ();
856
857#ifdef obj_begin
858  obj_begin ();
859#endif
860
861  argv++;			/* skip argv[0] */
862  argc--;			/* skip argv[0] */
863  while (argc--)
864    {
865      if (*argv)
866	{			/* Is it a file-name argument? */
867	  PROGRESS (1);
868	  saw_a_file++;
869	  /* argv->"" if stdin desired, else->filename */
870	  read_a_source_file (*argv);
871	}
872      argv++;			/* completed that argv */
873    }
874  if (!saw_a_file)
875    read_a_source_file ("");
876}				/* perform_an_assembly_pass() */
877
878/* The interface between the macro code and gas expression handling.  */
879
880static int
881macro_expr (emsg, idx, in, val)
882     const char *emsg;
883     int idx;
884     sb *in;
885     int *val;
886{
887  char *hold;
888  expressionS ex;
889
890  sb_terminate (in);
891
892  hold = input_line_pointer;
893  input_line_pointer = in->ptr + idx;
894  expression (&ex);
895  idx = input_line_pointer - in->ptr;
896  input_line_pointer = hold;
897
898  if (ex.X_op != O_constant)
899    as_bad ("%s", emsg);
900
901  *val = (int) ex.X_add_number;
902
903  return idx;
904}
905
906/* end of as.c */
907