Blame ld/ldmain.c

Packit ba3681
/* Main program of GNU linker.
Packit ba3681
   Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit ba3681
   Written by Steve Chamberlain steve@cygnus.com
Packit ba3681
Packit ba3681
   This file is part of the GNU Binutils.
Packit ba3681
Packit ba3681
   This program is free software; you can redistribute it and/or modify
Packit ba3681
   it under the terms of the GNU General Public License as published by
Packit ba3681
   the Free Software Foundation; either version 3 of the License, or
Packit ba3681
   (at your option) any later version.
Packit ba3681
Packit ba3681
   This program is distributed in the hope that it will be useful,
Packit ba3681
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ba3681
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit ba3681
   GNU General Public License for more details.
Packit ba3681
Packit ba3681
   You should have received a copy of the GNU General Public License
Packit ba3681
   along with this program; if not, write to the Free Software
Packit ba3681
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
Packit ba3681
   MA 02110-1301, USA.  */
Packit ba3681
Packit ba3681
#include "sysdep.h"
Packit ba3681
#include "bfd.h"
Packit ba3681
#include "safe-ctype.h"
Packit ba3681
#include "libiberty.h"
Packit ba3681
#include "progress.h"
Packit ba3681
#include "bfdlink.h"
Packit ba3681
#include "filenames.h"
Packit ba3681
Packit ba3681
#include "ld.h"
Packit ba3681
#include "ldmain.h"
Packit ba3681
#include "ldmisc.h"
Packit ba3681
#include "ldwrite.h"
Packit ba3681
#include "ldexp.h"
Packit ba3681
#include "ldlang.h"
Packit ba3681
#include <ldgram.h>
Packit ba3681
#include "ldlex.h"
Packit ba3681
#include "ldfile.h"
Packit ba3681
#include "ldemul.h"
Packit ba3681
#include "ldctor.h"
Packit ba3681
#ifdef ENABLE_PLUGINS
Packit ba3681
#include "plugin.h"
Packit ba3681
#include "plugin-api.h"
Packit ba3681
#endif /* ENABLE_PLUGINS */
Packit ba3681
Packit ba3681
/* Somewhere above, sys/stat.h got included.  */
Packit ba3681
#if !defined(S_ISDIR) && defined(S_IFDIR)
Packit ba3681
#define	S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
Packit ba3681
#endif
Packit ba3681
Packit ba3681
#include <string.h>
Packit ba3681
Packit ba3681
#ifndef TARGET_SYSTEM_ROOT
Packit ba3681
#define TARGET_SYSTEM_ROOT ""
Packit ba3681
#endif
Packit ba3681
Packit ba3681
/* EXPORTS */
Packit ba3681
Packit ba3681
FILE *saved_script_handle = NULL;
Packit ba3681
FILE *previous_script_handle = NULL;
Packit ba3681
bfd_boolean force_make_executable = FALSE;
Packit ba3681
Packit ba3681
char *default_target;
Packit ba3681
const char *output_filename = "a.out";
Packit ba3681
Packit ba3681
/* Name this program was invoked by.  */
Packit ba3681
char *program_name;
Packit ba3681
Packit ba3681
/* The prefix for system library directories.  */
Packit ba3681
const char *ld_sysroot;
Packit ba3681
Packit ba3681
/* The canonical representation of ld_sysroot.  */
Packit ba3681
char *ld_canon_sysroot;
Packit ba3681
int ld_canon_sysroot_len;
Packit ba3681
Packit ba3681
/* Set by -G argument, for targets like MIPS ELF.  */
Packit ba3681
int g_switch_value = 8;
Packit ba3681
Packit ba3681
/* Nonzero means print names of input files as processed.  */
Packit ba3681
bfd_boolean trace_files;
Packit ba3681
Packit ba3681
/* Nonzero means report actions taken by the linker, and describe the linker script in use.  */
Packit ba3681
bfd_boolean verbose;
Packit ba3681
Packit ba3681
/* Nonzero means version number was printed, so exit successfully
Packit ba3681
   instead of complaining if no input files are given.  */
Packit ba3681
bfd_boolean version_printed;
Packit ba3681
Packit ba3681
/* TRUE if we should demangle symbol names.  */
Packit ba3681
bfd_boolean demangling;
Packit ba3681
Packit ba3681
args_type command_line;
Packit ba3681
Packit ba3681
ld_config_type config;
Packit ba3681
Packit ba3681
sort_type sort_section;
Packit ba3681
Packit ba3681
static const char *get_sysroot
Packit ba3681
  (int, char **);
Packit ba3681
static char *get_emulation
Packit ba3681
  (int, char **);
Packit ba3681
static bfd_boolean add_archive_element
Packit ba3681
  (struct bfd_link_info *, bfd *, const char *, bfd **);
Packit ba3681
static void multiple_definition
Packit ba3681
  (struct bfd_link_info *, struct bfd_link_hash_entry *,
Packit ba3681
   bfd *, asection *, bfd_vma);
Packit ba3681
static void multiple_common
Packit ba3681
  (struct bfd_link_info *, struct bfd_link_hash_entry *,
Packit ba3681
   bfd *, enum bfd_link_hash_type, bfd_vma);
Packit ba3681
static void add_to_set
Packit ba3681
  (struct bfd_link_info *, struct bfd_link_hash_entry *,
Packit ba3681
   bfd_reloc_code_real_type, bfd *, asection *, bfd_vma);
Packit ba3681
static void constructor_callback
Packit ba3681
  (struct bfd_link_info *, bfd_boolean, const char *, bfd *,
Packit ba3681
   asection *, bfd_vma);
Packit ba3681
static void warning_callback
Packit ba3681
  (struct bfd_link_info *, const char *, const char *, bfd *,
Packit ba3681
   asection *, bfd_vma);
Packit ba3681
static void warning_find_reloc
Packit ba3681
  (bfd *, asection *, void *);
Packit ba3681
static void undefined_symbol
Packit ba3681
  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma,
Packit ba3681
   bfd_boolean);
Packit ba3681
static void reloc_overflow
Packit ba3681
  (struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
Packit ba3681
   const char *, bfd_vma, bfd *, asection *, bfd_vma);
Packit ba3681
static void reloc_dangerous
Packit ba3681
  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
Packit ba3681
static void unattached_reloc
Packit ba3681
  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
Packit ba3681
static bfd_boolean notice
Packit ba3681
  (struct bfd_link_info *, struct bfd_link_hash_entry *,
Packit ba3681
   struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma, flagword);
Packit ba3681
Packit ba3681
static struct bfd_link_callbacks link_callbacks =
Packit ba3681
{
Packit ba3681
  add_archive_element,
Packit ba3681
  multiple_definition,
Packit ba3681
  multiple_common,
Packit ba3681
  add_to_set,
Packit ba3681
  constructor_callback,
Packit ba3681
  warning_callback,
Packit ba3681
  undefined_symbol,
Packit ba3681
  reloc_overflow,
Packit ba3681
  reloc_dangerous,
Packit ba3681
  unattached_reloc,
Packit ba3681
  notice,
Packit ba3681
  einfo,
Packit ba3681
  info_msg,
Packit ba3681
  minfo,
Packit ba3681
  ldlang_override_segment_assignment
Packit ba3681
};
Packit ba3681
Packit ba3681
static bfd_assert_handler_type default_bfd_assert_handler;
Packit ba3681
static bfd_error_handler_type default_bfd_error_handler;
Packit ba3681
Packit ba3681
struct bfd_link_info link_info;
Packit ba3681

