X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldmain.c;h=21133ab72090a6e2f8fcb80a2c11f40f8fc12fb0;hb=aec6b87e0b66d707ead62ca40d220ee78b4cf5a5;hp=6e86c3d996fa763fedf2e489501d0366f63ace43;hpb=498cd2a0fdc89ee9a81ce4ad0019d64a1f6dbcd7;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldmain.c b/ld/ldmain.c index 6e86c3d996..21133ab720 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -1,7 +1,5 @@ /* 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 - Free Software Foundation, Inc. + Copyright (C) 1991-2016 Free Software Foundation, Inc. Written by Steve Chamberlain steve@cygnus.com This file is part of the GNU Binutils. @@ -43,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. */ @@ -82,31 +79,19 @@ const char *ld_sysroot; 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. */ bfd_boolean trace_files; -/* Nonzero means same, but note open failures, too. */ -bfd_boolean trace_file_tries; +/* Nonzero means report actions taken by the linker, and describe the linker script in use. */ +bfd_boolean verbose; /* Nonzero means version number was printed, so exit successfully instead of complaining if no input files are given. */ bfd_boolean version_printed; -/* Nonzero means link in every member of an archive. */ -bfd_boolean whole_archive; - -/* True means only create DT_NEEDED entries for dynamic libraries - if they actually satisfy some reference in a regular object. */ -bfd_boolean add_DT_NEEDED_for_regular; - -/* True means create DT_NEEDED entries for dynamic libraries that - are DT_NEEDED by dynamic libraries specifically mentioned on - the command line. */ -bfd_boolean add_DT_NEEDED_for_dynamic = TRUE; - /* TRUE if we should demangle symbol names. */ bfd_boolean demangling; @@ -123,11 +108,11 @@ static char *get_emulation static bfd_boolean add_archive_element (struct bfd_link_info *, bfd *, const char *, bfd **); static bfd_boolean multiple_definition - (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma, + (struct bfd_link_info *, struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma); static bfd_boolean multiple_common - (struct bfd_link_info *, const char *, bfd *, enum bfd_link_hash_type, - bfd_vma, bfd *, enum bfd_link_hash_type, bfd_vma); + (struct bfd_link_info *, struct bfd_link_hash_entry *, + bfd *, enum bfd_link_hash_type, bfd_vma); static bfd_boolean add_to_set (struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_reloc_code_real_type, bfd *, asection *, bfd_vma); @@ -150,7 +135,8 @@ static bfd_boolean reloc_dangerous static bfd_boolean unattached_reloc (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma); static bfd_boolean notice - (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma); + (struct bfd_link_info *, struct bfd_link_hash_entry *, + struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma, flagword); static struct bfd_link_callbacks link_callbacks = { @@ -171,6 +157,8 @@ static struct bfd_link_callbacks link_callbacks = ldlang_override_segment_assignment }; +static bfd_assert_handler_type default_bfd_assert_handler; + struct bfd_link_info link_info; static void @@ -184,11 +172,25 @@ ld_cleanup (void) unlink_if_ordinary (output_filename); } +/* If there's a BFD assertion, we'll notice and exit with an error + unless otherwise instructed. */ + +static void +ld_bfd_assert_handler (const char *fmt, const char *bfdver, + const char *file, int line) +{ + (*default_bfd_assert_handler) (fmt, bfdver, file, line); + config.make_executable = FALSE; +} + int main (int argc, char **argv) { 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, ""); @@ -210,20 +212,17 @@ main (int argc, char **argv) bfd_set_error_program_name (program_name); + /* We want to notice and fail on those nasty BFD assertions which are + likely to signal incorrect output being generated but otherwise may + leave no trace. */ + default_bfd_assert_handler = bfd_set_assert_handler (ld_bfd_assert_handler); + xatexit (ld_cleanup); /* 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); - } + ld_canon_sysroot = lrealpath (ld_sysroot); if (ld_canon_sysroot) ld_canon_sysroot_len = strlen (ld_canon_sysroot); else @@ -253,11 +252,11 @@ main (int argc, char **argv) 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 @@ -278,9 +277,14 @@ main (int argc, char **argv) link_info.init_function = "_init"; link_info.fini_function = "_fini"; link_info.relax_pass = 1; + link_info.extern_protected_data = -1; + link_info.dynamic_undefined_weak = -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); @@ -289,6 +293,7 @@ main (int argc, char **argv) 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); @@ -296,73 +301,12 @@ main (int argc, char **argv) if (config.hash_table_size != 0) bfd_hash_set_default_size (config.hash_table_size); - ldemul_set_symbols (); - - if (link_info.relocatable) - { - if (command_line.check_section_addresses < 0) - command_line.check_section_addresses = 0; - if (link_info.shared) - einfo (_("%P%F: -r and -shared may not be used together\n")); - } - - /* We may have -Bsymbolic, -Bsymbolic-functions, --dynamic-list-data, - --dynamic-list-cpp-new, --dynamic-list-cpp-typeinfo and - --dynamic-list FILE. -Bsymbolic and -Bsymbolic-functions are - for shared libraries. -Bsymbolic overrides all others and vice - versa. */ - switch (command_line.symbolic) - { - case symbolic_unset: - break; - case symbolic: - /* -Bsymbolic is for shared library only. */ - if (link_info.shared) - { - link_info.symbolic = TRUE; - /* Should we free the unused memory? */ - link_info.dynamic_list = NULL; - command_line.dynamic_list = dynamic_list_unset; - } - break; - case symbolic_functions: - /* -Bsymbolic-functions is for shared library only. */ - if (link_info.shared) - command_line.dynamic_list = dynamic_list_data; - break; - } - - switch (command_line.dynamic_list) - { - case dynamic_list_unset: - break; - case dynamic_list_data: - link_info.dynamic_data = TRUE; - case dynamic_list: - link_info.dynamic = TRUE; - break; - } - - if (! link_info.shared) - { - if (command_line.filter_shlib) - einfo (_("%P%F: -F may not be used without -shared\n")); - if (command_line.auxiliary_filters) - einfo (_("%P%F: -f may not be used without -shared\n")); - } - - if (! link_info.shared || link_info.pie) - link_info.executable = TRUE; +#ifdef ENABLE_PLUGINS + /* Now all the plugin arguments have been gathered, we can load them. */ + plugin_load_plugins (); +#endif /* ENABLE_PLUGINS */ - /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I - don't see how else this can be handled, since in this case we - must preserve all externally visible symbols. */ - if (link_info.relocatable && link_info.strip == strip_all) - { - link_info.strip = strip_debugger; - if (link_info.discard == discard_sec_merge) - link_info.discard = discard_all; - } + ldemul_set_symbols (); /* If we have not already opened and parsed a linker script, try the default script from command line first. */ @@ -386,14 +330,14 @@ main (int argc, char **argv) else { lex_string = s; - lex_redirect (s); + lex_redirect (s, _("built in linker script"), 1); } parser_input = input_script; yyparse (); lex_string = NULL; } - if (trace_file_tries) + if (verbose) { if (saved_script_handle) info_msg (_("using external linker script:")); @@ -426,11 +370,21 @@ main (int argc, char **argv) info_msg ("\n==================================================\n"); } + if (command_line.print_output_format) + info_msg ("%s\n", lang_get_output_target ()); + 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) + if (version_printed || command_line.print_output_format) xexit (0); einfo (_("%P%F: no input files\n")); } @@ -462,11 +416,18 @@ main (int argc, char **argv) /* 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) @@ -475,7 +436,17 @@ main (int argc, char **argv) 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 @@ -487,7 +458,7 @@ main (int argc, char **argv) einfo (_("%P: link errors found, deleting executable `%s'\n"), output_filename); - /* The file will be removed by remove_output. */ + /* The file will be removed by ld_cleanup. */ xexit (1); } else @@ -498,7 +469,8 @@ main (int argc, char **argv) /* 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); @@ -519,10 +491,10 @@ main (int argc, char **argv) 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) { @@ -555,12 +527,12 @@ main (int argc, char **argv) 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); } - /* Prevent remove_output from doing anything, after a successful link. */ + /* Prevent ld_cleanup from doing anything, after a successful link. */ output_filename = NULL; xexit (0); @@ -647,8 +619,10 @@ get_emulation (int argc, char **argv) || 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 @@ -693,6 +667,23 @@ add_ysym (const char *name) 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 @@ -777,6 +768,7 @@ add_keepsyms_file (const char *filename) free (buf); link_info.strip = strip_some; + fclose (file); } /* Callbacks from the BFD linker routines. */ @@ -804,44 +796,14 @@ add_archive_element (struct bfd_link_info *info, BFD, but we still want to output the original BFD filename. */ orig_input = *input; #ifdef ENABLE_PLUGINS - if (bfd_my_archive (abfd) != NULL && plugin_active_plugins_p ()) + if (link_info.lto_plugin_active && !no_more_claiming) { /* We must offer this archive member to the plugins to claim. */ - int fd = open (bfd_my_archive (abfd)->filename, O_RDONLY | O_BINARY); - if (fd >= 0) + plugin_maybe_claim (input); + if (input->flags.claimed) { - struct ld_plugin_input_file file; - int claimed = 0; - /* 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 = bfd_my_archive (abfd)->filename; - file.offset = abfd->origin; - file.filesize = arelt_size (abfd); - file.fd = fd; - /* We create a dummy BFD, initially empty, to house - whatever symbols the plugin may want to add. */ - file.handle = plugin_get_ir_dummy_bfd (abfd->filename, abfd); - if (plugin_call_claim_file (&file, &claimed)) - einfo (_("%P%F: %s: plugin reported error claiming file\n"), - plugin_error_plugin ()); - /* fd belongs to us, not the plugin; but we don't need it. */ - close (fd); - if (claimed) - { - /* Substitute the dummy BFD. */ - input->the_bfd = file.handle; - input->claimed = TRUE; - bfd_make_readable (input->the_bfd); - *subsbfd = input->the_bfd; - } - else - { - /* Abandon the dummy BFD. */ - bfd_close_all_done (file.handle); - input->claimed = FALSE; - } + input->flags.claim_archive = TRUE; + *subsbfd = input->the_bfd; } } #endif /* ENABLE_PLUGINS */ @@ -887,7 +849,8 @@ add_archive_element (struct bfd_link_info *info, { 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; } @@ -925,7 +888,7 @@ add_archive_element (struct bfd_link_info *info, minfo ("(%s)\n", name); } - if (trace_files || trace_file_tries) + if (trace_files || verbose) info_msg ("%I\n", &orig_input); return TRUE; } @@ -934,31 +897,49 @@ add_archive_element (struct bfd_link_info *info, multiple times. */ static bfd_boolean -multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, - const char *name, - bfd *obfd, - asection *osec, - bfd_vma oval, +multiple_definition (struct bfd_link_info *info, + struct bfd_link_hash_entry *h, bfd *nbfd, asection *nsec, bfd_vma nval) { -#ifdef ENABLE_PLUGINS - /* We may get called back even when --allow-multiple-definition is in - effect, as the plugin infrastructure needs to use this hook in - order to swap out IR-only symbols for real ones. In that case, - it will let us know not to continue by returning TRUE even if this - is not an IR-only vs. non-IR symbol conflict. */ - if (plugin_multiple_definition (info, name, obfd, osec, oval, nbfd, - nsec, nval)) + const char *name; + bfd *obfd; + asection *osec; + bfd_vma oval; + + if (info->allow_multiple_definition) + return TRUE; + + switch (h->type) + { + case bfd_link_hash_defined: + osec = h->u.def.section; + oval = h->u.def.value; + obfd = h->u.def.section->owner; + break; + case bfd_link_hash_indirect: + osec = bfd_ind_section_ptr; + oval = 0; + obfd = NULL; + break; + default: + abort (); + } + + /* Ignore a redefinition of an absolute symbol to the + same value; it's harmless. */ + if (h->type == bfd_link_hash_defined + && bfd_is_abs_section (osec) + && bfd_is_abs_section (nsec) + && nval == oval) return TRUE; -#endif /* ENABLE_PLUGINS */ /* If either section has the output_section field set to bfd_abs_section_ptr, it means that the section is being discarded, and this is not really a multiple definition at all. -FIXME: It would be cleaner to somehow ignore symbols defined in -sections which are being discarded. */ + FIXME: It would be cleaner to somehow ignore symbols defined in + sections which are being discarded. */ if ((osec->output_section != NULL && ! bfd_is_abs_section (osec) && bfd_is_abs_section (osec->output_section)) @@ -967,15 +948,23 @@ sections which are being discarded. */ && bfd_is_abs_section (nsec->output_section))) return TRUE; + name = h->root.string; + if (nbfd == NULL) + { + nbfd = obfd; + nsec = osec; + nval = oval; + obfd = NULL; + } einfo (_("%X%C: multiple definition of `%T'\n"), nbfd, nsec, nval, name); 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; @@ -988,17 +977,41 @@ sections which are being discarded. */ static bfd_boolean multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED, - const char *name, - bfd *obfd, - enum bfd_link_hash_type otype, - bfd_vma osize, + struct bfd_link_hash_entry *h, bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize) { - if (! config.warn_common) + const char *name; + bfd *obfd; + enum bfd_link_hash_type otype; + bfd_vma osize; + + if (!config.warn_common) return TRUE; + name = h->root.string; + otype = h->type; + if (otype == bfd_link_hash_common) + { + obfd = h->u.c.p->section->owner; + osize = h->u.c.size; + } + else if (otype == bfd_link_hash_defined + || otype == bfd_link_hash_defweak) + { + obfd = h->u.def.section->owner; + osize = 0; + } + else + { + /* FIXME: It would nice if we could report the BFD which defined + an indirect symbol, but we don't have anywhere to store the + information. */ + obfd = NULL; + osize = 0; + } + if (ntype == bfd_link_hash_defined || ntype == bfd_link_hash_defweak || ntype == bfd_link_hash_indirect) @@ -1105,8 +1118,8 @@ constructor_callback (struct bfd_link_info *info, /* 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 - && (info->relocatable + if (bfd_reloc_type_lookup (info->output_bfd, BFD_RELOC_CTOR) == NULL + && (bfd_link_relocatable (info) || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL)) einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n")); @@ -1145,6 +1158,25 @@ struct warning_callback_info 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 @@ -1167,24 +1199,14 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED, 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; @@ -1242,7 +1264,7 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg) /* 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, @@ -1254,25 +1276,14 @@ undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, #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 @@ -1350,7 +1361,7 @@ int overflow_cutoff_limit = 10; /* 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, @@ -1362,7 +1373,7 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, if (overflow_cutoff_limit == -1) return TRUE; - einfo ("%X%C:", abfd, section, address); + einfo ("%X%H:", abfd, section, address); if (overflow_cutoff_limit >= 0 && overflow_cutoff_limit-- == 0) @@ -1389,7 +1400,7 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, 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 (); @@ -1414,7 +1425,7 @@ reloc_dangerous (struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *section, bfd_vma address) { - einfo (_("%X%C: dangerous relocation: %s\n"), + einfo (_("%X%H: dangerous relocation: %s\n"), abfd, section, address, message); return TRUE; } @@ -1429,7 +1440,7 @@ unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED, asection *section, bfd_vma address) { - einfo (_("%X%C: reloc refers to symbol `%T' which is not being output\n"), + einfo (_("%X%H: reloc refers to symbol `%T' which is not being output\n"), abfd, section, address, name); return TRUE; } @@ -1443,29 +1454,25 @@ unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED, static bfd_boolean notice (struct bfd_link_info *info, - const char *name, + struct bfd_link_hash_entry *h, + struct bfd_link_hash_entry *inh ATTRIBUTE_UNUSED, bfd *abfd, asection *section, - bfd_vma value) + bfd_vma value, + flagword flags ATTRIBUTE_UNUSED) { - if (name == NULL) + const char *name; + + if (h == NULL) { if (command_line.cref || nocrossref_list != NULL) return handle_asneeded_cref (abfd, (enum notice_asneeded_action) value); return TRUE; } -#ifdef ENABLE_PLUGINS - /* We should hide symbols in the dummy IR BFDs from the nocrossrefs list - and let the real object files that are generated and added later trip - the error instead. Similarly would be better to trace the real symbol - from the real file than the temporary dummy. */ - if (!plugin_notice (info, name, abfd, section, value)) - return TRUE; -#endif /* ENABLE_PLUGINS */ - + name = h->root.string; if (info->notice_hash != NULL - && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL) + && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL) { if (bfd_is_und_section (section)) einfo ("%B: reference to %s\n", abfd, name);