/* Main program of GNU linker.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1991-2014 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of the GNU Binutils.
char * ld_canon_sysroot;
int ld_canon_sysroot_len;
-/* Set by -G argument, for MIPS ECOFF target. */
+/* Set by -G argument, for targets like MIPS ELF. */
int g_switch_value = 8;
/* Nonzero means print names of input files as processed. */
#endif
if (output_filename && delete_output_file_on_failure)
unlink_if_ordinary (output_filename);
+
+ /* See open_output in ldlang.c. */
+ if (output_bfd_hash_table_free_fn != NULL)
+ (*output_bfd_hash_table_free_fn) (link_info.hash);
}
/* If there's a BFD assertion, we'll notice and exit with an error
{
char *emulation;
long start_time = get_run_time ();
+#ifdef HAVE_SBRK
+ char *start_sbrk = (char *) sbrk (0);
+#endif
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
setlocale (LC_MESSAGES, "");
config.make_executable = TRUE;
config.magic_demand_paged = TRUE;
config.text_read_only = TRUE;
+ link_info.disable_target_specific_optimizations = -1;
command_line.warn_mismatch = TRUE;
command_line.warn_search_mismatch = TRUE;
command_line.check_section_addresses = -1;
- command_line.disable_target_specific_optimizations = -1;
/* We initialize DEMANGLING based on the environment variable
COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the
#ifdef ENABLE_PLUGINS
/* Now all the plugin arguments have been gathered, we can load them. */
- if (plugin_load_plugins ())
- einfo (_("%P%F: %s: error loading plugin\n"), plugin_error_plugin ());
+ plugin_load_plugins ();
#endif /* ENABLE_PLUGINS */
ldemul_set_symbols ();
lang_final ();
+ /* If the only command line argument has been -v or --version or --verbose
+ then ignore any input files provided by linker scripts and exit now.
+ We do not want to create an output file when the linker is just invoked
+ to provide version information. */
+ if (argc == 2 && version_printed)
+ xexit (0);
+
if (!lang_has_input_file)
{
if (version_printed || command_line.print_output_format)
output_cref (config.map_file != NULL ? config.map_file : stdout);
if (nocrossref_list != NULL)
check_nocrossrefs ();
+#if 0
+ {
+ struct bfd_link_hash_entry * h;
+ h = bfd_link_hash_lookup (link_info.hash, "__image_base__", 0,0,1);
+ fprintf (stderr, "lookup = %p val %lx\n", h, h ? h->u.def.value : 1);
+ }
+#endif
lang_finish ();
/* Even if we're producing relocatable output, some non-fatal errors should
program_name, run_time / 1000000, run_time % 1000000);
#ifdef HAVE_SBRK
fprintf (stderr, _("%s: data size %ld\n"), program_name,
- (long) (lim - (char *) &environ));
+ (long) (lim - start_sbrk));
#endif
fflush (stderr);
}
einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
}
+void
+add_ignoresym (struct bfd_link_info *info, const char *name)
+{
+ if (info->ignore_hash == NULL)
+ {
+ info->ignore_hash = xmalloc (sizeof (struct bfd_hash_table));
+ if (! bfd_hash_table_init_n (info->ignore_hash,
+ bfd_hash_newfunc,
+ sizeof (struct bfd_hash_entry),
+ 61))
+ einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
+ }
+
+ if (bfd_hash_lookup (info->ignore_hash, name, TRUE, TRUE) == NULL)
+ einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
+}
+
/* Record a symbol to be wrapped, from the --wrap option. */
void
free (buf);
link_info.strip = strip_some;
+ fclose (file);
}
\f
/* Callbacks from the BFD linker routines. */
{
char buf[100];
- sprintf (buf, _("Archive member included because of file (symbol)\n\n"));
+ sprintf (buf, _("Archive member included "
+ "to satisfy reference by file (symbol)\n\n"));
minfo ("%s", buf);
header_printed = TRUE;
}
if (obfd != NULL)
einfo (_("%D: first defined here\n"), obfd, osec, oval);
- if (RELAXATION_ENABLED)
+ if (RELAXATION_ENABLED_BY_USER)
{
einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
- command_line.disable_target_specific_optimizations = -1;
+ DISABLE_RELAXATION;
}
return TRUE;
/* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
useful error message. */
- if (bfd_reloc_type_lookup (link_info.output_bfd, BFD_RELOC_CTOR) == NULL
+ if (bfd_reloc_type_lookup (info->output_bfd, BFD_RELOC_CTOR) == NULL
&& (info->relocatable
|| bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
asymbol **asymbols;
};
+/* Look through the relocs to see if we can find a plausible address
+ for SYMBOL in ABFD. Return TRUE if found. Otherwise return FALSE. */
+
+static bfd_boolean
+symbol_warning (const char *warning, const char *symbol, bfd *abfd)
+{
+ struct warning_callback_info cinfo;
+
+ if (!bfd_generic_link_read_symbols (abfd))
+ einfo (_("%B%F: could not read symbols: %E\n"), abfd);
+
+ cinfo.found = FALSE;
+ cinfo.warning = warning;
+ cinfo.symbol = symbol;
+ cinfo.asymbols = bfd_get_outsymbols (abfd);
+ bfd_map_over_sections (abfd, warning_find_reloc, &cinfo);
+ return cinfo.found;
+}
+
/* This is called when there is a reference to a warning symbol. */
static bfd_boolean
einfo ("%P: %s%s\n", _("warning: "), warning);
else if (symbol == NULL)
einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
- else
+ else if (! symbol_warning (warning, symbol, abfd))
{
- struct warning_callback_info cinfo;
-
- /* Look through the relocs to see if we can find a plausible
- address. */
-
- if (!bfd_generic_link_read_symbols (abfd))
- einfo (_("%B%F: could not read symbols: %E\n"), abfd);
-
- cinfo.found = FALSE;
- cinfo.warning = warning;
- cinfo.symbol = symbol;
- cinfo.asymbols = bfd_get_outsymbols (abfd);
- bfd_map_over_sections (abfd, warning_find_reloc, &cinfo);
-
- if (! cinfo.found)
- einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
+ bfd *b;
+ /* Search all input files for a reference to SYMBOL. */
+ for (b = info->input_bfds; b; b = b->link_next)
+ if (b != abfd && symbol_warning (warning, symbol, b))
+ return TRUE;
+ einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
}
return TRUE;
/* This is called when an undefined symbol is found. */
static bfd_boolean
-undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+undefined_symbol (struct bfd_link_info *info,
const char *name,
bfd *abfd,
asection *section,
#define MAX_ERRORS_IN_A_ROW 5
+ if (info->ignore_hash != NULL
+ && bfd_hash_lookup (info->ignore_hash, name, FALSE, FALSE) != NULL)
+ return TRUE;
+
if (config.warn_once)
{
- static struct bfd_hash_table *hash;
-
/* Only warn once about a particular undefined symbol. */
- if (hash == NULL)
- {
- hash = (struct bfd_hash_table *)
- xmalloc (sizeof (struct bfd_hash_table));
- if (!bfd_hash_table_init (hash, bfd_hash_newfunc,
- sizeof (struct bfd_hash_entry)))
- einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
- }
-
- if (bfd_hash_lookup (hash, name, FALSE, FALSE) != NULL)
- return TRUE;
-
- if (bfd_hash_lookup (hash, name, TRUE, TRUE) == NULL)
- einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
+ add_ignoresym (info, name);
}
/* We never print more than a reasonable number of errors in a row
/* This is called when a reloc overflows. */
static bfd_boolean
-reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+reloc_overflow (struct bfd_link_info *info,
struct bfd_link_hash_entry *entry,
const char *name,
const char *reloc_name,
reloc_name, entry->root.string,
entry->u.def.section,
entry->u.def.section == bfd_abs_section_ptr
- ? link_info.output_bfd : entry->u.def.section->owner);
+ ? info->output_bfd : entry->u.def.section->owner);
break;
default:
abort ();