ldmain.c revision 61843
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 "ldemul.h"
4033965Sjdp#include "ldlex.h"
4133965Sjdp#include "ldfile.h"
4233965Sjdp#include "ldctor.h"
4333965Sjdp
4433965Sjdp/* 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
6833965Sjdp/* 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
13333965Sjdpstatic struct bfd_link_callbacks link_callbacks =
13433965Sjdp{
13533965Sjdp  add_archive_element,
13633965Sjdp  multiple_definition,
13733965Sjdp  multiple_common,
13833965Sjdp  add_to_set,
13933965Sjdp  constructor_callback,
14033965Sjdp  warning_callback,
14133965Sjdp  undefined_symbol,
14233965Sjdp  reloc_overflow,
14333965Sjdp  reloc_dangerous,
14433965Sjdp  unattached_reloc,
14533965Sjdp  notice
14633965Sjdp};
14733965Sjdp
14833965Sjdpstruct bfd_link_info link_info;
14933965Sjdp
15033965Sjdpstatic void
15133965Sjdpremove_output ()
15233965Sjdp{
15333965Sjdp  if (output_filename)
15433965Sjdp    {
15533965Sjdp      if (output_bfd && output_bfd->iostream)
15633965Sjdp	fclose((FILE *)(output_bfd->iostream));
15733965Sjdp      if (delete_output_file_on_failure)
15833965Sjdp	unlink (output_filename);
15933965Sjdp    }
16033965Sjdp}
16133965Sjdp
16233965Sjdpint
16333965Sjdpmain (argc, argv)
16433965Sjdp     int argc;
16533965Sjdp     char **argv;
16633965Sjdp{
16733965Sjdp  char *emulation;
16833965Sjdp  long start_time = get_run_time ();
16933965Sjdp
17060484Sobrien#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
17160484Sobrien  setlocale (LC_MESSAGES, "");
17260484Sobrien#endif
17360484Sobrien  bindtextdomain (PACKAGE, LOCALEDIR);
17460484Sobrien  textdomain (PACKAGE);
17560484Sobrien
17633965Sjdp  program_name = argv[0];
17733965Sjdp  xmalloc_set_program_name (program_name);
17833965Sjdp
17933965Sjdp  START_PROGRESS (program_name, 0);
18033965Sjdp
18133965Sjdp  bfd_init ();
18233965Sjdp
18333965Sjdp  bfd_set_error_program_name (program_name);
18433965Sjdp
18533965Sjdp  xatexit (remove_output);
18633965Sjdp
18733965Sjdp  /* Set the default BFD target based on the configured target.  Doing
18833965Sjdp     this permits the linker to be configured for a particular target,
18933965Sjdp     and linked against a shared BFD library which was configured for
19033965Sjdp     a different target.  The macro TARGET is defined by Makefile.  */
19133965Sjdp  if (! bfd_set_default_target (TARGET))
19233965Sjdp    {
19360484Sobrien      einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
19433965Sjdp      xexit (1);
19533965Sjdp    }
19633965Sjdp
19733965Sjdp  /* Initialize the data about options.  */
19833965Sjdp  trace_files = trace_file_tries = version_printed = false;
19933965Sjdp  whole_archive = false;
20033965Sjdp  config.build_constructors = true;
20133965Sjdp  config.dynamic_link = false;
20260484Sobrien  config.has_shared = false;
20333965Sjdp  command_line.force_common_definition = false;
20433965Sjdp  command_line.interpreter = NULL;
20533965Sjdp  command_line.rpath = NULL;
20638889Sjdp  command_line.warn_mismatch = true;
20760484Sobrien  command_line.check_section_addresses = true;
20833965Sjdp
20960484Sobrien  /* We initialize DEMANGLING based on the environment variable
21060484Sobrien     COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
21160484Sobrien     output of the linker, unless COLLECT_NO_DEMANGLE is set in the
21260484Sobrien     environment.  Acting the same way here lets us provide the same
21360484Sobrien     interface by default.  */
21460484Sobrien  demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;
21560484Sobrien
21633965Sjdp  link_info.callbacks = &link_callbacks;
21733965Sjdp  link_info.relocateable = false;
21833965Sjdp  link_info.shared = false;
21933965Sjdp  link_info.symbolic = false;
22033965Sjdp  link_info.static_link = false;
22133965Sjdp  link_info.traditional_format = false;
22260484Sobrien  link_info.optimize = false;
22360484Sobrien  link_info.no_undefined = false;
22433965Sjdp  link_info.strip = strip_none;
22533965Sjdp  link_info.discard = discard_none;
22633965Sjdp  link_info.keep_memory = true;
22733965Sjdp  link_info.input_bfds = NULL;
22833965Sjdp  link_info.create_object_symbols_section = NULL;
22933965Sjdp  link_info.hash = NULL;
23033965Sjdp  link_info.keep_hash = NULL;
23133965Sjdp  link_info.notice_all = false;
23233965Sjdp  link_info.notice_hash = NULL;
23333965Sjdp  link_info.wrap_hash = NULL;
23460484Sobrien  link_info.mpc860c0 = 0;
23560484Sobrien  /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
23660484Sobrien     and _fini symbols.  We are compatible.  */
23760484Sobrien  link_info.init_function = "_init";
23860484Sobrien  link_info.fini_function = "_fini";
23960484Sobrien
24033965Sjdp  ldfile_add_arch ("");
24133965Sjdp
24233965Sjdp  config.make_executable = true;
24333965Sjdp  force_make_executable = false;
24433965Sjdp  config.magic_demand_paged = true;
24533965Sjdp  config.text_read_only = true;
24633965Sjdp  config.make_executable = true;
24733965Sjdp
24833965Sjdp  emulation = get_emulation (argc, argv);
24933965Sjdp  ldemul_choose_mode (emulation);
25033965Sjdp  default_target = ldemul_choose_target ();
25133965Sjdp  lang_init ();
25233965Sjdp  ldemul_before_parse ();
25333965Sjdp  lang_has_input_file = false;
25433965Sjdp  parse_args (argc, argv);
25533965Sjdp
25633965Sjdp  ldemul_set_symbols ();
25733965Sjdp
25833965Sjdp  if (link_info.relocateable)
25933965Sjdp    {
26060484Sobrien      if (command_line.gc_sections)
26160484Sobrien	einfo ("%P%F: --gc-sections and -r may not be used together\n");
26260484Sobrien      if (link_info.mpc860c0)
26360484Sobrien	einfo (_("%P%F: -r and --mpc860c0 may not be used together\n"));
26460484Sobrien      else if (command_line.relax)
26560484Sobrien	einfo (_("%P%F: --relax and -r may not be used together\n"));
26633965Sjdp      if (link_info.shared)
26760484Sobrien	einfo (_("%P%F: -r and -shared may not be used together\n"));
26833965Sjdp    }
26933965Sjdp
27033965Sjdp  /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols).  I
27133965Sjdp     don't see how else this can be handled, since in this case we
27233965Sjdp     must preserve all externally visible symbols.  */
27333965Sjdp  if (link_info.relocateable && link_info.strip == strip_all)
27433965Sjdp    {
27533965Sjdp      link_info.strip = strip_debugger;
27633965Sjdp      if (link_info.discard == discard_none)
27733965Sjdp	link_info.discard = discard_all;
27833965Sjdp    }
27933965Sjdp
28033965Sjdp  /* This essentially adds another -L directory so this must be done after
28133965Sjdp     the -L's in argv have been processed.  */
28233965Sjdp  set_scripts_dir ();
28333965Sjdp
28433965Sjdp  if (had_script == false)
28533965Sjdp    {
28633965Sjdp      /* Read the emulation's appropriate default script.  */
28733965Sjdp      int isfile;
28833965Sjdp      char *s = ldemul_get_script (&isfile);
28933965Sjdp
29033965Sjdp      if (isfile)
29133965Sjdp	ldfile_open_command_file (s);
29233965Sjdp      else
29333965Sjdp	{
29433965Sjdp	  if (trace_file_tries)
29533965Sjdp	    {
29660484Sobrien	      info_msg (_("using internal linker script:\n"));
29733965Sjdp	      info_msg ("==================================================\n");
29833965Sjdp	      info_msg (s);
29933965Sjdp	      info_msg ("\n==================================================\n");
30033965Sjdp	    }
30133965Sjdp	  lex_string = s;
30233965Sjdp	  lex_redirect (s);
30333965Sjdp	}
30433965Sjdp      parser_input = input_script;
30533965Sjdp      yyparse ();
30633965Sjdp      lex_string = NULL;
30733965Sjdp    }
30833965Sjdp
30933965Sjdp  lang_final ();
31033965Sjdp
31133965Sjdp  if (lang_has_input_file == false)
31233965Sjdp    {
31333965Sjdp      if (version_printed)
31433965Sjdp	xexit (0);
31560484Sobrien      einfo (_("%P%F: no input files\n"));
31633965Sjdp    }
31733965Sjdp
31833965Sjdp  if (trace_files)
31933965Sjdp    {
32060484Sobrien      info_msg (_("%P: mode %s\n"), emulation);
32133965Sjdp    }
32233965Sjdp
32333965Sjdp  ldemul_after_parse ();
32433965Sjdp
32533965Sjdp
32633965Sjdp  if (config.map_filename)
32733965Sjdp    {
32833965Sjdp      if (strcmp (config.map_filename, "-") == 0)
32933965Sjdp	{
33033965Sjdp	  config.map_file = stdout;
33133965Sjdp	}
33233965Sjdp      else
33333965Sjdp	{
33433965Sjdp	  config.map_file = fopen (config.map_filename, FOPEN_WT);
33533965Sjdp	  if (config.map_file == (FILE *) NULL)
33633965Sjdp	    {
33733965Sjdp	      bfd_set_error (bfd_error_system_call);
33860484Sobrien	      einfo (_("%P%F: cannot open map file %s: %E\n"),
33933965Sjdp		     config.map_filename);
34033965Sjdp	    }
34133965Sjdp	}
34233965Sjdp    }
34333965Sjdp
34433965Sjdp
34533965Sjdp  lang_process ();
34633965Sjdp
34733965Sjdp  /* Print error messages for any missing symbols, for any warning
34833965Sjdp     symbols, and possibly multiple definitions */
34933965Sjdp
35033965Sjdp
35133965Sjdp  if (config.text_read_only)
35233965Sjdp    {
35333965Sjdp      /* Look for a text section and mark the readonly attribute in it */
35433965Sjdp      asection *found = bfd_get_section_by_name (output_bfd, ".text");
35533965Sjdp
35633965Sjdp      if (found != (asection *) NULL)
35733965Sjdp	{
35833965Sjdp	  found->flags |= SEC_READONLY;
35933965Sjdp	}
36033965Sjdp    }
36133965Sjdp
36233965Sjdp  if (link_info.relocateable)
36333965Sjdp    output_bfd->flags &= ~EXEC_P;
36433965Sjdp  else
36533965Sjdp    output_bfd->flags |= EXEC_P;
36633965Sjdp
36733965Sjdp  ldwrite ();
36833965Sjdp
36933965Sjdp  if (config.map_file != NULL)
37033965Sjdp    lang_map ();
37133965Sjdp  if (command_line.cref)
37233965Sjdp    output_cref (config.map_file != NULL ? config.map_file : stdout);
37333965Sjdp  if (nocrossref_list != NULL)
37433965Sjdp    check_nocrossrefs ();
37533965Sjdp
37633965Sjdp  /* Even if we're producing relocateable output, some non-fatal errors should
37733965Sjdp     be reported in the exit status.  (What non-fatal errors, if any, do we
37833965Sjdp     want to ignore for relocateable output?)  */
37933965Sjdp
38033965Sjdp  if (config.make_executable == false && force_make_executable == false)
38133965Sjdp    {
38233965Sjdp      if (trace_files == true)
38333965Sjdp	{
38460484Sobrien	  einfo (_("%P: link errors found, deleting executable `%s'\n"),
38533965Sjdp		 output_filename);
38633965Sjdp	}
38733965Sjdp
38833965Sjdp      /* The file will be removed by remove_output.  */
38933965Sjdp
39033965Sjdp      xexit (1);
39133965Sjdp    }
39233965Sjdp  else
39333965Sjdp    {
39433965Sjdp      if (! bfd_close (output_bfd))
39560484Sobrien	einfo (_("%F%B: final close failed: %E\n"), output_bfd);
39633965Sjdp
39733965Sjdp      /* If the --force-exe-suffix is enabled, and we're making an
39833965Sjdp	 executable file and it doesn't end in .exe, copy it to one which does. */
39933965Sjdp
40033965Sjdp      if (! link_info.relocateable && command_line.force_exe_suffix)
40133965Sjdp	{
40233965Sjdp	  int len = strlen (output_filename);
40333965Sjdp	  if (len < 4
40433965Sjdp	      || (strcasecmp (output_filename + len - 4, ".exe") != 0
40533965Sjdp		  && strcasecmp (output_filename + len - 4, ".dll") != 0))
40633965Sjdp	    {
40733965Sjdp	      FILE *src;
40833965Sjdp	      FILE *dst;
40933965Sjdp	      const int bsize = 4096;
41033965Sjdp	      char *buf = xmalloc (bsize);
41133965Sjdp	      int l;
41233965Sjdp	      char *dst_name = xmalloc (len + 5);
41333965Sjdp	      strcpy (dst_name, output_filename);
41433965Sjdp	      strcat (dst_name, ".exe");
41533965Sjdp	      src = fopen (output_filename, FOPEN_RB);
41633965Sjdp	      dst = fopen (dst_name, FOPEN_WB);
41733965Sjdp
41833965Sjdp	      if (!src)
41960484Sobrien		einfo (_("%X%P: unable to open for source of copy `%s'\n"), output_filename);
42033965Sjdp	      if (!dst)
42160484Sobrien		einfo (_("%X%P: unable to open for destination of copy `%s'\n"), dst_name);
42233965Sjdp	      while ((l = fread (buf, 1, bsize, src)) > 0)
42333965Sjdp		{
42433965Sjdp		  int done = fwrite (buf, 1, l, dst);
42533965Sjdp		  if (done != l)
42633965Sjdp		    {
42760484Sobrien		      einfo (_("%P: Error writing file `%s'\n"), dst_name);
42833965Sjdp		    }
42933965Sjdp		}
43033965Sjdp	      fclose (src);
43133965Sjdp	      if (fclose (dst) == EOF)
43233965Sjdp		{
43360484Sobrien		  einfo (_("%P: Error closing file `%s'\n"), dst_name);
43433965Sjdp		}
43533965Sjdp	      free (dst_name);
43633965Sjdp	      free (buf);
43733965Sjdp	    }
43833965Sjdp	}
43933965Sjdp    }
44033965Sjdp
44133965Sjdp  END_PROGRESS (program_name);
44233965Sjdp
44333965Sjdp  if (config.stats)
44433965Sjdp    {
44533965Sjdp#ifdef HAVE_SBRK
44633965Sjdp      char *lim = (char *) sbrk (0);
44733965Sjdp#endif
44833965Sjdp      long run_time = get_run_time () - start_time;
44933965Sjdp
45060484Sobrien      fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
45133965Sjdp	       program_name, run_time / 1000000, run_time % 1000000);
45233965Sjdp#ifdef HAVE_SBRK
45360484Sobrien      fprintf (stderr, _("%s: data size %ld\n"), program_name,
45433965Sjdp	       (long) (lim - (char *) &environ));
45533965Sjdp#endif
45633965Sjdp    }
45733965Sjdp
45833965Sjdp  /* Prevent remove_output from doing anything, after a successful link.  */
45933965Sjdp  output_filename = NULL;
46033965Sjdp
46133965Sjdp  xexit (0);
46233965Sjdp  return 0;
46333965Sjdp}
46433965Sjdp
46533965Sjdp/* We need to find any explicitly given emulation in order to initialize the
46633965Sjdp   state that's needed by the lex&yacc argument parser (parse_args).  */
46733965Sjdp
46833965Sjdpstatic char *
46933965Sjdpget_emulation (argc, argv)
47033965Sjdp     int argc;
47133965Sjdp     char **argv;
47233965Sjdp{
47333965Sjdp  char *emulation;
47433965Sjdp  int i;
47533965Sjdp
47633965Sjdp  emulation = getenv (EMULATION_ENVIRON);
47733965Sjdp  if (emulation == NULL)
47833965Sjdp    emulation = DEFAULT_EMULATION;
47933965Sjdp
48033965Sjdp  for (i = 1; i < argc; i++)
48133965Sjdp    {
48233965Sjdp      if (!strncmp (argv[i], "-m", 2))
48333965Sjdp	{
48433965Sjdp	  if (argv[i][2] == '\0')
48533965Sjdp	    {
48633965Sjdp	      /* -m EMUL */
48733965Sjdp	      if (i < argc - 1)
48833965Sjdp		{
48933965Sjdp		  emulation = argv[i + 1];
49033965Sjdp		  i++;
49133965Sjdp		}
49233965Sjdp	      else
49333965Sjdp		{
49460484Sobrien		  einfo(_("%P%F: missing argument to -m\n"));
49533965Sjdp		}
49633965Sjdp	    }
49733965Sjdp	  else if (strcmp (argv[i], "-mips1") == 0
49833965Sjdp		   || strcmp (argv[i], "-mips2") == 0
49933965Sjdp		   || strcmp (argv[i], "-mips3") == 0
50033965Sjdp		   || strcmp (argv[i], "-mips4") == 0)
50133965Sjdp	    {
50233965Sjdp	      /* FIXME: The arguments -mips1, -mips2 and -mips3 are
50333965Sjdp		 passed to the linker by some MIPS compilers.  They
50433965Sjdp		 generally tell the linker to use a slightly different
50533965Sjdp		 library path.  Perhaps someday these should be
50633965Sjdp		 implemented as emulations; until then, we just ignore
50733965Sjdp		 the arguments and hope that nobody ever creates
50833965Sjdp		 emulations named ips1, ips2 or ips3.  */
50933965Sjdp	    }
51033965Sjdp	  else if (strcmp (argv[i], "-m486") == 0)
51133965Sjdp	    {
51233965Sjdp	      /* FIXME: The argument -m486 is passed to the linker on
51333965Sjdp		 some Linux systems.  Hope that nobody creates an
51433965Sjdp		 emulation named 486.  */
51533965Sjdp	    }
51633965Sjdp	  else
51733965Sjdp	    {
51833965Sjdp	      /* -mEMUL */
51933965Sjdp	      emulation = &argv[i][2];
52033965Sjdp	    }
52133965Sjdp	}
52233965Sjdp    }
52333965Sjdp
52433965Sjdp  return emulation;
52533965Sjdp}
52633965Sjdp
52733965Sjdp/* If directory DIR contains an "ldscripts" subdirectory,
52833965Sjdp   add DIR to the library search path and return true,
52933965Sjdp   else return false.  */
53033965Sjdp
53133965Sjdpstatic boolean
53233965Sjdpcheck_for_scripts_dir (dir)
53333965Sjdp     char *dir;
53433965Sjdp{
53533965Sjdp  size_t dirlen;
53633965Sjdp  char *buf;
53733965Sjdp  struct stat s;
53833965Sjdp  boolean res;
53933965Sjdp
54033965Sjdp  dirlen = strlen (dir);
54133965Sjdp  /* sizeof counts the terminating NUL.  */
54233965Sjdp  buf = (char *) xmalloc (dirlen + sizeof("/ldscripts"));
54333965Sjdp  sprintf (buf, "%s/ldscripts", dir);
54433965Sjdp
54533965Sjdp  res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode);
54633965Sjdp  free (buf);
54733965Sjdp  if (res)
54833965Sjdp    ldfile_add_library_path (dir, false);
54933965Sjdp  return res;
55033965Sjdp}
55133965Sjdp
55233965Sjdp/* Set the default directory for finding script files.
55333965Sjdp   Libraries will be searched for here too, but that's ok.
55433965Sjdp   We look for the "ldscripts" directory in:
55533965Sjdp
55633965Sjdp   SCRIPTDIR (passed from Makefile)
55733965Sjdp   the dir where this program is (for using it from the build tree)
55833965Sjdp   the dir where this program is/../lib (for installing the tool suite elsewhere) */
55933965Sjdp
56033965Sjdpstatic void
56133965Sjdpset_scripts_dir ()
56233965Sjdp{
56333965Sjdp  char *end, *dir;
56433965Sjdp  size_t dirlen;
56533965Sjdp
56633965Sjdp  if (check_for_scripts_dir (SCRIPTDIR))
56733965Sjdp    return;			/* We've been installed normally.  */
56833965Sjdp
56933965Sjdp  /* Look for "ldscripts" in the dir where our binary is.  */
57033965Sjdp  end = strrchr (program_name, '/');
57161843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM
57261843Sobrien  {
57361843Sobrien    /* We could have \foo\bar, or /foo\bar.  */
57461843Sobrien    char *bslash = strrchr (program_name, '\\');
57561843Sobrien    if (bslash > end)
57661843Sobrien      end = bslash;
57761843Sobrien  }
57861843Sobrien#endif
57933965Sjdp
58033965Sjdp  if (end == NULL)
58133965Sjdp    {
58233965Sjdp      /* Don't look for ldscripts in the current directory.  There is
58333965Sjdp         too much potential for confusion.  */
58433965Sjdp      return;
58533965Sjdp    }
58633965Sjdp
58733965Sjdp  dirlen = end - program_name;
58833965Sjdp  /* Make a copy of program_name in dir.
58933965Sjdp     Leave room for later "/../lib".  */
59033965Sjdp  dir = (char *) xmalloc (dirlen + 8);
59133965Sjdp  strncpy (dir, program_name, dirlen);
59233965Sjdp  dir[dirlen] = '\0';
59333965Sjdp
59433965Sjdp  if (check_for_scripts_dir (dir))
59533965Sjdp    return;			/* Don't free dir.  */
59633965Sjdp
59733965Sjdp  /* Look for "ldscripts" in <the dir where our binary is>/../lib.  */
59833965Sjdp  strcpy (dir + dirlen, "/../lib");
59933965Sjdp  if (check_for_scripts_dir (dir))
60033965Sjdp    return;
60133965Sjdp
60233965Sjdp  free (dir);			/* Well, we tried.  */
60333965Sjdp}
60433965Sjdp
60533965Sjdpvoid
60633965Sjdpadd_ysym (name)
60733965Sjdp     const char *name;
60833965Sjdp{
60933965Sjdp  if (link_info.notice_hash == (struct bfd_hash_table *) NULL)
61033965Sjdp    {
61133965Sjdp      link_info.notice_hash = ((struct bfd_hash_table *)
61233965Sjdp			       xmalloc (sizeof (struct bfd_hash_table)));
61333965Sjdp      if (! bfd_hash_table_init_n (link_info.notice_hash,
61433965Sjdp				   bfd_hash_newfunc,
61533965Sjdp				   61))
61660484Sobrien	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
61733965Sjdp    }
61833965Sjdp
61933965Sjdp  if (bfd_hash_lookup (link_info.notice_hash, name, true, true)
62033965Sjdp      == (struct bfd_hash_entry *) NULL)
62160484Sobrien    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
62233965Sjdp}
62333965Sjdp
62433965Sjdp/* Record a symbol to be wrapped, from the --wrap option.  */
62533965Sjdp
62633965Sjdpvoid
62733965Sjdpadd_wrap (name)
62833965Sjdp     const char *name;
62933965Sjdp{
63033965Sjdp  if (link_info.wrap_hash == NULL)
63133965Sjdp    {
63233965Sjdp      link_info.wrap_hash = ((struct bfd_hash_table *)
63333965Sjdp			     xmalloc (sizeof (struct bfd_hash_table)));
63433965Sjdp      if (! bfd_hash_table_init_n (link_info.wrap_hash,
63533965Sjdp				   bfd_hash_newfunc,
63633965Sjdp				   61))
63760484Sobrien	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
63833965Sjdp    }
63933965Sjdp  if (bfd_hash_lookup (link_info.wrap_hash, name, true, true) == NULL)
64060484Sobrien    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
64133965Sjdp}
64233965Sjdp
64333965Sjdp/* Handle the -retain-symbols-file option.  */
64433965Sjdp
64533965Sjdpvoid
64633965Sjdpadd_keepsyms_file (filename)
64733965Sjdp     const char *filename;
64833965Sjdp{
64933965Sjdp  FILE *file;
65033965Sjdp  char *buf;
65133965Sjdp  size_t bufsize;
65233965Sjdp  int c;
65333965Sjdp
65433965Sjdp  if (link_info.strip == strip_some)
65560484Sobrien    einfo (_("%X%P: error: duplicate retain-symbols-file\n"));
65633965Sjdp
65733965Sjdp  file = fopen (filename, "r");
65833965Sjdp  if (file == (FILE *) NULL)
65933965Sjdp    {
66033965Sjdp      bfd_set_error (bfd_error_system_call);
66133965Sjdp      einfo ("%X%P: %s: %E\n", filename);
66233965Sjdp      return;
66333965Sjdp    }
66433965Sjdp
66533965Sjdp  link_info.keep_hash = ((struct bfd_hash_table *)
66633965Sjdp			 xmalloc (sizeof (struct bfd_hash_table)));
66733965Sjdp  if (! bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc))
66860484Sobrien    einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
66933965Sjdp
67033965Sjdp  bufsize = 100;
67133965Sjdp  buf = (char *) xmalloc (bufsize);
67233965Sjdp
67333965Sjdp  c = getc (file);
67433965Sjdp  while (c != EOF)
67533965Sjdp    {
67633965Sjdp      while (isspace (c))
67733965Sjdp	c = getc (file);
67833965Sjdp
67933965Sjdp      if (c != EOF)
68033965Sjdp	{
68133965Sjdp	  size_t len = 0;
68233965Sjdp
68333965Sjdp	  while (! isspace (c) && c != EOF)
68433965Sjdp	    {
68533965Sjdp	      buf[len] = c;
68633965Sjdp	      ++len;
68733965Sjdp	      if (len >= bufsize)
68833965Sjdp		{
68933965Sjdp		  bufsize *= 2;
69033965Sjdp		  buf = xrealloc (buf, bufsize);
69133965Sjdp		}
69233965Sjdp	      c = getc (file);
69333965Sjdp	    }
69433965Sjdp
69533965Sjdp	  buf[len] = '\0';
69633965Sjdp
69733965Sjdp	  if (bfd_hash_lookup (link_info.keep_hash, buf, true, true)
69833965Sjdp	      == (struct bfd_hash_entry *) NULL)
69960484Sobrien	    einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n"));
70033965Sjdp	}
70133965Sjdp    }
70233965Sjdp
70333965Sjdp  if (link_info.strip != strip_none)
70460484Sobrien    einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"));
70533965Sjdp
70633965Sjdp  link_info.strip = strip_some;
70733965Sjdp}
70833965Sjdp
70933965Sjdp/* Callbacks from the BFD linker routines.  */
71033965Sjdp
71133965Sjdp/* This is called when BFD has decided to include an archive member in
71233965Sjdp   a link.  */
71333965Sjdp
71433965Sjdp/*ARGSUSED*/
71533965Sjdpstatic boolean
71633965Sjdpadd_archive_element (info, abfd, name)
71760484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
71833965Sjdp     bfd *abfd;
71933965Sjdp     const char *name;
72033965Sjdp{
72133965Sjdp  lang_input_statement_type *input;
72233965Sjdp
72333965Sjdp  input = ((lang_input_statement_type *)
72433965Sjdp	   xmalloc (sizeof (lang_input_statement_type)));
72533965Sjdp  input->filename = abfd->filename;
72633965Sjdp  input->local_sym_name = abfd->filename;
72733965Sjdp  input->the_bfd = abfd;
72833965Sjdp  input->asymbols = NULL;
72933965Sjdp  input->next = NULL;
73033965Sjdp  input->just_syms_flag = false;
73133965Sjdp  input->loaded = false;
73233965Sjdp  input->search_dirs_flag = false;
73333965Sjdp
73433965Sjdp  /* FIXME: The following fields are not set: header.next,
73533965Sjdp     header.type, closed, passive_position, symbol_count,
73633965Sjdp     next_real_file, is_archive, target, real.  This bit of code is
73733965Sjdp     from the old decode_library_subfile function.  I don't know
73833965Sjdp     whether any of those fields matters.  */
73933965Sjdp
74033965Sjdp  ldlang_add_file (input);
74133965Sjdp
74233965Sjdp  if (config.map_file != (FILE *) NULL)
74333965Sjdp    {
74433965Sjdp      static boolean header_printed;
74533965Sjdp      struct bfd_link_hash_entry *h;
74633965Sjdp      bfd *from;
74733965Sjdp      int len;
74833965Sjdp
74933965Sjdp      h = bfd_link_hash_lookup (link_info.hash, name, false, false, true);
75033965Sjdp
75133965Sjdp      if (h == NULL)
75233965Sjdp	from = NULL;
75333965Sjdp      else
75433965Sjdp	{
75533965Sjdp	  switch (h->type)
75633965Sjdp	    {
75733965Sjdp	    default:
75833965Sjdp	      from = NULL;
75933965Sjdp	      break;
76033965Sjdp
76133965Sjdp	    case bfd_link_hash_defined:
76233965Sjdp	    case bfd_link_hash_defweak:
76333965Sjdp	      from = h->u.def.section->owner;
76433965Sjdp	      break;
76533965Sjdp
76633965Sjdp	    case bfd_link_hash_undefined:
76733965Sjdp	    case bfd_link_hash_undefweak:
76833965Sjdp	      from = h->u.undef.abfd;
76933965Sjdp	      break;
77033965Sjdp
77133965Sjdp	    case bfd_link_hash_common:
77233965Sjdp	      from = h->u.c.p->section->owner;
77333965Sjdp	      break;
77433965Sjdp	    }
77533965Sjdp	}
77633965Sjdp
77733965Sjdp      if (! header_printed)
77833965Sjdp	{
77933965Sjdp	  char buf[100];
78033965Sjdp
78160484Sobrien	  sprintf (buf, "%-29s %s\n\n", _("Archive member included"),
78260484Sobrien		   _("because of file (symbol)"));
78333965Sjdp	  minfo ("%s", buf);
78433965Sjdp	  header_printed = true;
78533965Sjdp	}
78633965Sjdp
78733965Sjdp      if (bfd_my_archive (abfd) == NULL)
78833965Sjdp	{
78933965Sjdp	  minfo ("%s", bfd_get_filename (abfd));
79033965Sjdp	  len = strlen (bfd_get_filename (abfd));
79133965Sjdp	}
79233965Sjdp      else
79333965Sjdp	{
79433965Sjdp	  minfo ("%s(%s)", bfd_get_filename (bfd_my_archive (abfd)),
79533965Sjdp		 bfd_get_filename (abfd));
79633965Sjdp	  len = (strlen (bfd_get_filename (bfd_my_archive (abfd)))
79733965Sjdp		 + strlen (bfd_get_filename (abfd))
79833965Sjdp		 + 2);
79933965Sjdp	}
80033965Sjdp
80133965Sjdp      if (len >= 29)
80233965Sjdp	{
80333965Sjdp	  print_nl ();
80433965Sjdp	  len = 0;
80533965Sjdp	}
80633965Sjdp      while (len < 30)
80733965Sjdp	{
80833965Sjdp	  print_space ();
80933965Sjdp	  ++len;
81033965Sjdp	}
81133965Sjdp
81233965Sjdp      if (from != NULL)
81333965Sjdp	minfo ("%B ", from);
81433965Sjdp      if (h != NULL)
81533965Sjdp	minfo ("(%T)\n", h->root.string);
81633965Sjdp      else
81733965Sjdp	minfo ("(%s)\n", name);
81833965Sjdp    }
81933965Sjdp
82033965Sjdp  if (trace_files || trace_file_tries)
82133965Sjdp    info_msg ("%I\n", input);
82233965Sjdp
82333965Sjdp  return true;
82433965Sjdp}
82533965Sjdp
82633965Sjdp/* This is called when BFD has discovered a symbol which is defined
82733965Sjdp   multiple times.  */
82833965Sjdp
82933965Sjdp/*ARGSUSED*/
83033965Sjdpstatic boolean
83133965Sjdpmultiple_definition (info, name, obfd, osec, oval, nbfd, nsec, nval)
83260484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
83333965Sjdp     const char *name;
83433965Sjdp     bfd *obfd;
83533965Sjdp     asection *osec;
83633965Sjdp     bfd_vma oval;
83733965Sjdp     bfd *nbfd;
83833965Sjdp     asection *nsec;
83933965Sjdp     bfd_vma nval;
84033965Sjdp{
84133965Sjdp  /* If either section has the output_section field set to
84233965Sjdp     bfd_abs_section_ptr, it means that the section is being
84333965Sjdp     discarded, and this is not really a multiple definition at all.
84433965Sjdp     FIXME: It would be cleaner to somehow ignore symbols defined in
84533965Sjdp     sections which are being discarded.  */
84633965Sjdp  if ((osec->output_section != NULL
84733965Sjdp       && ! bfd_is_abs_section (osec)
84833965Sjdp       && bfd_is_abs_section (osec->output_section))
84933965Sjdp      || (nsec->output_section != NULL
85033965Sjdp	  && ! bfd_is_abs_section (nsec)
85133965Sjdp	  && bfd_is_abs_section (nsec->output_section)))
85233965Sjdp    return true;
85333965Sjdp
85460484Sobrien  einfo (_("%X%C: multiple definition of `%T'\n"),
85533965Sjdp	 nbfd, nsec, nval, name);
85633965Sjdp  if (obfd != (bfd *) NULL)
85760484Sobrien    einfo (_("%D: first defined here\n"), obfd, osec, oval);
85833965Sjdp  return true;
85933965Sjdp}
86033965Sjdp
86133965Sjdp/* This is called when there is a definition of a common symbol, or
86233965Sjdp   when a common symbol is found for a symbol that is already defined,
86333965Sjdp   or when two common symbols are found.  We only do something if
86433965Sjdp   -warn-common was used.  */
86533965Sjdp
86633965Sjdp/*ARGSUSED*/
86733965Sjdpstatic boolean
86833965Sjdpmultiple_common (info, name, obfd, otype, osize, nbfd, ntype, nsize)
86960484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
87033965Sjdp     const char *name;
87133965Sjdp     bfd *obfd;
87233965Sjdp     enum bfd_link_hash_type otype;
87333965Sjdp     bfd_vma osize;
87433965Sjdp     bfd *nbfd;
87533965Sjdp     enum bfd_link_hash_type ntype;
87633965Sjdp     bfd_vma nsize;
87733965Sjdp{
87833965Sjdp  if (! config.warn_common)
87933965Sjdp    return true;
88033965Sjdp
88133965Sjdp  if (ntype == bfd_link_hash_defined
88233965Sjdp      || ntype == bfd_link_hash_defweak
88333965Sjdp      || ntype == bfd_link_hash_indirect)
88433965Sjdp    {
88533965Sjdp      ASSERT (otype == bfd_link_hash_common);
88660484Sobrien      einfo (_("%B: warning: definition of `%T' overriding common\n"),
88733965Sjdp	     nbfd, name);
88833965Sjdp      if (obfd != NULL)
88960484Sobrien	einfo (_("%B: warning: common is here\n"), obfd);
89033965Sjdp    }
89133965Sjdp  else if (otype == bfd_link_hash_defined
89233965Sjdp	   || otype == bfd_link_hash_defweak
89333965Sjdp	   || otype == bfd_link_hash_indirect)
89433965Sjdp    {
89533965Sjdp      ASSERT (ntype == bfd_link_hash_common);
89660484Sobrien      einfo (_("%B: warning: common of `%T' overridden by definition\n"),
89733965Sjdp	     nbfd, name);
89833965Sjdp      if (obfd != NULL)
89960484Sobrien	einfo (_("%B: warning: defined here\n"), obfd);
90033965Sjdp    }
90133965Sjdp  else
90233965Sjdp    {
90333965Sjdp      ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common);
90433965Sjdp      if (osize > nsize)
90533965Sjdp	{
90660484Sobrien	  einfo (_("%B: warning: common of `%T' overridden by larger common\n"),
90733965Sjdp		 nbfd, name);
90833965Sjdp	  if (obfd != NULL)
90960484Sobrien	    einfo (_("%B: warning: larger common is here\n"), obfd);
91033965Sjdp	}
91133965Sjdp      else if (nsize > osize)
91233965Sjdp	{
91360484Sobrien	  einfo (_("%B: warning: common of `%T' overriding smaller common\n"),
91433965Sjdp		 nbfd, name);
91533965Sjdp	  if (obfd != NULL)
91660484Sobrien	    einfo (_("%B: warning: smaller common is here\n"), obfd);
91733965Sjdp	}
91833965Sjdp      else
91933965Sjdp	{
92060484Sobrien	  einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name);
92133965Sjdp	  if (obfd != NULL)
92260484Sobrien	    einfo (_("%B: warning: previous common is here\n"), obfd);
92333965Sjdp	}
92433965Sjdp    }
92533965Sjdp
92633965Sjdp  return true;
92733965Sjdp}
92833965Sjdp
92933965Sjdp/* This is called when BFD has discovered a set element.  H is the
93033965Sjdp   entry in the linker hash table for the set.  SECTION and VALUE
93133965Sjdp   represent a value which should be added to the set.  */
93233965Sjdp
93333965Sjdp/*ARGSUSED*/
93433965Sjdpstatic boolean
93533965Sjdpadd_to_set (info, h, reloc, abfd, section, value)
93660484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
93733965Sjdp     struct bfd_link_hash_entry *h;
93833965Sjdp     bfd_reloc_code_real_type reloc;
93933965Sjdp     bfd *abfd;
94033965Sjdp     asection *section;
94133965Sjdp     bfd_vma value;
94233965Sjdp{
94333965Sjdp  if (config.warn_constructors)
94460484Sobrien    einfo (_("%P: warning: global constructor %s used\n"),
94533965Sjdp	   h->root.string);
94633965Sjdp
94733965Sjdp  if (! config.build_constructors)
94833965Sjdp    return true;
94933965Sjdp
95033965Sjdp  ldctor_add_set_entry (h, reloc, (const char *) NULL, section, value);
95133965Sjdp
95233965Sjdp  if (h->type == bfd_link_hash_new)
95333965Sjdp    {
95433965Sjdp      h->type = bfd_link_hash_undefined;
95533965Sjdp      h->u.undef.abfd = abfd;
95633965Sjdp      /* We don't call bfd_link_add_undef to add this to the list of
95733965Sjdp	 undefined symbols because we are going to define it
95833965Sjdp	 ourselves.  */
95933965Sjdp    }
96033965Sjdp
96133965Sjdp  return true;
96233965Sjdp}
96333965Sjdp
96433965Sjdp/* This is called when BFD has discovered a constructor.  This is only
96533965Sjdp   called for some object file formats--those which do not handle
96633965Sjdp   constructors in some more clever fashion.  This is similar to
96733965Sjdp   adding an element to a set, but less general.  */
96833965Sjdp
96933965Sjdpstatic boolean
97033965Sjdpconstructor_callback (info, constructor, name, abfd, section, value)
97133965Sjdp     struct bfd_link_info *info;
97233965Sjdp     boolean constructor;
97333965Sjdp     const char *name;
97433965Sjdp     bfd *abfd;
97533965Sjdp     asection *section;
97633965Sjdp     bfd_vma value;
97733965Sjdp{
97833965Sjdp  char *s;
97933965Sjdp  struct bfd_link_hash_entry *h;
98033965Sjdp  char set_name[1 + sizeof "__CTOR_LIST__"];
98133965Sjdp
98233965Sjdp  if (config.warn_constructors)
98360484Sobrien    einfo (_("%P: warning: global constructor %s used\n"), name);
98433965Sjdp
98533965Sjdp  if (! config.build_constructors)
98633965Sjdp    return true;
98733965Sjdp
98833965Sjdp  /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
98933965Sjdp     useful error message.  */
99033965Sjdp  if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL
99133965Sjdp      && (link_info.relocateable
99233965Sjdp	  || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
99360484Sobrien    einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
99433965Sjdp
99533965Sjdp  s = set_name;
99633965Sjdp  if (bfd_get_symbol_leading_char (abfd) != '\0')
99733965Sjdp    *s++ = bfd_get_symbol_leading_char (abfd);
99833965Sjdp  if (constructor)
99933965Sjdp    strcpy (s, "__CTOR_LIST__");
100033965Sjdp  else
100133965Sjdp    strcpy (s, "__DTOR_LIST__");
100233965Sjdp
100333965Sjdp  h = bfd_link_hash_lookup (info->hash, set_name, true, true, true);
100433965Sjdp  if (h == (struct bfd_link_hash_entry *) NULL)
100560484Sobrien    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
100633965Sjdp  if (h->type == bfd_link_hash_new)
100733965Sjdp    {
100833965Sjdp      h->type = bfd_link_hash_undefined;
100933965Sjdp      h->u.undef.abfd = abfd;
101033965Sjdp      /* We don't call bfd_link_add_undef to add this to the list of
101133965Sjdp	 undefined symbols because we are going to define it
101233965Sjdp	 ourselves.  */
101333965Sjdp    }
101433965Sjdp
101533965Sjdp  ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value);
101633965Sjdp  return true;
101733965Sjdp}
101833965Sjdp
101933965Sjdp/* A structure used by warning_callback to pass information through
102033965Sjdp   bfd_map_over_sections.  */
102133965Sjdp
102233965Sjdpstruct warning_callback_info
102333965Sjdp{
102433965Sjdp  boolean found;
102533965Sjdp  const char *warning;
102633965Sjdp  const char *symbol;
102733965Sjdp  asymbol **asymbols;
102833965Sjdp};
102933965Sjdp
103033965Sjdp/* This is called when there is a reference to a warning symbol.  */
103133965Sjdp
103233965Sjdp/*ARGSUSED*/
103333965Sjdpstatic boolean
103433965Sjdpwarning_callback (info, warning, symbol, abfd, section, address)
103560484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
103633965Sjdp     const char *warning;
103733965Sjdp     const char *symbol;
103833965Sjdp     bfd *abfd;
103933965Sjdp     asection *section;
104033965Sjdp     bfd_vma address;
104133965Sjdp{
104233965Sjdp  /* This is a hack to support warn_multiple_gp.  FIXME: This should
104333965Sjdp     have a cleaner interface, but what?  */
104433965Sjdp  if (! config.warn_multiple_gp
104533965Sjdp      && strcmp (warning, "using multiple gp values") == 0)
104633965Sjdp    return true;
104733965Sjdp
104833965Sjdp  if (section != NULL)
104933965Sjdp    einfo ("%C: %s\n", abfd, section, address, warning);
105033965Sjdp  else if (abfd == NULL)
105133965Sjdp    einfo ("%P: %s\n", warning);
105233965Sjdp  else if (symbol == NULL)
105333965Sjdp    einfo ("%B: %s\n", abfd, warning);
105433965Sjdp  else
105533965Sjdp    {
105633965Sjdp      lang_input_statement_type *entry;
105733965Sjdp      asymbol **asymbols;
105833965Sjdp      struct warning_callback_info info;
105933965Sjdp
106033965Sjdp      /* Look through the relocs to see if we can find a plausible
106133965Sjdp	 address.  */
106233965Sjdp
106333965Sjdp      entry = (lang_input_statement_type *) abfd->usrdata;
106433965Sjdp      if (entry != NULL && entry->asymbols != NULL)
106533965Sjdp	asymbols = entry->asymbols;
106633965Sjdp      else
106733965Sjdp	{
106833965Sjdp	  long symsize;
106933965Sjdp	  long symbol_count;
107033965Sjdp
107133965Sjdp	  symsize = bfd_get_symtab_upper_bound (abfd);
107233965Sjdp	  if (symsize < 0)
107360484Sobrien	    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
107433965Sjdp	  asymbols = (asymbol **) xmalloc (symsize);
107533965Sjdp	  symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
107633965Sjdp	  if (symbol_count < 0)
107760484Sobrien	    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
107833965Sjdp	  if (entry != NULL)
107933965Sjdp	    {
108033965Sjdp	      entry->asymbols = asymbols;
108133965Sjdp	      entry->symbol_count = symbol_count;
108233965Sjdp	    }
108333965Sjdp	}
108433965Sjdp
108533965Sjdp      info.found = false;
108633965Sjdp      info.warning = warning;
108733965Sjdp      info.symbol = symbol;
108833965Sjdp      info.asymbols = asymbols;
108933965Sjdp      bfd_map_over_sections (abfd, warning_find_reloc, (PTR) &info);
109033965Sjdp
109133965Sjdp      if (! info.found)
109233965Sjdp	einfo ("%B: %s\n", abfd, warning);
109333965Sjdp
109433965Sjdp      if (entry == NULL)
109533965Sjdp	free (asymbols);
109633965Sjdp    }
109733965Sjdp
109833965Sjdp  return true;
109933965Sjdp}
110033965Sjdp
110133965Sjdp/* This is called by warning_callback for each section.  It checks the
110233965Sjdp   relocs of the section to see if it can find a reference to the
110333965Sjdp   symbol which triggered the warning.  If it can, it uses the reloc
110433965Sjdp   to give an error message with a file and line number.  */
110533965Sjdp
110633965Sjdpstatic void
110733965Sjdpwarning_find_reloc (abfd, sec, iarg)
110833965Sjdp     bfd *abfd;
110933965Sjdp     asection *sec;
111033965Sjdp     PTR iarg;
111133965Sjdp{
111233965Sjdp  struct warning_callback_info *info = (struct warning_callback_info *) iarg;
111333965Sjdp  long relsize;
111433965Sjdp  arelent **relpp;
111533965Sjdp  long relcount;
111633965Sjdp  arelent **p, **pend;
111733965Sjdp
111833965Sjdp  if (info->found)
111933965Sjdp    return;
112033965Sjdp
112133965Sjdp  relsize = bfd_get_reloc_upper_bound (abfd, sec);
112233965Sjdp  if (relsize < 0)
112360484Sobrien    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
112433965Sjdp  if (relsize == 0)
112533965Sjdp    return;
112633965Sjdp
112733965Sjdp  relpp = (arelent **) xmalloc (relsize);
112833965Sjdp  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
112933965Sjdp  if (relcount < 0)
113060484Sobrien    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
113133965Sjdp
113233965Sjdp  p = relpp;
113333965Sjdp  pend = p + relcount;
113433965Sjdp  for (; p < pend && *p != NULL; p++)
113533965Sjdp    {
113633965Sjdp      arelent *q = *p;
113733965Sjdp
113833965Sjdp      if (q->sym_ptr_ptr != NULL
113933965Sjdp	  && *q->sym_ptr_ptr != NULL
114033965Sjdp	  && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
114133965Sjdp	{
114233965Sjdp	  /* We found a reloc for the symbol we are looking for.  */
114333965Sjdp	  einfo ("%C: %s\n", abfd, sec, q->address, info->warning);
114433965Sjdp	  info->found = true;
114533965Sjdp	  break;
114633965Sjdp	}
114733965Sjdp    }
114833965Sjdp
114933965Sjdp  free (relpp);
115033965Sjdp}
115133965Sjdp
115233965Sjdp/* This is called when an undefined symbol is found.  */
115333965Sjdp
115433965Sjdp/*ARGSUSED*/
115533965Sjdpstatic boolean
115660484Sobrienundefined_symbol (info, name, abfd, section, address, fatal)
115760484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
115833965Sjdp     const char *name;
115933965Sjdp     bfd *abfd;
116033965Sjdp     asection *section;
116133965Sjdp     bfd_vma address;
116260484Sobrien     boolean fatal;
116333965Sjdp{
116433965Sjdp  static char *error_name;
116533965Sjdp  static unsigned int error_count;
116633965Sjdp
116733965Sjdp#define MAX_ERRORS_IN_A_ROW 5
116833965Sjdp
116933965Sjdp  if (config.warn_once)
117033965Sjdp    {
117133965Sjdp      static struct bfd_hash_table *hash;
117233965Sjdp
117333965Sjdp      /* Only warn once about a particular undefined symbol.  */
117433965Sjdp
117533965Sjdp      if (hash == NULL)
117633965Sjdp	{
117733965Sjdp	  hash = ((struct bfd_hash_table *)
117833965Sjdp		  xmalloc (sizeof (struct bfd_hash_table)));
117933965Sjdp	  if (! bfd_hash_table_init (hash, bfd_hash_newfunc))
118060484Sobrien	    einfo (_("%F%P: bfd_hash_table_init failed: %E\n"));
118133965Sjdp	}
118233965Sjdp
118333965Sjdp      if (bfd_hash_lookup (hash, name, false, false) != NULL)
118433965Sjdp	return true;
118533965Sjdp
118633965Sjdp      if (bfd_hash_lookup (hash, name, true, true) == NULL)
118760484Sobrien	einfo (_("%F%P: bfd_hash_lookup failed: %E\n"));
118833965Sjdp    }
118933965Sjdp
119033965Sjdp  /* We never print more than a reasonable number of errors in a row
119133965Sjdp     for a single symbol.  */
119233965Sjdp  if (error_name != (char *) NULL
119333965Sjdp      && strcmp (name, error_name) == 0)
119433965Sjdp    ++error_count;
119533965Sjdp  else
119633965Sjdp    {
119733965Sjdp      error_count = 0;
119833965Sjdp      if (error_name != (char *) NULL)
119933965Sjdp	free (error_name);
120033965Sjdp      error_name = buystring (name);
120133965Sjdp    }
120233965Sjdp
120333965Sjdp  if (section != NULL)
120433965Sjdp    {
120533965Sjdp      if (error_count < MAX_ERRORS_IN_A_ROW)
120660484Sobrien	{
120760484Sobrien	  einfo (_("%C: undefined reference to `%T'\n"),
120860484Sobrien		 abfd, section, address, name);
120960484Sobrien	  if (fatal)
121060484Sobrien	    einfo ("%X");
121160484Sobrien	}
121233965Sjdp      else if (error_count == MAX_ERRORS_IN_A_ROW)
121360484Sobrien	einfo (_("%D: more undefined references to `%T' follow\n"),
121433965Sjdp	       abfd, section, address, name);
121533965Sjdp    }
121633965Sjdp  else
121733965Sjdp    {
121833965Sjdp      if (error_count < MAX_ERRORS_IN_A_ROW)
121960484Sobrien	{
122060484Sobrien	  einfo (_("%B: undefined reference to `%T'\n"),
122160484Sobrien		 abfd, name);
122260484Sobrien	  if (fatal)
122360484Sobrien	    einfo ("%X");
122460484Sobrien	}
122533965Sjdp      else if (error_count == MAX_ERRORS_IN_A_ROW)
122660484Sobrien	einfo (_("%B: more undefined references to `%T' follow\n"),
122733965Sjdp	       abfd, name);
122833965Sjdp    }
122933965Sjdp
123033965Sjdp  return true;
123133965Sjdp}
123233965Sjdp
123333965Sjdp/* This is called when a reloc overflows.  */
123433965Sjdp
123533965Sjdp/*ARGSUSED*/
123633965Sjdpstatic boolean
123733965Sjdpreloc_overflow (info, name, reloc_name, addend, abfd, section, address)
123860484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
123933965Sjdp     const char *name;
124033965Sjdp     const char *reloc_name;
124133965Sjdp     bfd_vma addend;
124233965Sjdp     bfd *abfd;
124333965Sjdp     asection *section;
124433965Sjdp     bfd_vma address;
124533965Sjdp{
124633965Sjdp  if (abfd == (bfd *) NULL)
124760484Sobrien    einfo (_("%P%X: generated"));
124833965Sjdp  else
124933965Sjdp    einfo ("%X%C:", abfd, section, address);
125060484Sobrien  einfo (_(" relocation truncated to fit: %s %T"), reloc_name, name);
125133965Sjdp  if (addend != 0)
125233965Sjdp    einfo ("+%v", addend);
125333965Sjdp  einfo ("\n");
125433965Sjdp  return true;
125533965Sjdp}
125633965Sjdp
125733965Sjdp/* This is called when a dangerous relocation is made.  */
125833965Sjdp
125933965Sjdp/*ARGSUSED*/
126033965Sjdpstatic boolean
126133965Sjdpreloc_dangerous (info, message, abfd, section, address)
126260484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
126333965Sjdp     const char *message;
126433965Sjdp     bfd *abfd;
126533965Sjdp     asection *section;
126633965Sjdp     bfd_vma address;
126733965Sjdp{
126833965Sjdp  if (abfd == (bfd *) NULL)
126960484Sobrien    einfo (_("%P%X: generated"));
127033965Sjdp  else
127133965Sjdp    einfo ("%X%C:", abfd, section, address);
127260484Sobrien  einfo (_("dangerous relocation: %s\n"), message);
127333965Sjdp  return true;
127433965Sjdp}
127533965Sjdp
127633965Sjdp/* This is called when a reloc is being generated attached to a symbol
127733965Sjdp   that is not being output.  */
127833965Sjdp
127933965Sjdp/*ARGSUSED*/
128033965Sjdpstatic boolean
128133965Sjdpunattached_reloc (info, name, abfd, section, address)
128260484Sobrien     struct bfd_link_info *info ATTRIBUTE_UNUSED;
128333965Sjdp     const char *name;
128433965Sjdp     bfd *abfd;
128533965Sjdp     asection *section;
128633965Sjdp     bfd_vma address;
128733965Sjdp{
128833965Sjdp  if (abfd == (bfd *) NULL)
128960484Sobrien    einfo (_("%P%X: generated"));
129033965Sjdp  else
129133965Sjdp    einfo ("%X%C:", abfd, section, address);
129260484Sobrien  einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name);
129333965Sjdp  return true;
129433965Sjdp}
129533965Sjdp
129633965Sjdp/* This is called if link_info.notice_all is set, or when a symbol in
129733965Sjdp   link_info.notice_hash is found.  Symbols are put in notice_hash
129833965Sjdp   using the -y option.  */
129933965Sjdp
130033965Sjdpstatic boolean
130133965Sjdpnotice (info, name, abfd, section, value)
130233965Sjdp     struct bfd_link_info *info;
130333965Sjdp     const char *name;
130433965Sjdp     bfd *abfd;
130533965Sjdp     asection *section;
130633965Sjdp     bfd_vma value;
130733965Sjdp{
130833965Sjdp  if (! info->notice_all
130933965Sjdp      || (info->notice_hash != NULL
131033965Sjdp	  && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL))
131160484Sobrien    {
131260484Sobrien      if (bfd_is_und_section (section))
131360484Sobrien	einfo ("%B: reference to %s\n", abfd, name);
131460484Sobrien      else
131560484Sobrien	einfo ("%B: definition of %s\n", abfd, name);
131660484Sobrien    }
131733965Sjdp
131833965Sjdp  if (command_line.cref || nocrossref_list != NULL)
131933965Sjdp    add_cref (name, abfd, section, value);
132033965Sjdp
132133965Sjdp  return true;
132233965Sjdp}
1323