xref: /openbsd-src/gnu/usr.bin/binutils/ld/ldmain.c (revision 2d6de53b6832b1a63b46fdbe0f539ec82f5350ac)
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