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