ldmain.c revision 77298
133965Sjdp/* Main program of GNU linker.
261843Sobrien   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
360484Sobrien   Free Software Foundation, Inc.
433965Sjdp   Written by Steve Chamberlain steve@cygnus.com
533965Sjdp
633965SjdpThis file is part of GLD, the Gnu Linker.
733965Sjdp
833965SjdpGLD is free software; you can redistribute it and/or modify
933965Sjdpit under the terms of the GNU General Public License as published by
1033965Sjdpthe Free Software Foundation; either version 2, or (at your option)
1133965Sjdpany later version.
1233965Sjdp
1333965SjdpGLD is distributed in the hope that it will be useful,
1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965SjdpGNU General Public License for more details.
1733965Sjdp
1833965SjdpYou should have received a copy of the GNU General Public License
1933965Sjdpalong with GLD; see the file COPYING.  If not, write to the Free
2033965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2133965Sjdp02111-1307, USA.  */
2233965Sjdp
2333965Sjdp#include "bfd.h"
2433965Sjdp#include "sysdep.h"
2533965Sjdp#include <stdio.h>
2633965Sjdp#include <ctype.h>
2733965Sjdp#include "libiberty.h"
2833965Sjdp#include "progress.h"
2933965Sjdp#include "bfdlink.h"
3061843Sobrien#include "filenames.h"
3133965Sjdp
3233965Sjdp#include "ld.h"
3333965Sjdp#include "ldmain.h"
3433965Sjdp#include "ldmisc.h"
3533965Sjdp#include "ldwrite.h"
3633965Sjdp#include "ldgram.h"
3733965Sjdp#include "ldexp.h"
3833965Sjdp#include "ldlang.h"
3933965Sjdp#include "ldlex.h"
4033965Sjdp#include "ldfile.h"
4177298Sobrien#include "ldemul.h"
4233965Sjdp#include "ldctor.h"
4333965Sjdp
4477298Sobrien/* Somewhere above, sys/stat.h got included . . . .  */
4533965Sjdp#if !defined(S_ISDIR) && defined(S_IFDIR)
4633965Sjdp#define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
4733965Sjdp#endif
4833965Sjdp
4933965Sjdp#include <string.h>
5033965Sjdp
5133965Sjdp#ifdef HAVE_SBRK
5233965Sjdp#ifdef NEED_DECLARATION_SBRK
5333965Sjdpextern PTR sbrk ();
5433965Sjdp#endif
5533965Sjdp#endif
5633965Sjdp
5733965Sjdpstatic char *get_emulation PARAMS ((int, char **));
5833965Sjdpstatic void set_scripts_dir PARAMS ((void));
5933965Sjdp
6033965Sjdp/* EXPORTS */
6133965Sjdp
6233965Sjdpchar *default_target;
6333965Sjdpconst char *output_filename = "a.out";
6433965Sjdp
6533965Sjdp/* Name this program was invoked by.  */
6633965Sjdpchar *program_name;
6733965Sjdp
6877298Sobrien/* The file that we're creating.  */
6933965Sjdpbfd *output_bfd = 0;
7033965Sjdp
7133965Sjdp/* Set by -G argument, for MIPS ECOFF target.  */
7233965Sjdpint g_switch_value = 8;
7333965Sjdp
7433965Sjdp/* Nonzero means print names of input files as processed.  */
7533965Sjdpboolean trace_files;
7633965Sjdp
7733965Sjdp/* Nonzero means same, but note open failures, too.  */
7833965Sjdpboolean trace_file_tries;
7933965Sjdp
8033965Sjdp/* Nonzero means version number was printed, so exit successfully
8133965Sjdp   instead of complaining if no input files are given.  */
8233965Sjdpboolean version_printed;
8333965Sjdp
8433965Sjdp/* Nonzero means link in every member of an archive.  */
8533965Sjdpboolean whole_archive;
8633965Sjdp
8760484Sobrien/* True if we should demangle symbol names.  */
8860484Sobrienboolean demangling;
8960484Sobrien
9033965Sjdpargs_type command_line;
9133965Sjdp
9233965Sjdpld_config_type config;
9333965Sjdp
9433965Sjdpstatic void remove_output PARAMS ((void));
9533965Sjdpstatic boolean check_for_scripts_dir PARAMS ((char *dir));
9633965Sjdpstatic boolean add_archive_element PARAMS ((struct bfd_link_info *, bfd *,
9733965Sjdp					    const char *));
9833965Sjdpstatic boolean multiple_definition PARAMS ((struct bfd_link_info *,
9933965Sjdp					    const char *,
10033965Sjdp					    bfd *, asection *, bfd_vma,
10133965Sjdp					    bfd *, asection *, bfd_vma));
10233965Sjdpstatic boolean multiple_common PARAMS ((struct bfd_link_info *,
10333965Sjdp					const char *, bfd *,
10433965Sjdp					enum bfd_link_hash_type, bfd_vma,
10533965Sjdp					bfd *, enum bfd_link_hash_type,
10633965Sjdp					bfd_vma));
10733965Sjdpstatic boolean add_to_set PARAMS ((struct bfd_link_info *,
10833965Sjdp				   struct bfd_link_hash_entry *,
10933965Sjdp				   bfd_reloc_code_real_type,
11033965Sjdp				   bfd *, asection *, bfd_vma));
11133965Sjdpstatic boolean constructor_callback PARAMS ((struct bfd_link_info *,
11233965Sjdp					     boolean constructor,
11333965Sjdp					     const char *name,
11433965Sjdp					     bfd *, asection *, bfd_vma));
11533965Sjdpstatic boolean warning_callback PARAMS ((struct bfd_link_info *,
11633965Sjdp					 const char *, const char *, bfd *,
11733965Sjdp					 asection *, bfd_vma));
11833965Sjdpstatic void warning_find_reloc PARAMS ((bfd *, asection *, PTR));
11933965Sjdpstatic boolean undefined_symbol PARAMS ((struct bfd_link_info *,
12033965Sjdp					 const char *, bfd *,
12160484Sobrien					 asection *, bfd_vma, boolean));
12233965Sjdpstatic boolean reloc_overflow PARAMS ((struct bfd_link_info *, const char *,
12333965Sjdp				       const char *, bfd_vma,
12433965Sjdp				       bfd *, asection *, bfd_vma));
12533965Sjdpstatic boolean reloc_dangerous PARAMS ((struct bfd_link_info *, const char *,
12633965Sjdp					bfd *, asection *, bfd_vma));
12733965Sjdpstatic boolean unattached_reloc PARAMS ((struct bfd_link_info *,
12833965Sjdp					 const char *, bfd *, asection *,
12933965Sjdp					 bfd_vma));
13033965Sjdpstatic boolean notice PARAMS ((struct bfd_link_info *, const char *,
13133965Sjdp			       bfd *, asection *, bfd_vma));
13233965Sjdp
13377298Sobrienstatic struct bfd_link_callbacks link_callbacks = {
13433965Sjdp  add_archive_element,
13533965Sjdp  multiple_definition,
13633965Sjdp  multiple_common,
13733965Sjdp  add_to_set,
13833965Sjdp  constructor_callback,
13933965Sjdp  warning_callback,
14033965Sjdp  undefined_symbol,
14133965Sjdp  reloc_overflow,
14233965Sjdp  reloc_dangerous,
14333965Sjdp  unattached_reloc,
14433965Sjdp  notice
14533965Sjdp};
14633965Sjdp
14733965Sjdpstruct bfd_link_info link_info;
14833965Sjdp
14933965Sjdpstatic void
15033965Sjdpremove_output ()
15133965Sjdp{
15277298Sobrien  if (output_filename)
15333965Sjdp    {
15433965Sjdp      if (output_bfd && output_bfd->iostream)
15577298Sobrien	fclose ((FILE *) (output_bfd->iostream));
15633965Sjdp      if (delete_output_file_on_failure)
15733965Sjdp	unlink (output_filename);
15833965Sjdp    }
15933965Sjdp}
16033965Sjdp
16133965Sjdpint
16233965Sjdpmain (argc, argv)
16333965Sjdp     int argc;
16433965Sjdp     char **argv;
16533965Sjdp{
16633965Sjdp  char *emulation;
16733965Sjdp  long start_time = get_run_time ();
16833965Sjdp
16960484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
17060484Sobrien  setlocale (LC_MESSAGES, "");
17160484Sobrien#endif
17260484Sobrien  bindtextdomain (PACKAGE, LOCALEDIR);
17360484Sobrien  textdomain (PACKAGE);
17460484Sobrien
17533965Sjdp  program_name = argv[0];
17633965Sjdp  xmalloc_set_program_name (program_name);
17733965Sjdp
17833965Sjdp  START_PROGRESS (program_name, 0);
17933965Sjdp
18033965Sjdp  bfd_init ();
18133965Sjdp
18233965Sjdp  bfd_set_error_program_name (program_name);
18333965Sjdp
18433965Sjdp  xatexit (remove_output);
18533965Sjdp
18633965Sjdp  /* Set the default BFD target based on the configured target.  Doing
18733965Sjdp     this permits the linker to be configured for a particular target,
18833965Sjdp     and linked against a shared BFD library which was configured for
18933965Sjdp     a different target.  The macro TARGET is defined by Makefile.  */
19033965Sjdp  if (! bfd_set_default_target (TARGET))
19133965Sjdp    {
19260484Sobrien      einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
19333965Sjdp      xexit (1);
19433965Sjdp    }
19533965Sjdp
19633965Sjdp  /* Initialize the data about options.  */
19733965Sjdp  trace_files = trace_file_tries = version_printed = false;
19833965Sjdp  whole_archive = false;
19933965Sjdp  config.build_constructors = true;
20033965Sjdp  config.dynamic_link = false;
20160484Sobrien  config.has_shared = false;
20277298Sobrien  config.split_by_reloc = (unsigned) -1;
20377298Sobrien  config.split_by_file = (bfd_size_type) -1;
20433965Sjdp  command_line.force_common_definition = false;
20533965Sjdp  command_line.interpreter = NULL;
20633965Sjdp  command_line.rpath = NULL;
20738889Sjdp  command_line.warn_mismatch = true;
20860484Sobrien  command_line.check_section_addresses = true;
20933965Sjdp
21060484Sobrien  /* We initialize DEMANGLING based on the environment variable
21160484Sobrien     COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
21260484Sobrien     output of the linker, unless COLLECT_NO_DEMANGLE is set in the
21360484Sobrien     environment.  Acting the same way here lets us provide the same
21460484Sobrien     interface by default.  */
21560484Sobrien  demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;
21660484Sobrien
21733965Sjdp  link_info.callbacks = &link_callbacks;
21833965Sjdp  link_info.relocateable = false;
21977298Sobrien  link_info.emitrelocations = false;
22033965Sjdp  link_info.shared = false;
22133965Sjdp  link_info.symbolic = false;
22233965Sjdp  link_info.static_link = false;
22333965Sjdp  link_info.traditional_format = false;
22460484Sobrien  link_info.optimize = false;
22560484Sobrien  link_info.no_undefined = false;
22677298Sobrien  link_info.allow_shlib_undefined = false;
22733965Sjdp  link_info.strip = strip_none;
22833965Sjdp  link_info.discard = discard_none;
22933965Sjdp  link_info.keep_memory = true;
23033965Sjdp  link_info.input_bfds = NULL;
23133965Sjdp  link_info.create_object_symbols_section = NULL;
23233965Sjdp  link_info.hash = NULL;
23333965Sjdp  link_info.keep_hash = NULL;
23433965Sjdp  link_info.notice_all = false;
23533965Sjdp  link_info.notice_hash = NULL;
23633965Sjdp  link_info.wrap_hash = NULL;
23760484Sobrien  link_info.mpc860c0 = 0;
23860484Sobrien  /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
23960484Sobrien     and _fini symbols.  We are compatible.  */
24060484Sobrien  link_info.init_function = "_init";
24160484Sobrien  link_info.fini_function = "_fini";
24277298Sobrien  link_info.new_dtags = false;
24377298Sobrien  link_info.flags = (bfd_vma) 0;
24477298Sobrien  link_info.flags_1 = (bfd_vma) 0;
24560484Sobrien
24633965Sjdp  ldfile_add_arch ("");
24733965Sjdp
24833965Sjdp  config.make_executable = true;
24933965Sjdp  force_make_executable = false;
25033965Sjdp  config.magic_demand_paged = true;
25133965Sjdp  config.text_read_only = true;
25233965Sjdp
25333965Sjdp  emulation = get_emulation (argc, argv);
25433965Sjdp  ldemul_choose_mode (emulation);
25533965Sjdp  default_target = ldemul_choose_target ();
25633965Sjdp  lang_init ();
25733965Sjdp  ldemul_before_parse ();
25833965Sjdp  lang_has_input_file = false;
25933965Sjdp  parse_args (argc, argv);
26033965Sjdp
26133965Sjdp  ldemul_set_symbols ();
26233965Sjdp
26333965Sjdp  if (link_info.relocateable)
26433965Sjdp    {
26560484Sobrien      if (command_line.gc_sections)
26660484Sobrien	einfo ("%P%F: --gc-sections and -r may not be used together\n");
26760484Sobrien      if (link_info.mpc860c0)
26860484Sobrien	einfo (_("%P%F: -r and --mpc860c0 may not be used together\n"));
26960484Sobrien      else if (command_line.relax)
27060484Sobrien	einfo (_("%P%F: --relax and -r may not be used together\n"));
27133965Sjdp      if (link_info.shared)
27260484Sobrien	einfo (_("%P%F: -r and -shared may not be used together\n"));
27333965Sjdp    }
27433965Sjdp
27533965Sjdp  /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I
27633965Sjdp     don't see how else this can be handled, since in this case we
27733965Sjdp     must preserve all externally visible symbols.  */
27833965Sjdp  if (link_info.relocateable && link_info.strip == strip_all)
27933965Sjdp    {
28033965Sjdp      link_info.strip = strip_debugger;
28133965Sjdp      if (link_info.discard == discard_none)
28233965Sjdp	link_info.discard = discard_all;
28333965Sjdp    }
28433965Sjdp
28533965Sjdp  /* This essentially adds another -L directory so this must be done after
28633965Sjdp     the -L's in argv have been processed.  */
28733965Sjdp  set_scripts_dir ();
28833965Sjdp
28933965Sjdp  if (had_script == false)
29033965Sjdp    {
29133965Sjdp      /* Read the emulation's appropriate default script.  */
29233965Sjdp      int isfile;
29333965Sjdp      char *s = ldemul_get_script (&isfile);
29433965Sjdp
29533965Sjdp      if (isfile)
29633965Sjdp	ldfile_open_command_file (s);
29733965Sjdp      else
29833965Sjdp	{
29933965Sjdp	  if (trace_file_tries)
30033965Sjdp	    {
30160484Sobrien	      info_msg (_("using internal linker script:\n"));
30233965Sjdp	      info_msg ("==================================================\n");
30333965Sjdp	      info_msg (s);
30433965Sjdp	      info_msg ("\n==================================================\n");
30533965Sjdp	    }
30633965Sjdp	  lex_string = s;
30733965Sjdp	  lex_redirect (s);
30833965Sjdp	}
30933965Sjdp      parser_input = input_script;
31033965Sjdp      yyparse ();
31133965Sjdp      lex_string = NULL;
31233965Sjdp    }
31333965Sjdp
31433965Sjdp  lang_final ();
31533965Sjdp
31633965Sjdp  if (lang_has_input_file == false)
31733965Sjdp    {
31833965Sjdp      if (version_printed)
31933965Sjdp	xexit (0);
32060484Sobrien      einfo (_("%P%F: no input files\n"));
32133965Sjdp    }
32233965Sjdp
32333965Sjdp  if (trace_files)
32433965Sjdp    {
32560484Sobrien      info_msg (_("%P: mode %s\n"), emulation);
32633965Sjdp    }
32733965Sjdp
32833965Sjdp  ldemul_after_parse ();
32933965Sjdp
33033965Sjdp  if (config.map_filename)
33133965Sjdp    {
33233965Sjdp      if (strcmp (config.map_filename, "-") == 0)
33333965Sjdp	{
33433965Sjdp	  config.map_file = stdout;
33533965Sjdp	}
33633965Sjdp      else
33733965Sjdp	{
33833965Sjdp	  config.map_file = fopen (config.map_filename, FOPEN_WT);
33933965Sjdp	  if (config.map_file == (FILE *) NULL)
34033965Sjdp	    {
34133965Sjdp	      bfd_set_error (bfd_error_system_call);
34260484Sobrien	      einfo (_("%P%F: cannot open map file %s: %E\n"),
34333965Sjdp		     config.map_filename);
34433965Sjdp	    }
34533965Sjdp	}
34633965Sjdp    }
34733965Sjdp
34833965Sjdp  lang_process ();
34933965Sjdp
35033965Sjdp  /* Print error messages for any missing symbols, for any warning
35177298Sobrien     symbols, and possibly multiple definitions.  */
35233965Sjdp
35377298Sobrien  if (! link_info.relocateable)
35433965Sjdp    {
35577298Sobrien      /* Look for a text section and switch the readonly attribute in it.  */
35633965Sjdp      asection *found = bfd_get_section_by_name (output_bfd, ".text");
35733965Sjdp
35833965Sjdp      if (found != (asection *) NULL)
35933965Sjdp	{
36077298Sobrien	  if (config.text_read_only)
36177298Sobrien	    found->flags |= SEC_READONLY;
36277298Sobrien	  else
36377298Sobrien	    found->flags &= ~SEC_READONLY;
36433965Sjdp	}
36533965Sjdp    }
36633965Sjdp
36733965Sjdp  if (link_info.relocateable)
36833965Sjdp    output_bfd->flags &= ~EXEC_P;
36933965Sjdp  else
37033965Sjdp    output_bfd->flags |= EXEC_P;
37133965Sjdp
37233965Sjdp  ldwrite ();
37333965Sjdp
37433965Sjdp  if (config.map_file != NULL)
37533965Sjdp    lang_map ();
37633965Sjdp  if (command_line.cref)
37733965Sjdp    output_cref (config.map_file != NULL ? config.map_file : stdout);
37833965Sjdp  if (nocrossref_list != NULL)
37933965Sjdp    check_nocrossrefs ();
38033965Sjdp
38133965Sjdp  /* Even if we're producing relocateable output, some non-fatal errors should
38233965Sjdp     be reported in the exit status.  (What non-fatal errors, if any, do we
38333965Sjdp     want to ignore for relocateable output?)  */
38433965Sjdp
38533965Sjdp  if (config.make_executable == false && force_make_executable == false)
38633965Sjdp    {
38733965Sjdp      if (trace_files == true)
38833965Sjdp	{
38960484Sobrien	  einfo (_("%P: link errors found, deleting executable `%s'\n"),
39033965Sjdp		 output_filename);
39133965Sjdp	}
39233965Sjdp
39333965Sjdp      /* The file will be removed by remove_output.  */
39433965Sjdp
39533965Sjdp      xexit (1);
39633965Sjdp    }
39733965Sjdp  else
39833965Sjdp    {
39933965Sjdp      if (! bfd_close (output_bfd))
40060484Sobrien	einfo (_("%F%B: final close failed: %E\n"), output_bfd);
40133965Sjdp
40233965Sjdp      /* If the --force-exe-suffix is enabled, and we're making an
40377298Sobrien	 executable file and it doesn't end in .exe, copy it to one
40477298Sobrien	 which does.  */
40533965Sjdp      if (! link_info.relocateable && command_line.force_exe_suffix)
40633965Sjdp	{
40733965Sjdp	  int len = strlen (output_filename);
40877298Sobrien	  if (len < 4
40933965Sjdp	      || (strcasecmp (output_filename + len - 4, ".exe") != 0
41033965Sjdp		  && strcasecmp (output_filename + len - 4, ".dll") != 0))
41133965Sjdp	    {
41233965Sjdp	      FILE *src;
41333965Sjdp	      FILE *dst;
41433965Sjdp	      const int bsize = 4096;
41533965Sjdp	      char *buf = xmalloc (bsize);
41633965Sjdp	      int l;
41733965Sjdp	      char *dst_name = xmalloc (len + 5);
41833965Sjdp	      strcpy (dst_name, output_filename);
41933965Sjdp	      strcat (dst_name, ".exe");
42033965Sjdp	      src = fopen (output_filename, FOPEN_RB);
42133965Sjdp	      dst = fopen (dst_name, FOPEN_WB);
42233965Sjdp
42333965Sjdp	      if (!src)
42460484Sobrien		einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename);
42533965Sjdp	      if (!dst)
42660484Sobrien		einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name);
42733965Sjdp	      while ((l = fread (buf, 1, bsize, src)) > 0)
42833965Sjdp		{
42933965Sjdp		  int done = fwrite (buf, 1, l, dst);
43033965Sjdp		  if (done != l)
43133965Sjdp		    {
43260484Sobrien		      einfo (_("%P: Error writing file `%s'\n"), dst_name);
43333965Sjdp		    }
43433965Sjdp		}
43533965Sjdp	      fclose (src);
43633965Sjdp	      if (fclose (dst) == EOF)
43733965Sjdp		{
43860484Sobrien		  einfo (_("%P: Error closing file `%s'\n"), dst_name);
43933965Sjdp		}
44033965Sjdp	      free (dst_name);
44133965Sjdp	      free (buf);
44233965Sjdp	    }
44333965Sjdp	}
44433965Sjdp    }
44533965Sjdp
44633965Sjdp  END_PROGRESS (program_name);
44733965Sjdp
44833965Sjdp  if (config.stats)
44933965Sjdp    {
45033965Sjdp#ifdef HAVE_SBRK
45133965Sjdp      char *lim = (char *) sbrk (0);
45233965Sjdp#endif
45333965Sjdp      long run_time = get_run_time () - start_time;
45433965Sjdp
45560484Sobrien      fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
45633965Sjdp	       program_name, run_time / 1000000, run_time % 1000000);
45733965Sjdp#ifdef HAVE_SBRK
45860484Sobrien      fprintf (stderr, _("%s: data size %ld\n"), program_name,
45933965Sjdp	       (long) (lim - (char *) &environ));
46033965Sjdp#endif
46133965Sjdp    }
46233965Sjdp
46333965Sjdp  /* Prevent remove_output from doing anything, after a successful link.  */
46433965Sjdp  output_filename = NULL;
46533965Sjdp
46633965Sjdp  xexit (0);
46733965Sjdp  return 0;
46833965Sjdp}
46933965Sjdp
47033965Sjdp/* We need to find any explicitly given emulation in order to initialize the
47133965Sjdp   state that's needed by the lex&yacc argument parser (parse_args).  */
47233965Sjdp
47333965Sjdpstatic char *
47433965Sjdpget_emulation (argc, argv)
47533965Sjdp     int argc;
47633965Sjdp     char **argv;
47733965Sjdp{
47833965Sjdp  char *emulation;
47933965Sjdp  int i;
48033965Sjdp
48133965Sjdp  emulation = getenv (EMULATION_ENVIRON);
48233965Sjdp  if (emulation == NULL)
48333965Sjdp    emulation = DEFAULT_EMULATION;
48433965Sjdp
48533965Sjdp  for (i = 1; i < argc; i++)
48633965Sjdp    {
48733965Sjdp      if (!strncmp (argv[i], "-m", 2))
48833965Sjdp	{
48933965Sjdp	  if (argv[i][2] == '\0')
49033965Sjdp	    {
49133965Sjdp	      /* -m EMUL */
49233965Sjdp	      if (i < argc - 1)
49333965Sjdp		{
49433965Sjdp		  emulation = argv[i + 1];
49533965Sjdp		  i++;
49633965Sjdp		}
49733965Sjdp	      else
49833965Sjdp		{
49977298Sobrien		  einfo (_("%P%F: missing argument to -m\n"));
50033965Sjdp		}
50133965Sjdp	    }
50233965Sjdp	  else if (strcmp (argv[i], "-mips1") == 0
50333965Sjdp		   || strcmp (argv[i], "-mips2") == 0
50433965Sjdp		   || strcmp (argv[i], "-mips3") == 0
50533965Sjdp		   || strcmp (argv[i], "-mips4") == 0)
50633965Sjdp	    {
50733965Sjdp	      /* FIXME: The arguments -mips1, -mips2 and -mips3 are
50833965Sjdp		 passed to the linker by some MIPS compilers.  They
50933965Sjdp		 generally tell the linker to use a slightly different
51033965Sjdp		 library path.  Perhaps someday these should be
51133965Sjdp		 implemented as emulations; until then, we just ignore
51233965Sjdp		 the arguments and hope that nobody ever creates
51333965Sjdp		 emulations named ips1, ips2 or ips3.  */
51433965Sjdp	    }
51533965Sjdp	  else if (strcmp (argv[i], "-m486") == 0)
51633965Sjdp	    {
51733965Sjdp	      /* FIXME: The argument -m486 is passed to the linker on
51833965Sjdp		 some Linux systems.  Hope that nobody creates an
51933965Sjdp		 emulation named 486.  */
52033965Sjdp	    }
52133965Sjdp	  else
52233965Sjdp	    {
52333965Sjdp	      /* -mEMUL */
52433965Sjdp	      emulation = &argv[i][2];
52533965Sjdp	    }
52633965Sjdp	}
52733965Sjdp    }
52833965Sjdp
52933965Sjdp  return emulation;
53033965Sjdp}
53133965Sjdp
53233965Sjdp/* If directory DIR contains an "ldscripts" subdirectory,
53333965Sjdp   add DIR to the library search path and return true,
53433965Sjdp   else return false.  */
53533965Sjdp
53633965Sjdpstatic boolean
53733965Sjdpcheck_for_scripts_dir (dir)
53833965Sjdp     char *dir;
53933965Sjdp{
54033965Sjdp  size_t dirlen;
54133965Sjdp  char *buf;
54233965Sjdp  struct stat s;
54333965Sjdp  boolean res;
54433965Sjdp
54533965Sjdp  dirlen = strlen (dir);
54633965Sjdp  /* sizeof counts the terminating NUL.  */
54777298Sobrien  buf = (char *) xmalloc (dirlen + sizeof ("/ldscripts"));
54833965Sjdp  sprintf (buf, "%s/ldscripts", dir);
54933965Sjdp
55033965Sjdp  res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
55133965Sjdp  free (buf);
55233965Sjdp  if (res)
55333965Sjdp    ldfile_add_library_path (dir, false);
55433965Sjdp  return res;
55533965Sjdp}
55633965Sjdp
55733965Sjdp/* Set the default directory for finding script files.
55833965Sjdp   Libraries will be searched for here too, but that's ok.
55933965Sjdp   We look for the "ldscripts" directory in:
56033965Sjdp
56133965Sjdp   SCRIPTDIR (passed from Makefile)
56233965Sjdp   the dir where this program is (for using it from the build tree)
56333965Sjdp   the dir where this program is/../lib (for installing the tool suite elsewhere) */
56433965Sjdp
56533965Sjdpstatic void
56633965Sjdpset_scripts_dir ()
56733965Sjdp{
56833965Sjdp  char *end, *dir;
56933965Sjdp  size_t dirlen;
57033965Sjdp
57133965Sjdp  if (check_for_scripts_dir (SCRIPTDIR))
57277298Sobrien    /* We've been installed normally.  */
57377298Sobrien    return;
57433965Sjdp
57533965Sjdp  /* Look for "ldscripts" in the dir where our binary is.  */
57633965Sjdp  end = strrchr (program_name, '/');
57761843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM
57861843Sobrien  {
57961843Sobrien    /* We could have \foo\bar, or /foo\bar.  */
58061843Sobrien    char *bslash = strrchr (program_name, '\\');
58177298Sobrien    if (end == NULL || (bslash != NULL && bslash > end))
58261843Sobrien      end = bslash;
58361843Sobrien  }
58461843Sobrien#endif
58533965Sjdp
58633965Sjdp  if (end == NULL)
58733965Sjdp    {
58833965Sjdp      /* Don't look for ldscripts in the current directory.  There is
58933965Sjdp         too much potential for confusion.  */
59033965Sjdp      return;
59133965Sjdp    }
59233965Sjdp
59333965Sjdp  dirlen = end - program_name;
59433965Sjdp  /* Make a copy of program_name in dir.
59533965Sjdp     Leave room for later "/../lib".  */
59633965Sjdp  dir = (char *) xmalloc (dirlen + 8);
59733965Sjdp  strncpy (dir, program_name, dirlen);
59833965Sjdp  dir[dirlen] = '\0';
59933965Sjdp
60033965Sjdp  if (check_for_scripts_dir (dir))
60177298Sobrien    /* Don't free dir.  */
60277298Sobrien    return;
60333965Sjdp
60433965Sjdp  /* Look for "ldscripts" in <the dir where our binary is>/../lib.  */
60533965Sjdp  strcpy (dir + dirlen, "/../lib");
60633965Sjdp  if (check_for_scripts_dir (dir))
60733965Sjdp    return;
60833965Sjdp
60977298Sobrien  /* Well, we tried.  */
61077298Sobrien  free (dir);
61133965Sjdp}
61233965Sjdp
61333965Sjdpvoid
61433965Sjdpadd_ysym (name)
61533965Sjdp     const char *name;
61633965Sjdp{
61733965Sjdp  if (link_info.notice_hash == (struct bfd_hash_table *) NULL)
61833965Sjdp    {
61933965Sjdp      link_info.notice_hash = ((struct bfd_hash_table *)
62033965Sjdp			       xmalloc (sizeof (struct bfd_hash_table)));
62133965Sjdp      if (! bfd_hash_table_init_n (link_info.notice_hash,
62233965Sjdp				   bfd_hash_newfunc,
62333965Sjdp				   61))
62460484Sobrien	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
62577298Sobrien    }
62633965Sjdp
62733965Sjdp  if (bfd_hash_lookup (link_info.notice_hash, name, true, true)
62833965Sjdp      == (struct bfd_hash_entry *) NULL)
62960484Sobrien    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
63033965Sjdp}
63133965Sjdp
63233965Sjdp/* Record a symbol to be wrapped, from the --wrap option.  */
63333965Sjdp
63433965Sjdpvoid
63533965Sjdpadd_wrap (name)
63633965Sjdp     const char *name;
63733965Sjdp{
63833965Sjdp  if (link_info.wrap_hash == NULL)
63933965Sjdp    {
64033965Sjdp      link_info.wrap_hash = ((struct bfd_hash_table *)
64133965Sjdp			     xmalloc (sizeof (struct bfd_hash_table)));
64233965Sjdp      if (! bfd_hash_table_init_n (link_info.wrap_hash,
64333965Sjdp				   bfd_hash_newfunc,
64433965Sjdp				   61))
64560484Sobrien	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
64633965Sjdp    }
64733965Sjdp  if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL)
64860484Sobrien    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
64933965Sjdp}
65033965Sjdp
65133965Sjdp/* Handle the -retain-symbols-file option.  */
65233965Sjdp
65333965Sjdpvoid
65433965Sjdpadd_keepsyms_file (filename)
65533965Sjdp     const char *filename;
65633965Sjdp{
65733965Sjdp  FILE *file;
65833965Sjdp  char *buf;
65933965Sjdp  size_t bufsize;
66033965Sjdp  int c;
66133965Sjdp
66233965Sjdp  if (link_info.strip == strip_some)
66360484Sobrien    einfo (_("%X%P: error: duplicate retain-symbols-file\n"));
66433965Sjdp
66533965Sjdp  file = fopen (filename, "r");
66633965Sjdp  if (file == (FILE *) NULL)
66733965Sjdp    {
66833965Sjdp      bfd_set_error (bfd_error_system_call);
66933965Sjdp      einfo ("%X%P: %s: %E\n", filename);
67033965Sjdp      return;
67133965Sjdp    }
67233965Sjdp
67333965Sjdp  link_info.keep_hash = ((struct bfd_hash_table *)
67433965Sjdp			 xmalloc (sizeof (struct bfd_hash_table)));
67533965Sjdp  if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc))
67660484Sobrien    einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
67733965Sjdp
67833965Sjdp  bufsize = 100;
67933965Sjdp  buf = (char *) xmalloc (bufsize);
68033965Sjdp
68133965Sjdp  c = getc (file);
68233965Sjdp  while (c != EOF)
68333965Sjdp    {
68433965Sjdp      while (isspace (c))
68533965Sjdp	c = getc (file);
68633965Sjdp
68733965Sjdp      if (c != EOF)
68833965Sjdp	{
68933965Sjdp	  size_t len = 0;
69033965Sjdp
69133965Sjdp	  while (! isspace (c) && c != EOF)
69233965Sjdp	    {
69333965Sjdp	      buf[len] = c;
69433965Sjdp	      ++len;
69533965Sjdp	      if (len >= bufsize)
69633965Sjdp		{
69733965Sjdp		  bufsize *= 2;
69833965Sjdp		  buf = xrealloc (buf, bufsize);
69933965Sjdp		}
70033965Sjdp	      c = getc (file);
70133965Sjdp	    }
70233965Sjdp
70333965Sjdp	  buf[len] = '\0';
70433965Sjdp
70533965Sjdp	  if (bfd_hash_lookup (link_info.keep_hash, buf, true, true)
70633965Sjdp	      == (struct bfd_hash_entry *) NULL)
70760484Sobrien	    einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n"));
70833965Sjdp	}
70933965Sjdp    }
71033965Sjdp
71133965Sjdp  if (link_info.strip != strip_none)
71260484Sobrien    einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"));
71333965Sjdp
71433965Sjdp  link_info.strip = strip_some;
71533965Sjdp}
71633965Sjdp
71733965Sjdp/* Callbacks from the BFD linker routines.  */
71833965Sjdp
71933965Sjdp/* This is called when BFD has decided to include an archive member in
72033965Sjdp   a link.  */
72133965Sjdp
72233965Sjdpstatic boolean
72333965Sjdpadd_archive_element (info, abfd, name)
72460484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
72533965Sjdp     bfd *abfd;
72633965Sjdp     const char *name;
72733965Sjdp{
72833965Sjdp  lang_input_statement_type *input;
72933965Sjdp
73033965Sjdp  input = ((lang_input_statement_type *)
73133965Sjdp	   xmalloc (sizeof (lang_input_statement_type)));
73233965Sjdp  input->filename = abfd->filename;
73333965Sjdp  input->local_sym_name = abfd->filename;
73433965Sjdp  input->the_bfd = abfd;
73533965Sjdp  input->asymbols = NULL;
73633965Sjdp  input->next = NULL;
73733965Sjdp  input->just_syms_flag = false;
73833965Sjdp  input->loaded = false;
73933965Sjdp  input->search_dirs_flag = false;
74033965Sjdp
74133965Sjdp  /* FIXME: The following fields are not set: header.next,
74233965Sjdp     header.type, closed, passive_position, symbol_count,
74333965Sjdp     next_real_file, is_archive, target, real.  This bit of code is
74433965Sjdp     from the old decode_library_subfile function.  I don't know
74533965Sjdp     whether any of those fields matters.  */
74633965Sjdp
74733965Sjdp  ldlang_add_file (input);
74833965Sjdp
74933965Sjdp  if (config.map_file != (FILE *) NULL)
75033965Sjdp    {
75133965Sjdp      static boolean header_printed;
75233965Sjdp      struct bfd_link_hash_entry *h;
75333965Sjdp      bfd *from;
75433965Sjdp      int len;
75533965Sjdp
75633965Sjdp      h = bfd_link_hash_lookup (link_info.hash, name, false, false, true);
75733965Sjdp
75833965Sjdp      if (h == NULL)
75933965Sjdp	from = NULL;
76033965Sjdp      else
76133965Sjdp	{
76233965Sjdp	  switch (h->type)
76333965Sjdp	    {
76433965Sjdp	    default:
76533965Sjdp	      from = NULL;
76633965Sjdp	      break;
76733965Sjdp
76833965Sjdp	    case bfd_link_hash_defined:
76933965Sjdp	    case bfd_link_hash_defweak:
77033965Sjdp	      from = h->u.def.section->owner;
77133965Sjdp	      break;
77233965Sjdp
77333965Sjdp	    case bfd_link_hash_undefined:
77433965Sjdp	    case bfd_link_hash_undefweak:
77533965Sjdp	      from = h->u.undef.abfd;
77633965Sjdp	      break;
77733965Sjdp
77833965Sjdp	    case bfd_link_hash_common:
77933965Sjdp	      from = h->u.c.p->section->owner;
78033965Sjdp	      break;
78133965Sjdp	    }
78233965Sjdp	}
78333965Sjdp
78433965Sjdp      if (! header_printed)
78533965Sjdp	{
78633965Sjdp	  char buf[100];
78733965Sjdp
78860484Sobrien	  sprintf (buf, "%-29s %s\n\n", _("Archive member included"),
78960484Sobrien		   _("because of file (symbol)"));
79033965Sjdp	  minfo ("%s", buf);
79133965Sjdp	  header_printed = true;
79233965Sjdp	}
79333965Sjdp
79433965Sjdp      if (bfd_my_archive (abfd) == NULL)
79533965Sjdp	{
79633965Sjdp	  minfo ("%s", bfd_get_filename (abfd));
79733965Sjdp	  len = strlen (bfd_get_filename (abfd));
79833965Sjdp	}
79933965Sjdp      else
80033965Sjdp	{
80133965Sjdp	  minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)),
80233965Sjdp		 bfd_get_filename (abfd));
80333965Sjdp	  len = (strlen (bfd_get_filename (bfd_my_archive (abfd)))
80433965Sjdp		 + strlen (bfd_get_filename (abfd))
80533965Sjdp		 + 2);
80633965Sjdp	}
80733965Sjdp
80833965Sjdp      if (len >= 29)
80933965Sjdp	{
81033965Sjdp	  print_nl ();
81133965Sjdp	  len = 0;
81233965Sjdp	}
81333965Sjdp      while (len < 30)
81433965Sjdp	{
81533965Sjdp	  print_space ();
81633965Sjdp	  ++len;
81733965Sjdp	}
81833965Sjdp
81933965Sjdp      if (from != NULL)
82033965Sjdp	minfo ("%B ", from);
82133965Sjdp      if (h != NULL)
82233965Sjdp	minfo ("(%T)\n", h->root.string);
82333965Sjdp      else
82433965Sjdp	minfo ("(%s)\n", name);
82533965Sjdp    }
82633965Sjdp
82733965Sjdp  if (trace_files || trace_file_tries)
82833965Sjdp    info_msg ("%I\n", input);
82933965Sjdp
83033965Sjdp  return true;
83133965Sjdp}
83233965Sjdp
83333965Sjdp/* This is called when BFD has discovered a symbol which is defined
83433965Sjdp   multiple times.  */
83533965Sjdp
83633965Sjdpstatic boolean
83733965Sjdpmultiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval)
83860484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
83933965Sjdp     const char *name;
84033965Sjdp     bfd *obfd;
84133965Sjdp     asection *osec;
84233965Sjdp     bfd_vma oval;
84333965Sjdp     bfd *nbfd;
84433965Sjdp     asection *nsec;
84533965Sjdp     bfd_vma nval;
84633965Sjdp{
84733965Sjdp  /* If either section has the output_section field set to
84833965Sjdp     bfd_abs_section_ptr, it means that the section is being
84933965Sjdp     discarded, and this is not really a multiple definition at all.
85033965Sjdp     FIXME: It would be cleaner to somehow ignore symbols defined in
85133965Sjdp     sections which are being discarded.  */
85233965Sjdp  if ((osec->output_section != NULL
85333965Sjdp       && ! bfd_is_abs_section (osec)
85433965Sjdp       && bfd_is_abs_section (osec->output_section))
85533965Sjdp      || (nsec->output_section != NULL
85633965Sjdp	  && ! bfd_is_abs_section (nsec)
85733965Sjdp	  && bfd_is_abs_section (nsec->output_section)))
85833965Sjdp    return true;
85933965Sjdp
86060484Sobrien  einfo (_("%X%C: multiple definition of `%T'\n"),
86133965Sjdp	 nbfd, nsec, nval, name);
86233965Sjdp  if (obfd != (bfd *) NULL)
86360484Sobrien    einfo (_("%D: first defined here\n"), obfd, osec, oval);
86477298Sobrien
86577298Sobrien  if (command_line.relax)
86677298Sobrien    {
86777298Sobrien      einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
86877298Sobrien      command_line.relax = 0;
86977298Sobrien    }
87077298Sobrien
87133965Sjdp  return true;
87233965Sjdp}
87333965Sjdp
87433965Sjdp/* This is called when there is a definition of a common symbol, or
87533965Sjdp   when a common symbol is found for a symbol that is already defined,
87633965Sjdp   or when two common symbols are found.  We only do something if
87733965Sjdp   -warn-common was used.  */
87833965Sjdp
87933965Sjdpstatic boolean
88033965Sjdpmultiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
88160484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
88233965Sjdp     const char *name;
88333965Sjdp     bfd *obfd;
88433965Sjdp     enum bfd_link_hash_type otype;
88533965Sjdp     bfd_vma osize;
88633965Sjdp     bfd *nbfd;
88733965Sjdp     enum bfd_link_hash_type ntype;
88833965Sjdp     bfd_vma nsize;
88933965Sjdp{
89033965Sjdp  if (! config.warn_common)
89133965Sjdp    return true;
89233965Sjdp
89333965Sjdp  if (ntype == bfd_link_hash_defined
89433965Sjdp      || ntype == bfd_link_hash_defweak
89533965Sjdp      || ntype == bfd_link_hash_indirect)
89633965Sjdp    {
89733965Sjdp      ASSERT (otype == bfd_link_hash_common);
89860484Sobrien      einfo (_("%B: warning: definition of `%T' overriding common\n"),
89933965Sjdp	     nbfd, name);
90033965Sjdp      if (obfd != NULL)
90160484Sobrien	einfo (_("%B: warning: common is here\n"), obfd);
90233965Sjdp    }
90333965Sjdp  else if (otype == bfd_link_hash_defined
90433965Sjdp	   || otype == bfd_link_hash_defweak
90533965Sjdp	   || otype == bfd_link_hash_indirect)
90633965Sjdp    {
90733965Sjdp      ASSERT (ntype == bfd_link_hash_common);
90860484Sobrien      einfo (_("%B: warning: common of `%T' overridden by definition\n"),
90933965Sjdp	     nbfd, name);
91033965Sjdp      if (obfd != NULL)
91160484Sobrien	einfo (_("%B: warning: defined here\n"), obfd);
91233965Sjdp    }
91333965Sjdp  else
91433965Sjdp    {
91533965Sjdp      ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common);
91633965Sjdp      if (osize > nsize)
91733965Sjdp	{
91860484Sobrien	  einfo (_("%B: warning: common of `%T' overridden by larger common\n"),
91933965Sjdp		 nbfd, name);
92033965Sjdp	  if (obfd != NULL)
92160484Sobrien	    einfo (_("%B: warning: larger common is here\n"), obfd);
92233965Sjdp	}
92333965Sjdp      else if (nsize > osize)
92433965Sjdp	{
92560484Sobrien	  einfo (_("%B: warning: common of `%T' overriding smaller common\n"),
92633965Sjdp		 nbfd, name);
92733965Sjdp	  if (obfd != NULL)
92860484Sobrien	    einfo (_("%B: warning: smaller common is here\n"), obfd);
92933965Sjdp	}
93033965Sjdp      else
93133965Sjdp	{
93260484Sobrien	  einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name);
93333965Sjdp	  if (obfd != NULL)
93460484Sobrien	    einfo (_("%B: warning: previous common is here\n"), obfd);
93533965Sjdp	}
93633965Sjdp    }
93733965Sjdp
93833965Sjdp  return true;
93933965Sjdp}
94033965Sjdp
94133965Sjdp/* This is called when BFD has discovered a set element.  H is the
94233965Sjdp   entry in the linker hash table for the set.  SECTION and VALUE
94333965Sjdp   represent a value which should be added to the set.  */
94433965Sjdp
94533965Sjdpstatic boolean
94633965Sjdpadd_to_set (info, h, reloc, abfd, section, value)
94760484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
94833965Sjdp     struct bfd_link_hash_entry *h;
94933965Sjdp     bfd_reloc_code_real_type reloc;
95033965Sjdp     bfd *abfd;
95133965Sjdp     asection *section;
95233965Sjdp     bfd_vma value;
95333965Sjdp{
95433965Sjdp  if (config.warn_constructors)
95560484Sobrien    einfo (_("%P: warning: global constructor %s used\n"),
95633965Sjdp	   h->root.string);
95733965Sjdp
95833965Sjdp  if (! config.build_constructors)
95933965Sjdp    return true;
96033965Sjdp
96133965Sjdp  ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value);
96233965Sjdp
96333965Sjdp  if (h->type == bfd_link_hash_new)
96433965Sjdp    {
96533965Sjdp      h->type = bfd_link_hash_undefined;
96633965Sjdp      h->u.undef.abfd = abfd;
96733965Sjdp      /* We don't call bfd_link_add_undef to add this to the list of
96833965Sjdp	 undefined symbols because we are going to define it
96933965Sjdp	 ourselves.  */
97033965Sjdp    }
97133965Sjdp
97233965Sjdp  return true;
97333965Sjdp}
97433965Sjdp
97533965Sjdp/* This is called when BFD has discovered a constructor.  This is only
97633965Sjdp   called for some object file formats--those which do not handle
97733965Sjdp   constructors in some more clever fashion.  This is similar to
97833965Sjdp   adding an element to a set, but less general.  */
97933965Sjdp
98033965Sjdpstatic boolean
98133965Sjdpconstructor_callback (info, constructor, name, abfd, section, value)
98233965Sjdp     struct bfd_link_info *info;
98333965Sjdp     boolean constructor;
98433965Sjdp     const char *name;
98533965Sjdp     bfd *abfd;
98633965Sjdp     asection *section;
98733965Sjdp     bfd_vma value;
98833965Sjdp{
98933965Sjdp  char *s;
99033965Sjdp  struct bfd_link_hash_entry *h;
99133965Sjdp  char set_name[1 + sizeof "__CTOR_LIST__"];
99233965Sjdp
99333965Sjdp  if (config.warn_constructors)
99460484Sobrien    einfo (_("%P: warning: global constructor %s used\n"), name);
99533965Sjdp
99633965Sjdp  if (! config.build_constructors)
99733965Sjdp    return true;
99833965Sjdp
99933965Sjdp  /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
100033965Sjdp     useful error message.  */
100133965Sjdp  if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL
100233965Sjdp      && (link_info.relocateable
100333965Sjdp	  || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
100460484Sobrien    einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
100533965Sjdp
100633965Sjdp  s = set_name;
100733965Sjdp  if (bfd_get_symbol_leading_char (abfd) != '\0')
100833965Sjdp    *s++ = bfd_get_symbol_leading_char (abfd);
100933965Sjdp  if (constructor)
101033965Sjdp    strcpy (s, "__CTOR_LIST__");
101133965Sjdp  else
101233965Sjdp    strcpy (s, "__DTOR_LIST__");
101333965Sjdp
101433965Sjdp  h = bfd_link_hash_lookup (info->hash, set_name, true, true, true);
101533965Sjdp  if (h == (struct bfd_link_hash_entry *) NULL)
101660484Sobrien    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
101733965Sjdp  if (h->type == bfd_link_hash_new)
101833965Sjdp    {
101933965Sjdp      h->type = bfd_link_hash_undefined;
102033965Sjdp      h->u.undef.abfd = abfd;
102133965Sjdp      /* We don't call bfd_link_add_undef to add this to the list of
102233965Sjdp	 undefined symbols because we are going to define it
102333965Sjdp	 ourselves.  */
102433965Sjdp    }
102533965Sjdp
102633965Sjdp  ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value);
102733965Sjdp  return true;
102833965Sjdp}
102933965Sjdp
103033965Sjdp/* A structure used by warning_callback to pass information through
103133965Sjdp   bfd_map_over_sections.  */
103233965Sjdp
103377298Sobrienstruct warning_callback_info {
103433965Sjdp  boolean found;
103533965Sjdp  const char *warning;
103633965Sjdp  const char *symbol;
103733965Sjdp  asymbol **asymbols;
103833965Sjdp};
103933965Sjdp
104033965Sjdp/* This is called when there is a reference to a warning symbol.  */
104133965Sjdp
104233965Sjdpstatic boolean
104333965Sjdpwarning_callback (info, warning, symbol, abfd, section, address)
104460484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
104533965Sjdp     const char *warning;
104633965Sjdp     const char *symbol;
104733965Sjdp     bfd *abfd;
104833965Sjdp     asection *section;
104933965Sjdp     bfd_vma address;
105033965Sjdp{
105133965Sjdp  /* This is a hack to support warn_multiple_gp.  FIXME: This should
105233965Sjdp     have a cleaner interface, but what?  */
105333965Sjdp  if (! config.warn_multiple_gp
105433965Sjdp      && strcmp (warning, "using multiple gp values") == 0)
105533965Sjdp    return true;
105633965Sjdp
105733965Sjdp  if (section != NULL)
105833965Sjdp    einfo ("%C: %s\n", abfd, section, address, warning);
105933965Sjdp  else if (abfd == NULL)
106033965Sjdp    einfo ("%P: %s\n", warning);
106133965Sjdp  else if (symbol == NULL)
106233965Sjdp    einfo ("%B: %s\n", abfd, warning);
106333965Sjdp  else
106433965Sjdp    {
106533965Sjdp      lang_input_statement_type *entry;
106633965Sjdp      asymbol **asymbols;
106733965Sjdp      struct warning_callback_info info;
106833965Sjdp
106933965Sjdp      /* Look through the relocs to see if we can find a plausible
107033965Sjdp	 address.  */
107133965Sjdp
107233965Sjdp      entry = (lang_input_statement_type *) abfd->usrdata;
107333965Sjdp      if (entry != NULL && entry->asymbols != NULL)
107433965Sjdp	asymbols = entry->asymbols;
107533965Sjdp      else
107633965Sjdp	{
107733965Sjdp	  long symsize;
107833965Sjdp	  long symbol_count;
107933965Sjdp
108033965Sjdp	  symsize = bfd_get_symtab_upper_bound (abfd);
108133965Sjdp	  if (symsize < 0)
108260484Sobrien	    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
108333965Sjdp	  asymbols = (asymbol **) xmalloc (symsize);
108433965Sjdp	  symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
108533965Sjdp	  if (symbol_count < 0)
108660484Sobrien	    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
108733965Sjdp	  if (entry != NULL)
108833965Sjdp	    {
108933965Sjdp	      entry->asymbols = asymbols;
109033965Sjdp	      entry->symbol_count = symbol_count;
109133965Sjdp	    }
109233965Sjdp	}
109333965Sjdp
109433965Sjdp      info.found = false;
109533965Sjdp      info.warning = warning;
109633965Sjdp      info.symbol = symbol;
109733965Sjdp      info.asymbols = asymbols;
109833965Sjdp      bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info);
109933965Sjdp
110033965Sjdp      if (! info.found)
110133965Sjdp	einfo ("%B: %s\n", abfd, warning);
110233965Sjdp
110333965Sjdp      if (entry == NULL)
110433965Sjdp	free (asymbols);
110533965Sjdp    }
110633965Sjdp
110733965Sjdp  return true;
110833965Sjdp}
110933965Sjdp
111033965Sjdp/* This is called by warning_callback for each section.  It checks the
111133965Sjdp   relocs of the section to see if it can find a reference to the
111233965Sjdp   symbol which triggered the warning.  If it can, it uses the reloc
111333965Sjdp   to give an error message with a file and line number.  */
111433965Sjdp
111533965Sjdpstatic void
111633965Sjdpwarning_find_reloc (abfd, sec, iarg)
111733965Sjdp     bfd *abfd;
111833965Sjdp     asection *sec;
111933965Sjdp     PTR iarg;
112033965Sjdp{
112133965Sjdp  struct warning_callback_info *info = (struct warning_callback_info *) iarg;
112233965Sjdp  long relsize;
112333965Sjdp  arelent **relpp;
112433965Sjdp  long relcount;
112533965Sjdp  arelent **p, **pend;
112633965Sjdp
112733965Sjdp  if (info->found)
112833965Sjdp    return;
112933965Sjdp
113033965Sjdp  relsize = bfd_get_reloc_upper_bound (abfd, sec);
113133965Sjdp  if (relsize < 0)
113260484Sobrien    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
113333965Sjdp  if (relsize == 0)
113433965Sjdp    return;
113533965Sjdp
113633965Sjdp  relpp = (arelent **) xmalloc (relsize);
113733965Sjdp  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
113833965Sjdp  if (relcount < 0)
113960484Sobrien    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
114033965Sjdp
114133965Sjdp  p = relpp;
114233965Sjdp  pend = p + relcount;
114333965Sjdp  for (; p < pend && *p != NULL; p++)
114433965Sjdp    {
114533965Sjdp      arelent *q = *p;
114633965Sjdp
114733965Sjdp      if (q->sym_ptr_ptr != NULL
114833965Sjdp	  && *q->sym_ptr_ptr != NULL
114933965Sjdp	  && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
115033965Sjdp	{
115133965Sjdp	  /* We found a reloc for the symbol we are looking for.  */
115233965Sjdp	  einfo ("%C: %s\n", abfd, sec, q->address, info->warning);
115333965Sjdp	  info->found = true;
115433965Sjdp	  break;
115533965Sjdp	}
115633965Sjdp    }
115733965Sjdp
115833965Sjdp  free (relpp);
115933965Sjdp}
116033965Sjdp
116133965Sjdp/* This is called when an undefined symbol is found.  */
116233965Sjdp
116333965Sjdpstatic boolean
116460484Sobrienundefined_symbol (info, name, abfd, section, address, fatal)
116560484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
116633965Sjdp     const char *name;
116733965Sjdp     bfd *abfd;
116833965Sjdp     asection *section;
116933965Sjdp     bfd_vma address;
117077298Sobrien     boolean fatal ATTRIBUTE_UNUSED;
117133965Sjdp{
117233965Sjdp  static char *error_name;
117333965Sjdp  static unsigned int error_count;
117433965Sjdp
117533965Sjdp#define MAX_ERRORS_IN_A_ROW 5
117633965Sjdp
117733965Sjdp  if (config.warn_once)
117833965Sjdp    {
117933965Sjdp      static struct bfd_hash_table *hash;
118033965Sjdp
118133965Sjdp      /* Only warn once about a particular undefined symbol.  */
118233965Sjdp
118333965Sjdp      if (hash == NULL)
118433965Sjdp	{
118533965Sjdp	  hash = ((struct bfd_hash_table *)
118633965Sjdp		  xmalloc (sizeof (struct bfd_hash_table)));
118733965Sjdp	  if (! bfd_hash_table_init (hash, bfd_hash_newfunc))
118860484Sobrien	    einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
118933965Sjdp	}
119033965Sjdp
119133965Sjdp      if (bfd_hash_lookup (hash, name, false, false) != NULL)
119233965Sjdp	return true;
119333965Sjdp
119433965Sjdp      if (bfd_hash_lookup (hash, name, true, true) == NULL)
119560484Sobrien	einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
119633965Sjdp    }
119733965Sjdp
119833965Sjdp  /* We never print more than a reasonable number of errors in a row
119933965Sjdp     for a single symbol.  */
120033965Sjdp  if (error_name != (char *) NULL
120133965Sjdp      && strcmp (name, error_name) == 0)
120233965Sjdp    ++error_count;
120333965Sjdp  else
120433965Sjdp    {
120533965Sjdp      error_count = 0;
120633965Sjdp      if (error_name != (char *) NULL)
120733965Sjdp	free (error_name);
120833965Sjdp      error_name = buystring (name);
120933965Sjdp    }
121033965Sjdp
121133965Sjdp  if (section != NULL)
121233965Sjdp    {
121333965Sjdp      if (error_count < MAX_ERRORS_IN_A_ROW)
121460484Sobrien	{
121560484Sobrien	  einfo (_("%C: undefined reference to `%T'\n"),
121660484Sobrien		 abfd, section, address, name);
121760484Sobrien	  if (fatal)
121860484Sobrien	    einfo ("%X");
121960484Sobrien	}
122033965Sjdp      else if (error_count == MAX_ERRORS_IN_A_ROW)
122160484Sobrien	einfo (_("%D: more undefined references to `%T' follow\n"),
122233965Sjdp	       abfd, section, address, name);
122333965Sjdp    }
122433965Sjdp  else
122533965Sjdp    {
122633965Sjdp      if (error_count < MAX_ERRORS_IN_A_ROW)
122760484Sobrien	{
122860484Sobrien	  einfo (_("%B: undefined reference to `%T'\n"),
122960484Sobrien		 abfd, name);
123060484Sobrien	  if (fatal)
123160484Sobrien	    einfo ("%X");
123260484Sobrien	}
123333965Sjdp      else if (error_count == MAX_ERRORS_IN_A_ROW)
123460484Sobrien	einfo (_("%B: more undefined references to `%T' follow\n"),
123533965Sjdp	       abfd, name);
123633965Sjdp    }
123733965Sjdp
123833965Sjdp  return true;
123933965Sjdp}
124033965Sjdp
124133965Sjdp/* This is called when a reloc overflows.  */
124233965Sjdp
124333965Sjdpstatic boolean
124433965Sjdpreloc_overflow (info, name, reloc_name, addend, abfd, section, address)
124560484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
124633965Sjdp     const char *name;
124733965Sjdp     const char *reloc_name;
124833965Sjdp     bfd_vma addend;
124933965Sjdp     bfd *abfd;
125033965Sjdp     asection *section;
125133965Sjdp     bfd_vma address;
125233965Sjdp{
125333965Sjdp  if (abfd == (bfd *) NULL)
125460484Sobrien    einfo (_("%P%X: generated"));
125533965Sjdp  else
125633965Sjdp    einfo ("%X%C:", abfd, section, address);
125760484Sobrien  einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name);
125833965Sjdp  if (addend != 0)
125933965Sjdp    einfo ("+%v", addend);
126033965Sjdp  einfo ("\n");
126133965Sjdp  return true;
126233965Sjdp}
126333965Sjdp
126433965Sjdp/* This is called when a dangerous relocation is made.  */
126533965Sjdp
126633965Sjdpstatic boolean
126733965Sjdpreloc_dangerous (info, message, abfd, section, address)
126860484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
126933965Sjdp     const char *message;
127033965Sjdp     bfd *abfd;
127133965Sjdp     asection *section;
127233965Sjdp     bfd_vma address;
127333965Sjdp{
127433965Sjdp  if (abfd == (bfd *) NULL)
127560484Sobrien    einfo (_("%P%X: generated"));
127633965Sjdp  else
127733965Sjdp    einfo ("%X%C:", abfd, section, address);
127860484Sobrien  einfo (_("dangerous relocation: %s\n"), message);
127933965Sjdp  return true;
128033965Sjdp}
128133965Sjdp
128233965Sjdp/* This is called when a reloc is being generated attached to a symbol
128333965Sjdp   that is not being output.  */
128433965Sjdp
128533965Sjdpstatic boolean
128633965Sjdpunattached_reloc (info, name, abfd, section, address)
128760484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
128833965Sjdp     const char *name;
128933965Sjdp     bfd *abfd;
129033965Sjdp     asection *section;
129133965Sjdp     bfd_vma address;
129233965Sjdp{
129333965Sjdp  if (abfd == (bfd *) NULL)
129460484Sobrien    einfo (_("%P%X: generated"));
129533965Sjdp  else
129633965Sjdp    einfo ("%X%C:", abfd, section, address);
129760484Sobrien  einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name);
129833965Sjdp  return true;
129933965Sjdp}
130033965Sjdp
130133965Sjdp/* This is called if link_info.notice_all is set, or when a symbol in
130233965Sjdp   link_info.notice_hash is found.  Symbols are put in notice_hash
130333965Sjdp   using the -y option.  */
130433965Sjdp
130533965Sjdpstatic boolean
130633965Sjdpnotice (info, name, abfd, section, value)
130733965Sjdp     struct bfd_link_info *info;
130833965Sjdp     const char *name;
130933965Sjdp     bfd *abfd;
131033965Sjdp     asection *section;
131133965Sjdp     bfd_vma value;
131233965Sjdp{
131333965Sjdp  if (! info->notice_all
131433965Sjdp      || (info->notice_hash != NULL
131533965Sjdp	  && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL))
131660484Sobrien    {
131760484Sobrien      if (bfd_is_und_section (section))
131860484Sobrien	einfo ("%B: reference to %s\n", abfd, name);
131960484Sobrien      else
132060484Sobrien	einfo ("%B: definition of %s\n", abfd, name);
132160484Sobrien    }
132233965Sjdp
132333965Sjdp  if (command_line.cref || nocrossref_list != NULL)
132433965Sjdp    add_cref (name, abfd, section, value);
132533965Sjdp
132633965Sjdp  return true;
132733965Sjdp}
1328