12159047fSniklas /* Main program of GNU linker.
2c074d1c9Sdrahn Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3007c2a45Smiod 2002, 2003, 2004
4b305b0f1Sespie Free Software Foundation, Inc.
52159047fSniklas Written by Steve Chamberlain steve@cygnus.com
62159047fSniklas
72159047fSniklas This file is part of GLD, the Gnu Linker.
82159047fSniklas
92159047fSniklas GLD is free software; you can redistribute it and/or modify
102159047fSniklas it under the terms of the GNU General Public License as published by
112159047fSniklas the Free Software Foundation; either version 2, or (at your option)
122159047fSniklas any later version.
132159047fSniklas
142159047fSniklas GLD is distributed in the hope that it will be useful,
152159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
162159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
172159047fSniklas GNU General Public License for more details.
182159047fSniklas
192159047fSniklas You should have received a copy of the GNU General Public License
200c6d0228Sniklas along with GLD; see the file COPYING. If not, write to the Free
210c6d0228Sniklas Software Foundation, 59 Temple Place - Suite 330, Boston, MA
220c6d0228Sniklas 02111-1307, USA. */
232159047fSniklas
242159047fSniklas #include "bfd.h"
252159047fSniklas #include "sysdep.h"
262159047fSniklas #include <stdio.h>
27c074d1c9Sdrahn #include "safe-ctype.h"
282159047fSniklas #include "libiberty.h"
292159047fSniklas #include "progress.h"
302159047fSniklas #include "bfdlink.h"
31b305b0f1Sespie #include "filenames.h"
322159047fSniklas
332159047fSniklas #include "ld.h"
342159047fSniklas #include "ldmain.h"
352159047fSniklas #include "ldmisc.h"
362159047fSniklas #include "ldwrite.h"
372159047fSniklas #include "ldexp.h"
382159047fSniklas #include "ldlang.h"
39c074d1c9Sdrahn #include <ldgram.h>
402159047fSniklas #include "ldlex.h"
412159047fSniklas #include "ldfile.h"
42b55d4692Sfgsch #include "ldemul.h"
432159047fSniklas #include "ldctor.h"
442159047fSniklas
45c074d1c9Sdrahn /* Somewhere above, sys/stat.h got included. */
462159047fSniklas #if !defined(S_ISDIR) && defined(S_IFDIR)
472159047fSniklas #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
482159047fSniklas #endif
492159047fSniklas
502159047fSniklas #include <string.h>
512159047fSniklas
520c6d0228Sniklas #ifdef HAVE_SBRK
530c6d0228Sniklas #ifdef NEED_DECLARATION_SBRK
54007c2a45Smiod extern void *sbrk ();
550c6d0228Sniklas #endif
560c6d0228Sniklas #endif
570c6d0228Sniklas
58c074d1c9Sdrahn #ifndef TARGET_SYSTEM_ROOT
59c074d1c9Sdrahn #define TARGET_SYSTEM_ROOT ""
60c074d1c9Sdrahn #endif
61c074d1c9Sdrahn
622159047fSniklas /* EXPORTS */
632159047fSniklas
642159047fSniklas char *default_target;
652159047fSniklas const char *output_filename = "a.out";
662159047fSniklas
672159047fSniklas /* Name this program was invoked by. */
682159047fSniklas char *program_name;
692159047fSniklas
70c074d1c9Sdrahn /* The prefix for system library directories. */
71c074d1c9Sdrahn char *ld_sysroot;
72c074d1c9Sdrahn
73c074d1c9Sdrahn /* The canonical representation of ld_sysroot. */
74c074d1c9Sdrahn char * ld_canon_sysroot;
75c074d1c9Sdrahn int ld_canon_sysroot_len;
76c074d1c9Sdrahn
77b55d4692Sfgsch /* The file that we're creating. */
782159047fSniklas bfd *output_bfd = 0;
792159047fSniklas
802159047fSniklas /* Set by -G argument, for MIPS ECOFF target. */
812159047fSniklas int g_switch_value = 8;
822159047fSniklas
832159047fSniklas /* Nonzero means print names of input files as processed. */
84c074d1c9Sdrahn bfd_boolean trace_files;
852159047fSniklas
862159047fSniklas /* Nonzero means same, but note open failures, too. */
87c074d1c9Sdrahn bfd_boolean trace_file_tries;
882159047fSniklas
892159047fSniklas /* Nonzero means version number was printed, so exit successfully
902159047fSniklas instead of complaining if no input files are given. */
91c074d1c9Sdrahn bfd_boolean version_printed;
922159047fSniklas
932159047fSniklas /* Nonzero means link in every member of an archive. */
94c074d1c9Sdrahn bfd_boolean whole_archive;
952159047fSniklas
96007c2a45Smiod /* Nonzero means create DT_NEEDED entries only if a dynamic library
97007c2a45Smiod actually satisfies some reference in a regular object. */
98007c2a45Smiod bfd_boolean as_needed;
99007c2a45Smiod
100c074d1c9Sdrahn /* TRUE if we should demangle symbol names. */
101c074d1c9Sdrahn bfd_boolean demangling;
102b305b0f1Sespie
1032159047fSniklas args_type command_line;
1042159047fSniklas
1052159047fSniklas ld_config_type config;
1062159047fSniklas
107c074d1c9Sdrahn static char *get_emulation
108007c2a45Smiod (int, char **);
109c074d1c9Sdrahn static void set_scripts_dir
110007c2a45Smiod (void);
111c074d1c9Sdrahn static bfd_boolean add_archive_element
112007c2a45Smiod (struct bfd_link_info *, bfd *, const char *);
113c074d1c9Sdrahn static bfd_boolean multiple_definition
114007c2a45Smiod (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma,
115007c2a45Smiod bfd *, asection *, bfd_vma);
116c074d1c9Sdrahn static bfd_boolean multiple_common
117007c2a45Smiod (struct bfd_link_info *, const char *, bfd *, enum bfd_link_hash_type,
118007c2a45Smiod bfd_vma, bfd *, enum bfd_link_hash_type, bfd_vma);
119c074d1c9Sdrahn static bfd_boolean add_to_set
120007c2a45Smiod (struct bfd_link_info *, struct bfd_link_hash_entry *,
121007c2a45Smiod bfd_reloc_code_real_type, bfd *, asection *, bfd_vma);
122c074d1c9Sdrahn static bfd_boolean constructor_callback
123007c2a45Smiod (struct bfd_link_info *, bfd_boolean, const char *, bfd *,
124007c2a45Smiod asection *, bfd_vma);
125c074d1c9Sdrahn static bfd_boolean warning_callback
126007c2a45Smiod (struct bfd_link_info *, const char *, const char *, bfd *,
127007c2a45Smiod asection *, bfd_vma);
128c074d1c9Sdrahn static void warning_find_reloc
129007c2a45Smiod (bfd *, asection *, void *);
130c074d1c9Sdrahn static bfd_boolean undefined_symbol
131007c2a45Smiod (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma,
132007c2a45Smiod bfd_boolean);
133c074d1c9Sdrahn static bfd_boolean reloc_overflow
134007c2a45Smiod (struct bfd_link_info *, const char *, const char *, bfd_vma,
135007c2a45Smiod bfd *, asection *, bfd_vma);
136c074d1c9Sdrahn static bfd_boolean reloc_dangerous
137007c2a45Smiod (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
138c074d1c9Sdrahn static bfd_boolean unattached_reloc
139007c2a45Smiod (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
140c074d1c9Sdrahn static bfd_boolean notice
141007c2a45Smiod (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
1422159047fSniklas
143c074d1c9Sdrahn static struct bfd_link_callbacks link_callbacks =
144c074d1c9Sdrahn {
1452159047fSniklas add_archive_element,
1462159047fSniklas multiple_definition,
1472159047fSniklas multiple_common,
1482159047fSniklas add_to_set,
1492159047fSniklas constructor_callback,
1502159047fSniklas warning_callback,
1512159047fSniklas undefined_symbol,
1522159047fSniklas reloc_overflow,
1532159047fSniklas reloc_dangerous,
1542159047fSniklas unattached_reloc,
155c074d1c9Sdrahn notice,
156c074d1c9Sdrahn error_handler
1572159047fSniklas };
1582159047fSniklas
1592159047fSniklas struct bfd_link_info link_info;
1602159047fSniklas
1612159047fSniklas static void
remove_output(void)162007c2a45Smiod remove_output (void)
1632159047fSniklas {
1642159047fSniklas if (output_filename)
1652159047fSniklas {
166007c2a45Smiod if (output_bfd)
167007c2a45Smiod bfd_cache_close (output_bfd);
1682159047fSniklas if (delete_output_file_on_failure)
1692159047fSniklas unlink (output_filename);
1702159047fSniklas }
1712159047fSniklas }
1722159047fSniklas
1732159047fSniklas int
main(int argc,char ** argv)174007c2a45Smiod main (int argc, char **argv)
1752159047fSniklas {
1762159047fSniklas char *emulation;
1772159047fSniklas long start_time = get_run_time ();
1782159047fSniklas
179b305b0f1Sespie #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
180b305b0f1Sespie setlocale (LC_MESSAGES, "");
181b305b0f1Sespie #endif
182c074d1c9Sdrahn #if defined (HAVE_SETLOCALE)
183c074d1c9Sdrahn setlocale (LC_CTYPE, "");
184c074d1c9Sdrahn #endif
185b305b0f1Sespie bindtextdomain (PACKAGE, LOCALEDIR);
186b305b0f1Sespie textdomain (PACKAGE);
187b305b0f1Sespie
1882159047fSniklas program_name = argv[0];
1892159047fSniklas xmalloc_set_program_name (program_name);
1902159047fSniklas
1912159047fSniklas START_PROGRESS (program_name, 0);
1922159047fSniklas
193a95e6fecStobiasu expandargv (&argc, &argv);
194a95e6fecStobiasu
1952159047fSniklas bfd_init ();
1962159047fSniklas
197191aa565Sniklas bfd_set_error_program_name (program_name);
198191aa565Sniklas
1992159047fSniklas xatexit (remove_output);
2002159047fSniklas
201c074d1c9Sdrahn #ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
202c074d1c9Sdrahn ld_sysroot = make_relative_prefix (program_name, BINDIR,
203c074d1c9Sdrahn TARGET_SYSTEM_ROOT);
204c074d1c9Sdrahn
205c074d1c9Sdrahn if (ld_sysroot)
206c074d1c9Sdrahn {
207c074d1c9Sdrahn struct stat s;
208c074d1c9Sdrahn int res = stat (ld_sysroot, &s) == 0 && S_ISDIR (s.st_mode);
209c074d1c9Sdrahn
210c074d1c9Sdrahn if (!res)
211c074d1c9Sdrahn {
212c074d1c9Sdrahn free (ld_sysroot);
213c074d1c9Sdrahn ld_sysroot = NULL;
214c074d1c9Sdrahn }
215c074d1c9Sdrahn }
216c074d1c9Sdrahn
217c074d1c9Sdrahn if (! ld_sysroot)
218c074d1c9Sdrahn {
219c074d1c9Sdrahn ld_sysroot = make_relative_prefix (program_name, TOOLBINDIR,
220c074d1c9Sdrahn TARGET_SYSTEM_ROOT);
221c074d1c9Sdrahn
222c074d1c9Sdrahn if (ld_sysroot)
223c074d1c9Sdrahn {
224c074d1c9Sdrahn struct stat s;
225c074d1c9Sdrahn int res = stat (ld_sysroot, &s) == 0 && S_ISDIR (s.st_mode);
226c074d1c9Sdrahn
227c074d1c9Sdrahn if (!res)
228c074d1c9Sdrahn {
229c074d1c9Sdrahn free (ld_sysroot);
230c074d1c9Sdrahn ld_sysroot = NULL;
231c074d1c9Sdrahn }
232c074d1c9Sdrahn }
233c074d1c9Sdrahn }
234c074d1c9Sdrahn
235c074d1c9Sdrahn if (! ld_sysroot)
236c074d1c9Sdrahn #endif
237c074d1c9Sdrahn ld_sysroot = TARGET_SYSTEM_ROOT;
238c074d1c9Sdrahn
239c074d1c9Sdrahn if (ld_sysroot && *ld_sysroot)
240c074d1c9Sdrahn ld_canon_sysroot = lrealpath (ld_sysroot);
241c074d1c9Sdrahn
242c074d1c9Sdrahn if (ld_canon_sysroot)
243c074d1c9Sdrahn ld_canon_sysroot_len = strlen (ld_canon_sysroot);
244c074d1c9Sdrahn else
245c074d1c9Sdrahn ld_canon_sysroot_len = -1;
246c074d1c9Sdrahn
247b305b0f1Sespie /* Set the default BFD target based on the configured target. Doing
248b305b0f1Sespie this permits the linker to be configured for a particular target,
249b305b0f1Sespie and linked against a shared BFD library which was configured for
250b305b0f1Sespie a different target. The macro TARGET is defined by Makefile. */
251b305b0f1Sespie if (! bfd_set_default_target (TARGET))
252b305b0f1Sespie {
253b305b0f1Sespie einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
254b305b0f1Sespie xexit (1);
255b305b0f1Sespie }
256b305b0f1Sespie
257c074d1c9Sdrahn #if YYDEBUG
258c074d1c9Sdrahn {
259c074d1c9Sdrahn extern int yydebug;
260c074d1c9Sdrahn yydebug = 1;
261c074d1c9Sdrahn }
262c074d1c9Sdrahn #endif
263c074d1c9Sdrahn
2642159047fSniklas /* Initialize the data about options. */
265c074d1c9Sdrahn trace_files = trace_file_tries = version_printed = FALSE;
266c074d1c9Sdrahn whole_archive = FALSE;
267c074d1c9Sdrahn config.build_constructors = TRUE;
268c074d1c9Sdrahn config.dynamic_link = FALSE;
269c074d1c9Sdrahn config.has_shared = FALSE;
270b55d4692Sfgsch config.split_by_reloc = (unsigned) -1;
271b55d4692Sfgsch config.split_by_file = (bfd_size_type) -1;
272c074d1c9Sdrahn command_line.force_common_definition = FALSE;
273c074d1c9Sdrahn command_line.inhibit_common_definition = FALSE;
2742159047fSniklas command_line.interpreter = NULL;
2752159047fSniklas command_line.rpath = NULL;
276c074d1c9Sdrahn command_line.warn_mismatch = TRUE;
277c074d1c9Sdrahn command_line.check_section_addresses = TRUE;
278c074d1c9Sdrahn command_line.accept_unknown_input_arch = FALSE;
279b305b0f1Sespie
280b305b0f1Sespie /* We initialize DEMANGLING based on the environment variable
281b305b0f1Sespie COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the
282b305b0f1Sespie output of the linker, unless COLLECT_NO_DEMANGLE is set in the
283b305b0f1Sespie environment. Acting the same way here lets us provide the same
284b305b0f1Sespie interface by default. */
285b305b0f1Sespie demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;
2862159047fSniklas
287007c2a45Smiod link_info.relocatable = FALSE;
288c074d1c9Sdrahn link_info.emitrelocations = FALSE;
289c074d1c9Sdrahn link_info.task_link = FALSE;
290c074d1c9Sdrahn link_info.shared = FALSE;
2919622a78fSpascal #ifdef PIE_DEFAULT
2929622a78fSpascal link_info.pie = TRUE;
2939622a78fSpascal #else
294007c2a45Smiod link_info.pie = FALSE;
2959622a78fSpascal #endif
296007c2a45Smiod link_info.executable = FALSE;
297c074d1c9Sdrahn link_info.symbolic = FALSE;
298c074d1c9Sdrahn link_info.export_dynamic = FALSE;
299c074d1c9Sdrahn link_info.static_link = FALSE;
300c074d1c9Sdrahn link_info.traditional_format = FALSE;
301c074d1c9Sdrahn link_info.optimize = FALSE;
302007c2a45Smiod link_info.unresolved_syms_in_objects = RM_NOT_YET_SET;
303007c2a45Smiod link_info.unresolved_syms_in_shared_libs = RM_NOT_YET_SET;
304c074d1c9Sdrahn link_info.allow_multiple_definition = FALSE;
305c074d1c9Sdrahn link_info.allow_undefined_version = TRUE;
306c074d1c9Sdrahn link_info.keep_memory = TRUE;
307c074d1c9Sdrahn link_info.notice_all = FALSE;
308c074d1c9Sdrahn link_info.nocopyreloc = FALSE;
309c074d1c9Sdrahn link_info.new_dtags = FALSE;
310c074d1c9Sdrahn link_info.combreloc = TRUE;
311c074d1c9Sdrahn link_info.eh_frame_hdr = FALSE;
312c074d1c9Sdrahn link_info.strip_discarded = TRUE;
3132159047fSniklas link_info.strip = strip_none;
314c074d1c9Sdrahn link_info.discard = discard_sec_merge;
315c074d1c9Sdrahn link_info.common_skip_ar_aymbols = bfd_link_common_skip_none;
316c074d1c9Sdrahn link_info.callbacks = &link_callbacks;
3172159047fSniklas link_info.hash = NULL;
3182159047fSniklas link_info.keep_hash = NULL;
3192159047fSniklas link_info.notice_hash = NULL;
320191aa565Sniklas link_info.wrap_hash = NULL;
321c074d1c9Sdrahn link_info.input_bfds = NULL;
322c074d1c9Sdrahn link_info.create_object_symbols_section = NULL;
323c074d1c9Sdrahn link_info.gc_sym_list = NULL;
324c074d1c9Sdrahn link_info.base_file = NULL;
325b305b0f1Sespie /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
326b305b0f1Sespie and _fini symbols. We are compatible. */
327b305b0f1Sespie link_info.init_function = "_init";
328b305b0f1Sespie link_info.fini_function = "_fini";
329c074d1c9Sdrahn link_info.pei386_auto_import = -1;
330c074d1c9Sdrahn link_info.pei386_runtime_pseudo_reloc = FALSE;
331c074d1c9Sdrahn link_info.spare_dynamic_tags = 5;
332007c2a45Smiod link_info.flags = 0;
333007c2a45Smiod link_info.flags_1 = 0;
334007c2a45Smiod link_info.need_relax_finalize = FALSE;
3352159047fSniklas
3362159047fSniklas ldfile_add_arch ("");
3372159047fSniklas
338c074d1c9Sdrahn config.make_executable = TRUE;
339c074d1c9Sdrahn force_make_executable = FALSE;
340c074d1c9Sdrahn config.magic_demand_paged = TRUE;
341c074d1c9Sdrahn config.text_read_only = TRUE;
342c074d1c9Sdrahn config.data_bss_contig = FALSE;
3432159047fSniklas
3442159047fSniklas emulation = get_emulation (argc, argv);
3452159047fSniklas ldemul_choose_mode (emulation);
346c074d1c9Sdrahn default_target = ldemul_choose_target (argc, argv);
3472159047fSniklas lang_init ();
3482159047fSniklas ldemul_before_parse ();
349c074d1c9Sdrahn lang_has_input_file = FALSE;
3502159047fSniklas parse_args (argc, argv);
3512159047fSniklas
3522159047fSniklas ldemul_set_symbols ();
3532159047fSniklas
3549622a78fSpascal if (! link_info.shared && link_info.pie)
3559622a78fSpascal {
3569622a78fSpascal if (link_info.relocatable)
3579622a78fSpascal link_info.pie = FALSE;
3589622a78fSpascal else
3599622a78fSpascal link_info.shared = TRUE;
3609622a78fSpascal }
3619622a78fSpascal
362007c2a45Smiod if (link_info.relocatable)
3632159047fSniklas {
364b305b0f1Sespie if (command_line.gc_sections)
365b305b0f1Sespie einfo ("%P%F: --gc-sections and -r may not be used together\n");
366b305b0f1Sespie else if (command_line.relax)
367b305b0f1Sespie einfo (_("%P%F: --relax and -r may not be used together\n"));
3682159047fSniklas if (link_info.shared)
369b305b0f1Sespie einfo (_("%P%F: -r and -shared may not be used together\n"));
3702159047fSniklas }
3712159047fSniklas
372c074d1c9Sdrahn if (! link_info.shared)
373c074d1c9Sdrahn {
374c074d1c9Sdrahn if (command_line.filter_shlib)
375c074d1c9Sdrahn einfo (_("%P%F: -F may not be used without -shared\n"));
376c074d1c9Sdrahn if (command_line.auxiliary_filters)
377c074d1c9Sdrahn einfo (_("%P%F: -f may not be used without -shared\n"));
378c074d1c9Sdrahn }
379c074d1c9Sdrahn
380007c2a45Smiod if (! link_info.shared || link_info.pie)
381007c2a45Smiod link_info.executable = TRUE;
382007c2a45Smiod
383*2d6de53bSkettenis if (! config.dynamic_link && link_info.pie)
384*2d6de53bSkettenis link_info.static_link = TRUE;
385*2d6de53bSkettenis
3862159047fSniklas /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I
3872159047fSniklas don't see how else this can be handled, since in this case we
3882159047fSniklas must preserve all externally visible symbols. */
389007c2a45Smiod if (link_info.relocatable && link_info.strip == strip_all)
3902159047fSniklas {
3912159047fSniklas link_info.strip = strip_debugger;
392c074d1c9Sdrahn if (link_info.discard == discard_sec_merge)
3932159047fSniklas link_info.discard = discard_all;
3942159047fSniklas }
3952159047fSniklas
3962159047fSniklas /* This essentially adds another -L directory so this must be done after
3972159047fSniklas the -L's in argv have been processed. */
3982159047fSniklas set_scripts_dir ();
3992159047fSniklas
400c074d1c9Sdrahn /* If we have not already opened and parsed a linker script
401c074d1c9Sdrahn read the emulation's appropriate default script. */
402c074d1c9Sdrahn if (saved_script_handle == NULL)
4032159047fSniklas {
4042159047fSniklas int isfile;
4052159047fSniklas char *s = ldemul_get_script (&isfile);
4062159047fSniklas
4072159047fSniklas if (isfile)
4082159047fSniklas ldfile_open_command_file (s);
4092159047fSniklas else
4102159047fSniklas {
4112159047fSniklas lex_string = s;
4122159047fSniklas lex_redirect (s);
4132159047fSniklas }
4142159047fSniklas parser_input = input_script;
4152159047fSniklas yyparse ();
4162159047fSniklas lex_string = NULL;
4172159047fSniklas }
4182159047fSniklas
419c074d1c9Sdrahn if (trace_file_tries)
420c074d1c9Sdrahn {
421c074d1c9Sdrahn if (saved_script_handle)
422c074d1c9Sdrahn info_msg (_("using external linker script:"));
423c074d1c9Sdrahn else
424c074d1c9Sdrahn info_msg (_("using internal linker script:"));
425c074d1c9Sdrahn info_msg ("\n==================================================\n");
426c074d1c9Sdrahn
427c074d1c9Sdrahn if (saved_script_handle)
428c074d1c9Sdrahn {
429c074d1c9Sdrahn static const int ld_bufsz = 8193;
430c074d1c9Sdrahn size_t n;
431c074d1c9Sdrahn char *buf = xmalloc (ld_bufsz);
432c074d1c9Sdrahn
433c074d1c9Sdrahn rewind (saved_script_handle);
434c074d1c9Sdrahn while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
435c074d1c9Sdrahn {
436c074d1c9Sdrahn buf[n] = 0;
437c074d1c9Sdrahn info_msg (buf);
438c074d1c9Sdrahn }
439c074d1c9Sdrahn rewind (saved_script_handle);
440c074d1c9Sdrahn free (buf);
441c074d1c9Sdrahn }
442c074d1c9Sdrahn else
443c074d1c9Sdrahn {
444c074d1c9Sdrahn int isfile;
445c074d1c9Sdrahn
446c074d1c9Sdrahn info_msg (ldemul_get_script (&isfile));
447c074d1c9Sdrahn }
448c074d1c9Sdrahn
449c074d1c9Sdrahn info_msg ("\n==================================================\n");
450c074d1c9Sdrahn }
451c074d1c9Sdrahn
4522159047fSniklas lang_final ();
4532159047fSniklas
454c074d1c9Sdrahn if (!lang_has_input_file)
4552159047fSniklas {
4562159047fSniklas if (version_printed)
4572159047fSniklas xexit (0);
458b305b0f1Sespie einfo (_("%P%F: no input files\n"));
4592159047fSniklas }
4602159047fSniklas
4612159047fSniklas if (trace_files)
462b305b0f1Sespie info_msg (_("%P: mode %s\n"), emulation);
4632159047fSniklas
4642159047fSniklas ldemul_after_parse ();
4652159047fSniklas
4662159047fSniklas if (config.map_filename)
4672159047fSniklas {
4682159047fSniklas if (strcmp (config.map_filename, "-") == 0)
4692159047fSniklas {
4702159047fSniklas config.map_file = stdout;
4712159047fSniklas }
4722159047fSniklas else
4732159047fSniklas {
4742159047fSniklas config.map_file = fopen (config.map_filename, FOPEN_WT);
4752159047fSniklas if (config.map_file == (FILE *) NULL)
4762159047fSniklas {
4772159047fSniklas bfd_set_error (bfd_error_system_call);
478b305b0f1Sespie einfo (_("%P%F: cannot open map file %s: %E\n"),
4792159047fSniklas config.map_filename);
4802159047fSniklas }
4812159047fSniklas }
4822159047fSniklas }
4832159047fSniklas
4842159047fSniklas lang_process ();
4852159047fSniklas
4862159047fSniklas /* Print error messages for any missing symbols, for any warning
487b55d4692Sfgsch symbols, and possibly multiple definitions. */
488007c2a45Smiod if (link_info.relocatable)
4892159047fSniklas output_bfd->flags &= ~EXEC_P;
4902159047fSniklas else
4912159047fSniklas output_bfd->flags |= EXEC_P;
4922159047fSniklas
4932159047fSniklas ldwrite ();
4942159047fSniklas
495191aa565Sniklas if (config.map_file != NULL)
496191aa565Sniklas lang_map ();
4970c6d0228Sniklas if (command_line.cref)
498191aa565Sniklas output_cref (config.map_file != NULL ? config.map_file : stdout);
4990c6d0228Sniklas if (nocrossref_list != NULL)
5000c6d0228Sniklas check_nocrossrefs ();
501191aa565Sniklas
502007c2a45Smiod /* Even if we're producing relocatable output, some non-fatal errors should
5032159047fSniklas be reported in the exit status. (What non-fatal errors, if any, do we
504007c2a45Smiod want to ignore for relocatable output?) */
505c074d1c9Sdrahn if (!config.make_executable && !force_make_executable)
5062159047fSniklas {
507c074d1c9Sdrahn if (trace_files)
508b305b0f1Sespie einfo (_("%P: link errors found, deleting executable `%s'\n"),
5092159047fSniklas output_filename);
5102159047fSniklas
511191aa565Sniklas /* The file will be removed by remove_output. */
5122159047fSniklas xexit (1);
5132159047fSniklas }
5142159047fSniklas else
5152159047fSniklas {
5162159047fSniklas if (! bfd_close (output_bfd))
517b305b0f1Sespie einfo (_("%F%B: final close failed: %E\n"), output_bfd);
518191aa565Sniklas
519191aa565Sniklas /* If the --force-exe-suffix is enabled, and we're making an
520b55d4692Sfgsch executable file and it doesn't end in .exe, copy it to one
521b55d4692Sfgsch which does. */
522007c2a45Smiod if (! link_info.relocatable && command_line.force_exe_suffix)
523191aa565Sniklas {
524191aa565Sniklas int len = strlen (output_filename);
525c074d1c9Sdrahn
526191aa565Sniklas if (len < 4
527191aa565Sniklas || (strcasecmp (output_filename + len - 4, ".exe") != 0
528191aa565Sniklas && strcasecmp (output_filename + len - 4, ".dll") != 0))
529191aa565Sniklas {
530191aa565Sniklas FILE *src;
531191aa565Sniklas FILE *dst;
532191aa565Sniklas const int bsize = 4096;
533191aa565Sniklas char *buf = xmalloc (bsize);
534191aa565Sniklas int l;
535191aa565Sniklas char *dst_name = xmalloc (len + 5);
536c074d1c9Sdrahn
537191aa565Sniklas strcpy (dst_name, output_filename);
538191aa565Sniklas strcat (dst_name, ".exe");
539191aa565Sniklas src = fopen (output_filename, FOPEN_RB);
540191aa565Sniklas dst = fopen (dst_name, FOPEN_WB);
541191aa565Sniklas
542191aa565Sniklas if (!src)
543007c2a45Smiod einfo (_("%X%P: unable to open for source of copy `%s'\n"),
544007c2a45Smiod output_filename);
545191aa565Sniklas if (!dst)
546007c2a45Smiod einfo (_("%X%P: unable to open for destination of copy `%s'\n"),
547007c2a45Smiod dst_name);
548191aa565Sniklas while ((l = fread (buf, 1, bsize, src)) > 0)
549191aa565Sniklas {
550191aa565Sniklas int done = fwrite (buf, 1, l, dst);
551c074d1c9Sdrahn
552191aa565Sniklas if (done != l)
553b305b0f1Sespie einfo (_("%P: Error writing file `%s'\n"), dst_name);
554191aa565Sniklas }
555c074d1c9Sdrahn
556191aa565Sniklas fclose (src);
557b305b0f1Sespie if (fclose (dst) == EOF)
558b305b0f1Sespie einfo (_("%P: Error closing file `%s'\n"), dst_name);
559191aa565Sniklas free (dst_name);
560191aa565Sniklas free (buf);
561191aa565Sniklas }
562191aa565Sniklas }
5632159047fSniklas }
5642159047fSniklas
5652159047fSniklas END_PROGRESS (program_name);
5662159047fSniklas
5672159047fSniklas if (config.stats)
5682159047fSniklas {
5692159047fSniklas #ifdef HAVE_SBRK
570007c2a45Smiod char *lim = sbrk (0);
5712159047fSniklas #endif
5722159047fSniklas long run_time = get_run_time () - start_time;
5732159047fSniklas
574b305b0f1Sespie fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
5752159047fSniklas program_name, run_time / 1000000, run_time % 1000000);
5762159047fSniklas #ifdef HAVE_SBRK
577b305b0f1Sespie fprintf (stderr, _("%s: data size %ld\n"), program_name,
5782159047fSniklas (long) (lim - (char *) &environ));
5792159047fSniklas #endif
5802159047fSniklas }
5812159047fSniklas
5822159047fSniklas /* Prevent remove_output from doing anything, after a successful link. */
5832159047fSniklas output_filename = NULL;
5842159047fSniklas
5852159047fSniklas xexit (0);
5862159047fSniklas return 0;
5872159047fSniklas }
5882159047fSniklas
5892159047fSniklas /* We need to find any explicitly given emulation in order to initialize the
5902159047fSniklas state that's needed by the lex&yacc argument parser (parse_args). */
5912159047fSniklas
5922159047fSniklas static char *
get_emulation(int argc,char ** argv)593007c2a45Smiod get_emulation (int argc, char **argv)
5942159047fSniklas {
5952159047fSniklas char *emulation;
5962159047fSniklas int i;
5972159047fSniklas
598b305b0f1Sespie emulation = getenv (EMULATION_ENVIRON);
5992159047fSniklas if (emulation == NULL)
6002159047fSniklas emulation = DEFAULT_EMULATION;
6012159047fSniklas
6022159047fSniklas for (i = 1; i < argc; i++)
6032159047fSniklas {
6042159047fSniklas if (!strncmp (argv[i], "-m", 2))
6052159047fSniklas {
6062159047fSniklas if (argv[i][2] == '\0')
6072159047fSniklas {
6082159047fSniklas /* -m EMUL */
6092159047fSniklas if (i < argc - 1)
6102159047fSniklas {
6112159047fSniklas emulation = argv[i + 1];
6122159047fSniklas i++;
6132159047fSniklas }
6142159047fSniklas else
615b305b0f1Sespie einfo (_("%P%F: missing argument to -m\n"));
6162159047fSniklas }
6172159047fSniklas else if (strcmp (argv[i], "-mips1") == 0
6182159047fSniklas || strcmp (argv[i], "-mips2") == 0
619e93f7393Sniklas || strcmp (argv[i], "-mips3") == 0
620c074d1c9Sdrahn || strcmp (argv[i], "-mips4") == 0
621c074d1c9Sdrahn || strcmp (argv[i], "-mips5") == 0
622c074d1c9Sdrahn || strcmp (argv[i], "-mips32") == 0
623c074d1c9Sdrahn || strcmp (argv[i], "-mips32r2") == 0
624007c2a45Smiod || strcmp (argv[i], "-mips64") == 0
625007c2a45Smiod || strcmp (argv[i], "-mips64r2") == 0)
6262159047fSniklas {
627c074d1c9Sdrahn /* FIXME: The arguments -mips1, -mips2, -mips3, etc. are
6282159047fSniklas passed to the linker by some MIPS compilers. They
6292159047fSniklas generally tell the linker to use a slightly different
6302159047fSniklas library path. Perhaps someday these should be
6312159047fSniklas implemented as emulations; until then, we just ignore
6322159047fSniklas the arguments and hope that nobody ever creates
6332159047fSniklas emulations named ips1, ips2 or ips3. */
6342159047fSniklas }
6352159047fSniklas else if (strcmp (argv[i], "-m486") == 0)
6362159047fSniklas {
6372159047fSniklas /* FIXME: The argument -m486 is passed to the linker on
6382159047fSniklas some Linux systems. Hope that nobody creates an
6392159047fSniklas emulation named 486. */
6402159047fSniklas }
6412159047fSniklas else
6422159047fSniklas {
6432159047fSniklas /* -mEMUL */
6442159047fSniklas emulation = &argv[i][2];
6452159047fSniklas }
6462159047fSniklas }
6472159047fSniklas }
6482159047fSniklas
6492159047fSniklas return emulation;
6502159047fSniklas }
6512159047fSniklas
6522159047fSniklas /* If directory DIR contains an "ldscripts" subdirectory,
653c074d1c9Sdrahn add DIR to the library search path and return TRUE,
654c074d1c9Sdrahn else return FALSE. */
6552159047fSniklas
656c074d1c9Sdrahn static bfd_boolean
check_for_scripts_dir(char * dir)657007c2a45Smiod check_for_scripts_dir (char *dir)
6582159047fSniklas {
6592159047fSniklas size_t dirlen;
6602159047fSniklas char *buf;
6612159047fSniklas struct stat s;
662c074d1c9Sdrahn bfd_boolean res;
6632159047fSniklas
6642159047fSniklas dirlen = strlen (dir);
6652159047fSniklas /* sizeof counts the terminating NUL. */
666007c2a45Smiod buf = xmalloc (dirlen + sizeof ("/ldscripts"));
6672159047fSniklas sprintf (buf, "%s/ldscripts", dir);
6682159047fSniklas
6692159047fSniklas res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
6702159047fSniklas free (buf);
6712159047fSniklas if (res)
672c074d1c9Sdrahn ldfile_add_library_path (dir, FALSE);
6732159047fSniklas return res;
6742159047fSniklas }
6752159047fSniklas
6762159047fSniklas /* Set the default directory for finding script files.
6772159047fSniklas Libraries will be searched for here too, but that's ok.
6782159047fSniklas We look for the "ldscripts" directory in:
6792159047fSniklas
6802159047fSniklas SCRIPTDIR (passed from Makefile)
681c074d1c9Sdrahn (adjusted according to the current location of the binary)
682c074d1c9Sdrahn SCRIPTDIR (passed from Makefile)
6832159047fSniklas the dir where this program is (for using it from the build tree)
684c074d1c9Sdrahn the dir where this program is/../lib
685c074d1c9Sdrahn (for installing the tool suite elsewhere). */
6862159047fSniklas
6872159047fSniklas static void
set_scripts_dir(void)688007c2a45Smiod set_scripts_dir (void)
6892159047fSniklas {
6902159047fSniklas char *end, *dir;
6912159047fSniklas size_t dirlen;
692c074d1c9Sdrahn bfd_boolean found;
693c074d1c9Sdrahn
694c074d1c9Sdrahn dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR);
695c074d1c9Sdrahn if (dir)
696c074d1c9Sdrahn {
697c074d1c9Sdrahn found = check_for_scripts_dir (dir);
698c074d1c9Sdrahn free (dir);
699c074d1c9Sdrahn if (found)
700c074d1c9Sdrahn return;
701c074d1c9Sdrahn }
702c074d1c9Sdrahn
703c074d1c9Sdrahn dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR);
704c074d1c9Sdrahn if (dir)
705c074d1c9Sdrahn {
706c074d1c9Sdrahn found = check_for_scripts_dir (dir);
707c074d1c9Sdrahn free (dir);
708c074d1c9Sdrahn if (found)
709c074d1c9Sdrahn return;
710c074d1c9Sdrahn }
7112159047fSniklas
7122159047fSniklas if (check_for_scripts_dir (SCRIPTDIR))
713b55d4692Sfgsch /* We've been installed normally. */
714b55d4692Sfgsch return;
7152159047fSniklas
7162159047fSniklas /* Look for "ldscripts" in the dir where our binary is. */
7172159047fSniklas end = strrchr (program_name, '/');
718b305b0f1Sespie #ifdef HAVE_DOS_BASED_FILE_SYSTEM
719b305b0f1Sespie {
720b305b0f1Sespie /* We could have \foo\bar, or /foo\bar. */
721b305b0f1Sespie char *bslash = strrchr (program_name, '\\');
722c074d1c9Sdrahn
723b55d4692Sfgsch if (end == NULL || (bslash != NULL && bslash > end))
724b305b0f1Sespie end = bslash;
725b305b0f1Sespie }
726b305b0f1Sespie #endif
7272159047fSniklas
7282159047fSniklas if (end == NULL)
7292159047fSniklas /* Don't look for ldscripts in the current directory. There is
7302159047fSniklas too much potential for confusion. */
7312159047fSniklas return;
7322159047fSniklas
7332159047fSniklas dirlen = end - program_name;
7342159047fSniklas /* Make a copy of program_name in dir.
7352159047fSniklas Leave room for later "/../lib". */
736007c2a45Smiod dir = xmalloc (dirlen + 8);
7372159047fSniklas strncpy (dir, program_name, dirlen);
7382159047fSniklas dir[dirlen] = '\0';
7392159047fSniklas
7402159047fSniklas if (check_for_scripts_dir (dir))
741c074d1c9Sdrahn {
742c074d1c9Sdrahn free (dir);
743b55d4692Sfgsch return;
744c074d1c9Sdrahn }
7452159047fSniklas
7462159047fSniklas /* Look for "ldscripts" in <the dir where our binary is>/../lib. */
7472159047fSniklas strcpy (dir + dirlen, "/../lib");
748c074d1c9Sdrahn check_for_scripts_dir (dir);
749b55d4692Sfgsch free (dir);
7502159047fSniklas }
7512159047fSniklas
7522159047fSniklas void
add_ysym(const char * name)753007c2a45Smiod add_ysym (const char *name)
7542159047fSniklas {
755007c2a45Smiod if (link_info.notice_hash == NULL)
7562159047fSniklas {
757007c2a45Smiod link_info.notice_hash = xmalloc (sizeof (struct bfd_hash_table));
7582159047fSniklas if (! bfd_hash_table_init_n (link_info.notice_hash,
7592159047fSniklas bfd_hash_newfunc,
7602159047fSniklas 61))
761b305b0f1Sespie einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
7622159047fSniklas }
7632159047fSniklas
764007c2a45Smiod if (bfd_hash_lookup (link_info.notice_hash, name, TRUE, TRUE) == NULL)
765b305b0f1Sespie einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
7662159047fSniklas }
7672159047fSniklas
768191aa565Sniklas /* Record a symbol to be wrapped, from the --wrap option. */
769191aa565Sniklas
770191aa565Sniklas void
add_wrap(const char * name)771007c2a45Smiod add_wrap (const char *name)
772191aa565Sniklas {
773191aa565Sniklas if (link_info.wrap_hash == NULL)
774191aa565Sniklas {
775007c2a45Smiod link_info.wrap_hash = xmalloc (sizeof (struct bfd_hash_table));
776191aa565Sniklas if (! bfd_hash_table_init_n (link_info.wrap_hash,
777191aa565Sniklas bfd_hash_newfunc,
778191aa565Sniklas 61))
779b305b0f1Sespie einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
780191aa565Sniklas }
781c074d1c9Sdrahn
782c074d1c9Sdrahn if (bfd_hash_lookup (link_info.wrap_hash, name, TRUE, TRUE) == NULL)
783b305b0f1Sespie einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
784191aa565Sniklas }
785191aa565Sniklas
7862159047fSniklas /* Handle the -retain-symbols-file option. */
7872159047fSniklas
7882159047fSniklas void
add_keepsyms_file(const char * filename)789007c2a45Smiod add_keepsyms_file (const char *filename)
7902159047fSniklas {
7912159047fSniklas FILE *file;
7922159047fSniklas char *buf;
7932159047fSniklas size_t bufsize;
7942159047fSniklas int c;
7952159047fSniklas
7962159047fSniklas if (link_info.strip == strip_some)
797b305b0f1Sespie einfo (_("%X%P: error: duplicate retain-symbols-file\n"));
7982159047fSniklas
7992159047fSniklas file = fopen (filename, "r");
800007c2a45Smiod if (file == NULL)
8012159047fSniklas {
8022159047fSniklas bfd_set_error (bfd_error_system_call);
8032159047fSniklas einfo ("%X%P: %s: %E\n", filename);
8042159047fSniklas return;
8052159047fSniklas }
8062159047fSniklas
807007c2a45Smiod link_info.keep_hash = xmalloc (sizeof (struct bfd_hash_table));
8082159047fSniklas if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc))
809b305b0f1Sespie einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
8102159047fSniklas
8112159047fSniklas bufsize = 100;
812007c2a45Smiod buf = xmalloc (bufsize);
8132159047fSniklas
8142159047fSniklas c = getc (file);
8152159047fSniklas while (c != EOF)
8162159047fSniklas {
817c074d1c9Sdrahn while (ISSPACE (c))
8182159047fSniklas c = getc (file);
8192159047fSniklas
8202159047fSniklas if (c != EOF)
8212159047fSniklas {
8222159047fSniklas size_t len = 0;
8232159047fSniklas
824c074d1c9Sdrahn while (! ISSPACE (c) && c != EOF)
8252159047fSniklas {
8262159047fSniklas buf[len] = c;
8272159047fSniklas ++len;
8282159047fSniklas if (len >= bufsize)
8292159047fSniklas {
8302159047fSniklas bufsize *= 2;
8312159047fSniklas buf = xrealloc (buf, bufsize);
8322159047fSniklas }
8332159047fSniklas c = getc (file);
8342159047fSniklas }
8352159047fSniklas
8362159047fSniklas buf[len] = '\0';
8372159047fSniklas
838007c2a45Smiod if (bfd_hash_lookup (link_info.keep_hash, buf, TRUE, TRUE) == NULL)
839b305b0f1Sespie einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n"));
8402159047fSniklas }
8412159047fSniklas }
8422159047fSniklas
8432159047fSniklas if (link_info.strip != strip_none)
844b305b0f1Sespie einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"));
8452159047fSniklas
846c074d1c9Sdrahn free (buf);
8472159047fSniklas link_info.strip = strip_some;
8482159047fSniklas }
8492159047fSniklas
8502159047fSniklas /* Callbacks from the BFD linker routines. */
8512159047fSniklas
8522159047fSniklas /* This is called when BFD has decided to include an archive member in
8532159047fSniklas a link. */
8542159047fSniklas
855c074d1c9Sdrahn static bfd_boolean
add_archive_element(struct bfd_link_info * info ATTRIBUTE_UNUSED,bfd * abfd,const char * name)856007c2a45Smiod add_archive_element (struct bfd_link_info *info ATTRIBUTE_UNUSED,
857007c2a45Smiod bfd *abfd,
858007c2a45Smiod const char *name)
8592159047fSniklas {
8602159047fSniklas lang_input_statement_type *input;
8612159047fSniklas
862007c2a45Smiod input = xmalloc (sizeof (lang_input_statement_type));
8632159047fSniklas input->filename = abfd->filename;
8642159047fSniklas input->local_sym_name = abfd->filename;
8652159047fSniklas input->the_bfd = abfd;
8662159047fSniklas input->asymbols = NULL;
8672159047fSniklas input->next = NULL;
868c074d1c9Sdrahn input->just_syms_flag = FALSE;
869c074d1c9Sdrahn input->loaded = FALSE;
870c074d1c9Sdrahn input->search_dirs_flag = FALSE;
8712159047fSniklas
8722159047fSniklas /* FIXME: The following fields are not set: header.next,
8732159047fSniklas header.type, closed, passive_position, symbol_count,
8740c6d0228Sniklas next_real_file, is_archive, target, real. This bit of code is
8750c6d0228Sniklas from the old decode_library_subfile function. I don't know
8760c6d0228Sniklas whether any of those fields matters. */
8772159047fSniklas
8782159047fSniklas ldlang_add_file (input);
8792159047fSniklas
880007c2a45Smiod if (config.map_file != NULL)
881191aa565Sniklas {
882c074d1c9Sdrahn static bfd_boolean header_printed;
883191aa565Sniklas struct bfd_link_hash_entry *h;
884191aa565Sniklas bfd *from;
885191aa565Sniklas int len;
886191aa565Sniklas
887c074d1c9Sdrahn h = bfd_link_hash_lookup (link_info.hash, name, FALSE, FALSE, TRUE);
888191aa565Sniklas
889191aa565Sniklas if (h == NULL)
890191aa565Sniklas from = NULL;
891191aa565Sniklas else
892191aa565Sniklas {
893191aa565Sniklas switch (h->type)
894191aa565Sniklas {
895191aa565Sniklas default:
896191aa565Sniklas from = NULL;
897191aa565Sniklas break;
898191aa565Sniklas
899191aa565Sniklas case bfd_link_hash_defined:
900191aa565Sniklas case bfd_link_hash_defweak:
901191aa565Sniklas from = h->u.def.section->owner;
902191aa565Sniklas break;
903191aa565Sniklas
904191aa565Sniklas case bfd_link_hash_undefined:
905191aa565Sniklas case bfd_link_hash_undefweak:
906191aa565Sniklas from = h->u.undef.abfd;
907191aa565Sniklas break;
908191aa565Sniklas
909191aa565Sniklas case bfd_link_hash_common:
910191aa565Sniklas from = h->u.c.p->section->owner;
911191aa565Sniklas break;
912191aa565Sniklas }
913191aa565Sniklas }
914191aa565Sniklas
915191aa565Sniklas if (! header_printed)
916191aa565Sniklas {
917191aa565Sniklas char buf[100];
918191aa565Sniklas
919c074d1c9Sdrahn sprintf (buf, _("Archive member included because of file (symbol)\n\n"));
920191aa565Sniklas minfo ("%s", buf);
921c074d1c9Sdrahn header_printed = TRUE;
922191aa565Sniklas }
923191aa565Sniklas
924191aa565Sniklas if (bfd_my_archive (abfd) == NULL)
925191aa565Sniklas {
926191aa565Sniklas minfo ("%s", bfd_get_filename (abfd));
927191aa565Sniklas len = strlen (bfd_get_filename (abfd));
928191aa565Sniklas }
929191aa565Sniklas else
930191aa565Sniklas {
931191aa565Sniklas minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)),
932191aa565Sniklas bfd_get_filename (abfd));
933191aa565Sniklas len = (strlen (bfd_get_filename (bfd_my_archive (abfd)))
934191aa565Sniklas + strlen (bfd_get_filename (abfd))
935191aa565Sniklas + 2);
936191aa565Sniklas }
937191aa565Sniklas
938191aa565Sniklas if (len >= 29)
939191aa565Sniklas {
940191aa565Sniklas print_nl ();
941191aa565Sniklas len = 0;
942191aa565Sniklas }
943191aa565Sniklas while (len < 30)
944191aa565Sniklas {
945191aa565Sniklas print_space ();
946191aa565Sniklas ++len;
947191aa565Sniklas }
948191aa565Sniklas
949191aa565Sniklas if (from != NULL)
950191aa565Sniklas minfo ("%B ", from);
951191aa565Sniklas if (h != NULL)
952191aa565Sniklas minfo ("(%T)\n", h->root.string);
953191aa565Sniklas else
954191aa565Sniklas minfo ("(%s)\n", name);
955191aa565Sniklas }
9562159047fSniklas
9572159047fSniklas if (trace_files || trace_file_tries)
9582159047fSniklas info_msg ("%I\n", input);
9592159047fSniklas
960c074d1c9Sdrahn return TRUE;
9612159047fSniklas }
9622159047fSniklas
9632159047fSniklas /* This is called when BFD has discovered a symbol which is defined
9642159047fSniklas multiple times. */
9652159047fSniklas
966c074d1c9Sdrahn static bfd_boolean
multiple_definition(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * name,bfd * obfd,asection * osec,bfd_vma oval,bfd * nbfd,asection * nsec,bfd_vma nval)967007c2a45Smiod multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED,
968007c2a45Smiod const char *name,
969007c2a45Smiod bfd *obfd,
970007c2a45Smiod asection *osec,
971007c2a45Smiod bfd_vma oval,
972007c2a45Smiod bfd *nbfd,
973007c2a45Smiod asection *nsec,
974007c2a45Smiod bfd_vma nval)
9752159047fSniklas {
976191aa565Sniklas /* If either section has the output_section field set to
977191aa565Sniklas bfd_abs_section_ptr, it means that the section is being
978191aa565Sniklas discarded, and this is not really a multiple definition at all.
979191aa565Sniklas FIXME: It would be cleaner to somehow ignore symbols defined in
980191aa565Sniklas sections which are being discarded. */
981191aa565Sniklas if ((osec->output_section != NULL
982b305b0f1Sespie && ! bfd_is_abs_section (osec)
983191aa565Sniklas && bfd_is_abs_section (osec->output_section))
984191aa565Sniklas || (nsec->output_section != NULL
985b305b0f1Sespie && ! bfd_is_abs_section (nsec)
986191aa565Sniklas && bfd_is_abs_section (nsec->output_section)))
987c074d1c9Sdrahn return TRUE;
988191aa565Sniklas
989b305b0f1Sespie einfo (_("%X%C: multiple definition of `%T'\n"),
9902159047fSniklas nbfd, nsec, nval, name);
991007c2a45Smiod if (obfd != NULL)
992b305b0f1Sespie einfo (_("%D: first defined here\n"), obfd, osec, oval);
993b55d4692Sfgsch
994b55d4692Sfgsch if (command_line.relax)
995b55d4692Sfgsch {
996b55d4692Sfgsch einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
997b55d4692Sfgsch command_line.relax = 0;
998b55d4692Sfgsch }
999b55d4692Sfgsch
1000c074d1c9Sdrahn return TRUE;
10012159047fSniklas }
10022159047fSniklas
10032159047fSniklas /* This is called when there is a definition of a common symbol, or
10042159047fSniklas when a common symbol is found for a symbol that is already defined,
10052159047fSniklas or when two common symbols are found. We only do something if
10062159047fSniklas -warn-common was used. */
10072159047fSniklas
1008c074d1c9Sdrahn 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,bfd * nbfd,enum bfd_link_hash_type ntype,bfd_vma nsize)1009007c2a45Smiod multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1010007c2a45Smiod const char *name,
1011007c2a45Smiod bfd *obfd,
1012007c2a45Smiod enum bfd_link_hash_type otype,
1013007c2a45Smiod bfd_vma osize,
1014007c2a45Smiod bfd *nbfd,
1015007c2a45Smiod enum bfd_link_hash_type ntype,
1016007c2a45Smiod bfd_vma nsize)
10172159047fSniklas {
10182159047fSniklas if (! config.warn_common)
1019c074d1c9Sdrahn return TRUE;
10202159047fSniklas
10212159047fSniklas if (ntype == bfd_link_hash_defined
10222159047fSniklas || ntype == bfd_link_hash_defweak
10232159047fSniklas || ntype == bfd_link_hash_indirect)
10242159047fSniklas {
10252159047fSniklas ASSERT (otype == bfd_link_hash_common);
1026b305b0f1Sespie einfo (_("%B: warning: definition of `%T' overriding common\n"),
10272159047fSniklas nbfd, name);
10282159047fSniklas if (obfd != NULL)
1029b305b0f1Sespie einfo (_("%B: warning: common is here\n"), obfd);
10302159047fSniklas }
10312159047fSniklas else if (otype == bfd_link_hash_defined
10322159047fSniklas || otype == bfd_link_hash_defweak
10332159047fSniklas || otype == bfd_link_hash_indirect)
10342159047fSniklas {
10352159047fSniklas ASSERT (ntype == bfd_link_hash_common);
1036b305b0f1Sespie einfo (_("%B: warning: common of `%T' overridden by definition\n"),
10372159047fSniklas nbfd, name);
10382159047fSniklas if (obfd != NULL)
1039b305b0f1Sespie einfo (_("%B: warning: defined here\n"), obfd);
10402159047fSniklas }
10412159047fSniklas else
10422159047fSniklas {
10432159047fSniklas ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common);
10442159047fSniklas if (osize > nsize)
10452159047fSniklas {
1046b305b0f1Sespie einfo (_("%B: warning: common of `%T' overridden by larger common\n"),
10472159047fSniklas nbfd, name);
10482159047fSniklas if (obfd != NULL)
1049b305b0f1Sespie einfo (_("%B: warning: larger common is here\n"), obfd);
10502159047fSniklas }
10512159047fSniklas else if (nsize > osize)
10522159047fSniklas {
1053b305b0f1Sespie einfo (_("%B: warning: common of `%T' overriding smaller common\n"),
10542159047fSniklas nbfd, name);
10552159047fSniklas if (obfd != NULL)
1056b305b0f1Sespie einfo (_("%B: warning: smaller common is here\n"), obfd);
10572159047fSniklas }
10582159047fSniklas else
10592159047fSniklas {
1060b305b0f1Sespie einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name);
10612159047fSniklas if (obfd != NULL)
1062b305b0f1Sespie einfo (_("%B: warning: previous common is here\n"), obfd);
10632159047fSniklas }
10642159047fSniklas }
10652159047fSniklas
1066c074d1c9Sdrahn return TRUE;
10672159047fSniklas }
10682159047fSniklas
10692159047fSniklas /* This is called when BFD has discovered a set element. H is the
10702159047fSniklas entry in the linker hash table for the set. SECTION and VALUE
10712159047fSniklas represent a value which should be added to the set. */
10722159047fSniklas
1073c074d1c9Sdrahn static bfd_boolean
add_to_set(struct bfd_link_info * info ATTRIBUTE_UNUSED,struct bfd_link_hash_entry * h,bfd_reloc_code_real_type reloc,bfd * abfd,asection * section,bfd_vma value)1074007c2a45Smiod add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1075007c2a45Smiod struct bfd_link_hash_entry *h,
1076007c2a45Smiod bfd_reloc_code_real_type reloc,
1077007c2a45Smiod bfd *abfd,
1078007c2a45Smiod asection *section,
1079007c2a45Smiod bfd_vma value)
10802159047fSniklas {
10812159047fSniklas if (config.warn_constructors)
1082b305b0f1Sespie einfo (_("%P: warning: global constructor %s used\n"),
10832159047fSniklas h->root.string);
10842159047fSniklas
10852159047fSniklas if (! config.build_constructors)
1086c074d1c9Sdrahn return TRUE;
10872159047fSniklas
1088007c2a45Smiod ldctor_add_set_entry (h, reloc, NULL, section, value);
10892159047fSniklas
10902159047fSniklas if (h->type == bfd_link_hash_new)
10912159047fSniklas {
10922159047fSniklas h->type = bfd_link_hash_undefined;
10932159047fSniklas h->u.undef.abfd = abfd;
10942159047fSniklas /* We don't call bfd_link_add_undef to add this to the list of
10952159047fSniklas undefined symbols because we are going to define it
10962159047fSniklas ourselves. */
10972159047fSniklas }
10982159047fSniklas
1099c074d1c9Sdrahn return TRUE;
11002159047fSniklas }
11012159047fSniklas
11022159047fSniklas /* This is called when BFD has discovered a constructor. This is only
11032159047fSniklas called for some object file formats--those which do not handle
11042159047fSniklas constructors in some more clever fashion. This is similar to
11052159047fSniklas adding an element to a set, but less general. */
11062159047fSniklas
1107c074d1c9Sdrahn static bfd_boolean
constructor_callback(struct bfd_link_info * info,bfd_boolean constructor,const char * name,bfd * abfd,asection * section,bfd_vma value)1108007c2a45Smiod constructor_callback (struct bfd_link_info *info,
1109007c2a45Smiod bfd_boolean constructor,
1110007c2a45Smiod const char *name,
1111007c2a45Smiod bfd *abfd,
1112007c2a45Smiod asection *section,
1113007c2a45Smiod bfd_vma value)
11142159047fSniklas {
11152159047fSniklas char *s;
11162159047fSniklas struct bfd_link_hash_entry *h;
11172159047fSniklas char set_name[1 + sizeof "__CTOR_LIST__"];
11182159047fSniklas
11192159047fSniklas if (config.warn_constructors)
1120b305b0f1Sespie einfo (_("%P: warning: global constructor %s used\n"), name);
11212159047fSniklas
11222159047fSniklas if (! config.build_constructors)
1123c074d1c9Sdrahn return TRUE;
11242159047fSniklas
11252159047fSniklas /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
11262159047fSniklas useful error message. */
1127191aa565Sniklas if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL
1128007c2a45Smiod && (link_info.relocatable
1129191aa565Sniklas || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
1130b305b0f1Sespie einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
11312159047fSniklas
11322159047fSniklas s = set_name;
11332159047fSniklas if (bfd_get_symbol_leading_char (abfd) != '\0')
11342159047fSniklas *s++ = bfd_get_symbol_leading_char (abfd);
11352159047fSniklas if (constructor)
11362159047fSniklas strcpy (s, "__CTOR_LIST__");
11372159047fSniklas else
11382159047fSniklas strcpy (s, "__DTOR_LIST__");
11392159047fSniklas
1140c074d1c9Sdrahn h = bfd_link_hash_lookup (info->hash, set_name, TRUE, TRUE, TRUE);
11412159047fSniklas if (h == (struct bfd_link_hash_entry *) NULL)
1142b305b0f1Sespie einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
11432159047fSniklas if (h->type == bfd_link_hash_new)
11442159047fSniklas {
11452159047fSniklas h->type = bfd_link_hash_undefined;
11462159047fSniklas h->u.undef.abfd = abfd;
11472159047fSniklas /* We don't call bfd_link_add_undef to add this to the list of
11482159047fSniklas undefined symbols because we are going to define it
11492159047fSniklas ourselves. */
11502159047fSniklas }
11512159047fSniklas
11522159047fSniklas ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value);
1153c074d1c9Sdrahn return TRUE;
11542159047fSniklas }
11552159047fSniklas
11562159047fSniklas /* A structure used by warning_callback to pass information through
11572159047fSniklas bfd_map_over_sections. */
11582159047fSniklas
1159c074d1c9Sdrahn struct warning_callback_info
1160c074d1c9Sdrahn {
1161c074d1c9Sdrahn bfd_boolean found;
11622159047fSniklas const char *warning;
11632159047fSniklas const char *symbol;
11642159047fSniklas asymbol **asymbols;
11652159047fSniklas };
11662159047fSniklas
11672159047fSniklas /* This is called when there is a reference to a warning symbol. */
11682159047fSniklas
1169c074d1c9Sdrahn static bfd_boolean
warning_callback(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * warning,const char * symbol,bfd * abfd,asection * section,bfd_vma address)1170007c2a45Smiod warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1171007c2a45Smiod const char *warning,
1172007c2a45Smiod const char *symbol,
1173007c2a45Smiod bfd *abfd,
1174007c2a45Smiod asection *section,
1175007c2a45Smiod bfd_vma address)
11762159047fSniklas {
1177191aa565Sniklas /* This is a hack to support warn_multiple_gp. FIXME: This should
1178191aa565Sniklas have a cleaner interface, but what? */
1179191aa565Sniklas if (! config.warn_multiple_gp
1180191aa565Sniklas && strcmp (warning, "using multiple gp values") == 0)
1181c074d1c9Sdrahn return TRUE;
1182191aa565Sniklas
11832159047fSniklas if (section != NULL)
11842159047fSniklas einfo ("%C: %s\n", abfd, section, address, warning);
11852159047fSniklas else if (abfd == NULL)
11862159047fSniklas einfo ("%P: %s\n", warning);
11872159047fSniklas else if (symbol == NULL)
11882159047fSniklas einfo ("%B: %s\n", abfd, warning);
11892159047fSniklas else
11902159047fSniklas {
11912159047fSniklas lang_input_statement_type *entry;
11922159047fSniklas asymbol **asymbols;
11932159047fSniklas struct warning_callback_info info;
11942159047fSniklas
11952159047fSniklas /* Look through the relocs to see if we can find a plausible
11962159047fSniklas address. */
11972159047fSniklas entry = (lang_input_statement_type *) abfd->usrdata;
11982159047fSniklas if (entry != NULL && entry->asymbols != NULL)
11992159047fSniklas asymbols = entry->asymbols;
12002159047fSniklas else
12012159047fSniklas {
12022159047fSniklas long symsize;
12032159047fSniklas long symbol_count;
12042159047fSniklas
12052159047fSniklas symsize = bfd_get_symtab_upper_bound (abfd);
12062159047fSniklas if (symsize < 0)
1207b305b0f1Sespie einfo (_("%B%F: could not read symbols: %E\n"), abfd);
1208007c2a45Smiod asymbols = xmalloc (symsize);
12092159047fSniklas symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
12102159047fSniklas if (symbol_count < 0)
1211b305b0f1Sespie einfo (_("%B%F: could not read symbols: %E\n"), abfd);
12122159047fSniklas if (entry != NULL)
12132159047fSniklas {
12142159047fSniklas entry->asymbols = asymbols;
12152159047fSniklas entry->symbol_count = symbol_count;
12162159047fSniklas }
12172159047fSniklas }
12182159047fSniklas
1219c074d1c9Sdrahn info.found = FALSE;
12202159047fSniklas info.warning = warning;
12212159047fSniklas info.symbol = symbol;
12222159047fSniklas info.asymbols = asymbols;
1223007c2a45Smiod bfd_map_over_sections (abfd, warning_find_reloc, &info);
12242159047fSniklas
12252159047fSniklas if (! info.found)
12262159047fSniklas einfo ("%B: %s\n", abfd, warning);
12270c6d0228Sniklas
12280c6d0228Sniklas if (entry == NULL)
12290c6d0228Sniklas free (asymbols);
12302159047fSniklas }
12312159047fSniklas
1232c074d1c9Sdrahn return TRUE;
12332159047fSniklas }
12342159047fSniklas
12352159047fSniklas /* This is called by warning_callback for each section. It checks the
12362159047fSniklas relocs of the section to see if it can find a reference to the
12372159047fSniklas symbol which triggered the warning. If it can, it uses the reloc
12382159047fSniklas to give an error message with a file and line number. */
12392159047fSniklas
12402159047fSniklas static void
warning_find_reloc(bfd * abfd,asection * sec,void * iarg)1241007c2a45Smiod warning_find_reloc (bfd *abfd, asection *sec, void *iarg)
12422159047fSniklas {
1243007c2a45Smiod struct warning_callback_info *info = iarg;
12442159047fSniklas long relsize;
12452159047fSniklas arelent **relpp;
12462159047fSniklas long relcount;
12472159047fSniklas arelent **p, **pend;
12482159047fSniklas
12492159047fSniklas if (info->found)
12502159047fSniklas return;
12512159047fSniklas
12522159047fSniklas relsize = bfd_get_reloc_upper_bound (abfd, sec);
12532159047fSniklas if (relsize < 0)
1254b305b0f1Sespie einfo (_("%B%F: could not read relocs: %E\n"), abfd);
12552159047fSniklas if (relsize == 0)
12562159047fSniklas return;
12572159047fSniklas
1258007c2a45Smiod relpp = xmalloc (relsize);
12592159047fSniklas relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
12602159047fSniklas if (relcount < 0)
1261b305b0f1Sespie einfo (_("%B%F: could not read relocs: %E\n"), abfd);
12622159047fSniklas
12632159047fSniklas p = relpp;
12642159047fSniklas pend = p + relcount;
12652159047fSniklas for (; p < pend && *p != NULL; p++)
12662159047fSniklas {
12672159047fSniklas arelent *q = *p;
12682159047fSniklas
12692159047fSniklas if (q->sym_ptr_ptr != NULL
12702159047fSniklas && *q->sym_ptr_ptr != NULL
12712159047fSniklas && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
12722159047fSniklas {
12732159047fSniklas /* We found a reloc for the symbol we are looking for. */
12742159047fSniklas einfo ("%C: %s\n", abfd, sec, q->address, info->warning);
1275c074d1c9Sdrahn info->found = TRUE;
12762159047fSniklas break;
12772159047fSniklas }
12782159047fSniklas }
12792159047fSniklas
12802159047fSniklas free (relpp);
12812159047fSniklas }
12822159047fSniklas
12832159047fSniklas /* This is called when an undefined symbol is found. */
12842159047fSniklas
1285c074d1c9Sdrahn static bfd_boolean
undefined_symbol(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * name,bfd * abfd,asection * section,bfd_vma address,bfd_boolean error)1286007c2a45Smiod undefined_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1287007c2a45Smiod const char *name,
1288007c2a45Smiod bfd *abfd,
1289007c2a45Smiod asection *section,
1290007c2a45Smiod bfd_vma address,
1291007c2a45Smiod bfd_boolean error)
12922159047fSniklas {
12932159047fSniklas static char *error_name;
12942159047fSniklas static unsigned int error_count;
12952159047fSniklas
12962159047fSniklas #define MAX_ERRORS_IN_A_ROW 5
12972159047fSniklas
12982159047fSniklas if (config.warn_once)
12992159047fSniklas {
13002159047fSniklas static struct bfd_hash_table *hash;
13012159047fSniklas
13022159047fSniklas /* Only warn once about a particular undefined symbol. */
13032159047fSniklas if (hash == NULL)
13042159047fSniklas {
1305007c2a45Smiod hash = xmalloc (sizeof (struct bfd_hash_table));
13062159047fSniklas if (! bfd_hash_table_init (hash, bfd_hash_newfunc))
1307b305b0f1Sespie einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
13082159047fSniklas }
13092159047fSniklas
1310c074d1c9Sdrahn if (bfd_hash_lookup (hash, name, FALSE, FALSE) != NULL)
1311c074d1c9Sdrahn return TRUE;
13122159047fSniklas
1313c074d1c9Sdrahn if (bfd_hash_lookup (hash, name, TRUE, TRUE) == NULL)
1314b305b0f1Sespie einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
13152159047fSniklas }
13162159047fSniklas
13172159047fSniklas /* We never print more than a reasonable number of errors in a row
13182159047fSniklas for a single symbol. */
1319007c2a45Smiod if (error_name != NULL
13202159047fSniklas && strcmp (name, error_name) == 0)
13212159047fSniklas ++error_count;
13222159047fSniklas else
13232159047fSniklas {
13242159047fSniklas error_count = 0;
1325007c2a45Smiod if (error_name != NULL)
13262159047fSniklas free (error_name);
1327b55d4692Sfgsch error_name = xstrdup (name);
13282159047fSniklas }
13292159047fSniklas
13302159047fSniklas if (section != NULL)
13312159047fSniklas {
13322159047fSniklas if (error_count < MAX_ERRORS_IN_A_ROW)
1333b305b0f1Sespie {
1334007c2a45Smiod if (error)
1335007c2a45Smiod einfo (_("%X%C: undefined reference to `%T'\n"),
13362159047fSniklas abfd, section, address, name);
1337007c2a45Smiod else
1338007c2a45Smiod einfo (_("%C: warning: undefined reference to `%T'\n"),
1339007c2a45Smiod abfd, section, address, name);
1340b305b0f1Sespie }
13412159047fSniklas else if (error_count == MAX_ERRORS_IN_A_ROW)
1342007c2a45Smiod {
1343007c2a45Smiod if (error)
1344007c2a45Smiod einfo (_("%X%D: more undefined references to `%T' follow\n"),
13452159047fSniklas abfd, section, address, name);
1346007c2a45Smiod else
1347007c2a45Smiod einfo (_("%D: warning: more undefined references to `%T' follow\n"),
1348007c2a45Smiod abfd, section, address, name);
1349007c2a45Smiod }
1350007c2a45Smiod else if (error)
1351007c2a45Smiod einfo ("%X");
13522159047fSniklas }
13532159047fSniklas else
13542159047fSniklas {
13552159047fSniklas if (error_count < MAX_ERRORS_IN_A_ROW)
1356b305b0f1Sespie {
1357007c2a45Smiod if (error)
1358007c2a45Smiod einfo (_("%X%B: undefined reference to `%T'\n"),
13592159047fSniklas abfd, name);
1360007c2a45Smiod else
1361007c2a45Smiod einfo (_("%B: warning: undefined reference to `%T'\n"),
1362007c2a45Smiod abfd, name);
1363b305b0f1Sespie }
13642159047fSniklas else if (error_count == MAX_ERRORS_IN_A_ROW)
1365007c2a45Smiod {
1366007c2a45Smiod if (error)
1367007c2a45Smiod einfo (_("%X%B: more undefined references to `%T' follow\n"),
13682159047fSniklas abfd, name);
1369007c2a45Smiod else
1370007c2a45Smiod einfo (_("%B: warning: more undefined references to `%T' follow\n"),
1371007c2a45Smiod abfd, name);
1372007c2a45Smiod }
1373007c2a45Smiod else if (error)
1374007c2a45Smiod einfo ("%X");
13752159047fSniklas }
13762159047fSniklas
1377c074d1c9Sdrahn return TRUE;
13782159047fSniklas }
13792159047fSniklas
1380007c2a45Smiod /* Counter to limit the number of relocation overflow error messages
1381007c2a45Smiod to print. Errors are printed as it is decremented. When it's
1382007c2a45Smiod called and the counter is zero, a final message is printed
1383007c2a45Smiod indicating more relocations were omitted. When it gets to -1, no
1384007c2a45Smiod such errors are printed. If it's initially set to a value less
1385007c2a45Smiod than -1, all such errors will be printed (--verbose does this). */
1386007c2a45Smiod
1387007c2a45Smiod int overflow_cutoff_limit = 10;
1388007c2a45Smiod
13892159047fSniklas /* This is called when a reloc overflows. */
13902159047fSniklas
1391c074d1c9Sdrahn static bfd_boolean
reloc_overflow(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * name,const char * reloc_name,bfd_vma addend,bfd * abfd,asection * section,bfd_vma address)1392007c2a45Smiod reloc_overflow (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1393007c2a45Smiod const char *name,
1394007c2a45Smiod const char *reloc_name,
1395007c2a45Smiod bfd_vma addend,
1396007c2a45Smiod bfd *abfd,
1397007c2a45Smiod asection *section,
1398007c2a45Smiod bfd_vma address)
13992159047fSniklas {
1400007c2a45Smiod if (overflow_cutoff_limit == -1)
1401007c2a45Smiod return TRUE;
1402007c2a45Smiod
1403007c2a45Smiod if (abfd == NULL)
1404b305b0f1Sespie einfo (_("%P%X: generated"));
14052159047fSniklas else
14062159047fSniklas einfo ("%X%C:", abfd, section, address);
1407007c2a45Smiod
1408007c2a45Smiod if (overflow_cutoff_limit >= 0
1409007c2a45Smiod && overflow_cutoff_limit-- == 0)
1410007c2a45Smiod {
1411007c2a45Smiod einfo (_(" additional relocation overflows omitted from the output\n"));
1412007c2a45Smiod return TRUE;
1413007c2a45Smiod }
1414007c2a45Smiod
1415b305b0f1Sespie einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name);
14162159047fSniklas if (addend != 0)
14172159047fSniklas einfo ("+%v", addend);
14182159047fSniklas einfo ("\n");
1419c074d1c9Sdrahn return TRUE;
14202159047fSniklas }
14212159047fSniklas
14222159047fSniklas /* This is called when a dangerous relocation is made. */
14232159047fSniklas
1424c074d1c9Sdrahn static bfd_boolean
reloc_dangerous(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * message,bfd * abfd,asection * section,bfd_vma address)1425007c2a45Smiod reloc_dangerous (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1426007c2a45Smiod const char *message,
1427007c2a45Smiod bfd *abfd,
1428007c2a45Smiod asection *section,
1429007c2a45Smiod bfd_vma address)
14302159047fSniklas {
1431007c2a45Smiod if (abfd == NULL)
1432b305b0f1Sespie einfo (_("%P%X: generated"));
14332159047fSniklas else
14342159047fSniklas einfo ("%X%C:", abfd, section, address);
1435b305b0f1Sespie einfo (_("dangerous relocation: %s\n"), message);
1436c074d1c9Sdrahn return TRUE;
14372159047fSniklas }
14382159047fSniklas
14392159047fSniklas /* This is called when a reloc is being generated attached to a symbol
14402159047fSniklas that is not being output. */
14412159047fSniklas
1442c074d1c9Sdrahn static bfd_boolean
unattached_reloc(struct bfd_link_info * info ATTRIBUTE_UNUSED,const char * name,bfd * abfd,asection * section,bfd_vma address)1443007c2a45Smiod unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
1444007c2a45Smiod const char *name,
1445007c2a45Smiod bfd *abfd,
1446007c2a45Smiod asection *section,
1447007c2a45Smiod bfd_vma address)
14482159047fSniklas {
1449007c2a45Smiod if (abfd == NULL)
1450b305b0f1Sespie einfo (_("%P%X: generated"));
14512159047fSniklas else
14522159047fSniklas einfo ("%X%C:", abfd, section, address);
1453b305b0f1Sespie einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name);
1454c074d1c9Sdrahn return TRUE;
14552159047fSniklas }
14562159047fSniklas
1457191aa565Sniklas /* This is called if link_info.notice_all is set, or when a symbol in
1458191aa565Sniklas link_info.notice_hash is found. Symbols are put in notice_hash
1459191aa565Sniklas using the -y option. */
14602159047fSniklas
1461c074d1c9Sdrahn static bfd_boolean
notice(struct bfd_link_info * info,const char * name,bfd * abfd,asection * section,bfd_vma value)1462007c2a45Smiod notice (struct bfd_link_info *info,
1463007c2a45Smiod const char *name,
1464007c2a45Smiod bfd *abfd,
1465007c2a45Smiod asection *section,
1466007c2a45Smiod bfd_vma value)
14672159047fSniklas {
1468191aa565Sniklas if (! info->notice_all
1469191aa565Sniklas || (info->notice_hash != NULL
1470c074d1c9Sdrahn && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
1471b305b0f1Sespie {
1472b305b0f1Sespie if (bfd_is_und_section (section))
1473b305b0f1Sespie einfo ("%B: reference to %s\n", abfd, name);
1474b305b0f1Sespie else
1475b305b0f1Sespie einfo ("%B: definition of %s\n", abfd, name);
1476b305b0f1Sespie }
1477191aa565Sniklas
14780c6d0228Sniklas if (command_line.cref || nocrossref_list != NULL)
1479191aa565Sniklas add_cref (name, abfd, section, value);
1480191aa565Sniklas
1481c074d1c9Sdrahn return TRUE;
14822159047fSniklas }
1483