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