/* as.c - GAS main program.
- Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1987-2016 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
Understands command arguments.
Has a few routines that don't fit in other modules because they
are shared.
-
+
bugs
-
+
: initialisers
Since no-one else says they will support them in future: I
don't support them now. */
#ifdef HAVE_ITBL_CPU
#include "itbl-ops.h"
#else
-#define itbl_parse(itbl_file) 1
#define itbl_init()
#endif
#ifdef HAVE_SBRK
#ifdef NEED_DECLARATION_SBRK
-extern PTR sbrk ();
+extern void *sbrk ();
#endif
#endif
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
/* Enable verbose mode. */
int verbose = 0;
+#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
+int flag_use_elf_stt_common = DEFAULT_GENERATE_ELF_STT_COMMON;
+#endif
+
+/* Keep the output file. */
+static int keep_it = 0;
+
segT reg_section;
segT expr_section;
segT text_section;
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;
+#ifdef HAVE_SBRK
+char *start_sbrk;
+#endif
static int flag_macro_alternate;
#define EMULATION_ENVIRON "AS_EMULATION"
extern struct emulation mipsbelf, mipslelf, mipself;
-extern struct emulation mipsbecoff, mipslecoff, mipsecoff;
extern struct emulation i386coff, i386elf, i386aout;
extern struct emulation crisaout, criself;
select_emulation_mode (int argc, char **argv)
{
int i;
- char *p, *em = 0;
+ char *p;
+ const char *em = NULL;
for (i = 1; i < argc; i++)
if (!strncmp ("--em", argv[i], 4))
VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
}
+#ifdef DEFAULT_FLAG_COMPRESS_DEBUG
+enum compressed_debug_section_type flag_compress_debug
+ = COMPRESS_DEBUG_GABI_ZLIB;
+#endif
+
static void
show_usage (FILE * stream)
{
Sub-options [default hls]:\n\
c omit false conditionals\n\
d omit debugging directives\n\
+ g include general info\n\
h include high-level source\n\
l include assembly\n\
m include macro expansions\n\
fprintf (stream, _("\
--alternate initially turn on alternate macro syntax\n"));
+#ifdef DEFAULT_FLAG_COMPRESS_DEBUG
+ fprintf (stream, _("\
+ --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
+ compress DWARF debug sections using zlib [default]\n"));
+ fprintf (stream, _("\
+ --nocompress-debug-sections\n\
+ don't compress DWARF debug sections\n"));
+#else
+ fprintf (stream, _("\
+ --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
+ compress DWARF debug sections using zlib\n"));
+ fprintf (stream, _("\
+ --nocompress-debug-sections\n\
+ don't compress DWARF debug sections [default]\n"));
+#endif
fprintf (stream, _("\
-D produce assembler debugging messages\n"));
fprintf (stream, _("\
+ --debug-prefix-map OLD=NEW\n\
+ map OLD to NEW in debug information\n"));
+ fprintf (stream, _("\
--defsym SYM=VAL define symbol SYM to given value\n"));
#ifdef USE_EMULATIONS
{
int i;
- char *def_em;
+ const char *def_em;
fprintf (stream, "\
--em=[");
--execstack require executable stack for this object\n"));
fprintf (stream, _("\
--noexecstack don't require executable stack for this object\n"));
+ fprintf (stream, _("\
+ --size-check=[error|warning]\n\
+ ELF .size directive check (default --size-check=error)\n"));
+ fprintf (stream, _("\
+ --elf-stt-common=[no|yes]\n\
+ generate ELF common symbols with STT_COMMON type\n"));
+ fprintf (stream, _("\
+ --sectname-subst enable section name substitution sequences\n"));
#endif
fprintf (stream, _("\
-f skip whitespace and comment preprocessing\n"));
fprintf (stream, _("\
--gdwarf-2 generate DWARF2 debugging information\n"));
fprintf (stream, _("\
+ --gdwarf-sections generate per-function section names for DWARF line information\n"));
+ fprintf (stream, _("\
--hash-size=<value> set the hash table size close to <value>\n"));
fprintf (stream, _("\
--help show this message and exit\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, _("\
--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"));
+ @FILE read options from FILE\n"));
md_show_usage (stream);
'v',
#endif
'w', 'X',
+#ifdef HAVE_ITBL_CPU
/* New option for extending instruction set (see also --itbl below). */
't', ':',
+#endif
'\0'
};
struct option *longopts;
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_GSTABS,
OPTION_GSTABS_PLUS,
OPTION_GDWARF2,
+ OPTION_GDWARF_SECTIONS,
OPTION_STRIP_LOCAL_ABSOLUTE,
OPTION_TRADITIONAL_FORMAT,
OPTION_WARN,
OPTION_TARGET_HELP,
OPTION_EXECSTACK,
OPTION_NOEXECSTACK,
+ OPTION_SIZE_CHECK,
+ OPTION_ELF_STT_COMMON,
+ OPTION_SECTNAME_SUBST,
OPTION_ALTERNATE,
OPTION_AL,
OPTION_HASH_TABLE_SIZE,
OPTION_REDUCE_MEMORY_OVERHEADS,
- OPTION_WARN_FATAL
+ OPTION_WARN_FATAL,
+ OPTION_COMPRESS_DEBUG,
+ OPTION_NOCOMPRESS_DEBUG
/* When you add options here, check that they do
not collide with OPTION_MD_BASE. See as.h. */
};
-
+
static const struct option std_longopts[] =
{
/* Note: commas are placed at the start of the line rather than
- the end of the preceeding line so that it is simpler to
+ the end of the preceding 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
,{"a", optional_argument, NULL, 'a'}
/* Handle -al=<FILE>. */
,{"al", optional_argument, NULL, OPTION_AL}
+ ,{"compress-debug-sections", optional_argument, NULL, OPTION_COMPRESS_DEBUG}
+ ,{"nocompress-debug-sections", no_argument, NULL, OPTION_NOCOMPRESS_DEBUG}
+ ,{"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}
+ ,{"size-check", required_argument, NULL, OPTION_SIZE_CHECK}
+ ,{"elf-stt-common", required_argument, NULL, OPTION_ELF_STT_COMMON}
+ ,{"sectname-subst", no_argument, NULL, OPTION_SECTNAME_SUBST}
#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}
+ ,{"gdwarf-sections", no_argument, NULL, OPTION_GDWARF_SECTIONS}
,{"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}
+ ,{"itbl", required_argument, NULL, 't'}
+#endif
/* 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. */
dependent list. Include space for an extra NULL option and
always NULL terminate. */
shortopts = concat (std_shortopts, md_shortopts, (char *) NULL);
- longopts = xmalloc (sizeof (std_longopts) + md_longopts_size + sizeof (struct option));
+ longopts = (struct option *) xmalloc (sizeof (std_longopts)
+ + md_longopts_size + sizeof (struct option));
memcpy (longopts, std_longopts, sizeof (std_longopts));
memcpy (((char *) longopts) + sizeof (std_longopts), md_longopts, md_longopts_size);
memset (((char *) longopts) + sizeof (std_longopts) + md_longopts_size,
old_argv = *pargv;
/* Initialize a new argv that contains no options. */
- new_argv = xmalloc (sizeof (char *) * (old_argc + 1));
+ new_argv = (char **) xmalloc (sizeof (char *) * (old_argc + 1));
new_argv[0] = old_argv[0];
new_argc = 1;
new_argv[new_argc] = NULL;
case OPTION_VERSION:
/* This output is intended to follow the GNU standards document. */
printf (_("GNU assembler %s\n"), BFD_VERSION_STRING);
- printf (_("Copyright 2007 Free Software Foundation, Inc.\n"));
+ printf (_("Copyright (C) 2016 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);
#endif
exit (EXIT_SUCCESS);
+ case OPTION_COMPRESS_DEBUG:
+ if (optarg)
+ {
+#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
+ if (strcasecmp (optarg, "none") == 0)
+ flag_compress_debug = COMPRESS_DEBUG_NONE;
+ else if (strcasecmp (optarg, "zlib") == 0)
+ flag_compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+ else if (strcasecmp (optarg, "zlib-gnu") == 0)
+ flag_compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
+ else if (strcasecmp (optarg, "zlib-gabi") == 0)
+ flag_compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+ else
+ as_fatal (_("Invalid --compress-debug-sections option: `%s'"),
+ optarg);
+#else
+ as_fatal (_("--compress-debug-sections=%s is unsupported"),
+ optarg);
+#endif
+ }
+ else
+ flag_compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+ break;
+
+ case OPTION_NOCOMPRESS_DEBUG:
+ flag_compress_debug = COMPRESS_DEBUG_NONE;
+ break;
+
+ case OPTION_DEBUG_PREFIX_MAP:
+ add_debug_prefix_map (optarg);
+ break;
+
case OPTION_DEFSYM:
{
char *s;
as_fatal (_("bad defsym; format is --defsym name=value"));
*s++ = '\0';
i = bfd_scan_vma (s, (const char **) NULL, 0);
- n = xmalloc (sizeof *n);
+ n = (struct defsym_list *) xmalloc (sizeof *n);
n->next = defsyms;
n->name = optarg;
n->value = i;
}
break;
- case OPTION_INSTTBL:
+#ifdef HAVE_ITBL_CPU
case 't':
{
/* optarg is the name of the file containing the instruction
itbl_files->name);
}
break;
+#endif
case OPTION_DEPFILE:
start_dependencies (optarg);
debug_type = DEBUG_DWARF2;
break;
+ case OPTION_GDWARF_SECTIONS:
+ flag_dwarf_sections = TRUE;
+ break;
+
case 'J':
flag_signed_overflow_ok = 1;
break;
flag_noexecstack = 1;
flag_execstack = 0;
break;
+
+ case OPTION_SIZE_CHECK:
+ if (strcasecmp (optarg, "error") == 0)
+ flag_size_check = size_check_error;
+ else if (strcasecmp (optarg, "warning") == 0)
+ flag_size_check = size_check_warning;
+ else
+ as_fatal (_("Invalid --size-check= option: `%s'"), optarg);
+ break;
+
+ case OPTION_ELF_STT_COMMON:
+ if (strcasecmp (optarg, "no") == 0)
+ flag_use_elf_stt_common = 0;
+ else if (strcasecmp (optarg, "yes") == 0)
+ flag_use_elf_stt_common = 1;
+ else
+ as_fatal (_("Invalid --elf-stt-common= option: `%s'"),
+ optarg);
+ break;
+
+ case OPTION_SECTNAME_SUBST:
+ flag_sectname_subst = 1;
+ break;
#endif
case 'Z':
flag_always_generate_output = 1;
case 'd':
listing |= LISTING_NODEBUG;
break;
+ case 'g':
+ listing |= LISTING_GENERAL;
+ break;
case 'h':
listing |= LISTING_HLL;
break;
myname, run_time / 1000000, run_time % 1000000);
#ifdef HAVE_SBRK
fprintf (stderr, _("%s: data size %ld\n"),
- myname, (long) (lim - (char *) &environ));
+ myname, (long) (lim - start_sbrk));
#endif
subsegs_print_statistics (stderr);
#endif
}
-#ifndef OBJ_VMS
static void
close_output_file (void)
{
output_file_close (out_file_name);
+ if (!keep_it)
+ unlink_if_ordinary (out_file_name);
}
-#endif
/* The interface between the macro code and gas expression handling. */
-static int
-macro_expr (const char *emsg, int idx, sb *in, int *val)
+static size_t
+macro_expr (const char *emsg, size_t idx, sb *in, offsetT *val)
{
char *hold;
expressionS ex;
if (ex.X_op != O_constant)
as_bad ("%s", emsg);
- *val = (int) ex.X_add_number;
+ *val = ex.X_add_number;
return idx;
}
perform_an_assembly_pass (int argc, char ** argv)
{
int saw_a_file = 0;
+#ifndef OBJ_MACH_O
flagword applicable;
+#endif
need_pass_2 = 0;
+#ifndef OBJ_MACH_O
/* Create the standard sections, and those the assembler uses
internally. */
text_section = subseg_new (TEXT_SECTION_NAME, 0);
| SEC_DATA));
bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
seg_info (bss_section)->bss = 1;
+#endif
subseg_new (BFD_ABS_SECTION_NAME, 0);
subseg_new (BFD_UND_SECTION_NAME, 0);
reg_section = subseg_new ("*GAS `reg' section*", 0);
expr_section = subseg_new ("*GAS `expr' section*", 0);
+#ifndef OBJ_MACH_O
subseg_set (text_section, 0);
+#endif
/* This may add symbol table entries, which requires having an open BFD,
and sections already created. */
int
main (int argc, char ** argv)
{
+ char ** argv_orig = argv;
+
int macro_strip_at;
- int keep_it;
start_time = get_run_time ();
+#ifdef HAVE_SBRK
+ start_sbrk = (char *) sbrk (0);
+#endif
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
setlocale (LC_MESSAGES, "");
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);
PROGRESS (1);
output_file_create (out_file_name);
- assert (stdoutput != 0);
+ gas_assert (stdoutput != 0);
+
+ dot_symbol_init ();
#ifdef tc_init_after_args
tc_init_after_args ();
itbl_init ();
+ dwarf2_init ();
+
+ local_symbol_make (".gasversion.", absolute_section,
+ BFD_VERSION / 10000UL, &predefined_address_frag);
+
/* Now that we have fully initialized, and have created the output
file, define any symbols requested by --defsym command line
arguments. */
gnustack = subseg_new (".note.GNU-stack", 0);
bfd_set_section_flags (stdoutput, gnustack,
SEC_READONLY | (flag_execstack ? SEC_CODE : 0));
-
+
}
#endif
assembly debugging or on behalf of the compiler, emit it now. */
dwarf2_finish ();
- /* If we constructed dwarf2 .eh_frame info, either via .cfi
+ /* If we constructed dwarf2 .eh_frame info, either via .cfi
directives from the user or by the backend, emit it now. */
cfi_finish ();
- if (seen_at_least_1_file ()
- && (flag_always_generate_output || had_errors () == 0))
- keep_it = 1;
- else
- keep_it = 0;
+ keep_it = 0;
+ if (seen_at_least_1_file ())
+ {
+ int n_warns, n_errs;
+ char warn_msg[50];
+ char err_msg[50];
- /* 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 ();
+ write_object_file ();
- if (keep_it)
- write_object_file ();
+ n_warns = had_warnings ();
+ n_errs = had_errors ();
-#ifndef NO_LISTING
- listing_print (listing_filename);
-#endif
+ if (n_warns == 1)
+ sprintf (warn_msg, _("%d warning"), n_warns);
+ else
+ sprintf (warn_msg, _("%d warnings"), n_warns);
+ if (n_errs == 1)
+ sprintf (err_msg, _("%d error"), n_errs);
+ else
+ sprintf (err_msg, _("%d errors"), n_errs);
+
+ if (flag_fatal_warnings && n_warns != 0)
+ {
+ if (n_errs == 0)
+ as_bad (_("%s, treating warnings as errors"), warn_msg);
+ n_errs += n_warns;
+ }
- if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0)
- as_bad (_("%d warnings, treating warnings as errors"), had_warnings ());
+ if (n_errs == 0)
+ keep_it = 1;
+ else if (flag_always_generate_output)
+ {
+ /* The -Z flag indicates that an object file should be generated,
+ regardless of warnings and errors. */
+ keep_it = 1;
+ fprintf (stderr, _("%s, %s, generating bad object file\n"),
+ err_msg, warn_msg);
+ }
+ }
- if (had_errors () > 0 && ! flag_always_generate_output)
- keep_it = 0;
+ fflush (stderr);
- if (!keep_it)
- unlink_if_ordinary (out_file_name);
+#ifndef NO_LISTING
+ listing_print (listing_filename, argv_orig);
+#endif
input_scrub_end ();
/* Use xexit instead of return, because under VMS environments they
may not place the same interpretation on the value given. */
- if (had_errors () > 0)
+ if (had_errors () != 0)
xexit (EXIT_FAILURE);
/* Only generate dependency file if assembler was successful. */