Packit ba3681
static void
Packit ba3681
ld_cleanup (void)
Packit ba3681
{
Packit ba3681
  bfd_cache_close_all ();
Packit ba3681
#ifdef ENABLE_PLUGINS
Packit ba3681
  plugin_call_cleanup ();
Packit ba3681
#endif
Packit ba3681
  if (output_filename && delete_output_file_on_failure)
Packit ba3681
    unlink_if_ordinary (output_filename);
Packit ba3681
}
Packit ba3681
Packit ba3681
/* Hook to notice BFD assertions.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
ld_bfd_assert_handler (const char *fmt, const char *bfdver,
Packit ba3681
		       const char *file, int line)
Packit ba3681
{
Packit ba3681
  config.make_executable = FALSE;
Packit ba3681
  (*default_bfd_assert_handler) (fmt, bfdver, file, line);
Packit ba3681
}
Packit ba3681
Packit ba3681
/* Hook the bfd error/warning handler for --fatal-warnings.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
ld_bfd_error_handler (const char *fmt, va_list ap)
Packit ba3681
{
Packit ba3681
  if (config.fatal_warnings)
Packit ba3681
    config.make_executable = FALSE;
Packit ba3681
  (*default_bfd_error_handler) (fmt, ap);
Packit ba3681
}
Packit ba3681
Packit ba3681
int
Packit ba3681
main (int argc, char **argv)
Packit ba3681
{
Packit ba3681
  char *emulation;
Packit ba3681
  long start_time = get_run_time ();
Packit ba3681
Packit ba3681
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
Packit ba3681
  setlocale (LC_MESSAGES, "");
Packit ba3681
#endif
Packit ba3681
#if defined (HAVE_SETLOCALE)
Packit ba3681
  setlocale (LC_CTYPE, "");
Packit ba3681
#endif
Packit ba3681
  bindtextdomain (PACKAGE, LOCALEDIR);
Packit ba3681
  textdomain (PACKAGE);
Packit ba3681
Packit ba3681
  program_name = argv[0];
Packit ba3681
  xmalloc_set_program_name (program_name);
Packit ba3681
Packit ba3681
  START_PROGRESS (program_name, 0);
Packit ba3681
Packit ba3681
  expandargv (&argc, &argv);
Packit ba3681
Packit ba3681
  bfd_init ();
Packit ba3681
Packit ba3681
  bfd_set_error_program_name (program_name);
Packit ba3681
Packit ba3681
  /* We want to notice and fail on those nasty BFD assertions which are
Packit ba3681
     likely to signal incorrect output being generated but otherwise may
Packit ba3681
     leave no trace.  */
Packit ba3681
  default_bfd_assert_handler = bfd_set_assert_handler (ld_bfd_assert_handler);
Packit ba3681
Packit ba3681
  /* Also hook the bfd error/warning handler for --fatal-warnings.  */
Packit ba3681
  default_bfd_error_handler = bfd_set_error_handler (ld_bfd_error_handler);
Packit ba3681
Packit ba3681
  xatexit (ld_cleanup);
Packit ba3681
Packit ba3681
  /* Set up the sysroot directory.  */
Packit ba3681
  ld_sysroot = get_sysroot (argc, argv);
Packit ba3681
  if (*ld_sysroot)
Packit ba3681
    ld_canon_sysroot = lrealpath (ld_sysroot);
Packit ba3681
  if (ld_canon_sysroot)
Packit ba3681
    ld_canon_sysroot_len = strlen (ld_canon_sysroot);
Packit ba3681
  else
Packit ba3681
    ld_canon_sysroot_len = -1;
Packit ba3681
Packit ba3681
  /* Set the default BFD target based on the configured target.  Doing
Packit ba3681
     this permits the linker to be configured for a particular target,
Packit ba3681
     and linked against a shared BFD library which was configured for
Packit ba3681
     a different target.  The macro TARGET is defined by Makefile.  */
Packit ba3681
  if (!bfd_set_default_target (TARGET))
Packit ba3681
    {
Packit ba3681
      einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
Packit ba3681
      xexit (1);
Packit ba3681
    }
Packit ba3681
Packit ba3681
#if YYDEBUG
Packit ba3681
  {
Packit ba3681
    extern int yydebug;
Packit ba3681
    yydebug = 1;
Packit ba3681
  }
Packit ba3681
#endif
Packit ba3681
Packit ba3681
  config.build_constructors = TRUE;
Packit ba3681
  config.rpath_separator = ':';
Packit ba3681
  config.split_by_reloc = (unsigned) -1;
Packit ba3681
  config.split_by_file = (bfd_size_type) -1;
Packit ba3681
  config.make_executable = TRUE;
Packit ba3681
  config.magic_demand_paged = TRUE;
Packit ba3681
  config.text_read_only = TRUE;
Packit ba3681
  link_info.disable_target_specific_optimizations = -1;
Packit ba3681
Packit ba3681
  command_line.warn_mismatch = TRUE;
Packit ba3681
  command_line.warn_search_mismatch = TRUE;
Packit ba3681
  command_line.check_section_addresses = -1;
Packit ba3681
Packit ba3681
  /* We initialize DEMANGLING based on the environment variable
Packit ba3681
     COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
Packit ba3681
     output of the linker, unless COLLECT_NO_DEMANGLE is set in the
Packit ba3681
     environment.  Acting the same way here lets us provide the same
Packit ba3681
     interface by default.  */
Packit ba3681
  demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;
Packit ba3681
Packit ba3681
  link_info.allow_undefined_version = TRUE;
Packit ba3681
  link_info.keep_memory = TRUE;
Packit ba3681
  link_info.combreloc = TRUE;
Packit ba3681
  link_info.strip_discarded = TRUE;
Packit ba3681
  link_info.emit_hash = DEFAULT_EMIT_SYSV_HASH;
Packit ba3681
  link_info.emit_gnu_hash = DEFAULT_EMIT_GNU_HASH;
Packit ba3681
  link_info.callbacks = &link_callbacks;
Packit ba3681
  link_info.input_bfds_tail = &link_info.input_bfds;
Packit ba3681
  /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
Packit ba3681
     and _fini symbols.  We are compatible.  */
Packit ba3681
  link_info.init_function = "_init";
Packit ba3681
  link_info.fini_function = "_fini";
Packit ba3681
  link_info.relax_pass = 1;
Packit ba3681
  link_info.extern_protected_data = -1;
Packit ba3681
  link_info.dynamic_undefined_weak = -1;
Packit ba3681
  link_info.pei386_auto_import = -1;
Packit ba3681
  link_info.spare_dynamic_tags = 5;
Packit ba3681
  link_info.path_separator = ':';
Packit ba3681
#ifdef DEFAULT_FLAG_COMPRESS_DEBUG
Packit ba3681
  link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
Packit ba3681
#endif
Packit ba3681
#ifdef DEFAULT_NEW_DTAGS
Packit ba3681
  link_info.new_dtags = DEFAULT_NEW_DTAGS;
Packit ba3681
#endif
Packit ba3681
Packit ba3681
  ldfile_add_arch ("");
Packit ba3681
  emulation = get_emulation (argc, argv);
Packit ba3681
  ldemul_choose_mode (emulation);
Packit ba3681
  default_target = ldemul_choose_target (argc, argv);
Packit ba3681
  config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
Packit ba3681
  config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
Packit ba3681
  lang_init ();
Packit ba3681
  ldexp_init ();
Packit ba3681
  ldemul_before_parse ();
Packit ba3681
  lang_has_input_file = FALSE;
Packit ba3681
  parse_args (argc, argv);
Packit ba3681
Packit ba3681
  if (config.hash_table_size != 0)
Packit ba3681
    bfd_hash_set_default_size (config.hash_table_size);
Packit ba3681
Packit ba3681
#ifdef ENABLE_PLUGINS
Packit ba3681
  /* Now all the plugin arguments have been gathered, we can load them.  */
Packit ba3681
  plugin_load_plugins ();
Packit ba3681
#endif /* ENABLE_PLUGINS */
Packit ba3681
Packit ba3681
  ldemul_set_symbols ();
Packit ba3681
Packit ba3681
  /* If we have not already opened and parsed a linker script,
Packit ba3681
     try the default script from command line first.  */
Packit ba3681
  if (saved_script_handle == NULL
Packit ba3681
      && command_line.default_script != NULL)
Packit ba3681
    {
Packit ba3681
      ldfile_open_command_file (command_line.default_script);
Packit ba3681
      parser_input = input_script;
Packit ba3681
      yyparse ();
Packit ba3681
    }
Packit ba3681
Packit ba3681
  /* If we have not already opened and parsed a linker script
Packit ba3681
     read the emulation's appropriate default script.  */
Packit ba3681
  if (saved_script_handle == NULL)
