1,5 → 1,5 |
/* Main program of GNU linker. |
Copyright 1991-2013 Free Software Foundation, Inc. |
Copyright (C) 1991-2015 Free Software Foundation, Inc. |
Written by Steve Chamberlain steve@cygnus.com |
|
This file is part of the GNU Binutils. |
41,7 → 41,6 |
#ifdef ENABLE_PLUGINS |
#include "plugin.h" |
#include "plugin-api.h" |
#include "libbfd.h" |
#endif /* ENABLE_PLUGINS */ |
|
/* Somewhere above, sys/stat.h got included. */ |
137,7 → 136,7 |
(struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma); |
static bfd_boolean notice |
(struct bfd_link_info *, struct bfd_link_hash_entry *, |
bfd *, asection *, bfd_vma, flagword, const char *); |
struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma, flagword); |
|
static struct bfd_link_callbacks link_callbacks = |
{ |
223,15 → 222,7 |
/* Set up the sysroot directory. */ |
ld_sysroot = get_sysroot (argc, argv); |
if (*ld_sysroot) |
{ |
if (*TARGET_SYSTEM_ROOT == 0) |
{ |
einfo ("%P%F: this linker was not configured to use sysroots\n"); |
ld_sysroot = ""; |
} |
else |
ld_canon_sysroot = lrealpath (ld_sysroot); |
} |
if (ld_canon_sysroot) |
ld_canon_sysroot_len = strlen (ld_canon_sysroot); |
else |
286,9 → 277,13 |
link_info.init_function = "_init"; |
link_info.fini_function = "_fini"; |
link_info.relax_pass = 1; |
link_info.extern_protected_data = -1; |
link_info.pei386_auto_import = -1; |
link_info.spare_dynamic_tags = 5; |
link_info.path_separator = ':'; |
#ifdef DEFAULT_FLAG_COMPRESS_DEBUG |
link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; |
#endif |
|
ldfile_add_arch (""); |
emulation = get_emulation (argc, argv); |
297,6 → 292,7 |
config.maxpagesize = bfd_emul_get_maxpagesize (default_target); |
config.commonpagesize = bfd_emul_get_commonpagesize (default_target); |
lang_init (); |
ldexp_init (); |
ldemul_before_parse (); |
lang_has_input_file = FALSE; |
parse_args (argc, argv); |
378,6 → 374,13 |
|
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) |
412,11 → 415,18 |
|
/* Print error messages for any missing symbols, for any warning |
symbols, and possibly multiple definitions. */ |
if (link_info.relocatable) |
if (bfd_link_relocatable (&link_info)) |
link_info.output_bfd->flags &= ~EXEC_P; |
else |
link_info.output_bfd->flags |= EXEC_P; |
|
if ((link_info.compress_debug & COMPRESS_DEBUG)) |
{ |
link_info.output_bfd->flags |= BFD_COMPRESS; |
if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB) |
link_info.output_bfd->flags |= BFD_COMPRESS_GABI; |
} |
|
ldwrite (); |
|
if (config.map_file != NULL) |
425,7 → 435,17 |
output_cref (config.map_file != NULL ? config.map_file : stdout); |
if (nocrossref_list != NULL) |
check_nocrossrefs (); |
if (command_line.print_memory_usage) |
lang_print_memory_usage (); |
#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 |
ldexp_finish (); |
lang_finish (); |
|
/* Even if we're producing relocatable output, some non-fatal errors should |
448,7 → 468,8 |
/* If the --force-exe-suffix is enabled, and we're making an |
executable file and it doesn't end in .exe, copy it to one |
which does. */ |
if (! link_info.relocatable && command_line.force_exe_suffix) |
if (!bfd_link_relocatable (&link_info) |
&& command_line.force_exe_suffix) |
{ |
int len = strlen (output_filename); |
|
469,10 → 490,10 |
dst = fopen (dst_name, FOPEN_WB); |
|
if (!src) |
einfo (_("%X%P: unable to open for source of copy `%s'\n"), |
einfo (_("%P%F: unable to open for source of copy `%s'\n"), |
output_filename); |
if (!dst) |
einfo (_("%X%P: unable to open for destination of copy `%s'\n"), |
einfo (_("%P%F: unable to open for destination of copy `%s'\n"), |
dst_name); |
while ((l = fread (buf, 1, bsize, src)) > 0) |
{ |
597,8 → 618,10 |
|| strcmp (argv[i], "-mips5") == 0 |
|| strcmp (argv[i], "-mips32") == 0 |
|| strcmp (argv[i], "-mips32r2") == 0 |
|| strcmp (argv[i], "-mips32r6") == 0 |
|| strcmp (argv[i], "-mips64") == 0 |
|| strcmp (argv[i], "-mips64r2") == 0) |
|| strcmp (argv[i], "-mips64r2") == 0 |
|| strcmp (argv[i], "-mips64r6") == 0) |
{ |
/* FIXME: The arguments -mips1, -mips2, -mips3, etc. are |
passed to the linker by some MIPS compilers. They |
744,6 → 767,7 |
|
free (buf); |
link_info.strip = strip_some; |
fclose (file); |
} |
|
/* Callbacks from the BFD linker routines. */ |
771,25 → 795,10 |
BFD, but we still want to output the original BFD filename. */ |
orig_input = *input; |
#ifdef ENABLE_PLUGINS |
if (plugin_active_plugins_p () && !no_more_claiming) |
if (link_info.lto_plugin_active && !no_more_claiming) |
{ |
/* We must offer this archive member to the plugins to claim. */ |
const char *filename = (bfd_my_archive (abfd) != NULL |
? bfd_my_archive (abfd)->filename : abfd->filename); |
int fd = open (filename, O_RDONLY | O_BINARY); |
if (fd >= 0) |
{ |
struct ld_plugin_input_file file; |
|
/* Offset and filesize must refer to the individual archive |
member, not the whole file, and must exclude the header. |
Fortunately for us, that is how the data is stored in the |
origin field of the bfd and in the arelt_data. */ |
file.name = filename; |
file.offset = abfd->origin; |
file.filesize = arelt_size (abfd); |
file.fd = fd; |
plugin_maybe_claim (&file, input); |
plugin_maybe_claim (input); |
if (input->flags.claimed) |
{ |
input->flags.claim_archive = TRUE; |
796,7 → 805,6 |
*subsbfd = input->the_bfd; |
} |
} |
} |
#endif /* ENABLE_PLUGINS */ |
|
ldlang_add_file (input); |
840,7 → 848,8 |
{ |
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; |
} |
1109,7 → 1118,7 |
/* Ensure that BFD_RELOC_CTOR exists now, so that we can give a |
useful error message. */ |
if (bfd_reloc_type_lookup (info->output_bfd, BFD_RELOC_CTOR) == NULL |
&& (info->relocatable |
&& (bfd_link_relocatable (info) |
|| bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) |
einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); |
|
1148,6 → 1157,25 |
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 |
1170,23 → 1198,13 |
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) |
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); |
} |
|
1436,11 → 1454,11 |
static bfd_boolean |
notice (struct bfd_link_info *info, |
struct bfd_link_hash_entry *h, |
struct bfd_link_hash_entry *inh ATTRIBUTE_UNUSED, |
bfd *abfd, |
asection *section, |
bfd_vma value, |
flagword flags ATTRIBUTE_UNUSED, |
const char *string ATTRIBUTE_UNUSED) |
flagword flags ATTRIBUTE_UNUSED) |
{ |
const char *name; |
|