X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fas.c;h=200a4d10e375ee71623f86eb9db6a8c5feb48711;hb=b1b17bc508cd93e4ed8b6318bdaf9e48d89e4811;hp=8b27316d8bd901941bd4439fdea6a2e6bcd4049c;hpb=c2059446380ed39ede4bb55ad2dbdb8cfb9df5dd;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/as.c b/gas/as.c index 8b27316d8b..200a4d10e3 100644 --- a/gas/as.c +++ b/gas/as.c @@ -1,24 +1,24 @@ /* as.c - GAS main program. Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. - GAS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + GAS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ /* Main program for AS; a 32-bit assembler of GNU. Understands command arguments. @@ -31,8 +31,6 @@ Since no-one else says they will support them in future: I don't support them now. */ -#include "ansidecl.h" - #define COMMON #include "as.h" @@ -42,15 +40,11 @@ #include "macro.h" #include "dwarf2dbg.h" #include "dw2gencfi.h" - -#ifdef BFD_ASSEMBLER #include "bfdver.h" -#endif #ifdef HAVE_ITBL_CPU #include "itbl-ops.h" #else -#define itbl_parse(itbl_file) 1 #define itbl_init() #endif @@ -65,13 +59,6 @@ extern PTR sbrk (); extern void gas_cgen_begin (void); #endif -/* Keep a record of the itbl files we read in. */ -struct itbl_file_list -{ - struct itbl_file_list *next; - char *name; -}; - /* We build a list of defsyms as we read the options, and then define them after we have initialized everything. */ struct defsym_list @@ -87,12 +74,18 @@ int listing; /* Type of debugging to generate. */ enum debug_info_type debug_type = DEBUG_UNSPECIFIED; +int use_gnu_debug_info_extensions = 0; + +#ifndef MD_DEBUG_FORMAT_SELECTOR +#define MD_DEBUG_FORMAT_SELECTOR NULL +#endif +static enum debug_info_type (*md_debug_format_selector) (int *) = MD_DEBUG_FORMAT_SELECTOR; /* Maximum level of macro nesting. */ int max_macro_nest = 100; /* argv[0] */ -char * myname; +static char * myname; /* The default obstack chunk size. If we set this to zero, the obstack code will use whatever will fit in a 4096 byte block. */ @@ -105,23 +98,31 @@ int debug_memory = 0; /* Enable verbose mode. */ int verbose = 0; -#ifdef BFD_ASSEMBLER segT reg_section; segT expr_section; segT text_section; segT data_section; segT bss_section; -#endif /* Name of listing file. */ static char *listing_filename = NULL; static struct defsym_list *defsyms; +#ifdef HAVE_ITBL_CPU +/* Keep a record of the itbl files we read in. */ +struct itbl_file_list +{ + struct itbl_file_list *next; + char *name; +}; static struct itbl_file_list *itbl_files; +#endif static long start_time; +static int flag_macro_alternate; + #ifdef USE_EMULATIONS #define EMULATION_ENVIRON "AS_EMULATION" @@ -216,13 +217,8 @@ print_version_id (void) return; printed = 1; -#ifdef BFD_ASSEMBLER - fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s"), + fprintf (stderr, _("GNU assembler version %s (%s) using BFD version %s\n"), VERSION, TARGET_ALIAS, BFD_VERSION_STRING); -#else - fprintf (stderr, _("GNU assembler version %s (%s)"), VERSION, TARGET_ALIAS); -#endif - fprintf (stderr, "\n"); } static void @@ -243,9 +239,13 @@ Options:\n\ s include symbols\n\ =FILE list to FILE (must be last sub-option)\n")); + fprintf (stream, _("\ + --alternate initially turn on alternate macro syntax\n")); fprintf (stream, _("\ -D produce assembler debugging messages\n")); fprintf (stream, _("\ + --debug-prefix-map OLD=NEW Map OLD to NEW in debug information\n")); + fprintf (stream, _("\ --defsym SYM=VAL define symbol SYM to given value\n")); #ifdef USE_EMULATIONS { @@ -265,7 +265,7 @@ Options:\n\ emulate output (default %s)\n"), def_em); } #endif -#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF) +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF fprintf (stream, _("\ --execstack require executable stack for this object\n")); fprintf (stream, _("\ @@ -274,9 +274,15 @@ Options:\n\ fprintf (stream, _("\ -f skip whitespace and comment preprocessing\n")); fprintf (stream, _("\ - --gstabs generate stabs debugging information\n")); + -g --gen-debug generate debugging information\n")); + fprintf (stream, _("\ + --gstabs generate STABS debugging information\n")); + fprintf (stream, _("\ + --gstabs+ generate STABS debug info with GNU extensions\n")); + fprintf (stream, _("\ + --gdwarf-2 generate DWARF2 debugging information\n")); fprintf (stream, _("\ - --gdwarf2 generate DWARF2 debugging information\n")); + --hash-size= set the hash table size close to \n")); fprintf (stream, _("\ --help show this message and exit\n")); fprintf (stream, _("\ @@ -300,6 +306,10 @@ Options:\n\ fprintf (stream, _("\ -R fold data section into text section\n")); fprintf (stream, _("\ + --reduce-memory-overheads \n\ + prefer smaller memory use at the cost of longer\n\ + assembly times\n")); + fprintf (stream, _("\ --statistics print various measured statistics from execution\n")); fprintf (stream, _("\ --strip-local-absolute strip local absolute symbols\n")); @@ -313,9 +323,11 @@ Options:\n\ --warn don't suppress warnings\n")); fprintf (stream, _("\ --fatal-warnings treat warnings as errors\n")); +#ifdef HAVE_ITBL_CPU fprintf (stream, _("\ --itbl INSTTBL extend instruction set to include instructions\n\ matching the specifications defined in file INSTTBL\n")); +#endif fprintf (stream, _("\ -w ignored\n")); fprintf (stream, _("\ @@ -335,11 +347,15 @@ Options:\n\ fprintf (stream, _("\ --listing-cont-lines set the maximum number of continuation lines used\n\ for the output data column of the listing\n")); + fprintf (stream, _("\ + @FILE read options from FILE\n")); md_show_usage (stream); fputc ('\n', stream); - fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); + + if (REPORT_BUGS_TO[0] && stream == stdout) + fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); } /* Since it is easy to do here we interpret the special arg "-" @@ -371,15 +387,17 @@ parse_args (int * pargc, char *** pargv) /* -K is not meaningful if .word is not being hacked. */ 'K', #endif - 'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'I', ':', 'o', ':', + 'L', 'M', 'R', 'W', 'Z', 'a', ':', ':', 'D', 'f', 'g', ':',':', 'I', ':', 'o', ':', #ifndef VMS /* -v takes an argument on VMS, so we don't make it a generic option. */ 'v', #endif 'w', 'X', +#ifdef HAVE_ITBL_CPU /* New option for extending instruction set (see also --itbl below). */ 't', ':', +#endif '\0' }; struct option *longopts; @@ -395,66 +413,92 @@ parse_args (int * pargc, char *** pargv) OPTION_DUMPCONFIG, OPTION_VERBOSE, OPTION_EMULATION, + OPTION_DEBUG_PREFIX_MAP, OPTION_DEFSYM, - OPTION_INSTTBL, OPTION_LISTING_LHS_WIDTH, OPTION_LISTING_LHS_WIDTH2, OPTION_LISTING_RHS_WIDTH, OPTION_LISTING_CONT_LINES, OPTION_DEPFILE, OPTION_GSTABS, + OPTION_GSTABS_PLUS, + OPTION_GDWARF2, OPTION_STRIP_LOCAL_ABSOLUTE, OPTION_TRADITIONAL_FORMAT, - OPTION_GDWARF2, OPTION_WARN, OPTION_TARGET_HELP, OPTION_EXECSTACK, OPTION_NOEXECSTACK, + OPTION_ALTERNATE, + OPTION_AL, + OPTION_HASH_TABLE_SIZE, + OPTION_REDUCE_MEMORY_OVERHEADS, OPTION_WARN_FATAL + /* When you add options here, check that they do + not collide with OPTION_MD_BASE. See as.h. */ }; static const struct option std_longopts[] = { - {"help", no_argument, NULL, OPTION_HELP}, - /* getopt allows abbreviations, so we do this to stop it from - treating -k as an abbreviation for --keep-locals. Some - ports use -k to enable PIC assembly. */ - {"keep-locals", no_argument, NULL, 'L'}, - {"keep-locals", no_argument, NULL, 'L'}, - {"mri", no_argument, NULL, 'M'}, - {"nocpp", no_argument, NULL, OPTION_NOCPP}, - {"statistics", no_argument, NULL, OPTION_STATISTICS}, - {"version", no_argument, NULL, OPTION_VERSION}, - {"dump-config", no_argument, NULL, OPTION_DUMPCONFIG}, - {"verbose", no_argument, NULL, OPTION_VERBOSE}, - {"emulation", required_argument, NULL, OPTION_EMULATION}, - {"defsym", required_argument, NULL, OPTION_DEFSYM}, + /* Note: commas are placed at the start of the line rather than + the end of the preceeding line so that it is simpler to + selectively add and remove lines from this list. */ + {"alternate", no_argument, NULL, OPTION_ALTERNATE} + /* The entry for "a" is here to prevent getopt_long_only() from + considering that -a is an abbreviation for --alternate. This is + necessary because -a= is a valid switch but getopt would + normally reject it since --alternate does not take an argument. */ + ,{"a", optional_argument, NULL, 'a'} + /* Handle -al=. */ + ,{"al", optional_argument, NULL, OPTION_AL} + ,{"debug-prefix-map", required_argument, NULL, OPTION_DEBUG_PREFIX_MAP} + ,{"defsym", required_argument, NULL, OPTION_DEFSYM} + ,{"dump-config", no_argument, NULL, OPTION_DUMPCONFIG} + ,{"emulation", required_argument, NULL, OPTION_EMULATION} +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF + ,{"execstack", no_argument, NULL, OPTION_EXECSTACK} + ,{"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK} +#endif + ,{"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL} + ,{"gdwarf-2", no_argument, NULL, OPTION_GDWARF2} + /* GCC uses --gdwarf-2 but GAS uses to use --gdwarf2, + so we keep it here for backwards compatibility. */ + ,{"gdwarf2", no_argument, NULL, OPTION_GDWARF2} + ,{"gen-debug", no_argument, NULL, 'g'} + ,{"gstabs", no_argument, NULL, OPTION_GSTABS} + ,{"gstabs+", no_argument, NULL, OPTION_GSTABS_PLUS} + ,{"hash-size", required_argument, NULL, OPTION_HASH_TABLE_SIZE} + ,{"help", no_argument, NULL, OPTION_HELP} +#ifdef HAVE_ITBL_CPU /* New option for extending instruction set (see also -t above). The "-t file" or "--itbl file" option extends the basic set of valid instructions by reading "file", a text file containing a list of instruction formats. The additional opcodes and their formats are added to the built-in set of instructions, and mnemonics for new registers may also be defined. */ - {"itbl", required_argument, NULL, OPTION_INSTTBL}, - {"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH}, - {"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2}, - {"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH}, - {"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES}, - {"MD", required_argument, NULL, OPTION_DEPFILE}, - {"gstabs", no_argument, NULL, OPTION_GSTABS}, - {"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE}, - {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT}, - {"gdwarf2", no_argument, NULL, OPTION_GDWARF2}, - {"no-warn", no_argument, NULL, 'W'}, - {"warn", no_argument, NULL, OPTION_WARN}, - {"target-help", no_argument, NULL, OPTION_TARGET_HELP}, -#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF) - {"execstack", no_argument, NULL, OPTION_EXECSTACK}, - {"noexecstack", no_argument, NULL, OPTION_NOEXECSTACK}, + ,{"itbl", required_argument, NULL, 't'} #endif - {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL} - /* When you add options here, check that they do not collide with - OPTION_MD_BASE. See as.h. */ + /* getopt allows abbreviations, so we do this to stop it from + treating -k as an abbreviation for --keep-locals. Some + ports use -k to enable PIC assembly. */ + ,{"keep-locals", no_argument, NULL, 'L'} + ,{"keep-locals", no_argument, NULL, 'L'} + ,{"listing-lhs-width", required_argument, NULL, OPTION_LISTING_LHS_WIDTH} + ,{"listing-lhs-width2", required_argument, NULL, OPTION_LISTING_LHS_WIDTH2} + ,{"listing-rhs-width", required_argument, NULL, OPTION_LISTING_RHS_WIDTH} + ,{"listing-cont-lines", required_argument, NULL, OPTION_LISTING_CONT_LINES} + ,{"MD", required_argument, NULL, OPTION_DEPFILE} + ,{"mri", no_argument, NULL, 'M'} + ,{"nocpp", no_argument, NULL, OPTION_NOCPP} + ,{"no-warn", no_argument, NULL, 'W'} + ,{"reduce-memory-overheads", no_argument, NULL, OPTION_REDUCE_MEMORY_OVERHEADS} + ,{"statistics", no_argument, NULL, OPTION_STATISTICS} + ,{"strip-local-absolute", no_argument, NULL, OPTION_STRIP_LOCAL_ABSOLUTE} + ,{"version", no_argument, NULL, OPTION_VERSION} + ,{"verbose", no_argument, NULL, OPTION_VERBOSE} + ,{"target-help", no_argument, NULL, OPTION_TARGET_HELP} + ,{"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT} + ,{"warn", no_argument, NULL, OPTION_WARN} }; /* Construct the option lists from the standard list and the target @@ -496,7 +540,7 @@ parse_args (int * pargc, char *** pargv) if (md_parse_option (optc, optarg) != 0) break; /* `-v' isn't included in the general short_opts list, so check for - it explicity here before deciding we've gotten a bad argument. */ + it explicitly here before deciding we've gotten a bad argument. */ if (optc == 'v') { #ifdef VMS @@ -515,6 +559,8 @@ parse_args (int * pargc, char *** pargv) verbose = 1; break; } + else + as_bad (_("unrecognized option -%c%s"), optc, optarg ? optarg : ""); /* Fall through. */ case '?': @@ -552,15 +598,12 @@ parse_args (int * pargc, char *** pargv) case OPTION_VERSION: /* This output is intended to follow the GNU standards document. */ -#ifdef BFD_ASSEMBLER printf (_("GNU assembler %s\n"), BFD_VERSION_STRING); -#else - printf (_("GNU assembler %s\n"), VERSION); -#endif - printf (_("Copyright 2002 Free Software Foundation, Inc.\n")); + printf (_("Copyright 2007 Free Software Foundation, Inc.\n")); printf (_("\ This program is free software; you may redistribute it under the terms of\n\ -the GNU General Public License. This program has absolutely no warranty.\n")); +the GNU General Public License version 3 or later.\n\ +This program has absolutely no warranty.\n")); printf (_("This assembler was configured for a target of `%s'.\n"), TARGET_ALIAS); exit (EXIT_SUCCESS); @@ -586,6 +629,10 @@ the GNU General Public License. This program has absolutely no warranty.\n")); #endif exit (EXIT_SUCCESS); + case OPTION_DEBUG_PREFIX_MAP: + add_debug_prefix_map (optarg); + break; + case OPTION_DEFSYM: { char *s; @@ -597,11 +644,7 @@ the GNU General Public License. This program has absolutely no warranty.\n")); if (*s == '\0') as_fatal (_("bad defsym; format is --defsym name=value")); *s++ = '\0'; -#ifdef BFD_ASSEMBLER i = bfd_scan_vma (s, (const char **) NULL, 0); -#else - i = strtol (s, (char **) NULL, 0); -#endif n = xmalloc (sizeof *n); n->next = defsyms; n->name = optarg; @@ -610,7 +653,7 @@ the GNU General Public License. This program has absolutely no warranty.\n")); } break; - case OPTION_INSTTBL: +#ifdef HAVE_ITBL_CPU case 't': { /* optarg is the name of the file containing the instruction @@ -638,11 +681,31 @@ the GNU General Public License. This program has absolutely no warranty.\n")); itbl_files->name); } break; +#endif case OPTION_DEPFILE: start_dependencies (optarg); break; + case 'g': + /* Some backends, eg Alpha and Mips, use the -g switch for their + own purposes. So we check here for an explicit -g and allow + the backend to decide if it wants to process it. */ + if ( old_argv[optind - 1][1] == 'g' + && md_parse_option (optc, optarg)) + continue; + + if (md_debug_format_selector) + debug_type = md_debug_format_selector (& use_gnu_debug_info_extensions); + else if (IS_ELF) + debug_type = DEBUG_DWARF2; + else + debug_type = DEBUG_STABS; + break; + + case OPTION_GSTABS_PLUS: + use_gnu_debug_info_extensions = 1; + /* Fall through. */ case OPTION_GSTABS: debug_type = DEBUG_STABS; break; @@ -672,6 +735,7 @@ the GNU General Public License. This program has absolutely no warranty.\n")); case OPTION_LISTING_LHS_WIDTH2: { int tmp = atoi (optarg); + if (tmp > listing_lhs_width) listing_lhs_width_second = tmp; } @@ -708,7 +772,7 @@ the GNU General Public License. This program has absolutely no warranty.\n")); flag_fatal_warnings = 1; break; -#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF) +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF case OPTION_EXECSTACK: flag_execstack = 1; flag_noexecstack = 0; @@ -723,9 +787,31 @@ the GNU General Public License. This program has absolutely no warranty.\n")); flag_always_generate_output = 1; break; + case OPTION_AL: + listing |= LISTING_LISTING; + if (optarg) + listing_filename = xstrdup (optarg); + break; + + case OPTION_ALTERNATE: + optarg = old_argv [optind - 1]; + while (* optarg == '-') + optarg ++; + + if (strcmp (optarg, "alternate") == 0) + { + flag_macro_alternate = 1; + break; + } + optarg ++; + /* Fall through. */ + case 'a': if (optarg) { + if (optarg != old_argv[optind] && optarg[-1] == '=') + --optarg; + if (md_parse_option (optc, optarg) != 0) break; @@ -782,6 +868,7 @@ the GNU General Public License. This program has absolutely no warranty.\n")); case 'I': { /* Include file directory. */ char *temp = xstrdup (optarg); + add_include_dir (temp); break; } @@ -796,6 +883,24 @@ the GNU General Public License. This program has absolutely no warranty.\n")); case 'X': /* -X means treat warnings as errors. */ break; + + case OPTION_REDUCE_MEMORY_OVERHEADS: + /* The only change we make at the moment is to reduce + the size of the hash tables that we use. */ + set_gas_hash_table_size (4051); + break; + + case OPTION_HASH_TABLE_SIZE: + { + unsigned long new_size; + + new_size = strtoul (optarg, NULL, 0); + if (new_size) + set_gas_hash_table_size (new_size); + else + as_fatal (_("--hash-size needs a numeric argument")); + break; + } } } @@ -839,6 +944,14 @@ dump_statistics (void) #endif } +#ifndef OBJ_VMS +static void +close_output_file (void) +{ + output_file_close (out_file_name); +} +#endif + /* The interface between the macro code and gas expression handling. */ static int @@ -851,7 +964,7 @@ macro_expr (const char *emsg, int idx, sb *in, int *val) hold = input_line_pointer; input_line_pointer = in->ptr + idx; - expression (&ex); + expression_and_evaluate (&ex); idx = input_line_pointer - in->ptr; input_line_pointer = hold; @@ -876,44 +989,10 @@ static void perform_an_assembly_pass (int argc, char ** argv) { int saw_a_file = 0; -#ifdef BFD_ASSEMBLER flagword applicable; -#endif need_pass_2 = 0; -#ifndef BFD_ASSEMBLER -#ifdef MANY_SEGMENTS - { - unsigned int i; - for (i = SEG_E0; i < SEG_UNKNOWN; i++) - segment_info[i].fix_root = 0; - } - /* Create the three fixed ones. */ - { - segT seg; - -#ifdef TE_APOLLO - seg = subseg_new (".wtext", 0); -#else - seg = subseg_new (".text", 0); -#endif - assert (seg == SEG_E0); - seg = subseg_new (".data", 0); - assert (seg == SEG_E1); - seg = subseg_new (".bss", 0); - assert (seg == SEG_E2); -#ifdef TE_APOLLO - create_target_segments (); -#endif - } - -#else /* not MANY_SEGMENTS. */ - text_fix_root = NULL; - data_fix_root = NULL; - bss_fix_root = NULL; -#endif /* not MANY_SEGMENTS. */ -#else /* BFD_ASSEMBLER. */ /* Create the standard sections, and those the assembler uses internally. */ text_section = subseg_new (TEXT_SECTION_NAME, 0); @@ -935,12 +1014,10 @@ perform_an_assembly_pass (int argc, char ** argv) reg_section = subseg_new ("*GAS `reg' section*", 0); expr_section = subseg_new ("*GAS `expr' section*", 0); -#endif /* BFD_ASSEMBLER. */ - subseg_set (text_section, 0); /* This may add symbol table entries, which requires having an open BFD, - and sections already created, in BFD_ASSEMBLER mode. */ + and sections already created. */ md_begin (); #ifdef USING_CGEN @@ -969,11 +1046,37 @@ perform_an_assembly_pass (int argc, char ** argv) read_a_source_file (""); } +#ifdef OBJ_ELF +static void +create_obj_attrs_section (void) +{ + segT s; + char *p; + addressT addr; + offsetT size; + const char *name; + + size = bfd_elf_obj_attr_size (stdoutput); + if (size) + { + name = get_elf_backend_data (stdoutput)->obj_attrs_section; + if (!name) + name = ".gnu.attributes"; + s = subseg_new (name, 0); + elf_section_type (s) + = get_elf_backend_data (stdoutput)->obj_attrs_section_type; + bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA); + addr = frag_now_fix (); + p = frag_more (size); + bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size); + } +} +#endif + int main (int argc, char ** argv) { - int macro_alternate; int macro_strip_at; int keep_it; @@ -998,6 +1101,8 @@ main (int argc, char ** argv) myname = argv[0]; xmalloc_set_program_name (myname); + expandargv (&argc, &argv); + START_PROGRESS (myname, 0); #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME @@ -1007,47 +1112,43 @@ main (int argc, char ** argv) out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME; hex_init (); -#ifdef BFD_ASSEMBLER bfd_init (); bfd_set_error_program_name (myname); -#endif #ifdef USE_EMULATIONS select_emulation_mode (argc, argv); #endif PROGRESS (1); + /* Call parse_args before any of the init/begin functions + so that switches like --hash-size can be honored. */ + parse_args (&argc, &argv); symbol_begin (); frag_init (); subsegs_begin (); - parse_args (&argc, &argv); read_begin (); input_scrub_begin (); expr_begin (); +#ifndef OBJ_VMS /* Does its own file handling. */ + /* It has to be called after dump_statistics (). */ + xatexit (close_output_file); +#endif + if (flag_print_statistics) xatexit (dump_statistics); - macro_alternate = 0; macro_strip_at = 0; #ifdef TC_I960 macro_strip_at = flag_mri; #endif -#ifdef TC_A29K - /* For compatibility with the AMD 29K family macro assembler - specification. */ - macro_alternate = 1; - macro_strip_at = 1; -#endif - macro_init (macro_alternate, flag_mri, macro_strip_at, macro_expr); + macro_init (flag_macro_alternate, flag_mri, macro_strip_at, macro_expr); PROGRESS (1); -#ifdef BFD_ASSEMBLER output_file_create (out_file_name); assert (stdoutput != 0); -#endif #ifdef tc_init_after_args tc_init_after_args (); @@ -1065,6 +1166,11 @@ main (int argc, char ** argv) sym = symbol_new (defsyms->name, absolute_section, defsyms->value, &zero_address_frag); + /* Make symbols defined on the command line volatile, so that they + can be redefined inside a source file. This makes this assembler's + behaviour compatible with earlier versions, but it may not be + completely intuitive. */ + S_SET_VOLATILE (sym); symbol_table_insert (sym); next = defsyms->next; free (defsyms); @@ -1082,7 +1188,12 @@ main (int argc, char ** argv) md_end (); #endif -#if defined BFD_ASSEMBLER && (defined OBJ_ELF || defined OBJ_MAYBE_ELF) +#ifdef OBJ_ELF + if (IS_ELF) + create_obj_attrs_section (); +#endif + +#if defined OBJ_ELF || defined OBJ_MAYBE_ELF if ((flag_execstack || flag_noexecstack) && OUTPUT_FLAVOR == bfd_target_elf_flavour) { @@ -1109,28 +1220,21 @@ main (int argc, char ** argv) else keep_it = 0; -#if defined (BFD_ASSEMBLER) || !defined (BFD) /* This used to be done at the start of write_object_file in write.c, but that caused problems when doing listings when keep_it was zero. This could probably be moved above md_end, but I didn't want to risk the change. */ subsegs_finish (); -#endif if (keep_it) write_object_file (); + fflush (stderr); + #ifndef NO_LISTING listing_print (listing_filename); #endif -#ifndef OBJ_VMS /* Does its own file handling. */ -#ifndef BFD_ASSEMBLER - if (keep_it) -#endif - output_file_close (out_file_name); -#endif - if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0) as_bad (_("%d warnings, treating warnings as errors"), had_warnings ()); @@ -1138,7 +1242,7 @@ main (int argc, char ** argv) keep_it = 0; if (!keep_it) - unlink (out_file_name); + unlink_if_ordinary (out_file_name); input_scrub_end (); @@ -1154,4 +1258,3 @@ main (int argc, char ** argv) xexit (EXIT_SUCCESS); } -