Packit ba3681
    {
Packit ba3681
      int isfile;
Packit ba3681
      char *s = ldemul_get_script (&isfile);
Packit ba3681
Packit ba3681
      if (isfile)
Packit ba3681
	ldfile_open_default_command_file (s);
Packit ba3681
      else
Packit ba3681
	{
Packit ba3681
	  lex_string = s;
Packit ba3681
	  lex_redirect (s, _("built in linker script"), 1);
Packit ba3681
	}
Packit ba3681
      parser_input = input_script;
Packit ba3681
      yyparse ();
Packit ba3681
      lex_string = NULL;
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (verbose)
Packit ba3681
    {
Packit ba3681
      if (saved_script_handle)
Packit ba3681
	info_msg (_("using external linker script:"));
Packit ba3681
      else
Packit ba3681
	info_msg (_("using internal linker script:"));
Packit ba3681
      info_msg ("\n==================================================\n");
Packit ba3681
Packit ba3681
      if (saved_script_handle)
Packit ba3681
	{
Packit ba3681
	  static const int ld_bufsz = 8193;
Packit ba3681
	  size_t n;
Packit ba3681
	  char *buf = (char *) xmalloc (ld_bufsz);
Packit ba3681
Packit ba3681
	  rewind (saved_script_handle);
Packit ba3681
	  while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
Packit ba3681
	    {
Packit ba3681
	      buf[n] = 0;
Packit ba3681
	      info_msg ("%s", buf);
Packit ba3681
	    }
Packit ba3681
	  rewind (saved_script_handle);
Packit ba3681
	  free (buf);
Packit ba3681
	}
Packit ba3681
      else
Packit ba3681
	{
Packit ba3681
	  int isfile;
Packit ba3681
Packit ba3681
	  info_msg (ldemul_get_script (&isfile));
Packit ba3681
	}
Packit ba3681
Packit ba3681
      info_msg ("\n==================================================\n");
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (command_line.force_group_allocation
Packit ba3681
      || !bfd_link_relocatable (&link_info))
Packit ba3681
    link_info.resolve_section_groups = TRUE;
Packit ba3681
  else
Packit ba3681
    link_info.resolve_section_groups = FALSE;
Packit ba3681
Packit ba3681
  if (command_line.print_output_format)
Packit ba3681
    info_msg ("%s\n", lang_get_output_target ());
Packit ba3681
Packit ba3681
  lang_final ();
Packit ba3681
Packit ba3681
  /* If the only command line argument has been -v or --version or --verbose
Packit ba3681
     then ignore any input files provided by linker scripts and exit now.
Packit ba3681
     We do not want to create an output file when the linker is just invoked
Packit ba3681
     to provide version information.  */
Packit ba3681
  if (argc == 2 && version_printed)
Packit ba3681
    xexit (0);
Packit ba3681
Packit ba3681
  if (link_info.inhibit_common_definition && !bfd_link_dll (&link_info))
Packit ba3681
    einfo (_("%P%F: --no-define-common may not be used without -shared\n"));
Packit ba3681
Packit ba3681
  if (!lang_has_input_file)
Packit ba3681
    {
Packit ba3681
      if (version_printed || command_line.print_output_format)
Packit ba3681
	xexit (0);
Packit ba3681
      einfo (_("%P%F: no input files\n"));
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (trace_files)
Packit ba3681
    info_msg (_("%P: mode %s\n"), emulation);
Packit ba3681
Packit ba3681
  ldemul_after_parse ();
Packit ba3681
Packit ba3681
  if (config.map_filename)
Packit ba3681
    {
Packit ba3681
      if (strcmp (config.map_filename, "-") == 0)
Packit ba3681
	{
Packit ba3681
	  config.map_file = stdout;
Packit ba3681
	}
Packit ba3681
      else
Packit ba3681
	{
Packit ba3681
	  config.map_file = fopen (config.map_filename, FOPEN_WT);
Packit ba3681
	  if (config.map_file == (FILE *) NULL)
Packit ba3681
	    {
Packit ba3681
	      bfd_set_error (bfd_error_system_call);
Packit ba3681
	      einfo (_("%P%F: cannot open map file %s: %E\n"),
Packit ba3681
		     config.map_filename);
Packit ba3681
	    }
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
Packit ba3681
  lang_process ();
Packit ba3681
Packit ba3681
  /* Print error messages for any missing symbols, for any warning
Packit ba3681
     symbols, and possibly multiple definitions.  */
Packit ba3681
  if (bfd_link_relocatable (&link_info))
Packit ba3681
    link_info.output_bfd->flags &= ~EXEC_P;
Packit ba3681
  else
Packit ba3681
    link_info.output_bfd->flags |= EXEC_P;
Packit ba3681
Packit ba3681
  if ((link_info.compress_debug & COMPRESS_DEBUG))
Packit ba3681
    {
Packit ba3681
      link_info.output_bfd->flags |= BFD_COMPRESS;
Packit ba3681
      if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
Packit ba3681
	link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
Packit ba3681
    }
Packit ba3681
Packit ba3681
  ldwrite ();
Packit ba3681
Packit ba3681
  if (config.map_file != NULL)
Packit ba3681
    lang_map ();
Packit ba3681
  if (command_line.cref)
Packit ba3681
    output_cref (config.map_file != NULL ? config.map_file : stdout);
Packit ba3681
  if (nocrossref_list != NULL)
Packit ba3681
    check_nocrossrefs ();
Packit ba3681
  if (command_line.print_memory_usage)
Packit ba3681
    lang_print_memory_usage ();
Packit ba3681
#if 0
Packit ba3681
  {
Packit ba3681
    struct bfd_link_hash_entry *h;
Packit ba3681
Packit ba3681
    h = bfd_link_hash_lookup (link_info.hash, "__image_base__", 0,0,1);
Packit ba3681
    fprintf (stderr, "lookup = %p val %lx\n", h, h ? h->u.def.value : 1);
Packit ba3681
  }
Packit ba3681
#endif
Packit ba3681
  ldexp_finish ();
Packit ba3681
  lang_finish ();
Packit ba3681
Packit ba3681
  /* Even if we're producing relocatable output, some non-fatal errors should
Packit ba3681
     be reported in the exit status.  (What non-fatal errors, if any, do we
Packit ba3681
     want to ignore for relocatable output?)  */
Packit ba3681
  if (!config.make_executable && !force_make_executable)
Packit ba3681
    {
Packit ba3681
      if (trace_files)
Packit ba3681
	einfo (_("%P: link errors found, deleting executable `%s'\n"),
Packit ba3681
	       output_filename);
Packit ba3681
Packit ba3681
      /* The file will be removed by ld_cleanup.  */
Packit ba3681
      xexit (1);
Packit ba3681
    }
Packit ba3681
  else
Packit ba3681
    {
Packit ba3681
      if (!bfd_close (link_info.output_bfd))
Packit ba3681
	einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd);
Packit ba3681
Packit ba3681
      /* If the --force-exe-suffix is enabled, and we're making an
Packit ba3681
	 executable file and it doesn't end in .exe, copy it to one
Packit ba3681
	 which does.  */
Packit ba3681
      if (!bfd_link_relocatable (&link_info)
Packit ba3681
	  && command_line.force_exe_suffix)
Packit ba3681
	{
Packit ba3681
	  int len = strlen (output_filename);
Packit ba3681
Packit ba3681
	  if (len < 4
Packit ba3681
	      || (strcasecmp (output_filename + len - 4, ".exe") != 0
Packit ba3681
		  && strcasecmp (output_filename + len - 4, ".dll") != 0))
Packit ba3681
	    {
Packit ba3681
	      FILE *src;
Packit ba3681
	      FILE *dst;
Packit ba3681
	      const int bsize = 4096;
Packit ba3681
	      char *buf = (char *) xmalloc (bsize);
Packit ba3681
	      int l;
Packit ba3681
	      char *dst_name = (char *) xmalloc (len + 5);
Packit ba3681
Packit ba3681
	      strcpy (dst_name, output_filename);
Packit ba3681
	      strcat (dst_name, ".exe");
Packit ba3681
	      src = fopen (output_filename, FOPEN_RB);
Packit ba3681
	      dst = fopen (dst_name, FOPEN_WB);
Packit ba3681
Packit ba3681
	      if (!src)
Packit ba3681
		einfo (_("%P%F: unable to open for source of copy `%s'\n"),
Packit ba3681
		       output_filename);
Packit ba3681
	      if (!dst)
Packit ba3681
		einfo (_("%P%F: unable to open for destination of copy `%s'\n"),
Packit ba3681
		       dst_name);
Packit ba3681
	      while ((l = fread (buf, 1, bsize, src)) > 0)
Packit ba3681
		{
Packit ba3681
		  int done = fwrite (buf, 1, l, dst);
Packit ba3681
Packit ba3681
		  if (done != l)
Packit ba3681
		    einfo (_("%P: Error writing file `%s'\n"), dst_name);
Packit ba3681
		}
Packit ba3681
Packit ba3681
	      fclose (src);
Packit ba3681
	      if (fclose (dst) == EOF)
Packit ba3681
		einfo (_("%P: Error closing file `%s'\n"), dst_name);
Packit ba3681
	      free (dst_name);
Packit ba3681
	      free (buf);
Packit ba3681
	    }
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
Packit ba3681
  END_PROGRESS (program_name);
Packit ba3681
Packit ba3681
  if (config.stats)
Packit ba3681
    {
Packit ba3681
      long run_time = get_run_time () - start_time;
Packit ba3681
Packit ba3681
      fflush (stdout);
Packit ba3681
      fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
Packit ba3681
	       program_name, run_time / 1000000, run_time % 1000000);
Packit ba3681
      fflush (stderr);
Packit ba3681
    }
Packit ba3681
Packit ba3681
  /* Prevent ld_cleanup from doing anything, after a successful link.  */
Packit ba3681
  output_filename = NULL;
Packit ba3681
Packit ba3681
  xexit (0);
Packit ba3681
  return 0;
Packit ba3681
}
Packit ba3681
Packit ba3681
/* If the configured sysroot is relocatable, try relocating it based on
Packit ba3681
   default prefix FROM.  Return the relocated directory if it exists,
Packit ba3681
   otherwise return null.  */
Packit ba3681
Packit ba3681
static char *
Packit ba3681
get_relative_sysroot (const char *from ATTRIBUTE_UNUSED)
Packit ba3681
{
Packit ba3681
#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
Packit ba3681
  char *path;
Packit ba3681
  struct stat s;
Packit ba3681
Packit ba3681
  path = make_relative_prefix (program_name, from, TARGET_SYSTEM_ROOT);
Packit ba3681
  if (path)
Packit ba3681
    {
Packit ba3681
      if (stat (path, &s) == 0 && S_ISDIR (s.st_mode))
Packit ba3681
	return path;
Packit ba3681
      free (path);
Packit ba3681
    }
Packit ba3681
#endif
Packit ba3681
  return 0;
Packit ba3681
}
Packit ba3681
Packit ba3681
/* Return the sysroot directory.  Return "" if no sysroot is being used.  */
Packit ba3681
Packit ba3681
static const char *
Packit ba3681
get_sysroot (int argc, char **argv)
Packit ba3681
{
Packit ba3681
  int i;
Packit ba3681
  const char *path;
Packit ba3681
Packit ba3681
  for (i = 1; i < argc; i++)
Packit ba3681
    if (CONST_STRNEQ (argv[i], "--sysroot="))
Packit ba3681
      return argv[i] + strlen ("--sysroot=");
Packit ba3681
Packit ba3681
  path = get_relative_sysroot (BINDIR);
Packit ba3681
  if (path)
Packit ba3681
    return path;
Packit ba3681
Packit ba3681
  path = get_relative_sysroot (TOOLBINDIR);
Packit ba3681
  if (path)
Packit ba3681
    return path;
Packit ba3681
Packit ba3681
  return TARGET_SYSTEM_ROOT;
Packit ba3681
}
Packit ba3681
Packit ba3681
/* We need to find any explicitly given emulation in order to initialize the
Packit ba3681
   state that's needed by the lex&yacc argument parser (parse_args).  */
Packit ba3681
Packit ba3681
static char *
Packit ba3681
get_emulation (int argc, char **argv)
Packit ba3681
{
Packit ba3681
  char *emulation;
Packit ba3681
  int i;
Packit ba3681
Packit ba3681
  emulation = getenv (EMULATION_ENVIRON);
Packit ba3681
  if (emulation == NULL)
Packit ba3681
    emulation = DEFAULT_EMULATION;
Packit ba3681
Packit ba3681
  for (i = 1; i < argc; i++)
Packit ba3681
    {
Packit ba3681
      if (CONST_STRNEQ (argv[i], "-m"))
Packit ba3681
	{
Packit ba3681
	  if (argv[i][2] == '\0')
Packit ba3681
	    {
Packit ba3681
	      /* -m EMUL */
Packit ba3681
	      if (i < argc - 1)
Packit ba3681
		{
Packit ba3681
		  emulation = argv[i + 1];
Packit ba3681
		  i++;
Packit ba3681
		}
Packit ba3681
	      else
Packit ba3681
		einfo (_("%P%F: missing argument to -m\n"));
Packit ba3681
	    }
Packit ba3681
	  else if (strcmp (argv[i], "-mips1") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips2") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips3") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips4") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips5") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips32") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips32r2") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips32r6") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips64") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips64r2") == 0
Packit ba3681
		   || strcmp (argv[i], "-mips64r6") == 0)
Packit ba3681
	    {
Packit ba3681
	      /* FIXME: The arguments -mips1, -mips2, -mips3, etc. are
Packit ba3681
		 passed to the linker by some MIPS compilers.  They
Packit ba3681
		 generally tell the linker to use a slightly different
Packit ba3681
		 library path.  Perhaps someday these should be
Packit ba3681
		 implemented as emulations; until then, we just ignore
Packit ba3681
		 the arguments and hope that nobody ever creates
Packit ba3681
		 emulations named ips1, ips2 or ips3.  */
Packit ba3681
	    }
Packit ba3681
	  else if (strcmp (argv[i], "-m486") == 0)
Packit ba3681
	    {
Packit ba3681
	      /* FIXME: The argument -m486 is passed to the linker on
Packit ba3681
		 some Linux systems.  Hope that nobody creates an
Packit ba3681
		 emulation named 486.  */
Packit ba3681
	    }
Packit ba3681
	  else
Packit ba3681
	    {
Packit ba3681
	      /* -mEMUL */
Packit ba3681
	      emulation = &argv[i][2];
Packit ba3681
	    }
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
Packit ba3681
  return emulation;
Packit ba3681
}
Packit ba3681
Packit ba3681
void
Packit ba3681
add_ysym (const char *name)
Packit ba3681
{
Packit ba3681
  if (link_info.notice_hash == NULL)
Packit ba3681
    {
Packit ba3681
      link_info.notice_hash
Packit ba3681
	= (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table));
Packit ba3681
      if (!bfd_hash_table_init_n (link_info.notice_hash,
Packit ba3681
				  bfd_hash_newfunc,
Packit ba3681
				  sizeof (struct bfd_hash_entry),
Packit ba3681
				  61))
Packit ba3681
	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (bfd_hash_lookup (link_info.notice_hash, name, TRUE, TRUE) == NULL)
Packit ba3681
    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
Packit ba3681
}
Packit ba3681
Packit ba3681
void
Packit ba3681
add_ignoresym (struct bfd_link_info *info, const char *name)
Packit ba3681
{
Packit ba3681
  if (info->ignore_hash == NULL)
Packit ba3681
    {
Packit ba3681
      info->ignore_hash = xmalloc (sizeof (struct bfd_hash_table));
Packit ba3681
      if (!bfd_hash_table_init_n (info->ignore_hash,
Packit ba3681
				  bfd_hash_newfunc,
Packit ba3681
				  sizeof (struct bfd_hash_entry),
Packit ba3681
				  61))
Packit ba3681
	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (bfd_hash_lookup (info->ignore_hash, name, TRUE, TRUE) == NULL)
Packit ba3681
    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
Packit ba3681
}
Packit ba3681
Packit ba3681
/* Record a symbol to be wrapped, from the --wrap option.  */
Packit ba3681
Packit ba3681
void
Packit ba3681
add_wrap (const char *name)
Packit ba3681
{
Packit ba3681
  if (link_info.wrap_hash == NULL)
Packit ba3681
    {
Packit ba3681
      link_info.wrap_hash
Packit ba3681
	= (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table));
Packit ba3681
      if (!bfd_hash_table_init_n (link_info.wrap_hash,
Packit ba3681
				  bfd_hash_newfunc,
Packit ba3681
				  sizeof (struct bfd_hash_entry),
Packit ba3681
				  61))
Packit ba3681
	einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (bfd_hash_lookup (link_info.wrap_hash, name, TRUE, TRUE) == NULL)
Packit ba3681
    einfo (_("%P%F: bfd_hash_lookup failed: %E\n"));
Packit ba3681
}
Packit ba3681
Packit ba3681
/* Handle the -retain-symbols-file option.  */
Packit ba3681
Packit ba3681
void
Packit ba3681
add_keepsyms_file (const char *filename)
Packit ba3681
{
Packit ba3681
  FILE *file;
Packit ba3681
  char *buf;
Packit ba3681
  size_t bufsize;
Packit ba3681
  int c;
Packit ba3681
Packit ba3681
  if (link_info.strip == strip_some)
Packit ba3681
    einfo (_("%X%P: error: duplicate retain-symbols-file\n"));
Packit ba3681
Packit ba3681
  file = fopen (filename, "r");
Packit ba3681
  if (file == NULL)
Packit ba3681
    {
Packit ba3681
      bfd_set_error (bfd_error_system_call);
Packit ba3681
      einfo ("%X%P: %s: %E\n", filename);
Packit ba3681
      return;
Packit ba3681
    }
Packit ba3681
Packit ba3681
  link_info.keep_hash = (struct bfd_hash_table *)
Packit ba3681
      xmalloc (sizeof (struct bfd_hash_table));
Packit ba3681
  if (!bfd_hash_table_init (link_info.keep_hash, bfd_hash_newfunc,
Packit ba3681
			    sizeof (struct bfd_hash_entry)))
Packit ba3681
    einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
Packit ba3681
Packit ba3681
  bufsize = 100;
Packit ba3681
  buf = (char *) xmalloc (bufsize);
Packit ba3681
Packit ba3681
  c = getc (file);
Packit ba3681
  while (c != EOF)
Packit ba3681
    {
Packit ba3681
      while (ISSPACE (c))
Packit ba3681
	c = getc (file);
Packit ba3681
Packit ba3681
      if (c != EOF)
Packit ba3681
	{
Packit ba3681
	  size_t len = 0;
Packit ba3681
Packit ba3681
	  while (!ISSPACE (c) && c != EOF)
Packit ba3681
	    {
Packit ba3681
	      buf[len] = c;
Packit ba3681
	      ++len;
Packit ba3681
	      if (len >= bufsize)
Packit ba3681
		{
Packit ba3681
		  bufsize *= 2;
Packit ba3681
		  buf = (char *) xrealloc (buf, bufsize);
Packit ba3681
		}
Packit ba3681
	      c = getc (file);
Packit ba3681
	    }
Packit ba3681
Packit ba3681
	  buf[len] = '\0';
Packit ba3681
Packit ba3681
	  if (bfd_hash_lookup (link_info.keep_hash, buf, TRUE, TRUE) == NULL)
Packit ba3681
	    einfo (_("%P%F: bfd_hash_lookup for insertion failed: %E\n"));
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (link_info.strip != strip_none)
Packit ba3681
    einfo (_("%P: `-retain-symbols-file' overrides `-s' and `-S'\n"));
Packit ba3681
Packit ba3681
  free (buf);
Packit ba3681
  link_info.strip = strip_some;
Packit ba3681
  fclose (file);
Packit ba3681
}
Packit ba3681

Packit ba3681
/* Callbacks from the BFD linker routines.  */
Packit ba3681
Packit ba3681
/* This is called when BFD has decided to include an archive member in
Packit ba3681
   a link.  */
Packit ba3681
Packit ba3681
static bfd_boolean
Packit ba3681
add_archive_element (struct bfd_link_info *info,
Packit ba3681
		     bfd *abfd,
Packit ba3681
		     const char *name,
Packit ba3681
		     bfd **subsbfd ATTRIBUTE_UNUSED)
Packit ba3681
{
Packit ba3681
  lang_input_statement_type *input;
Packit ba3681
  lang_input_statement_type orig_input;
Packit ba3681
Packit ba3681
  input = (lang_input_statement_type *)
Packit ba3681
      xcalloc (1, sizeof (lang_input_statement_type));
Packit ba3681
  input->header.type = lang_input_statement_enum;
Packit ba3681
  input->filename = abfd->filename;
Packit ba3681
  input->local_sym_name = abfd->filename;
Packit ba3681
  input->the_bfd = abfd;
Packit ba3681
Packit ba3681
  /* Save the original data for trace files/tries below, as plugins
Packit ba3681
     (if enabled) may possibly alter it to point to a replacement
Packit ba3681
     BFD, but we still want to output the original BFD filename.  */
Packit ba3681
  orig_input = *input;
Packit ba3681
#ifdef ENABLE_PLUGINS
Packit ba3681
  if (link_info.lto_plugin_active)
Packit ba3681
    {
Packit ba3681
      /* We must offer this archive member to the plugins to claim.  */
Packit ba3681
      plugin_maybe_claim (input);
Packit ba3681
      if (input->flags.claimed)
Packit ba3681
	{
Packit ba3681
	  if (no_more_claiming)
Packit ba3681
	    {
Packit ba3681
	      /* Don't claim new IR symbols after all IR symbols have
Packit ba3681
		 been claimed.  */
Packit ba3681
	      if (trace_files || verbose)
Packit ba3681
		info_msg ("%I: no new IR symbols to claimi\n",
Packit ba3681
			  &orig_input);
Packit ba3681
	      input->flags.claimed = 0;
Packit ba3681
	      return FALSE;
Packit ba3681
	    }
Packit ba3681
	  input->flags.claim_archive = TRUE;
Packit ba3681
	  *subsbfd = input->the_bfd;
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
#endif /* ENABLE_PLUGINS */
Packit ba3681
Packit ba3681
  ldlang_add_file (input);
Packit ba3681
Packit ba3681
  if (config.map_file != NULL)
Packit ba3681
    {
Packit ba3681
      static bfd_boolean header_printed;
Packit ba3681
      struct bfd_link_hash_entry *h;
Packit ba3681
      bfd *from;
Packit ba3681
      int len;
Packit ba3681
Packit ba3681
      h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
Packit ba3681
Packit ba3681
      if (h == NULL)
Packit ba3681
	from = NULL;
Packit ba3681
      else
Packit ba3681
	{
Packit ba3681
	  switch (h->type)
Packit ba3681
	    {
Packit ba3681
	    default:
Packit ba3681
	      from = NULL;
Packit ba3681
	      break;
Packit ba3681
Packit ba3681
	    case bfd_link_hash_defined:
Packit ba3681
	    case bfd_link_hash_defweak:
Packit ba3681
	      from = h->u.def.section->owner;
Packit ba3681
	      break;
Packit ba3681
Packit ba3681
	    case bfd_link_hash_undefined:
Packit ba3681
	    case bfd_link_hash_undefweak:
Packit ba3681
	      from = h->u.undef.abfd;
Packit ba3681
	      break;
Packit ba3681
Packit ba3681
	    case bfd_link_hash_common:
Packit ba3681
	      from = h->u.c.p->section->owner;
Packit ba3681
	      break;
Packit ba3681
	    }
Packit ba3681
	}
Packit ba3681
Packit ba3681
      if (!header_printed)
Packit ba3681
	{
Packit ba3681
	  minfo (_("Archive member included to satisfy reference by file (symbol)\n\n"));
Packit ba3681
	  header_printed = TRUE;
Packit ba3681
	}
Packit ba3681
Packit ba3681
      if (abfd->my_archive == NULL
Packit ba3681
	  || bfd_is_thin_archive (abfd->my_archive))
Packit ba3681
	{
Packit ba3681
	  minfo ("%s", bfd_get_filename (abfd));
Packit ba3681
	  len = strlen (bfd_get_filename (abfd));
Packit ba3681
	}
Packit ba3681
      else
Packit ba3681
	{
Packit ba3681
	  minfo ("%s(%s)", bfd_get_filename (abfd->my_archive),
Packit ba3681
		 bfd_get_filename (abfd));
Packit ba3681
	  len = (strlen (bfd_get_filename (abfd->my_archive))
Packit ba3681
		 + strlen (bfd_get_filename (abfd))
Packit ba3681
		 + 2);
Packit ba3681
	}
Packit ba3681
Packit ba3681
      if (len >= 29)
Packit ba3681
	{
Packit ba3681
	  print_nl ();
Packit ba3681
	  len = 0;
Packit ba3681
	}
Packit ba3681
      while (len < 30)
Packit ba3681
	{
Packit ba3681
	  print_space ();
Packit ba3681
	  ++len;
Packit ba3681
	}
Packit ba3681
Packit ba3681
      if (from != NULL)
Packit ba3681
	minfo ("%B ", from);
Packit ba3681
      if (h != NULL)
Packit ba3681
	minfo ("(%T)\n", h->root.string);
Packit ba3681
      else
Packit ba3681
	minfo ("(%s)\n", name);
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (trace_files || verbose)
Packit ba3681
    info_msg ("%I\n", &orig_input);
Packit ba3681
  return TRUE;
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when BFD has discovered a symbol which is defined
Packit ba3681
   multiple times.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
multiple_definition (struct bfd_link_info *info,
Packit ba3681
		     struct bfd_link_hash_entry *h,
Packit ba3681
		     bfd *nbfd,
Packit ba3681
		     asection *nsec,
Packit ba3681
		     bfd_vma nval)
Packit ba3681
{
Packit ba3681
  const char *name;
Packit ba3681
  bfd *obfd;
Packit ba3681
  asection *osec;
Packit ba3681
  bfd_vma oval;
Packit ba3681
Packit ba3681
  if (info->allow_multiple_definition)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  switch (h->type)
Packit ba3681
    {
Packit ba3681
    case bfd_link_hash_defined:
Packit ba3681
      osec = h->u.def.section;
Packit ba3681
      oval = h->u.def.value;
Packit ba3681
      obfd = h->u.def.section->owner;
Packit ba3681
      break;
Packit ba3681
    case bfd_link_hash_indirect:
Packit ba3681
      osec = bfd_ind_section_ptr;
Packit ba3681
      oval = 0;
Packit ba3681
      obfd = NULL;
Packit ba3681
      break;
Packit ba3681
    default:
Packit ba3681
      abort ();
Packit ba3681
    }
Packit ba3681
Packit ba3681
  /* Ignore a redefinition of an absolute symbol to the
Packit ba3681
     same value; it's harmless.  */
Packit ba3681
  if (h->type == bfd_link_hash_defined
Packit ba3681
      && bfd_is_abs_section (osec)
Packit ba3681
      && bfd_is_abs_section (nsec)
Packit ba3681
      && nval == oval)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  /* If either section has the output_section field set to
Packit ba3681
     bfd_abs_section_ptr, it means that the section is being
Packit ba3681
     discarded, and this is not really a multiple definition at all.
Packit ba3681
     FIXME: It would be cleaner to somehow ignore symbols defined in
Packit ba3681
     sections which are being discarded.  */
Packit ba3681
  if ((osec->output_section != NULL
Packit ba3681
       && !bfd_is_abs_section (osec)
Packit ba3681
       && bfd_is_abs_section (osec->output_section))
Packit ba3681
      || (nsec->output_section != NULL
Packit ba3681
	  && !bfd_is_abs_section (nsec)
Packit ba3681
	  && bfd_is_abs_section (nsec->output_section)))
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  name = h->root.string;
Packit ba3681
  if (nbfd == NULL)
Packit ba3681
    {
Packit ba3681
      nbfd = obfd;
Packit ba3681
      nsec = osec;
Packit ba3681
      nval = oval;
Packit ba3681
      obfd = NULL;
Packit ba3681
    }
Packit ba3681
  einfo (_("%X%C: multiple definition of `%T'\n"),
Packit ba3681
	 nbfd, nsec, nval, name);
Packit ba3681
  if (obfd != NULL)
Packit ba3681
    einfo (_("%D: first defined here\n"), obfd, osec, oval);
Packit ba3681
Packit ba3681
  if (RELAXATION_ENABLED_BY_USER)
Packit ba3681
    {
Packit ba3681
      einfo (_("%P: Disabling relaxation: it will not work with multiple definitions\n"));
Packit ba3681
      DISABLE_RELAXATION;
Packit ba3681
    }
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when there is a definition of a common symbol, or
Packit ba3681
   when a common symbol is found for a symbol that is already defined,
Packit ba3681
   or when two common symbols are found.  We only do something if
Packit ba3681
   -warn-common was used.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
Packit ba3681
		 struct bfd_link_hash_entry *h,
Packit ba3681
		 bfd *nbfd,
Packit ba3681
		 enum bfd_link_hash_type ntype,
Packit ba3681
		 bfd_vma nsize)
Packit ba3681
{
Packit ba3681
  const char *name;
Packit ba3681
  bfd *obfd;
Packit ba3681
  enum bfd_link_hash_type otype;
Packit ba3681
  bfd_vma osize;
Packit ba3681
Packit ba3681
  if (!config.warn_common)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  name = h->root.string;
Packit ba3681
  otype = h->type;
Packit ba3681
  if (otype == bfd_link_hash_common)
Packit ba3681
    {
Packit ba3681
      obfd = h->u.c.p->section->owner;
Packit ba3681
      osize = h->u.c.size;
Packit ba3681
    }
Packit ba3681
  else if (otype == bfd_link_hash_defined
Packit ba3681
	   || otype == bfd_link_hash_defweak)
Packit ba3681
    {
Packit ba3681
      obfd = h->u.def.section->owner;
Packit ba3681
      osize = 0;
Packit ba3681
    }
Packit ba3681
  else
Packit ba3681
    {
Packit ba3681
      /* FIXME: It would nice if we could report the BFD which defined
Packit ba3681
	 an indirect symbol, but we don't have anywhere to store the
Packit ba3681
	 information.  */
Packit ba3681
      obfd = NULL;
Packit ba3681
      osize = 0;
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (ntype == bfd_link_hash_defined
Packit ba3681
      || ntype == bfd_link_hash_defweak
Packit ba3681
      || ntype == bfd_link_hash_indirect)
Packit ba3681
    {
Packit ba3681
      ASSERT (otype == bfd_link_hash_common);
Packit ba3681
      einfo (_("%B: warning: definition of `%T' overriding common\n"),
Packit ba3681
	     nbfd, name);
Packit ba3681
      if (obfd != NULL)
Packit ba3681
	einfo (_("%B: warning: common is here\n"), obfd);
Packit ba3681
    }
Packit ba3681
  else if (otype == bfd_link_hash_defined
Packit ba3681
	   || otype == bfd_link_hash_defweak
Packit ba3681
	   || otype == bfd_link_hash_indirect)
Packit ba3681
    {
Packit ba3681
      ASSERT (ntype == bfd_link_hash_common);
Packit ba3681
      einfo (_("%B: warning: common of `%T' overridden by definition\n"),
Packit ba3681
	     nbfd, name);
Packit ba3681
      if (obfd != NULL)
Packit ba3681
	einfo (_("%B: warning: defined here\n"), obfd);
Packit ba3681
    }
Packit ba3681
  else
Packit ba3681
    {
Packit ba3681
      ASSERT (otype == bfd_link_hash_common && ntype == bfd_link_hash_common);
Packit ba3681
      if (osize > nsize)
Packit ba3681
	{
Packit ba3681
	  einfo (_("%B: warning: common of `%T' overridden by larger common\n"),
Packit ba3681
		 nbfd, name);
Packit ba3681
	  if (obfd != NULL)
Packit ba3681
	    einfo (_("%B: warning: larger common is here\n"), obfd);
Packit ba3681
	}
Packit ba3681
      else if (nsize > osize)
Packit ba3681
	{
Packit ba3681
	  einfo (_("%B: warning: common of `%T' overriding smaller common\n"),
Packit ba3681
		 nbfd, name);
Packit ba3681
	  if (obfd != NULL)
Packit ba3681
	    einfo (_("%B: warning: smaller common is here\n"), obfd);
Packit ba3681
	}
Packit ba3681
      else
Packit ba3681
	{
Packit ba3681
	  einfo (_("%B: warning: multiple common of `%T'\n"), nbfd, name);
Packit ba3681
	  if (obfd != NULL)
Packit ba3681
	    einfo (_("%B: warning: previous common is here\n"), obfd);
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when BFD has discovered a set element.  H is the
Packit ba3681
   entry in the linker hash table for the set.  SECTION and VALUE
Packit ba3681
   represent a value which should be added to the set.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
add_to_set (struct bfd_link_info *info ATTRIBUTE_UNUSED,
Packit ba3681
	    struct bfd_link_hash_entry *h,
Packit ba3681
	    bfd_reloc_code_real_type reloc,
Packit ba3681
	    bfd *abfd,
Packit ba3681
	    asection *section,
Packit ba3681
	    bfd_vma value)
Packit ba3681
{
Packit ba3681
  if (config.warn_constructors)
Packit ba3681
    einfo (_("%P: warning: global constructor %s used\n"),
Packit ba3681
	   h->root.string);
Packit ba3681
Packit ba3681
  if (!config.build_constructors)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  ldctor_add_set_entry (h, reloc, NULL, section, value);
Packit ba3681
Packit ba3681
  if (h->type == bfd_link_hash_new)
Packit ba3681
    {
Packit ba3681
      h->type = bfd_link_hash_undefined;
Packit ba3681
      h->u.undef.abfd = abfd;
Packit ba3681
      /* We don't call bfd_link_add_undef to add this to the list of
Packit ba3681
	 undefined symbols because we are going to define it
Packit ba3681
	 ourselves.  */
Packit ba3681
    }
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when BFD has discovered a constructor.  This is only
Packit ba3681
   called for some object file formats--those which do not handle
Packit ba3681
   constructors in some more clever fashion.  This is similar to
Packit ba3681
   adding an element to a set, but less general.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
constructor_callback (struct bfd_link_info *info,
Packit ba3681
		      bfd_boolean constructor,
Packit ba3681
		      const char *name,
Packit ba3681
		      bfd *abfd,
Packit ba3681
		      asection *section,
Packit ba3681
		      bfd_vma value)
Packit ba3681
{
Packit ba3681
  char *s;
Packit ba3681
  struct bfd_link_hash_entry *h;
Packit ba3681
  char set_name[1 + sizeof "__CTOR_LIST__"];
Packit ba3681
Packit ba3681
  if (config.warn_constructors)
Packit ba3681
    einfo (_("%P: warning: global constructor %s used\n"), name);
Packit ba3681
Packit ba3681
  if (!config.build_constructors)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
Packit ba3681
     useful error message.  */
Packit ba3681
  if (bfd_reloc_type_lookup (info->output_bfd, BFD_RELOC_CTOR) == NULL
Packit ba3681
      && (bfd_link_relocatable (info)
Packit ba3681
	  || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
Packit ba3681
    einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
Packit ba3681
Packit ba3681
  s = set_name;
Packit ba3681
  if (bfd_get_symbol_leading_char (abfd) != '\0')
Packit ba3681
    *s++ = bfd_get_symbol_leading_char (abfd);
Packit ba3681
  if (constructor)
Packit ba3681
    strcpy (s, "__CTOR_LIST__");
Packit ba3681
  else
Packit ba3681
    strcpy (s, "__DTOR_LIST__");
Packit ba3681
Packit ba3681
  h = bfd_link_hash_lookup (info->hash, set_name, TRUE, TRUE, TRUE);
Packit ba3681
  if (h == (struct bfd_link_hash_entry *) NULL)
Packit ba3681
    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
Packit ba3681
  if (h->type == bfd_link_hash_new)
Packit ba3681
    {
Packit ba3681
      h->type = bfd_link_hash_undefined;
Packit ba3681
      h->u.undef.abfd = abfd;
Packit ba3681
      /* We don't call bfd_link_add_undef to add this to the list of
Packit ba3681
	 undefined symbols because we are going to define it
Packit ba3681
	 ourselves.  */
Packit ba3681
    }
Packit ba3681
Packit ba3681
  ldctor_add_set_entry (h, BFD_RELOC_CTOR, name, section, value);
Packit ba3681
}
Packit ba3681
Packit ba3681
/* A structure used by warning_callback to pass information through
Packit ba3681
   bfd_map_over_sections.  */
Packit ba3681
Packit ba3681
struct warning_callback_info
Packit ba3681
{
Packit ba3681
  bfd_boolean found;
Packit ba3681
  const char *warning;
Packit ba3681
  const char *symbol;
Packit ba3681
  asymbol **asymbols;
Packit ba3681
};
Packit ba3681
Packit ba3681
/* Look through the relocs to see if we can find a plausible address
Packit ba3681
   for SYMBOL in ABFD.  Return TRUE if found.  Otherwise return FALSE.  */
Packit ba3681
Packit ba3681
static bfd_boolean
Packit ba3681
symbol_warning (const char *warning, const char *symbol, bfd *abfd)
Packit ba3681
{
Packit ba3681
  struct warning_callback_info cinfo;
Packit ba3681
Packit ba3681
  if (!bfd_generic_link_read_symbols (abfd))
Packit ba3681
    einfo (_("%B%F: could not read symbols: %E\n"), abfd);
Packit ba3681
Packit ba3681
  cinfo.found = FALSE;
Packit ba3681
  cinfo.warning = warning;
Packit ba3681
  cinfo.symbol = symbol;
Packit ba3681
  cinfo.asymbols = bfd_get_outsymbols (abfd);
Packit ba3681
  bfd_map_over_sections (abfd, warning_find_reloc, &cinfo);
Packit ba3681
  return cinfo.found;
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when there is a reference to a warning symbol.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
warning_callback (struct bfd_link_info *info ATTRIBUTE_UNUSED,
Packit ba3681
		  const char *warning,
Packit ba3681
		  const char *symbol,
Packit ba3681
		  bfd *abfd,
Packit ba3681
		  asection *section,
Packit ba3681
		  bfd_vma address)
Packit ba3681
{
Packit ba3681
  /* This is a hack to support warn_multiple_gp.  FIXME: This should
Packit ba3681
     have a cleaner interface, but what?  */
Packit ba3681
  if (!config.warn_multiple_gp
Packit ba3681
      && strcmp (warning, "using multiple gp values") == 0)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  if (section != NULL)
Packit ba3681
    einfo ("%C: %s%s\n", abfd, section, address, _("warning: "), warning);
Packit ba3681
  else if (abfd == NULL)
Packit ba3681
    einfo ("%P: %s%s\n", _("warning: "), warning);
Packit ba3681
  else if (symbol == NULL)
Packit ba3681
    einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
Packit ba3681
  else if (!symbol_warning (warning, symbol, abfd))
Packit ba3681
    {
Packit ba3681
      bfd *b;
Packit ba3681
      /* Search all input files for a reference to SYMBOL.  */
Packit ba3681
      for (b = info->input_bfds; b; b = b->link.next)
Packit ba3681
	if (b != abfd && symbol_warning (warning, symbol, b))
Packit ba3681
	  return;
Packit ba3681
      einfo ("%B: %s%s\n", abfd, _("warning: "), warning);
Packit ba3681
    }
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called by warning_callback for each section.  It checks the
Packit ba3681
   relocs of the section to see if it can find a reference to the
Packit ba3681
   symbol which triggered the warning.  If it can, it uses the reloc
Packit ba3681
   to give an error message with a file and line number.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
warning_find_reloc (bfd *abfd, asection *sec, void *iarg)
Packit ba3681
{
Packit ba3681
  struct warning_callback_info *info = (struct warning_callback_info *) iarg;
Packit ba3681
  long relsize;
Packit ba3681
  arelent **relpp;
Packit ba3681
  long relcount;
Packit ba3681
  arelent **p, **pend;
Packit ba3681
Packit ba3681
  if (info->found)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  relsize = bfd_get_reloc_upper_bound (abfd, sec);
Packit ba3681
  if (relsize < 0)
Packit ba3681
    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
Packit ba3681
  if (relsize == 0)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  relpp = (arelent **) xmalloc (relsize);
Packit ba3681
  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
Packit ba3681
  if (relcount < 0)
Packit ba3681
    einfo (_("%B%F: could not read relocs: %E\n"), abfd);
Packit ba3681
Packit ba3681
  p = relpp;
Packit ba3681
  pend = p + relcount;
Packit ba3681
  for (; p < pend && *p != NULL; p++)
Packit ba3681
    {
Packit ba3681
      arelent *q = *p;
Packit ba3681
Packit ba3681
      if (q->sym_ptr_ptr != NULL
Packit ba3681
	  && *q->sym_ptr_ptr != NULL
Packit ba3681
	  && strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), info->symbol) == 0)
Packit ba3681
	{
Packit ba3681
	  /* We found a reloc for the symbol we are looking for.  */
Packit ba3681
	  einfo ("%C: %s%s\n", abfd, sec, q->address, _("warning: "),
Packit ba3681
		 info->warning);
Packit ba3681
	  info->found = TRUE;
Packit ba3681
	  break;
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
Packit ba3681
  free (relpp);
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when an undefined symbol is found.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
undefined_symbol (struct bfd_link_info *info,
Packit ba3681
		  const char *name,
Packit ba3681
		  bfd *abfd,
Packit ba3681
		  asection *section,
Packit ba3681
		  bfd_vma address,
Packit ba3681
		  bfd_boolean error)
Packit ba3681
{
Packit ba3681
  static char *error_name;
Packit ba3681
  static unsigned int error_count;
Packit ba3681
Packit ba3681
#define MAX_ERRORS_IN_A_ROW 5
Packit ba3681
Packit ba3681
  if (info->ignore_hash != NULL
Packit ba3681
      && bfd_hash_lookup (info->ignore_hash, name, FALSE, FALSE) != NULL)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  if (config.warn_once)
Packit ba3681
    {
Packit ba3681
      /* Only warn once about a particular undefined symbol.  */
Packit ba3681
      add_ignoresym (info, name);
Packit ba3681
    }
Packit ba3681
Packit ba3681
  /* We never print more than a reasonable number of errors in a row
Packit ba3681
     for a single symbol.  */
Packit ba3681
  if (error_name != NULL
Packit ba3681
      && strcmp (name, error_name) == 0)
Packit ba3681
    ++error_count;
Packit ba3681
  else
Packit ba3681
    {
Packit ba3681
      error_count = 0;
Packit ba3681
      if (error_name != NULL)
Packit ba3681
	free (error_name);
Packit ba3681
      error_name = xstrdup (name);
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (section != NULL)
Packit ba3681
    {
Packit ba3681
      if (error_count < MAX_ERRORS_IN_A_ROW)
Packit ba3681
	{
Packit ba3681
	  if (error)
Packit ba3681
	    einfo (_("%X%C: undefined reference to `%T'\n"),
Packit ba3681
		   abfd, section, address, name);
Packit ba3681
	  else
Packit ba3681
	    einfo (_("%C: warning: undefined reference to `%T'\n"),
Packit ba3681
		   abfd, section, address, name);
Packit ba3681
	}
Packit ba3681
      else if (error_count == MAX_ERRORS_IN_A_ROW)
Packit ba3681
	{
Packit ba3681
	  if (error)
Packit ba3681
	    einfo (_("%X%D: more undefined references to `%T' follow\n"),
Packit ba3681
		   abfd, section, address, name);
Packit ba3681
	  else
Packit ba3681
	    einfo (_("%D: warning: more undefined references to `%T' follow\n"),
Packit ba3681
		   abfd, section, address, name);
Packit ba3681
	}
Packit ba3681
      else if (error)
Packit ba3681
	einfo ("%X");
Packit ba3681
    }
Packit ba3681
  else
Packit ba3681
    {
Packit ba3681
      if (error_count < MAX_ERRORS_IN_A_ROW)
Packit ba3681
	{
Packit ba3681
	  if (error)
Packit ba3681
	    einfo (_("%X%B: undefined reference to `%T'\n"),
Packit ba3681
		   abfd, name);
Packit ba3681
	  else
Packit ba3681
	    einfo (_("%B: warning: undefined reference to `%T'\n"),
Packit ba3681
		   abfd, name);
Packit ba3681
	}
Packit ba3681
      else if (error_count == MAX_ERRORS_IN_A_ROW)
Packit ba3681
	{
Packit ba3681
	  if (error)
Packit ba3681
	    einfo (_("%X%B: more undefined references to `%T' follow\n"),
Packit ba3681
		   abfd, name);
Packit ba3681
	  else
Packit ba3681
	    einfo (_("%B: warning: more undefined references to `%T' follow\n"),
Packit ba3681
		   abfd, name);
Packit ba3681
	}
Packit ba3681
      else if (error)
Packit ba3681
	einfo ("%X");
Packit ba3681
    }
Packit ba3681
}
Packit ba3681
Packit ba3681
/* Counter to limit the number of relocation overflow error messages
Packit ba3681
   to print.  Errors are printed as it is decremented.  When it's
Packit ba3681
   called and the counter is zero, a final message is printed
Packit ba3681
   indicating more relocations were omitted.  When it gets to -1, no
Packit ba3681
   such errors are printed.  If it's initially set to a value less
Packit ba3681
   than -1, all such errors will be printed (--verbose does this).  */
Packit ba3681
Packit ba3681
int overflow_cutoff_limit = 10;
Packit ba3681
Packit ba3681
/* This is called when a reloc overflows.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
reloc_overflow (struct bfd_link_info *info,
Packit ba3681
		struct bfd_link_hash_entry *entry,
Packit ba3681
		const char *name,
Packit ba3681
		const char *reloc_name,
Packit ba3681
		bfd_vma addend,
Packit ba3681
		bfd *abfd,
Packit ba3681
		asection *section,
Packit ba3681
		bfd_vma address)
Packit ba3681
{
Packit ba3681
  if (overflow_cutoff_limit == -1)
Packit ba3681
    return;
Packit ba3681
Packit ba3681
  einfo ("%X%H:", abfd, section, address);
Packit ba3681
Packit ba3681
  if (overflow_cutoff_limit >= 0
Packit ba3681
      && overflow_cutoff_limit-- == 0)
Packit ba3681
    {
Packit ba3681
      einfo (_(" additional relocation overflows omitted from the output\n"));
Packit ba3681
      return;
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (entry)
Packit ba3681
    {
Packit ba3681
      while (entry->type == bfd_link_hash_indirect
Packit ba3681
	     || entry->type == bfd_link_hash_warning)
Packit ba3681
	entry = entry->u.i.link;
Packit ba3681
      switch (entry->type)
Packit ba3681
	{
Packit ba3681
	case bfd_link_hash_undefined:
Packit ba3681
	case bfd_link_hash_undefweak:
Packit ba3681
	  einfo (_(" relocation truncated to fit: "
Packit ba3681
		   "%s against undefined symbol `%T'"),
Packit ba3681
		 reloc_name, entry->root.string);
Packit ba3681
	  break;
Packit ba3681
	case bfd_link_hash_defined:
Packit ba3681
	case bfd_link_hash_defweak:
Packit ba3681
	  einfo (_(" relocation truncated to fit: "
Packit ba3681
		   "%s against symbol `%T' defined in %A section in %B"),
Packit ba3681
		 reloc_name, entry->root.string,
Packit ba3681
		 entry->u.def.section,
Packit ba3681
		 entry->u.def.section == bfd_abs_section_ptr
Packit ba3681
		 ? info->output_bfd : entry->u.def.section->owner);
Packit ba3681
	  break;
Packit ba3681
	default:
Packit ba3681
	  abort ();
Packit ba3681
	  break;
Packit ba3681
	}
Packit ba3681
    }
Packit ba3681
  else
Packit ba3681
    einfo (_(" relocation truncated to fit: %s against `%T'"),
Packit ba3681
	   reloc_name, name);
Packit ba3681
  if (addend != 0)
Packit ba3681
    einfo ("+%v", addend);
Packit ba3681
  einfo ("\n");
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when a dangerous relocation is made.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
reloc_dangerous (struct bfd_link_info *info ATTRIBUTE_UNUSED,
Packit ba3681
		 const char *message,
Packit ba3681
		 bfd *abfd,
Packit ba3681
		 asection *section,
Packit ba3681
		 bfd_vma address)
Packit ba3681
{
Packit ba3681
  einfo (_("%X%H: dangerous relocation: %s\n"),
Packit ba3681
	 abfd, section, address, message);
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called when a reloc is being generated attached to a symbol
Packit ba3681
   that is not being output.  */
Packit ba3681
Packit ba3681
static void
Packit ba3681
unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
Packit ba3681
		  const char *name,
Packit ba3681
		  bfd *abfd,
Packit ba3681
		  asection *section,
Packit ba3681
		  bfd_vma address)
Packit ba3681
{
Packit ba3681
  einfo (_("%X%H: reloc refers to symbol `%T' which is not being output\n"),
Packit ba3681
	 abfd, section, address, name);
Packit ba3681
}
Packit ba3681
Packit ba3681
/* This is called if link_info.notice_all is set, or when a symbol in
Packit ba3681
   link_info.notice_hash is found.  Symbols are put in notice_hash
Packit ba3681
   using the -y option, while notice_all is set if the --cref option
Packit ba3681
   has been supplied, or if there are any NOCROSSREFS sections in the
Packit ba3681
   linker script; and if plugins are active, since they need to monitor
Packit ba3681
   all references from non-IR files.  */
Packit ba3681
Packit ba3681
static bfd_boolean
Packit ba3681
notice (struct bfd_link_info *info,
Packit ba3681
	struct bfd_link_hash_entry *h,
Packit ba3681
	struct bfd_link_hash_entry *inh ATTRIBUTE_UNUSED,
Packit ba3681
	bfd *abfd,
Packit ba3681
	asection *section,
Packit ba3681
	bfd_vma value,
Packit ba3681
	flagword flags ATTRIBUTE_UNUSED)
Packit ba3681
{
Packit ba3681
  const char *name;
Packit ba3681
Packit ba3681
  if (h == NULL)
Packit ba3681
    {
Packit ba3681
      if (command_line.cref || nocrossref_list != NULL)
Packit ba3681
	return handle_asneeded_cref (abfd, (enum notice_asneeded_action) value);
Packit ba3681
      return TRUE;
Packit ba3681
    }
Packit ba3681
Packit ba3681
  name = h->root.string;
Packit ba3681
  if (info->notice_hash != NULL
Packit ba3681
      && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)
Packit ba3681
    {
Packit ba3681
      if (bfd_is_und_section (section))
Packit ba3681
	einfo (_("%B: reference to %s\n"), abfd, name);
Packit ba3681
      else
Packit ba3681
	einfo (_("%B: definition of %s\n"), abfd, name);
Packit ba3681
    }
Packit ba3681
Packit ba3681
  if (command_line.cref || nocrossref_list != NULL)
Packit ba3681
    add_cref (name, abfd, section, value);
Packit ba3681
Packit ba3681
  return TRUE;
Packit ba3681
}