X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=ld%2Fldmain.c;h=c4af10f4e9121949b1b66df6428e95e66ce3eed4;hb=7a1a12f4d1c6152017142d74c736dc1cc6b0e81c;hp=2e9e1e65f30dd48814fa81d91296240fbb44e62a;hpb=ddbb8a31d5f6d13c91a416e13f6ad11ac6604102;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldmain.c b/ld/ldmain.c index 2e9e1e65f3..c4af10f4e9 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 - Free Software Foundation, Inc. + Copyright (C) 1991-2020 Free Software Foundation, Inc. Written by Steve Chamberlain steve@cygnus.com This file is part of the GNU Binutils. @@ -27,6 +25,7 @@ #include "libiberty.h" #include "progress.h" #include "bfdlink.h" +#include "ctf-api.h" #include "filenames.h" #include "ld.h" @@ -40,6 +39,10 @@ #include "ldfile.h" #include "ldemul.h" #include "ldctor.h" +#ifdef ENABLE_PLUGINS +#include "plugin.h" +#include "plugin-api.h" +#endif /* ENABLE_PLUGINS */ /* Somewhere above, sys/stat.h got included. */ #if !defined(S_ISDIR) && defined(S_IFDIR) @@ -48,12 +51,6 @@ #include -#ifdef HAVE_SBRK -#if !HAVE_DECL_SBRK -extern void *sbrk (); -#endif -#endif - #ifndef TARGET_SYSTEM_ROOT #define TARGET_SYSTEM_ROOT "" #endif @@ -74,34 +71,22 @@ char *program_name; const char *ld_sysroot; /* The canonical representation of ld_sysroot. */ -char * ld_canon_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; +unsigned int 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 if we should demangle symbol names. */ bfd_boolean demangling; @@ -116,36 +101,37 @@ static const char *get_sysroot static char *get_emulation (int, char **); static bfd_boolean add_archive_element - (struct bfd_link_info *, bfd *, const char *); -static bfd_boolean multiple_definition - (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma, + (struct bfd_link_info *, bfd *, const char *, bfd **); +static void multiple_definition + (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); -static bfd_boolean add_to_set +static void multiple_common + (struct bfd_link_info *, struct bfd_link_hash_entry *, + bfd *, enum bfd_link_hash_type, bfd_vma); +static void add_to_set (struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_reloc_code_real_type, bfd *, asection *, bfd_vma); -static bfd_boolean constructor_callback +static void constructor_callback (struct bfd_link_info *, bfd_boolean, const char *, bfd *, asection *, bfd_vma); -static bfd_boolean warning_callback +static void warning_callback (struct bfd_link_info *, const char *, const char *, bfd *, asection *, bfd_vma); static void warning_find_reloc (bfd *, asection *, void *); -static bfd_boolean undefined_symbol +static void undefined_symbol (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma, bfd_boolean); -static bfd_boolean reloc_overflow +static void reloc_overflow (struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, const char *, bfd_vma, bfd *, asection *, bfd_vma); -static bfd_boolean reloc_dangerous +static void reloc_dangerous (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma); -static bfd_boolean unattached_reloc +static void 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 = { @@ -163,21 +149,45 @@ static struct bfd_link_callbacks link_callbacks = einfo, info_msg, minfo, - ldlang_override_segment_assignment + ldlang_override_segment_assignment, + ldlang_ctf_apply_strsym, + ldlang_write_ctf_late }; +static bfd_assert_handler_type default_bfd_assert_handler; +static bfd_error_handler_type default_bfd_error_handler; + struct bfd_link_info link_info; static void -remove_output (void) +ld_cleanup (void) { - if (output_filename) - { - if (link_info.output_bfd) - bfd_cache_close (link_info.output_bfd); - if (delete_output_file_on_failure) - unlink_if_ordinary (output_filename); - } + bfd_cache_close_all (); +#ifdef ENABLE_PLUGINS + plugin_call_cleanup (); +#endif + if (output_filename && delete_output_file_on_failure) + unlink_if_ordinary (output_filename); +} + +/* Hook to notice BFD assertions. */ + +static void +ld_bfd_assert_handler (const char *fmt, const char *bfdver, + const char *file, int line) +{ + config.make_executable = FALSE; + (*default_bfd_assert_handler) (fmt, bfdver, file, line); +} + +/* Hook the bfd error/warning handler for --fatal-warnings. */ + +static void +ld_bfd_error_handler (const char *fmt, va_list ap) +{ + if (config.fatal_warnings) + config.make_executable = FALSE; + (*default_bfd_error_handler) (fmt, ap); } int @@ -202,26 +212,34 @@ main (int argc, char **argv) expandargv (&argc, &argv); - bfd_init (); + if (bfd_init () != BFD_INIT_MAGIC) + einfo (_("%F%P: fatal error: libbfd ABI mismatch\n")); bfd_set_error_program_name (program_name); - xatexit (remove_output); + /* 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); + + /* Also hook the bfd error/warning handler for --fatal-warnings. */ + default_bfd_error_handler = bfd_set_error_handler (ld_bfd_error_handler); + + xatexit (ld_cleanup); /* Set up the sysroot directory. */ ld_sysroot = get_sysroot (argc, argv); if (*ld_sysroot) + ld_canon_sysroot = lrealpath (ld_sysroot); + if (ld_canon_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_len = strlen (ld_canon_sysroot); + + /* is_sysrooted_pathname() relies on no trailing dirsep. */ + if (ld_canon_sysroot_len > 0 + && IS_DIR_SEPARATOR (ld_canon_sysroot [ld_canon_sysroot_len - 1])) + ld_canon_sysroot [--ld_canon_sysroot_len] = '\0'; } - if (ld_canon_sysroot) - ld_canon_sysroot_len = strlen (ld_canon_sysroot); else ld_canon_sysroot_len = -1; @@ -229,7 +247,7 @@ main (int argc, char **argv) this permits the linker to be configured for a particular target, and linked against a shared BFD library which was configured for a different target. The macro TARGET is defined by Makefile. */ - if (! bfd_set_default_target (TARGET)) + if (!bfd_set_default_target (TARGET)) { einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET); xexit (1); @@ -249,6 +267,8 @@ main (int argc, char **argv) config.make_executable = TRUE; config.magic_demand_paged = TRUE; config.text_read_only = TRUE; + config.print_map_discarded = TRUE; + link_info.disable_target_specific_optimizations = -1; command_line.warn_mismatch = TRUE; command_line.warn_search_mismatch = TRUE; @@ -265,7 +285,9 @@ main (int argc, char **argv) link_info.keep_memory = TRUE; link_info.combreloc = TRUE; link_info.strip_discarded = TRUE; - link_info.emit_hash = TRUE; + link_info.prohibit_multiple_definition_absolute = FALSE; + link_info.emit_hash = DEFAULT_EMIT_SYSV_HASH; + link_info.emit_gnu_hash = DEFAULT_EMIT_GNU_HASH; link_info.callbacks = &link_callbacks; link_info.input_bfds_tail = &link_info.input_bfds; /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init @@ -273,17 +295,24 @@ 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 +#ifdef DEFAULT_NEW_DTAGS + link_info.new_dtags = DEFAULT_NEW_DTAGS; +#endif ldfile_add_arch (""); emulation = get_emulation (argc, argv); ldemul_choose_mode (emulation); default_target = ldemul_choose_target (argc, 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); @@ -291,80 +320,19 @@ 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. */ if (saved_script_handle == NULL && command_line.default_script != NULL) { - ldfile_open_command_file (command_line.default_script); + ldfile_open_script_file (command_line.default_script); parser_input = input_script; yyparse (); } @@ -381,14 +349,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:")); @@ -406,7 +374,7 @@ main (int argc, char **argv) while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) { buf[n] = 0; - info_msg (buf); + info_msg ("%s", buf); } rewind (saved_script_handle); free (buf); @@ -421,16 +389,35 @@ main (int argc, char **argv) info_msg ("\n==================================================\n"); } + if (command_line.force_group_allocation + || !bfd_link_relocatable (&link_info)) + link_info.resolve_section_groups = TRUE; + else + link_info.resolve_section_groups = FALSE; + + 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 (link_info.inhibit_common_definition && !bfd_link_dll (&link_info)) + einfo (_("%F%P: --no-define-common may not be used without -shared\n")); + 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")); + einfo (_("%F%P: no input files\n")); } - if (trace_files) + if (verbose) info_msg (_("%P: mode %s\n"), emulation); ldemul_after_parse (); @@ -447,21 +434,29 @@ main (int argc, char **argv) if (config.map_file == (FILE *) NULL) { bfd_set_error (bfd_error_system_call); - einfo (_("%P%F: cannot open map file %s: %E\n"), + einfo (_("%F%P: cannot open map file %s: %E\n"), config.map_filename); } } + link_info.has_map_file = TRUE; } lang_process (); /* 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) @@ -470,7 +465,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 @@ -478,22 +483,23 @@ main (int argc, char **argv) want to ignore for relocatable output?) */ if (!config.make_executable && !force_make_executable) { - if (trace_files) + if (verbose) 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 { - if (! bfd_close (link_info.output_bfd)) - einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd); + if (!bfd_close (link_info.output_bfd)) + einfo (_("%F%P: %pB: final close failed: %E\n"), link_info.output_bfd); /* 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); @@ -514,22 +520,22 @@ 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 (_("%F%P: 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 (_("%F%P: unable to open for destination of copy `%s'\n"), dst_name); while ((l = fread (buf, 1, bsize, src)) > 0) { int done = fwrite (buf, 1, l, dst); if (done != l) - einfo (_("%P: Error writing file `%s'\n"), dst_name); + einfo (_("%P: error writing file `%s'\n"), dst_name); } fclose (src); if (fclose (dst) == EOF) - einfo (_("%P: Error closing file `%s'\n"), dst_name); + einfo (_("%P: error closing file `%s'\n"), dst_name); free (dst_name); free (buf); } @@ -540,20 +546,15 @@ main (int argc, char **argv) if (config.stats) { -#ifdef HAVE_SBRK - char *lim = (char *) sbrk (0); -#endif long run_time = get_run_time () - start_time; + fflush (stdout); fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"), program_name, run_time / 1000000, run_time % 1000000); -#ifdef HAVE_SBRK - fprintf (stderr, _("%s: data size %ld\n"), program_name, - (long) (lim - (char *) &environ)); -#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); @@ -588,21 +589,25 @@ static const char * get_sysroot (int argc, char **argv) { int i; - const char *path; + const char *path = NULL; for (i = 1; i < argc; i++) if (CONST_STRNEQ (argv[i], "--sysroot=")) - return argv[i] + strlen ("--sysroot="); + path = argv[i] + strlen ("--sysroot="); - path = get_relative_sysroot (BINDIR); - if (path) - return path; + if (!path) + path = get_relative_sysroot (BINDIR); - path = get_relative_sysroot (TOOLBINDIR); - if (path) - return path; + if (!path) + path = get_relative_sysroot (TOOLBINDIR); - return TARGET_SYSTEM_ROOT; + if (!path) + path = TARGET_SYSTEM_ROOT; + + if (IS_DIR_SEPARATOR (*path) && path[1] == 0) + path = ""; + + return path; } /* We need to find any explicitly given emulation in order to initialize the @@ -631,7 +636,7 @@ get_emulation (int argc, char **argv) i++; } else - einfo (_("%P%F: missing argument to -m\n")); + einfo (_("%F%P: missing argument to -m\n")); } else if (strcmp (argv[i], "-mips1") == 0 || strcmp (argv[i], "-mips2") == 0 @@ -640,8 +645,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 @@ -673,17 +680,34 @@ add_ysym (const char *name) { if (link_info.notice_hash == NULL) { - link_info.notice_hash = - (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table)); + link_info.notice_hash + = (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table)); if (!bfd_hash_table_init_n (link_info.notice_hash, bfd_hash_newfunc, sizeof (struct bfd_hash_entry), 61)) - einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); + einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); } if (bfd_hash_lookup (link_info.notice_hash, name, TRUE, TRUE) == NULL) - einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); + einfo (_("%F%P: 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 (_("%F%P: bfd_hash_table_init failed: %E\n")); + } + + if (bfd_hash_lookup (info->ignore_hash, name, TRUE, TRUE) == NULL) + einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); } /* Record a symbol to be wrapped, from the --wrap option. */ @@ -693,17 +717,17 @@ add_wrap (const char *name) { if (link_info.wrap_hash == NULL) { - link_info.wrap_hash = - (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table)); + link_info.wrap_hash + = (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table)); if (!bfd_hash_table_init_n (link_info.wrap_hash, bfd_hash_newfunc, sizeof (struct bfd_hash_entry), 61)) - einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); + einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); } if (bfd_hash_lookup (link_info.wrap_hash, name, TRUE, TRUE) == NULL) - einfo (_("%P%F: bfd_hash_lookup failed: %E\n")); + einfo (_("%F%P: bfd_hash_lookup failed: %E\n")); } /* Handle the -retain-symbols-file option. */ @@ -731,7 +755,7 @@ add_keepsyms_file (const char *filename) xmalloc (sizeof (struct bfd_hash_table)); if (!bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc, sizeof (struct bfd_hash_entry))) - einfo (_("%P%F: bfd_hash_table_init failed: %E\n")); + einfo (_("%F%P: bfd_hash_table_init failed: %E\n")); bufsize = 100; buf = (char *) xmalloc (bufsize); @@ -746,7 +770,7 @@ add_keepsyms_file (const char *filename) { size_t len = 0; - while (! ISSPACE (c) && c != EOF) + while (!ISSPACE (c) && c != EOF) { buf[len] = c; ++len; @@ -761,7 +785,7 @@ add_keepsyms_file (const char *filename) buf[len] = '\0'; if (bfd_hash_lookup (link_info.keep_hash, buf, TRUE, TRUE) == NULL) - einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n")); + einfo (_("%F%P: bfd_hash_lookup for insertion failed: %E\n")); } } @@ -770,6 +794,7 @@ add_keepsyms_file (const char *filename) free (buf); link_info.strip = strip_some; + fclose (file); } /* Callbacks from the BFD linker routines. */ @@ -780,16 +805,51 @@ add_keepsyms_file (const char *filename) static bfd_boolean add_archive_element (struct bfd_link_info *info, bfd *abfd, - const char *name) + const char *name, + bfd **subsbfd ATTRIBUTE_UNUSED) { lang_input_statement_type *input; + lang_input_statement_type *parent; + lang_input_statement_type orig_input; input = (lang_input_statement_type *) xcalloc (1, sizeof (lang_input_statement_type)); + input->header.type = lang_input_statement_enum; input->filename = abfd->filename; input->local_sym_name = abfd->filename; input->the_bfd = abfd; + parent = bfd_usrdata (abfd->my_archive); + if (parent != NULL && !parent->flags.reload) + parent->next = input; + + /* Save the original data for trace files/tries below, as plugins + (if enabled) may possibly alter it to point to a replacement + BFD, but we still want to output the original BFD filename. */ + orig_input = *input; +#ifdef ENABLE_PLUGINS + if (link_info.lto_plugin_active) + { + /* We must offer this archive member to the plugins to claim. */ + plugin_maybe_claim (input); + if (input->flags.claimed) + { + if (no_more_claiming) + { + /* Don't claim new IR symbols after all IR symbols have + been claimed. */ + if (verbose) + info_msg ("%pI: no new IR symbols to claimi\n", + &orig_input); + input->flags.claimed = 0; + return FALSE; + } + input->flags.claim_archive = TRUE; + *subsbfd = input->the_bfd; + } + } +#endif /* ENABLE_PLUGINS */ + ldlang_add_file (input); if (config.map_file != NULL) @@ -800,6 +860,10 @@ add_archive_element (struct bfd_link_info *info, int len; h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); + if (h == NULL + && info->pei386_auto_import + && CONST_STRNEQ (name, "__imp_")) + h = bfd_link_hash_lookup (info->hash, name + 6, FALSE, FALSE, TRUE); if (h == NULL) from = NULL; @@ -827,25 +891,23 @@ add_archive_element (struct bfd_link_info *info, } } - if (! header_printed) + if (!header_printed) { - char buf[100]; - - sprintf (buf, _("Archive member included because of file (symbol)\n\n")); - minfo ("%s", buf); + minfo (_("Archive member included to satisfy reference by file (symbol)\n\n")); header_printed = TRUE; } - if (bfd_my_archive (abfd) == NULL) + if (abfd->my_archive == NULL + || bfd_is_thin_archive (abfd->my_archive)) { minfo ("%s", bfd_get_filename (abfd)); len = strlen (bfd_get_filename (abfd)); } else { - minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)), + minfo ("%s(%s)", bfd_get_filename (abfd->my_archive), bfd_get_filename (abfd)); - len = (strlen (bfd_get_filename (bfd_my_archive (abfd))) + len = (strlen (bfd_get_filename (abfd->my_archive)) + strlen (bfd_get_filename (abfd)) + 2); } @@ -862,57 +924,95 @@ add_archive_element (struct bfd_link_info *info, } if (from != NULL) - minfo ("%B ", from); + minfo ("%pB ", from); if (h != NULL) - minfo ("(%T)\n", h->root.string); + minfo ("(%pT)\n", h->root.string); else minfo ("(%s)\n", name); } - if (trace_files || trace_file_tries) - info_msg ("%I\n", input); - + if (verbose + || trace_files > 1 + || (trace_files && bfd_is_thin_archive (orig_input.the_bfd->my_archive))) + info_msg ("%pI\n", &orig_input); return TRUE; } /* This is called when BFD has discovered a symbol which is defined multiple times. */ -static bfd_boolean -multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, - const char *name, - bfd *obfd, - asection *osec, - bfd_vma oval, +static void +multiple_definition (struct bfd_link_info *info, + struct bfd_link_hash_entry *h, bfd *nbfd, asection *nsec, bfd_vma nval) { + const char *name; + bfd *obfd; + asection *osec; + bfd_vma oval; + + if (info->allow_multiple_definition) + return; + + 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; + /* 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. */ - if ((osec->output_section != NULL - && ! bfd_is_abs_section (osec) - && bfd_is_abs_section (osec->output_section)) - || (nsec->output_section != NULL - && ! bfd_is_abs_section (nsec) - && bfd_is_abs_section (nsec->output_section))) - return TRUE; - - einfo (_("%X%C: multiple definition of `%T'\n"), + if (!info->prohibit_multiple_definition_absolute + && ((osec->output_section != NULL + && ! bfd_is_abs_section (osec) + && bfd_is_abs_section (osec->output_section)) + || (nsec->output_section != NULL + && !bfd_is_abs_section (nsec) + && bfd_is_abs_section (nsec->output_section)))) + return; + + name = h->root.string; + if (nbfd == NULL) + { + nbfd = obfd; + nsec = osec; + nval = oval; + obfd = NULL; + } + einfo (_("%X%P: %C: multiple definition of `%pT'"), nbfd, nsec, nval, name); if (obfd != NULL) - einfo (_("%D: first defined here\n"), obfd, osec, oval); + einfo (_("; %D: first defined here"), obfd, osec, oval); + einfo ("\n"); - if (command_line.relax) + if (RELAXATION_ENABLED_BY_USER) { - einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n")); - command_line.relax = 0; + einfo (_("%P: disabling relaxation; it will not work with multiple definitions\n")); + DISABLE_RELAXATION; } - - return TRUE; } /* This is called when there is a definition of a common symbol, or @@ -920,72 +1020,111 @@ multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED, or when two common symbols are found. We only do something if -warn-common was used. */ -static bfd_boolean +static void 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) - return TRUE; + const char *name; + bfd *obfd; + enum bfd_link_hash_type otype; + bfd_vma osize; + + if (!config.warn_common) + return; + + 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) { ASSERT (otype == bfd_link_hash_common); - einfo (_("%B: warning: definition of `%T' overriding common\n"), - nbfd, name); if (obfd != NULL) - einfo (_("%B: warning: common is here\n"), obfd); + einfo (_("%P: %pB: warning: definition of `%pT' overriding common" + " from %pB\n"), + nbfd, name, obfd); + else + einfo (_("%P: %pB: warning: definition of `%pT' overriding common\n"), + nbfd, name); } else if (otype == bfd_link_hash_defined || otype == bfd_link_hash_defweak || otype == bfd_link_hash_indirect) { ASSERT (ntype == bfd_link_hash_common); - einfo (_("%B: warning: common of `%T' overridden by definition\n"), - nbfd, name); if (obfd != NULL) - einfo (_("%B: warning: defined here\n"), obfd); + einfo (_("%P: %pB: warning: common of `%pT' overridden by definition" + " from %pB\n"), + nbfd, name, obfd); + else + einfo (_("%P: %pB: warning: common of `%pT' overridden by definition\n"), + nbfd, name); } else { ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common); if (osize > nsize) { - einfo (_("%B: warning: common of `%T' overridden by larger common\n"), - nbfd, name); if (obfd != NULL) - einfo (_("%B: warning: larger common is here\n"), obfd); + einfo (_("%P: %pB: warning: common of `%pT' overridden" + " by larger common from %pB\n"), + nbfd, name, obfd); + else + einfo (_("%P: %pB: warning: common of `%pT' overridden" + " by larger common\n"), + nbfd, name); } else if (nsize > osize) { - einfo (_("%B: warning: common of `%T' overriding smaller common\n"), - nbfd, name); if (obfd != NULL) - einfo (_("%B: warning: smaller common is here\n"), obfd); + einfo (_("%P: %pB: warning: common of `%pT' overriding" + " smaller common from %pB\n"), + nbfd, name, obfd); + else + einfo (_("%P: %pB: warning: common of `%pT' overriding" + " smaller common\n"), + nbfd, name); } else { - einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name); if (obfd != NULL) - einfo (_("%B: warning: previous common is here\n"), obfd); + einfo (_("%P: %pB and %pB: warning: multiple common of `%pT'\n"), + nbfd, obfd, name); + else + einfo (_("%P: %pB: warning: multiple common of `%pT'\n"), + nbfd, name); } } - - return TRUE; } /* This is called when BFD has discovered a set element. H is the entry in the linker hash table for the set. SECTION and VALUE represent a value which should be added to the set. */ -static bfd_boolean +static void add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED, struct bfd_link_hash_entry *h, bfd_reloc_code_real_type reloc, @@ -997,8 +1136,8 @@ add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED, einfo (_("%P: warning: global constructor %s used\n"), h->root.string); - if (! config.build_constructors) - return TRUE; + if (!config.build_constructors) + return; ldctor_add_set_entry (h, reloc, NULL, section, value); @@ -1010,8 +1149,6 @@ add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED, undefined symbols because we are going to define it ourselves. */ } - - return TRUE; } /* This is called when BFD has discovered a constructor. This is only @@ -1019,7 +1156,7 @@ add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED, constructors in some more clever fashion. This is similar to adding an element to a set, but less general. */ -static bfd_boolean +static void constructor_callback (struct bfd_link_info *info, bfd_boolean constructor, const char *name, @@ -1034,15 +1171,15 @@ constructor_callback (struct bfd_link_info *info, if (config.warn_constructors) einfo (_("%P: warning: global constructor %s used\n"), name); - if (! config.build_constructors) - return TRUE; + if (!config.build_constructors) + return; /* 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")); + einfo (_("%F%P: BFD backend error: BFD_RELOC_CTOR unsupported\n")); s = set_name; if (bfd_get_symbol_leading_char (abfd) != '\0') @@ -1054,7 +1191,7 @@ constructor_callback (struct bfd_link_info *info, h = bfd_link_hash_lookup (info->hash, set_name, TRUE, TRUE, TRUE); if (h == (struct bfd_link_hash_entry *) NULL) - einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); + einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n")); if (h->type == bfd_link_hash_new) { h->type = bfd_link_hash_undefined; @@ -1065,7 +1202,6 @@ constructor_callback (struct bfd_link_info *info, } ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value); - return TRUE; } /* A structure used by warning_callback to pass information through @@ -1079,9 +1215,28 @@ struct warning_callback_info asymbol **asymbols; }; -/* This is called when there is a reference to a warning symbol. */ +/* 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 (_("%F%P: %pB: 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 void warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *warning, const char *symbol, @@ -1091,37 +1246,25 @@ warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED, { /* This is a hack to support warn_multiple_gp. FIXME: This should have a cleaner interface, but what? */ - if (! config.warn_multiple_gp + if (!config.warn_multiple_gp && strcmp (warning, "using multiple gp values") == 0) - return TRUE; + return; if (section != NULL) - einfo ("%C: %s%s\n", abfd, section, address, _("warning: "), warning); + einfo ("%P: %C: %s%s\n", abfd, section, address, _("warning: "), warning); else if (abfd == NULL) einfo ("%P: %s%s\n", _("warning: "), warning); else if (symbol == NULL) - einfo ("%B: %s%s\n", abfd, _("warning: "), warning); - else + einfo ("%P: %pB: %s%s\n", abfd, _("warning: "), warning); + else if (!symbol_warning (warning, symbol, abfd)) { - struct warning_callback_info info; - - /* 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); - - info.found = FALSE; - info.warning = warning; - info.symbol = symbol; - info.asymbols = bfd_get_outsymbols (abfd); - bfd_map_over_sections (abfd, warning_find_reloc, &info); - - if (! info.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; + einfo ("%P: %pB: %s%s\n", abfd, _("warning: "), warning); } - - return TRUE; } /* This is called by warning_callback for each section. It checks the @@ -1143,14 +1286,14 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg) relsize = bfd_get_reloc_upper_bound (abfd, sec); if (relsize < 0) - einfo (_("%B%F: could not read relocs: %E\n"), abfd); + einfo (_("%F%P: %pB: could not read relocs: %E\n"), abfd); if (relsize == 0) return; relpp = (arelent **) xmalloc (relsize); relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); if (relcount < 0) - einfo (_("%B%F: could not read relocs: %E\n"), abfd); + einfo (_("%F%P: %pB: could not read relocs: %E\n"), abfd); p = relpp; pend = p + relcount; @@ -1163,7 +1306,7 @@ warning_find_reloc (bfd *abfd, asection *sec, void *iarg) && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0) { /* We found a reloc for the symbol we are looking for. */ - einfo ("%C: %s%s\n", abfd, sec, q->address, _("warning: "), + einfo ("%P: %C: %s%s\n", abfd, sec, q->address, _("warning: "), info->warning); info->found = TRUE; break; @@ -1175,8 +1318,8 @@ 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, +static void +undefined_symbol (struct bfd_link_info *info, const char *name, bfd *abfd, asection *section, @@ -1188,25 +1331,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; + 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 @@ -1227,19 +1359,19 @@ undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, if (error_count < MAX_ERRORS_IN_A_ROW) { if (error) - einfo (_("%X%C: undefined reference to `%T'\n"), + einfo (_("%X%P: %C: undefined reference to `%pT'\n"), abfd, section, address, name); else - einfo (_("%C: warning: undefined reference to `%T'\n"), + einfo (_("%P: %C: warning: undefined reference to `%pT'\n"), abfd, section, address, name); } else if (error_count == MAX_ERRORS_IN_A_ROW) { if (error) - einfo (_("%X%D: more undefined references to `%T' follow\n"), + einfo (_("%X%P: %D: more undefined references to `%pT' follow\n"), abfd, section, address, name); else - einfo (_("%D: warning: more undefined references to `%T' follow\n"), + einfo (_("%P: %D: warning: more undefined references to `%pT' follow\n"), abfd, section, address, name); } else if (error) @@ -1250,26 +1382,24 @@ undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, if (error_count < MAX_ERRORS_IN_A_ROW) { if (error) - einfo (_("%X%B: undefined reference to `%T'\n"), + einfo (_("%X%P: %pB: undefined reference to `%pT'\n"), abfd, name); else - einfo (_("%B: warning: undefined reference to `%T'\n"), + einfo (_("%P: %pB: warning: undefined reference to `%pT'\n"), abfd, name); } else if (error_count == MAX_ERRORS_IN_A_ROW) { if (error) - einfo (_("%X%B: more undefined references to `%T' follow\n"), + einfo (_("%X%P: %pB: more undefined references to `%pT' follow\n"), abfd, name); else - einfo (_("%B: warning: more undefined references to `%T' follow\n"), + einfo (_("%P: %pB: warning: more undefined references to `%pT' follow\n"), abfd, name); } else if (error) einfo ("%X"); } - - return TRUE; } /* Counter to limit the number of relocation overflow error messages @@ -1283,8 +1413,8 @@ int overflow_cutoff_limit = 10; /* This is called when a reloc overflows. */ -static bfd_boolean -reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, +static void +reloc_overflow (struct bfd_link_info *info, struct bfd_link_hash_entry *entry, const char *name, const char *reloc_name, @@ -1294,15 +1424,15 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, bfd_vma address) { if (overflow_cutoff_limit == -1) - return TRUE; + return; - einfo ("%X%C:", abfd, section, address); + einfo ("%X%H:", abfd, section, address); if (overflow_cutoff_limit >= 0 && overflow_cutoff_limit-- == 0) { einfo (_(" additional relocation overflows omitted from the output\n")); - return TRUE; + return; } if (entry) @@ -1314,16 +1444,18 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, { case bfd_link_hash_undefined: case bfd_link_hash_undefweak: - einfo (_(" relocation truncated to fit: %s against undefined symbol `%T'"), + einfo (_(" relocation truncated to fit: " + "%s against undefined symbol `%pT'"), reloc_name, entry->root.string); break; case bfd_link_hash_defined: case bfd_link_hash_defweak: - einfo (_(" relocation truncated to fit: %s against symbol `%T' defined in %A section in %B"), + einfo (_(" relocation truncated to fit: " + "%s against symbol `%pT' defined in %pA section in %pB"), 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 (); @@ -1331,69 +1463,73 @@ reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED, } } else - einfo (_(" relocation truncated to fit: %s against `%T'"), + einfo (_(" relocation truncated to fit: %s against `%pT'"), reloc_name, name); if (addend != 0) einfo ("+%v", addend); einfo ("\n"); - return TRUE; } /* This is called when a dangerous relocation is made. */ -static bfd_boolean +static void reloc_dangerous (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *message, bfd *abfd, 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; } /* This is called when a reloc is being generated attached to a symbol that is not being output. */ -static bfd_boolean +static void unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED, const char *name, bfd *abfd, 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 `%pT' which is not being output\n"), abfd, section, address, name); - return TRUE; } /* This is called if link_info.notice_all is set, or when a symbol in link_info.notice_hash is found. Symbols are put in notice_hash - using the -y option. */ + using the -y option, while notice_all is set if the --cref option + has been supplied, or if there are any NOCROSSREFS sections in the + linker script; and if plugins are active, since they need to monitor + all references from non-IR files. */ 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; } - if (! info->notice_all - || (info->notice_hash != NULL - && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)) + name = h->root.string; + if (info->notice_hash != 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); + einfo (_("%P: %pB: reference to %s\n"), abfd, name); else - einfo ("%B: definition of %s\n", abfd, name); + einfo (_("%P: %pB: definition of %s\n"), abfd, name); } if (command_line.cref || nocrossref_list != NULL)