/* linker.c -- BFD linker routines
   Copyright (C) 1993-2026 Free Software Foundation, Inc.
   Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "bfdlink.h"
#include "genlink.h"

/*
SECTION
	Linker Functions

@cindex Linker
	The linker uses three special entry points in the BFD target
	vector.  It is not necessary to write special routines for
	these entry points when creating a new BFD back end, since
	generic versions are provided.  However, writing them can
	speed up linking and make it use significantly less runtime
	memory.

	The first routine creates a hash table used by the other
	routines.  The second routine adds the symbols from an object
	file to the hash table.  The third routine takes all the
	object files and links them together to create the output
	file.  These routines are designed so that the linker proper
	does not need to know anything about the symbols in the object
	files that it is linking.  The linker merely arranges the
	sections as directed by the linker script and lets BFD handle
	the details of symbols and relocs.

	The second routine and third routines are passed a pointer to
	a <<struct bfd_link_info>> structure (defined in
	<<bfdlink.h>>) which holds information relevant to the link,
	including the linker hash table (which was created by the
	first routine) and a set of callback functions to the linker
	proper.

	The generic linker routines are in <<linker.c>>, and use the
	header file <<genlink.h>>.  As of this writing, the only back
	ends which have implemented versions of these routines are
	a.out (in <<aoutx.h>>) and ECOFF (in <<ecoff.c>>).  The a.out
	routines are used as examples throughout this section.

@menu
@* Creating a Linker Hash Table::
@* Adding Symbols to the Hash Table::
@* Performing the Final Link::
@end menu

INODE
Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions
SUBSECTION
	Creating a linker hash table

@cindex _bfd_link_hash_table_create in target vector
@cindex target vector (_bfd_link_hash_table_create)
	The linker routines must create a hash table, which must be
	derived from <<struct bfd_link_hash_table>> described in
	<<bfdlink.c>>.  @xref{Hash Tables}, for information on how to
	create a derived hash table.  This entry point is called using
	the target vector of the linker output file.

	The <<_bfd_link_hash_table_create>> entry point must allocate
	and initialize an instance of the desired hash table.  If the
	back end does not require any additional information to be
	stored with the entries in the hash table, the entry point may
	simply create a <<struct bfd_link_hash_table>>.  Most likely,
	however, some additional information will be needed.

	For example, with each entry in the hash table the a.out
	linker keeps the index the symbol has in the final output file
	(this index number is used so that when doing a relocatable
	link the symbol index used in the output file can be quickly
	filled in when copying over a reloc).  The a.out linker code
	defines the required structures and functions for a hash table
	derived from <<struct bfd_link_hash_table>>.  The a.out linker
	hash table is created by the function
	<<NAME(aout,link_hash_table_create)>>; it simply allocates
	space for the hash table, initializes it, and returns a
	pointer to it.

	When writing the linker routines for a new back end, you will
	generally not know exactly which fields will be required until
	you have finished.  You should simply create a new hash table
	which defines no additional fields, and then simply add fields
	as they become necessary.

INODE
Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions
SUBSECTION
	Adding symbols to the hash table

@cindex _bfd_link_add_symbols in target vector
@cindex target vector (_bfd_link_add_symbols)
	The linker proper will call the <<_bfd_link_add_symbols>>
	entry point for each object file or archive which is to be
	linked (typically these are the files named on the command
	line, but some may also come from the linker script).  The
	entry point is responsible for examining the file.  For an
	object file, BFD must add any relevant symbol information to
	the hash table.  For an archive, BFD must determine which
	elements of the archive should be used and adding them to the
	link.

	The a.out version of this entry point is
	<<NAME(aout,link_add_symbols)>>.

@menu
@* Differing file formats::
@* Adding symbols from an object file::
@* Adding symbols from an archive::
@end menu

INODE
Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table
SUBSUBSECTION
	Differing file formats

	Normally all the files involved in a link will be of the same
	format, but it is also possible to link together different
	format object files, and the back end must support that.  The
	<<_bfd_link_add_symbols>> entry point is called via the target
	vector of the file to be added.  This has an important
	consequence: the function may not assume that the hash table
	is the type created by the corresponding
	<<_bfd_link_hash_table_create>> vector.  All the
	<<_bfd_link_add_symbols>> function can assume about the hash
	table is that it is derived from <<struct
	bfd_link_hash_table>>.

	Sometimes the <<_bfd_link_add_symbols>> function must store
	some information in the hash table entry to be used by the
	<<_bfd_final_link>> function.  In such a case the output bfd
	xvec must be checked to make sure that the hash table was
	created by an object file of the same format.

	The <<_bfd_final_link>> routine must be prepared to handle a
	hash entry without any extra information added by the
	<<_bfd_link_add_symbols>> function.  A hash entry without
	extra information will also occur when the linker script
	directs the linker to create a symbol.  Note that, regardless
	of how a hash table entry is added, all the fields will be
	initialized to some sort of null value by the hash table entry
	initialization function.

	See <<ecoff_link_add_externals>> for an example of how to
	check the output bfd before saving information (in this
	case, the ECOFF external symbol debugging information) in a
	hash table entry.

INODE
Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table
SUBSUBSECTION
	Adding symbols from an object file

	When the <<_bfd_link_add_symbols>> routine is passed an object
	file, it must add all externally visible symbols in that
	object file to the hash table.  The actual work of adding the
	symbol to the hash table is normally handled by the function
	<<_bfd_generic_link_add_one_symbol>>.  The
	<<_bfd_link_add_symbols>> routine is responsible for reading
	all the symbols from the object file and passing the correct
	information to <<_bfd_generic_link_add_one_symbol>>.

	The <<_bfd_link_add_symbols>> routine should not use
	<<bfd_canonicalize_symtab>> to read the symbols.  The point of
	providing this routine is to avoid the overhead of converting
	the symbols into generic <<asymbol>> structures.

@findex _bfd_generic_link_add_one_symbol
	<<_bfd_generic_link_add_one_symbol>> handles the details of
	combining common symbols, warning about multiple definitions,
	and so forth.  It takes arguments which describe the symbol to
	add, notably symbol flags, a section, and an offset.  The
	symbol flags include such things as <<BSF_WEAK>> or
	<<BSF_INDIRECT>>.  The section is a section in the object
	file, or something like <<bfd_und_section_ptr>> for an undefined
	symbol or <<bfd_com_section_ptr>> for a common symbol.

	If the <<_bfd_final_link>> routine is also going to need to
	read the symbol information, the <<_bfd_link_add_symbols>>
	routine should save it somewhere attached to the object file
	BFD.  However, the information should only be saved if the
	<<keep_memory>> field of the <<info>> argument is TRUE, so
	that the <<-no-keep-memory>> linker switch is effective.

	The a.out function which adds symbols from an object file is
	<<aout_link_add_object_symbols>>, and most of the interesting
	work is in <<aout_link_add_symbols>>.  The latter saves
	pointers to the hash tables entries created by
	<<_bfd_generic_link_add_one_symbol>> indexed by symbol number,
	so that the <<_bfd_final_link>> routine does not have to call
	the hash table lookup routine to locate the entry.

INODE
Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table
SUBSUBSECTION
	Adding symbols from an archive

	When the <<_bfd_link_add_symbols>> routine is passed an
	archive, it must look through the symbols defined by the
	archive and decide which elements of the archive should be
	included in the link.  For each such element it must call the
	<<add_archive_element>> linker callback, and it must add the
	symbols from the object file to the linker hash table.  (The
	callback may in fact indicate that a replacement BFD should be
	used, in which case the symbols from that BFD should be added
	to the linker hash table instead.)

@findex _bfd_generic_link_add_archive_symbols
	In most cases the work of looking through the symbols in the
	archive should be done by the
	<<_bfd_generic_link_add_archive_symbols>> function.
	<<_bfd_generic_link_add_archive_symbols>> is passed a function
	to call to make the final decision about adding an archive
	element to the link and to do the actual work of adding the
	symbols to the linker hash table.  If the element is to
	be included, the <<add_archive_element>> linker callback
	routine must be called with the element as an argument, and
	the element's symbols must be added to the linker hash table
	just as though the element had itself been passed to the
	<<_bfd_link_add_symbols>> function.

	When the a.out <<_bfd_link_add_symbols>> function receives an
	archive, it calls <<_bfd_generic_link_add_archive_symbols>>
	passing <<aout_link_check_archive_element>> as the function
	argument. <<aout_link_check_archive_element>> calls
	<<aout_link_check_ar_symbols>>.  If the latter decides to add
	the element (an element is only added if it provides a real,
	non-common, definition for a previously undefined or common
	symbol) it calls the <<add_archive_element>> callback and then
	<<aout_link_check_archive_element>> calls
	<<aout_link_add_symbols>> to actually add the symbols to the
	linker hash table - possibly those of a substitute BFD, if the
	<<add_archive_element>> callback avails itself of that option.

	The ECOFF back end is unusual in that it does not normally
	call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF
	archives already contain a hash table of symbols.  The ECOFF
	back end searches the archive itself to avoid the overhead of
	creating a new hash table.

INODE
Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions
SUBSECTION
	Performing the final link

@cindex _bfd_link_final_link in target vector
@cindex target vector (_bfd_final_link)
	When all the input files have been processed, the linker calls
	the <<_bfd_final_link>> entry point of the output BFD.  This
	routine is responsible for producing the final output file,
	which has several aspects.  It must relocate the contents of
	the input sections and copy the data into the output sections.
	It must build an output symbol table including any local
	symbols from the input files and the global symbols from the
	hash table.  When producing relocatable output, it must
	modify the input relocs and write them into the output file.
	There may also be object format dependent work to be done.

	The linker will also call the <<write_object_contents>> entry
	point when the BFD is closed.  The two entry points must work
	together in order to produce the correct output file.

	The details of how this works are inevitably dependent upon
	the specific object file format.  The a.out
	<<_bfd_final_link>> routine is <<NAME(aout,final_link)>>.

@menu
@* Information provided by the linker::
@* Relocating the section contents::
@* Writing the symbol table::
@end menu

INODE
Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link
SUBSUBSECTION
	Information provided by the linker

	Before the linker calls the <<_bfd_final_link>> entry point,
	it sets up some data structures for the function to use.

	The <<input_bfds>> field of the <<bfd_link_info>> structure
	will point to a list of all the input files included in the
	link.  These files are linked through the <<link.next>> field
	of the <<bfd>> structure.

	Each section in the output file will have a list of
	<<link_order>> structures attached to the <<map_head.link_order>>
	field (the <<link_order>> structure is defined in
	<<bfdlink.h>>).  These structures describe how to create the
	contents of the output section in terms of the contents of
	various input sections, fill constants, and, eventually, other
	types of information.  They also describe relocs that must be
	created by the BFD backend, but do not correspond to any input
	file; this is used to support -Ur, which builds constructors
	while generating a relocatable object file.

INODE
Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link
SUBSUBSECTION
	Relocating the section contents

	The <<_bfd_final_link>> function should look through the
	<<link_order>> structures attached to each section of the
	output file.  Each <<link_order>> structure should either be
	handled specially, or it should be passed to the function
	<<_bfd_default_link_order>> which will do the right thing
	(<<_bfd_default_link_order>> is defined in <<linker.c>>).

	For efficiency, a <<link_order>> of type
	<<bfd_indirect_link_order>> whose associated section belongs
	to a BFD of the same format as the output BFD must be handled
	specially.  This type of <<link_order>> describes part of an
	output section in terms of a section belonging to one of the
	input files.  The <<_bfd_final_link>> function should read the
	contents of the section and any associated relocs, apply the
	relocs to the section contents, and write out the modified
	section contents.  If performing a relocatable link, the
	relocs themselves must also be modified and written out.

@findex _bfd_relocate_contents
@findex _bfd_final_link_relocate
	The functions <<_bfd_relocate_contents>> and
	<<_bfd_final_link_relocate>> provide some general support for
	performing the actual relocations, notably overflow checking.
	Their arguments include information about the symbol the
	relocation is against and a <<reloc_howto_type>> argument
	which describes the relocation to perform.  These functions
	are defined in <<reloc.c>>.

	The a.out function which handles reading, relocating, and
	writing section contents is <<aout_link_input_section>>.  The
	actual relocation is done in <<aout_link_input_section_std>>
	and <<aout_link_input_section_ext>>.

INODE
Writing the symbol table, , Relocating the section contents, Performing the Final Link
SUBSUBSECTION
	Writing the symbol table

	The <<_bfd_final_link>> function must gather all the symbols
	in the input files and write them out.  It must also write out
	all the symbols in the global hash table.  This must be
	controlled by the <<strip>> and <<discard>> fields of the
	<<bfd_link_info>> structure.

	The local symbols of the input files will not have been
	entered into the linker hash table.  The <<_bfd_final_link>>
	routine must consider each input file and include the symbols
	in the output file.  It may be convenient to do this when
	looking through the <<link_order>> structures, or it may be
	done by stepping through the <<input_bfds>> list.

	The <<_bfd_final_link>> routine must also traverse the global
	hash table to gather all the externally visible symbols.  It
	is possible that most of the externally visible symbols may be
	written out when considering the symbols of each input file,
	but it is still necessary to traverse the hash table since the
	linker script may have defined some symbols that are not in
	any of the input files.

	The <<strip>> field of the <<bfd_link_info>> structure
	controls which symbols are written out.  The possible values
	are listed in <<bfdlink.h>>.  If the value is <<strip_some>>,
	then the <<keep_hash>> field of the <<bfd_link_info>>
	structure is a hash table of symbols to keep; each symbol
	should be looked up in this hash table, and only symbols which
	are present should be included in the output file.

	If the <<strip>> field of the <<bfd_link_info>> structure
	permits local symbols to be written out, the <<discard>> field
	is used to further controls which local symbols are included
	in the output file.  If the value is <<discard_l>>, then all
	local symbols which begin with a certain prefix are discarded;
	this is controlled by the <<bfd_is_local_label_name>> entry point.

	The a.out backend handles symbols by calling
	<<aout_link_write_symbols>> on each input BFD and then
	traversing the global hash table with the function
	<<aout_link_write_other_symbol>>.  It builds a string table
	while writing out the symbols, which is written to the output
	file at the end of <<NAME(aout,final_link)>>.
*/

/* This structure is used to pass information to
   _bfd_generic_link_write_global_symbol, which may be called via
   _bfd_generic_link_hash_traverse.  */

struct generic_write_global_symbol_info
{
  struct bfd_link_info *info;
  bfd *output_bfd;
  size_t *psymalloc;
  bool failed;
};

static bool generic_link_add_object_symbols
  (bfd *, struct bfd_link_info *);
static bool generic_link_check_archive_element
  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
   bool *);
static bool generic_link_add_symbol_list
  (bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **);
static bool generic_add_output_symbol
  (bfd *, size_t *psymalloc, asymbol *);
static bool default_data_link_order
  (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
static bool default_indirect_link_order
  (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *,
   bool);
static bool _bfd_generic_link_output_symbols
  (bfd *, bfd *, struct bfd_link_info *, size_t *);
static bool _bfd_generic_link_write_global_symbol
  (struct generic_link_hash_entry *, void *);

/* The link hash table structure is defined in bfdlink.h.  It provides
   a base hash table which the backend specific hash tables are built
   upon.  */

/* Routine to create an entry in the link hash table.  */

struct bfd_hash_entry *
_bfd_link_hash_newfunc (struct bfd_hash_entry *entry,
			struct bfd_hash_table *table,
			const char *string)
{
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (entry == NULL)
    {
      entry = (struct bfd_hash_entry *)
	  bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry));
      if (entry == NULL)
	return entry;
    }

  /* Call the allocation method of the superclass.  */
  entry = bfd_hash_newfunc (entry, table, string);
  if (entry)
    {
      struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;

      /* Initialize the local fields.  */
      memset ((char *) &h->root + sizeof (h->root), 0,
	      sizeof (*h) - sizeof (h->root));
    }

  return entry;
}

/* Initialize a link hash table.  The BFD argument is the one
   responsible for creating this table.  */

bool
_bfd_link_hash_table_init
  (struct bfd_link_hash_table *table,
   bfd *abfd ATTRIBUTE_UNUSED,
   struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
				      struct bfd_hash_table *,
				      const char *),
   unsigned int entsize)
{
  bool ret;

  BFD_ASSERT (!abfd->is_linker_output && !abfd->link.hash);
  table->undefs = NULL;
  table->undefs_tail = NULL;
  table->type = bfd_link_generic_hash_table;

  ret = bfd_hash_table_init (&table->table, newfunc, entsize);
  if (ret)
    {
      /* Arrange for destruction of this hash table on closing ABFD.  */
      table->hash_table_free = _bfd_generic_link_hash_table_free;
      table->merge_info = NULL;
      abfd->link.hash = table;
      abfd->is_linker_output = true;
    }
  return ret;
}

/* Look up a symbol in a link hash table.  If follow is TRUE, we
   follow bfd_link_hash_indirect and bfd_link_hash_warning links to
   the real symbol.

.{* Return TRUE if the symbol described by a linker hash entry H
.   is going to be absolute.  Linker-script defined symbols can be
.   converted from absolute to section-relative ones late in the
.   link.  Use this macro to correctly determine whether the symbol
.   will actually end up absolute in output.  *}
.#define bfd_is_abs_symbol(H) \
.  (((H)->type == bfd_link_hash_defined \
.    || (H)->type == bfd_link_hash_defweak) \
.   && bfd_is_abs_section ((H)->u.def.section) \
.   && !(H)->rel_from_abs)
.
*/

struct bfd_link_hash_entry *
bfd_link_hash_lookup (struct bfd_link_hash_table *table,
		      const char *string,
		      bool create,
		      bool copy,
		      bool follow)
{
  struct bfd_link_hash_entry *ret;

  if (table == NULL || string == NULL)
    return NULL;

  ret = ((struct bfd_link_hash_entry *)
	 bfd_hash_lookup (&table->table, string, create, copy));

  if (follow && ret != NULL)
    {
      while (ret->type == bfd_link_hash_indirect
	     || ret->type == bfd_link_hash_warning)
	ret = ret->u.i.link;
    }

  return ret;
}

/* Look up a symbol in the main linker hash table if the symbol might
   be wrapped.  This should only be used for references to an
   undefined symbol, not for definitions of a symbol.  */

struct bfd_link_hash_entry *
bfd_wrapped_link_hash_lookup (bfd *abfd,
			      struct bfd_link_info *info,
			      const char *string,
			      bool create,
			      bool copy,
			      bool follow)
{
  size_t amt;

  if (info->wrap_hash != NULL)
    {
      const char *l;
      char prefix = '\0';

      l = string;
      if (*l
	  && (*l == bfd_get_symbol_leading_char (abfd)
	      || *l == info->wrap_char))
	{
	  prefix = *l;
	  ++l;
	}

#undef WRAP
#define WRAP "__wrap_"

      if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL)
	{
	  char *n;
	  struct bfd_link_hash_entry *h;

	  /* This symbol is being wrapped.  We want to replace all
	     references to SYM with references to __wrap_SYM.  */

	  amt = strlen (l) + sizeof WRAP + 1;
	  n = (char *) bfd_malloc (amt);
	  if (n == NULL)
	    return NULL;

	  n[0] = prefix;
	  n[1] = '\0';
	  strcat (n, WRAP);
	  strcat (n, l);
	  h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
	  if (h != NULL)
	    h->wrapper_symbol = true;
	  free (n);
	  return h;
	}

#undef  REAL
#define REAL "__real_"

      if (*l == '_'
	  && startswith (l, REAL)
	  && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1,
			      false, false) != NULL)
	{
	  char *n;
	  struct bfd_link_hash_entry *h;

	  /* This is a reference to __real_SYM, where SYM is being
	     wrapped.  We want to replace all references to __real_SYM
	     with references to SYM.  */

	  amt = strlen (l + sizeof REAL - 1) + 2;
	  n = (char *) bfd_malloc (amt);
	  if (n == NULL)
	    return NULL;

	  n[0] = prefix;
	  n[1] = '\0';
	  strcat (n, l + sizeof REAL - 1);
	  h = bfd_link_hash_lookup (info->hash, n, create, true, follow);
	  if (h != NULL)
	    h->ref_real = 1;
	  free (n);
	  return h;
	}

#undef REAL
    }

  return bfd_link_hash_lookup (info->hash, string, create, copy, follow);
}

/* If H is a wrapped symbol, ie. the symbol name starts with "__wrap_"
   and the remainder is found in wrap_hash, return the real symbol.  */

struct bfd_link_hash_entry *
unwrap_hash_lookup (struct bfd_link_info *info,
		    bfd *input_bfd,
		    struct bfd_link_hash_entry *h)
{
  const char *l = h->root.string;

  if (*l
      && (*l == bfd_get_symbol_leading_char (input_bfd)
	  || *l == info->wrap_char))
    ++l;

  if (startswith (l, WRAP))
    {
      l += sizeof WRAP - 1;

      if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL)
	{
	  char save = 0;
	  if (l - (sizeof WRAP - 1) != h->root.string)
	    {
	      --l;
	      save = *l;
	      *(char *) l = *h->root.string;
	    }
	  h = bfd_link_hash_lookup (info->hash, l, false, false, false);
	  if (save)
	    *(char *) l = save;
	}
    }
  return h;
}
#undef WRAP

/* Traverse a generic link hash table.  Differs from bfd_hash_traverse
   in the treatment of warning symbols.  When warning symbols are
   created they replace the real symbol, so you don't get to see the
   real symbol in a bfd_hash_traverse.  This traversal calls func with
   the real symbol.  */

void
bfd_link_hash_traverse
  (struct bfd_link_hash_table *htab,
   bool (*func) (struct bfd_link_hash_entry *, void *),
   void *info)
{
  unsigned int i;

  htab->table.frozen = 1;
  for (i = 0; i < htab->table.size; i++)
    {
      struct bfd_link_hash_entry *p;

      p = (struct bfd_link_hash_entry *) htab->table.table[i];
      for (; p != NULL; p = (struct bfd_link_hash_entry *) p->root.next)
	if (!(*func) (p->type == bfd_link_hash_warning ? p->u.i.link : p, info))
	  goto out;
    }
 out:
  htab->table.frozen = 0;
}

/* Add a symbol to the linker hash table undefs list.  */

void
bfd_link_add_undef (struct bfd_link_hash_table *table,
		    struct bfd_link_hash_entry *h)
{
  BFD_ASSERT (h->u.undef.next == NULL);
  if (table->undefs_tail != NULL)
    table->undefs_tail->u.undef.next = h;
  if (table->undefs == NULL)
    table->undefs = h;
  table->undefs_tail = h;
}

/* The undefs list was designed so that in normal use we don't need to
   remove entries.  However, if symbols on the list are changed from
   bfd_link_hash_undefined to either bfd_link_hash_undefweak or
   bfd_link_hash_new for some reason, then they must be removed from the
   list.  Failure to do so might result in the linker attempting to add
   the symbol to the list again at a later stage.  */

void
bfd_link_repair_undef_list (struct bfd_link_hash_table *table)
{
  struct bfd_link_hash_entry **pun;

  pun = &table->undefs;
  while (*pun != NULL)
    {
      struct bfd_link_hash_entry *h = *pun;

      if (h->type == bfd_link_hash_new
	  || h->type == bfd_link_hash_undefweak)
	{
	  *pun = h->u.undef.next;
	  h->u.undef.next = NULL;
	  if (h == table->undefs_tail)
	    {
	      if (pun == &table->undefs)
		table->undefs_tail = NULL;
	      else
		/* pun points at an u.undef.next field.  Go back to
		   the start of the link_hash_entry.  */
		table->undefs_tail = (struct bfd_link_hash_entry *)
		  ((char *) pun - ((char *) &h->u.undef.next - (char *) h));
	      break;
	    }
	}
      else
	pun = &h->u.undef.next;
    }
}

/* Routine to create an entry in a generic link hash table.  */

static struct bfd_hash_entry *
_bfd_generic_link_hash_newfunc (struct bfd_hash_entry *entry,
				struct bfd_hash_table *table,
				const char *string)
{
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (entry == NULL)
    {
      entry = (struct bfd_hash_entry *)
	bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry));
      if (entry == NULL)
	return entry;
    }

  /* Call the allocation method of the superclass.  */
  entry = _bfd_link_hash_newfunc (entry, table, string);
  if (entry)
    {
      struct generic_link_hash_entry *ret;

      /* Set local fields.  */
      ret = (struct generic_link_hash_entry *) entry;
      ret->written = false;
      ret->sym = NULL;
    }

  return entry;
}

/* Create a generic link hash table.  */

struct bfd_link_hash_table *
_bfd_generic_link_hash_table_create (bfd *abfd)
{
  struct generic_link_hash_table *ret;
  size_t amt = sizeof (struct generic_link_hash_table);

  ret = (struct generic_link_hash_table *) bfd_malloc (amt);
  if (ret == NULL)
    return NULL;
  if (! _bfd_link_hash_table_init (&ret->root, abfd,
				   _bfd_generic_link_hash_newfunc,
				   sizeof (struct generic_link_hash_entry)))
    {
      free (ret);
      return NULL;
    }
  return &ret->root;
}

void
_bfd_generic_link_hash_table_free (bfd *obfd)
{
  struct generic_link_hash_table *ret;

  BFD_ASSERT (obfd->is_linker_output && obfd->link.hash);
  ret = (struct generic_link_hash_table *) obfd->link.hash;
  _bfd_merge_sections_free (ret->root.merge_info);
  bfd_hash_table_free (&ret->root.table);
  free (ret);
  obfd->link.hash = NULL;
  obfd->is_linker_output = false;
}

/* Grab the symbols for an object file when doing a generic link.  We
   store the symbols in the outsymbols field.  We need to keep them
   around for the entire link to ensure that we only read them once.
   If we read them multiple times, we might wind up with relocs and
   the hash table pointing to different instances of the symbol
   structure.  */

bool
bfd_generic_link_read_symbols (bfd *abfd)
{
  if (bfd_get_outsymbols (abfd) == NULL)
    {
      long symsize;
      long symcount;

      symsize = bfd_get_symtab_upper_bound (abfd);
      if (symsize < 0)
	return false;
      abfd->outsymbols = bfd_alloc (abfd, symsize);
      if (bfd_get_outsymbols (abfd) == NULL && symsize != 0)
	return false;
      symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd));
      if (symcount < 0)
	return false;
      abfd->symcount = symcount;
    }

  return true;
}

/* Indicate that we are only retrieving symbol values from this
   section.  We want the symbols to act as though the values in the
   file are absolute.  */

void
_bfd_generic_link_just_syms (asection *sec,
			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS;
  sec->output_section = bfd_abs_section_ptr;
  sec->output_offset = sec->vma;
}

/* Copy the symbol type and other attributes for a linker script
   assignment from HSRC to HDEST.
   The default implementation does nothing.  */
void
_bfd_generic_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED,
    struct bfd_link_hash_entry *hdest ATTRIBUTE_UNUSED,
    struct bfd_link_hash_entry *hsrc ATTRIBUTE_UNUSED)
{
}

/* Generic function to add symbols from an object file to the
   global hash table.  */

bool
_bfd_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
  bool ret;

  switch (bfd_get_format (abfd))
    {
    case bfd_object:
      ret = generic_link_add_object_symbols (abfd, info);
      break;
    case bfd_archive:
      ret = (_bfd_generic_link_add_archive_symbols
	     (abfd, info, generic_link_check_archive_element));
      break;
    default:
      bfd_set_error (bfd_error_wrong_format);
      ret = false;
    }

  return ret;
}

/* Add symbols from an object file to the global hash table.  */

static bool
generic_link_add_object_symbols (bfd *abfd,
				 struct bfd_link_info *info)
{
  bfd_size_type symcount;
  struct bfd_symbol **outsyms;

  if (!bfd_generic_link_read_symbols (abfd))
    return false;
  symcount = _bfd_generic_link_get_symcount (abfd);
  outsyms = _bfd_generic_link_get_symbols (abfd);
  return generic_link_add_symbol_list (abfd, info, symcount, outsyms);
}

/* Generic function to add symbols from an archive file to the global
   hash file.  This function presumes that the archive symbol table
   has already been read in (this is normally done by the
   bfd_check_format entry point).  It looks through the archive symbol
   table for symbols that are undefined or common in the linker global
   symbol hash table.  When one is found, the CHECKFN argument is used
   to see if an object file should be included.  This allows targets
   to customize common symbol behaviour.  CHECKFN should set *PNEEDED
   to TRUE if the object file should be included, and must also call
   the bfd_link_info add_archive_element callback function and handle
   adding the symbols to the global hash table.  CHECKFN must notice
   if the callback indicates a substitute BFD, and arrange to add
   those symbols instead if it does so.  CHECKFN should only return
   FALSE if some sort of error occurs.  */

bool
_bfd_generic_link_add_archive_symbols
  (bfd *abfd,
   struct bfd_link_info *info,
   bool (*checkfn) (bfd *, struct bfd_link_info *,
		    struct bfd_link_hash_entry *, const char *, bool *))
{
  bool loop;
  bfd_size_type amt;
  unsigned char *included;

  if (! bfd_has_map (abfd))
    {
      bfd *first_one = bfd_openr_next_archived_file (abfd, NULL);

      /* An empty archive is a special case.  */
      if (first_one == NULL)
	return true;

      if (!_bfd_make_armap (abfd, first_one))
	return false;
    }

  amt = bfd_ardata (abfd)->symdef_count;
  if (amt == 0)
    return true;
  amt *= sizeof (*included);
  included = (unsigned char *) bfd_zmalloc (amt);
  if (included == NULL)
    return false;

  do
    {
      carsym *arsyms;
      carsym *arsym_end;
      carsym *arsym;
      unsigned int indx;
      ufile_ptr_or_bfd last = _bfd_elt_nil (abfd);
      bool needed = false;
      bfd *element = NULL;

      loop = false;
      arsyms = bfd_ardata (abfd)->symdefs;
      arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
      for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
	{
	  struct bfd_link_hash_entry *h;
	  struct bfd_link_hash_entry *undefs_tail;

	  if (included[indx])
	    continue;
	  if (needed && _bfd_elt_eq (abfd, arsym->u, last))
	    {
	      included[indx] = 1;
	      continue;
	    }

	  if (arsym->name == NULL)
	    goto error_return;

	  h = bfd_link_hash_lookup (info->hash, arsym->name,
				    false, false, true);

	  if (h == NULL
	      && info->pei386_auto_import
	      && startswith (arsym->name, "__imp_"))
	    h = bfd_link_hash_lookup (info->hash, arsym->name + 6,
				      false, false, true);
	  if (h == NULL)
	    continue;

	  if (h->type != bfd_link_hash_undefined
	      && h->type != bfd_link_hash_common)
	    {
	      if (h->type != bfd_link_hash_undefweak)
		/* Symbol must be defined.  Don't check it again.  */
		included[indx] = 1;
	      continue;
	    }

	  if (!_bfd_elt_eq (abfd, last, arsym->u))
	    {
	      last = arsym->u;
	      element = _bfd_get_elt_from_symdef (abfd, arsym, info);
	      if (element == NULL
		  || !bfd_check_format (element, bfd_object))
		goto error_return;
	    }

	  undefs_tail = info->hash->undefs_tail;

	  /* CHECKFN will see if this element should be included, and
	     go ahead and include it if appropriate.  */
	  if (! (*checkfn) (element, info, h, arsym->name, &needed))
	    goto error_return;

	  if (needed)
	    {
	      unsigned int mark;

	      /* Look backward to mark all symbols from this object file
		 which we have already seen in this pass.  */
	      mark = indx;
	      do
		{
		  included[mark] = 1;
		  if (mark == 0)
		    break;
		  --mark;
		}
	      while (_bfd_elt_eq (abfd, arsyms[mark].u, last));

	      if (undefs_tail != info->hash->undefs_tail)
		loop = true;
	    }
	}
    } while (loop);

  free (included);
  return true;

 error_return:
  free (included);
  return false;
}

/* See if we should include an archive element.  */

static bool
generic_link_check_archive_element (bfd *abfd,
				    struct bfd_link_info *info,
				    struct bfd_link_hash_entry *h,
				    const char *name ATTRIBUTE_UNUSED,
				    bool *pneeded)
{
  asymbol **pp, **ppend;

  *pneeded = false;

  if (!bfd_generic_link_read_symbols (abfd))
    return false;

  pp = _bfd_generic_link_get_symbols (abfd);
  ppend = pp + _bfd_generic_link_get_symcount (abfd);
  for (; pp < ppend; pp++)
    {
      asymbol *p;

      p = *pp;

      /* We are only interested in globally visible symbols.  */
      if (! bfd_is_com_section (p->section)
	  && (p->flags & (BSF_GLOBAL | BSF_INDIRECT | BSF_WEAK)) == 0)
	continue;

      /* We are only interested if we know something about this
	 symbol, and it is undefined or common.  An undefined weak
	 symbol (type bfd_link_hash_undefweak) is not considered to be
	 a reference when pulling files out of an archive.  See the
	 SVR4 ABI, p. 4-27.  */
      h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false,
				false, true);
      if (h == NULL
	  || (h->type != bfd_link_hash_undefined
	      && h->type != bfd_link_hash_common))
	continue;

      /* P is a symbol we are looking for.  */

      if (! bfd_is_com_section (p->section)
	  || (h->type == bfd_link_hash_undefined
	      && h->u.undef.abfd == NULL))
	{
	  /* P is not a common symbol, or an undefined reference was
	     created from outside BFD such as from a linker -u option.
	     This object file defines the symbol, so pull it in.  */
	  *pneeded = true;
	  if (!(*info->callbacks
		->add_archive_element) (info, abfd, bfd_asymbol_name (p),
					&abfd))
	    return false;
	  /* Potentially, the add_archive_element hook may have set a
	     substitute BFD for us.  */
	  return bfd_link_add_symbols (abfd, info);
	}

      /* P is a common symbol.  */

      if (h->type == bfd_link_hash_undefined)
	{
	  bfd *symbfd;
	  bfd_vma size;
	  unsigned int power;

	  /* Turn the symbol into a common symbol but do not link in
	     the object file.  This is how a.out works.  Object
	     formats that require different semantics must implement
	     this function differently.  This symbol is already on the
	     undefs list.  We add the section to a common section
	     attached to symbfd to ensure that it is in a BFD which
	     will be linked in.  */
	  symbfd = h->u.undef.abfd;
	  h->type = bfd_link_hash_common;
	  h->u.c.p = (struct bfd_link_hash_common_entry *)
	    bfd_hash_allocate (&info->hash->table,
			       sizeof (struct bfd_link_hash_common_entry));
	  if (h->u.c.p == NULL)
	    return false;

	  size = bfd_asymbol_value (p);
	  h->u.c.size = size;

	  power = bfd_log2 (size);
	  if (power > 4)
	    power = 4;
	  h->u.c.p->alignment_power = power;

	  if (p->section == bfd_com_section_ptr)
	    h->u.c.p->section = bfd_make_section_old_way (symbfd, "COMMON");
	  else
	    h->u.c.p->section = bfd_make_section_old_way (symbfd,
							  p->section->name);
	  h->u.c.p->section->flags |= SEC_ALLOC;
	}
      else
	{
	  /* Adjust the size of the common symbol if necessary.  This
	     is how a.out works.  Object formats that require
	     different semantics must implement this function
	     differently.  */
	  if (bfd_asymbol_value (p) > h->u.c.size)
	    h->u.c.size = bfd_asymbol_value (p);
	}
    }

  /* This archive element is not needed.  */
  return true;
}

/* Add the symbols from an object file to the global hash table.  ABFD
   is the object file.  INFO is the linker information.  SYMBOL_COUNT
   is the number of symbols.  SYMBOLS is the list of symbols.  */

static bool
generic_link_add_symbol_list (bfd *abfd,
			      struct bfd_link_info *info,
			      bfd_size_type symbol_count,
			      asymbol **symbols)
{
  asymbol **pp, **ppend;

  pp = symbols;
  ppend = symbols + symbol_count;
  for (; pp < ppend; pp++)
    {
      asymbol *p;

      p = *pp;

      if ((p->flags & (BSF_INDIRECT
		       | BSF_WARNING
		       | BSF_GLOBAL
		       | BSF_CONSTRUCTOR
		       | BSF_WEAK)) != 0
	  || bfd_is_und_section (bfd_asymbol_section (p))
	  || bfd_is_com_section (bfd_asymbol_section (p))
	  || bfd_is_ind_section (bfd_asymbol_section (p)))
	{
	  const char *name;
	  const char *string;
	  struct generic_link_hash_entry *h;
	  struct bfd_link_hash_entry *bh;

	  string = name = bfd_asymbol_name (p);
	  if (((p->flags & BSF_INDIRECT) != 0
	       || bfd_is_ind_section (p->section))
	      && pp + 1 < ppend)
	    {
	      pp++;
	      string = bfd_asymbol_name (*pp);
	    }
	  else if ((p->flags & BSF_WARNING) != 0
		   && pp + 1 < ppend)
	    {
	      /* The name of P is actually the warning string, and the
		 next symbol is the one to warn about.  */
	      pp++;
	      name = bfd_asymbol_name (*pp);
	    }

	  bh = NULL;
	  if (! (_bfd_generic_link_add_one_symbol
		 (info, abfd, name, p->flags, bfd_asymbol_section (p),
		  p->value, string, false, false, &bh)))
	    return false;
	  h = (struct generic_link_hash_entry *) bh;

	  /* If this is a constructor symbol, and the linker didn't do
	     anything with it, then we want to just pass the symbol
	     through to the output file.  This will happen when
	     linking with -r.  */
	  if ((p->flags & BSF_CONSTRUCTOR) != 0
	      && (h == NULL || h->root.type == bfd_link_hash_new))
	    {
	      p->udata.p = NULL;
	      continue;
	    }

	  /* Save the BFD symbol so that we don't lose any backend
	     specific information that may be attached to it.  We only
	     want this one if it gives more information than the
	     existing one; we don't want to replace a defined symbol
	     with an undefined one.  This routine may be called with a
	     hash table other than the generic hash table, so we only
	     do this if we are certain that the hash table is a
	     generic one.  */
	  if (info->output_bfd->xvec == abfd->xvec)
	    {
	      if (h->sym == NULL
		  || (! bfd_is_und_section (bfd_asymbol_section (p))
		      && (! bfd_is_com_section (bfd_asymbol_section (p))
			  || bfd_is_und_section (bfd_asymbol_section (h->sym)))))
		{
		  h->sym = p;
		  /* BSF_OLD_COMMON is a hack to support COFF reloc
		     reading, and it should go away when the COFF
		     linker is switched to the new version.  */
		  if (bfd_is_com_section (bfd_asymbol_section (p)))
		    p->flags |= BSF_OLD_COMMON;
		}
	    }

	  /* Store a back pointer from the symbol to the hash
	     table entry for the benefit of relaxation code until
	     it gets rewritten to not use asymbol structures.
	     Setting this is also used to check whether these
	     symbols were set up by the generic linker.  */
	  p->udata.p = h;
	}
    }

  return true;
}

/* We use a state table to deal with adding symbols from an object
   file.  The first index into the state table describes the symbol
   from the object file.  The second index into the state table is the
   type of the symbol in the hash table.  */

/* The symbol from the object file is turned into one of these row
   values.  */

enum link_row
{
  UNDEF_ROW,		/* Undefined.  */
  UNDEFW_ROW,		/* Weak undefined.  */
  DEF_ROW,		/* Defined.  */
  DEFW_ROW,		/* Weak defined.  */
  COMMON_ROW,		/* Common.  */
  INDR_ROW,		/* Indirect.  */
  WARN_ROW,		/* Warning.  */
  SET_ROW		/* Member of set.  */
};

/* apparently needed for Hitachi 3050R(HI-UX/WE2)? */
#undef FAIL

/* The actions to take in the state table.  */

enum link_action
{
  FAIL,		/* Abort.  */
  UND,		/* Mark symbol undefined.  */
  WEAK,		/* Mark symbol weak undefined.  */
  DEF,		/* Mark symbol defined.  */
  DEFW,		/* Mark symbol weak defined.  */
  COM,		/* Mark symbol common.  */
  REF,		/* Mark defined symbol referenced.  */
  CREF,		/* Possibly warn about common reference to defined symbol.  */
  CDEF,		/* Define existing common symbol.  */
  NOACT,	/* No action.  */
  BIG,		/* Mark symbol common using largest size.  */
  MDEF,		/* Multiple definition error.  */
  MIND,		/* Multiple indirect symbols.  */
  IND,		/* Make indirect symbol.  */
  CIND,		/* Make indirect symbol from existing common symbol.  */
  SET,		/* Add value to set.  */
  MWARN,	/* Make warning symbol.  */
  WARN,		/* Warn if referenced, else MWARN.  */
  CYCLE,	/* Repeat with symbol pointed to.  */
  REFC,		/* Mark indirect symbol referenced and then CYCLE.  */
  WARNC		/* Issue warning and then CYCLE.  */
};

/* The state table itself.  The first index is a link_row and the
   second index is a bfd_link_hash_type.  */

static const enum link_action link_action[8][8] =
{
  /* current\prev    new    undef  undefw def    defw   com    indr   warn  */
  /* UNDEF_ROW	*/  {UND,   NOACT, UND,   REF,   REF,   NOACT, REFC,  WARNC },
  /* UNDEFW_ROW	*/  {WEAK,  NOACT, NOACT, REF,   REF,   NOACT, REFC,  WARNC },
  /* DEF_ROW	*/  {DEF,   DEF,   DEF,   MDEF,  DEF,   CDEF,  MIND,  CYCLE },
  /* DEFW_ROW	*/  {DEFW,  DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT, CYCLE },
  /* COMMON_ROW	*/  {COM,   COM,   COM,   CREF,  COM,   BIG,   REFC,  WARNC },
  /* INDR_ROW	*/  {IND,   IND,   IND,   MDEF,  IND,   CIND,  MIND,  CYCLE },
  /* WARN_ROW   */  {MWARN, WARN,  WARN,  WARN,  WARN,  WARN,  WARN,  NOACT },
  /* SET_ROW	*/  {SET,   SET,   SET,   SET,   SET,   SET,   CYCLE, CYCLE }
};

/* Most of the entries in the LINK_ACTION table are straightforward,
   but a few are somewhat subtle.

   A reference to an indirect symbol (UNDEF_ROW/indr or
   UNDEFW_ROW/indr) is counted as a reference both to the indirect
   symbol and to the symbol the indirect symbol points to.

   A reference to a warning symbol (UNDEF_ROW/warn or UNDEFW_ROW/warn)
   causes the warning to be issued.

   A common definition of an indirect symbol (COMMON_ROW/indr) is
   treated as a multiple definition error.  Likewise for an indirect
   definition of a common symbol (INDR_ROW/com).

   An indirect definition of a warning (INDR_ROW/warn) does not cause
   the warning to be issued.

   If a warning is created for an indirect symbol (WARN_ROW/indr) no
   warning is created for the symbol the indirect symbol points to.

   Adding an entry to a set does not count as a reference to a set,
   and no warning is issued (SET_ROW/warn).  */

/* Return the BFD in which a hash entry has been defined, if known.  */

static bfd *
hash_entry_bfd (struct bfd_link_hash_entry *h)
{
  while (h->type == bfd_link_hash_warning)
    h = h->u.i.link;
  switch (h->type)
    {
    default:
      return NULL;
    case bfd_link_hash_undefined:
    case bfd_link_hash_undefweak:
      return h->u.undef.abfd;
    case bfd_link_hash_defined:
    case bfd_link_hash_defweak:
      return h->u.def.section->owner;
    case bfd_link_hash_common:
      return h->u.c.p->section->owner;
    }
  /*NOTREACHED*/
}

/*
FUNCTION
	_bfd_generic_link_add_one_symbol

SYNOPSIS
	bool _bfd_generic_link_add_one_symbol
	  (struct bfd_link_info *info,
	   bfd *abfd,
	   const char *name,
	   flagword flags,
	   asection *section,
	   bfd_vma value,
	   const char *string,
	   bool copy,
	   bool collect,
	   struct bfd_link_hash_entry **hashp);

DESCRIPTION
   Add a symbol to the global hash table.
   ABFD is the BFD the symbol comes from.
   NAME is the name of the symbol.
   FLAGS is the BSF_* bits associated with the symbol.
   SECTION is the section in which the symbol is defined; this may be
     bfd_und_section_ptr or bfd_com_section_ptr.
   VALUE is the value of the symbol, relative to the section.
   STRING is used for either an indirect symbol, in which case it is
     the name of the symbol to indirect to, or a warning symbol, in
     which case it is the warning string.
   COPY is TRUE if NAME or STRING must be copied into locally
     allocated memory if they need to be saved.
   COLLECT is TRUE if we should automatically collect gcc constructor
     or destructor names as collect2 does.
   HASHP, if not NULL, is a place to store the created hash table
     entry; if *HASHP is not NULL, the caller has already looked up
     the hash table entry, and stored it in *HASHP.  */

bool
_bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
				  bfd *abfd,
				  const char *name,
				  flagword flags,
				  asection *section,
				  bfd_vma value,
				  const char *string,
				  bool copy,
				  bool collect,
				  struct bfd_link_hash_entry **hashp)
{
  enum link_row row;
  struct bfd_link_hash_entry *h;
  struct bfd_link_hash_entry *inh = NULL;
  bool cycle;

  BFD_ASSERT (section != NULL);

  if (bfd_is_ind_section (section)
      || (flags & BSF_INDIRECT) != 0)
    {
      row = INDR_ROW;
      /* Create the indirect symbol here.  This is for the benefit of
	 the plugin "notice" function.
	 STRING is the name of the symbol we want to indirect to.  */
      inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true,
					  copy, false);
      if (inh == NULL)
	return false;
    }
  else if ((flags & BSF_WARNING) != 0)
    row = WARN_ROW;
  else if ((flags & BSF_CONSTRUCTOR) != 0)
    row = SET_ROW;
  else if (bfd_is_und_section (section))
    {
      if ((flags & BSF_WEAK) != 0)
	row = UNDEFW_ROW;
      else
	row = UNDEF_ROW;
    }
  else if ((flags & BSF_WEAK) != 0)
    row = DEFW_ROW;
  else if (bfd_is_com_section (section))
    {
      row = COMMON_ROW;
      if (!bfd_link_relocatable (info)
	  && name != NULL
	  && name[0] == '_'
	  && name[1] == '_'
	  && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0)
	_bfd_error_handler
	  (_("%pB: plugin needed to handle lto object"), abfd);
    }
  else
    row = DEF_ROW;

  if (hashp != NULL && *hashp != NULL)
    h = *hashp;
  else
    {
      if (row == UNDEF_ROW || row == UNDEFW_ROW)
	h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false);
      else
	h = bfd_link_hash_lookup (info->hash, name, true, copy, false);
      if (h == NULL)
	{
	  if (hashp != NULL)
	    *hashp = NULL;
	  return false;
	}
    }

  if (info->notice_all
      || (info->notice_hash != NULL
	  && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL))
    {
      if (! (*info->callbacks->notice) (info, h, inh,
					abfd, section, value, flags))
	return false;
    }

  if (hashp != NULL)
    *hashp = h;

  do
    {
      enum link_action action;
      int prev;

      prev = h->type;
      /* Treat symbols defined by early linker script pass as undefined.  */
      if (h->ldscript_def)
	prev = bfd_link_hash_undefined;
      cycle = false;
      action = link_action[(int) row][prev];
      switch (action)
	{
	case FAIL:
	  abort ();

	case NOACT:
	  /* Do nothing.  */
	  break;

	case UND:
	  /* Make a new undefined symbol.  */
	  h->type = bfd_link_hash_undefined;
	  h->u.undef.abfd = abfd;
	  bfd_link_add_undef (info->hash, h);
	  break;

	case WEAK:
	  /* Make a new weak undefined symbol.  */
	  h->type = bfd_link_hash_undefweak;
	  h->u.undef.abfd = abfd;
	  break;

	case CDEF:
	  /* We have found a definition for a symbol which was
	     previously common.  */
	  BFD_ASSERT (h->type == bfd_link_hash_common);
	  (*info->callbacks->multiple_common) (info, h, abfd,
					       bfd_link_hash_defined, 0);
	  /* Fall through.  */
	case DEF:
	case DEFW:
	  {
	    enum bfd_link_hash_type oldtype;

	    /* Define a symbol.  */
	    oldtype = h->type;
	    if (action == DEFW)
	      h->type = bfd_link_hash_defweak;
	    else
	      h->type = bfd_link_hash_defined;
	    h->u.def.section = section;
	    h->u.def.value = value;
	    h->linker_def = 0;
	    h->ldscript_def = 0;

	    /* If we have been asked to, we act like collect2 and
	       identify all functions that might be global
	       constructors and destructors and pass them up in a
	       callback.  We only do this for certain object file
	       types, since many object file types can handle this
	       automatically.  */
	    if (collect && name[0] == '_')
	      {
		const char *s;

		/* A constructor or destructor name starts like this:
		   _+GLOBAL_[_.$][ID][_.$] where the first [_.$] and
		   the second are the same character (we accept any
		   character there, in case a new object file format
		   comes along with even worse naming restrictions).  */

#define CONS_PREFIX "GLOBAL_"
#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1)

		s = name + 1;
		while (*s == '_')
		  ++s;
		if (s[0] == 'G' && startswith (s, CONS_PREFIX))
		  {
		    char c;

		    c = s[CONS_PREFIX_LEN + 1];
		    if ((c == 'I' || c == 'D')
			&& s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2])
		      {
			/* If this is a definition of a symbol which
			   was previously weakly defined, we are in
			   trouble.  We have already added a
			   constructor entry for the weak defined
			   symbol, and now we are trying to add one
			   for the new symbol.  Fortunately, this case
			   should never arise in practice.  */
			if (oldtype == bfd_link_hash_defweak)
			  abort ();

			(*info->callbacks->constructor) (info, c == 'I',
							 h->root.string, abfd,
							 section, value);
		      }
		  }
	      }
	  }

	  break;

	case COM:
	  /* We have found a common definition for a symbol.  */
	  if (h->type == bfd_link_hash_new)
	    bfd_link_add_undef (info->hash, h);
	  h->type = bfd_link_hash_common;
	  h->u.c.p = (struct bfd_link_hash_common_entry *)
	    bfd_hash_allocate (&info->hash->table,
			       sizeof (struct bfd_link_hash_common_entry));
	  if (h->u.c.p == NULL)
	    return false;

	  h->u.c.size = value;

	  /* Select a default alignment based on the size.  This may
	     be overridden by the caller.  */
	  {
	    unsigned int power;

	    power = bfd_log2 (value);
	    if (power > 4)
	      power = 4;
	    h->u.c.p->alignment_power = power;
	  }

	  /* The section of a common symbol is only used if the common
	     symbol is actually allocated.  It basically provides a
	     hook for the linker script to decide which output section
	     the common symbols should be put in.  In most cases, the
	     section of a common symbol will be bfd_com_section_ptr,
	     the code here will choose a common symbol section named
	     "COMMON", and the linker script will contain *(COMMON) in
	     the appropriate place.  A few targets use separate common
	     sections for small symbols, and they require special
	     handling.  */
	  if (section == bfd_com_section_ptr)
	    {
	      h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON");
	      h->u.c.p->section->flags |= SEC_ALLOC;
	    }
	  else if (section->owner != abfd)
	    {
	      h->u.c.p->section = bfd_make_section_old_way (abfd,
							    section->name);
	      h->u.c.p->section->flags |= SEC_ALLOC;
	    }
	  else
	    h->u.c.p->section = section;
	  h->linker_def = 0;
	  h->ldscript_def = 0;
	  break;

	case REF:
	  /* A reference to a defined symbol.  */
	  if (h->u.undef.next == NULL && info->hash->undefs_tail != h)
	    h->u.undef.next = h;
	  break;

	case BIG:
	  /* We have found a common definition for a symbol which
	     already had a common definition.  Use the maximum of the
	     two sizes, and use the section required by the larger symbol.  */
	  BFD_ASSERT (h->type == bfd_link_hash_common);
	  (*info->callbacks->multiple_common) (info, h, abfd,
					       bfd_link_hash_common, value);
	  if (value > h->u.c.size)
	    {
	      unsigned int power;

	      h->u.c.size = value;

	      /* Select a default alignment based on the size.  This may
		 be overridden by the caller.  */
	      power = bfd_log2 (value);
	      if (power > 4)
		power = 4;
	      h->u.c.p->alignment_power = power;

	      /* Some systems have special treatment for small commons,
		 hence we want to select the section used by the larger
		 symbol.  This makes sure the symbol does not go in a
		 small common section if it is now too large.  */
	      if (section == bfd_com_section_ptr)
		{
		  h->u.c.p->section
		    = bfd_make_section_old_way (abfd, "COMMON");
		  h->u.c.p->section->flags |= SEC_ALLOC;
		}
	      else if (section->owner != abfd)
		{
		  h->u.c.p->section
		    = bfd_make_section_old_way (abfd, section->name);
		  h->u.c.p->section->flags |= SEC_ALLOC;
		}
	      else
		h->u.c.p->section = section;
	    }
	  break;

	case CREF:
	  /* We have found a common definition for a symbol which
	     was already defined.  */
	  (*info->callbacks->multiple_common) (info, h, abfd,
					       bfd_link_hash_common, value);
	  break;

	case MIND:
	  /* Multiple indirect symbols.  This is OK if they both point
	     to the same symbol.  */
	  if (h->u.i.link == inh)
	    break;
	  if (h->u.i.link->type == bfd_link_hash_defweak)
	    {
	      /* It is also OK to redefine a symbol that indirects to
		 a weak definition.  So for sym@ver -> sym@@ver where
		 sym@@ver is weak and we have a new strong sym@ver,
		 redefine sym@@ver.  Of course if there exists
		 sym -> sym@@ver then this also redefines sym.  */
	      h = h->u.i.link;
	      cycle = true;
	      break;
	    }
	  /* Fall through.  */
	case MDEF:
	  /* Handle a multiple definition.  */
	  (*info->callbacks->multiple_definition) (info, h,
						   abfd, section, value);
	  break;

	case CIND:
	  /* Create an indirect symbol from an existing common symbol.  */
	  BFD_ASSERT (h->type == bfd_link_hash_common);
	  (*info->callbacks->multiple_common) (info, h, abfd,
					       bfd_link_hash_indirect, 0);
	  /* Fall through.  */
	case IND:
	  if (inh->type == bfd_link_hash_indirect
	      && inh->u.i.link == h)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: indirect symbol `%s' to `%s' is a loop"),
		 abfd, name, string);
	      bfd_set_error (bfd_error_invalid_operation);
	      return false;
	    }
	  if (inh->type == bfd_link_hash_new)
	    {
	      inh->type = bfd_link_hash_undefined;
	      inh->u.undef.abfd = abfd;
	      bfd_link_add_undef (info->hash, inh);
	    }

	  /* If the indirect symbol has been referenced, we need to
	     push the reference down to the symbol we are referencing.  */
	  if (h->type != bfd_link_hash_new)
	    {
	      /* ??? If inh->type == bfd_link_hash_undefweak this
		 converts inh to bfd_link_hash_undefined.  */
	      row = UNDEF_ROW;
	      cycle = true;
	    }

	  h->type = bfd_link_hash_indirect;
	  h->u.i.link = inh;
	  /* Not setting h = h->u.i.link here means that when cycle is
	     set above we'll always go to REFC, and then cycle again
	     to the indirected symbol.  This means that any successful
	     change of an existing symbol to indirect counts as a
	     reference.  ??? That may not be correct when the existing
	     symbol was defweak.  */
	  break;

	case SET:
	  /* Add an entry to a set.  */
	  (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR,
					  abfd, section, value);
	  break;

	case WARNC:
	  /* Issue a warning and cycle, except when the reference is
	     in LTO IR.  */
	  if (h->u.i.warning != NULL
	      && (abfd->flags & BFD_PLUGIN) == 0)
	    {
	      (*info->callbacks->warning) (info, h->u.i.warning,
					   h->root.string, abfd, NULL, 0);
	      /* Only issue a warning once.  */
	      h->u.i.warning = NULL;
	    }
	  /* Fall through.  */
	case CYCLE:
	  /* Try again with the referenced symbol.  */
	  h = h->u.i.link;
	  cycle = true;
	  break;

	case REFC:
	  /* A reference to an indirect symbol.  */
	  if (h->u.undef.next == NULL && info->hash->undefs_tail != h)
	    h->u.undef.next = h;
	  h = h->u.i.link;
	  cycle = true;
	  break;

	case WARN:
	  /* Warn if this symbol has been referenced already from non-IR,
	     otherwise add a warning.  */
	  if ((!info->lto_plugin_active
	       && (h->u.undef.next != NULL || info->hash->undefs_tail == h))
	      || h->non_ir_ref_regular
	      || h->non_ir_ref_dynamic)
	    {
	      (*info->callbacks->warning) (info, string, h->root.string,
					   hash_entry_bfd (h), NULL, 0);
	      /* PR 31067: If garbage collection is enabled then the
		 referenced symbol may actually be discarded later on.
		 This could be very confusing to the user.  So give them
		 a hint as to what might be happening.  */
	      if (info->gc_sections)
		(*info->callbacks->info)
		  (_("%P: %pB: note: the message above does not take linker garbage collection into account\n"),
		   hash_entry_bfd (h));
	      break;
	    }
	  /* Fall through.  */
	case MWARN:
	  /* Make a warning symbol.  */
	  {
	    struct bfd_link_hash_entry *sub;

	    /* STRING is the warning to give.  */
	    sub = ((struct bfd_link_hash_entry *)
		   ((*info->hash->table.newfunc)
		    (NULL, &info->hash->table, h->root.string)));
	    if (sub == NULL)
	      return false;
	    *sub = *h;
	    sub->type = bfd_link_hash_warning;
	    sub->u.i.link = h;
	    if (! copy)
	      sub->u.i.warning = string;
	    else
	      {
		char *w;
		size_t len = strlen (string) + 1;

		w = (char *) bfd_hash_allocate (&info->hash->table, len);
		if (w == NULL)
		  return false;
		memcpy (w, string, len);
		sub->u.i.warning = w;
	      }

	    bfd_hash_replace (&info->hash->table,
			      (struct bfd_hash_entry *) h,
			      (struct bfd_hash_entry *) sub);
	    if (hashp != NULL)
	      *hashp = sub;
	  }
	  break;
	}
    }
  while (cycle);

  return true;
}

/*
FUNCTION
	bfd_link_align_section

SYNOPSIS
	bool bfd_link_align_section (asection *, unsigned int);

DESCRIPTION
	Increase section alignment if the current section alignment is
	less than the requested value.  Adjust output section
	alignment too, so that linker layout adjusts for alignment on
	the current lang_size_sections pass.  This is important for
	lang_size_relro_segment.  If the output section alignment
	isn't adjusted, the linker will place the output section at an
	address depending on its current alignment.  When sizing the
	output section, input sections attached transfer any increase
	in alignment to the output section, which will affect layout
	for the next sizing pass.  Which is all well and good except
	that lang_size_relro_segment for the current sizing pass uses
	that possibly increased alignment with a layout that doesn't
	suit.
*/

bool
bfd_link_align_section (asection *sec, unsigned int align_p2)
{
  if (align_p2 > bfd_section_alignment (sec))
    {
      if (!bfd_set_section_alignment (sec, align_p2))
	return false;
      asection *osec = sec->output_section;
      if (osec && align_p2 > bfd_section_alignment (osec))
	{
	  if (!bfd_set_section_alignment (osec, align_p2))
	    return false;
	}
    }
  return true;
}

/* Generic final link routine.  */

bool
_bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info)
{
  bfd *sub;
  asection *o;
  struct bfd_link_order *p;
  size_t outsymalloc;
  struct generic_write_global_symbol_info wginfo;

  abfd->outsymbols = NULL;
  abfd->symcount = 0;
  outsymalloc = 0;

  /* Mark all sections which will be included in the output file.  */
  for (o = abfd->sections; o != NULL; o = o->next)
    for (p = o->map_head.link_order; p != NULL; p = p->next)
      if (p->type == bfd_indirect_link_order)
	p->u.indirect.section->linker_mark = true;

  /* Build the output symbol table.  */
  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
    if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc))
      return false;

  /* Accumulate the global symbols.  */
  wginfo.info = info;
  wginfo.output_bfd = abfd;
  wginfo.psymalloc = &outsymalloc;
  wginfo.failed = false;
  _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info),
				   _bfd_generic_link_write_global_symbol,
				   &wginfo);
  if (wginfo.failed)
    return false;

  /* Make sure we have a trailing NULL pointer on OUTSYMBOLS.  We
     shouldn't really need one, since we have SYMCOUNT, but some old
     code still expects one.  */
  if (! generic_add_output_symbol (abfd, &outsymalloc, NULL))
    return false;

  if (bfd_link_relocatable (info))
    {
      /* Allocate space for the output relocs for each section.  */
      for (o = abfd->sections; o != NULL; o = o->next)
	{
	  o->reloc_count = 0;
	  for (p = o->map_head.link_order; p != NULL; p = p->next)
	    {
	      if (p->type == bfd_section_reloc_link_order
		  || p->type == bfd_symbol_reloc_link_order)
		++o->reloc_count;
	      else if (p->type == bfd_indirect_link_order)
		{
		  asection *input_section;
		  bfd *input_bfd;
		  long relsize;
		  arelent **relocs;
		  asymbol **symbols;
		  long reloc_count;

		  input_section = p->u.indirect.section;
		  input_bfd = input_section->owner;
		  relsize = bfd_get_reloc_upper_bound (input_bfd,
						       input_section);
		  if (relsize < 0)
		    return false;
		  relocs = (arelent **) bfd_malloc (relsize);
		  if (!relocs && relsize != 0)
		    return false;
		  symbols = _bfd_generic_link_get_symbols (input_bfd);
		  reloc_count = bfd_canonicalize_reloc (input_bfd,
							input_section,
							relocs,
							symbols);
		  free (relocs);
		  if (reloc_count < 0)
		    return false;
		  BFD_ASSERT ((unsigned long) reloc_count
			      == input_section->reloc_count);
		  o->reloc_count += reloc_count;
		}
	    }
	  if (o->reloc_count > 0)
	    {
	      bfd_size_type amt;

	      amt = o->reloc_count;
	      amt *= sizeof (arelent *);
	      o->orelocation = (struct reloc_cache_entry **) bfd_alloc (abfd, amt);
	      if (!o->orelocation)
		return false;
	      o->flags |= SEC_RELOC;
	      /* Reset the count so that it can be used as an index
		 when putting in the output relocs.  */
	      o->reloc_count = 0;
	    }
	}
    }

  /* Handle all the link order information for the sections.  */
  for (o = abfd->sections; o != NULL; o = o->next)
    {
      for (p = o->map_head.link_order; p != NULL; p = p->next)
	{
	  switch (p->type)
	    {
	    case bfd_section_reloc_link_order:
	    case bfd_symbol_reloc_link_order:
	      if (! _bfd_generic_reloc_link_order (abfd, info, o, p))
		return false;
	      break;
	    case bfd_indirect_link_order:
	      if (! default_indirect_link_order (abfd, info, o, p, true))
		return false;
	      break;
	    default:
	      if (! _bfd_default_link_order (abfd, info, o, p))
		return false;
	      break;
	    }
	}
    }

  return true;
}

/* Add an output symbol to the output BFD.  */

static bool
generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym)
{
  if (!(bfd_applicable_file_flags (output_bfd) & HAS_SYMS))
    return true;

  if (bfd_get_symcount (output_bfd) >= *psymalloc)
    {
      asymbol **newsyms;
      bfd_size_type amt;

      if (*psymalloc == 0)
	*psymalloc = 124;
      else
	*psymalloc *= 2;
      amt = *psymalloc;
      amt *= sizeof (asymbol *);
      newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt);
      if (newsyms == NULL)
	return false;
      output_bfd->outsymbols = newsyms;
    }

  output_bfd->outsymbols[output_bfd->symcount] = sym;
  if (sym != NULL)
    ++output_bfd->symcount;

  return true;
}

/* Handle the symbols for an input BFD.  */

static bool
_bfd_generic_link_output_symbols (bfd *output_bfd,
				  bfd *input_bfd,
				  struct bfd_link_info *info,
				  size_t *psymalloc)
{
  asymbol **sym_ptr;
  asymbol **sym_end;

  if (!bfd_generic_link_read_symbols (input_bfd))
    return false;

  /* Create a filename symbol if we are supposed to.  */
  if (info->create_object_symbols_section != NULL)
    {
      asection *sec;

      for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
	{
	  if (sec->output_section == info->create_object_symbols_section)
	    {
	      asymbol *newsym;

	      newsym = bfd_make_empty_symbol (input_bfd);
	      if (!newsym)
		return false;
	      newsym->name = bfd_get_filename (input_bfd);
	      newsym->value = 0;
	      newsym->flags = BSF_LOCAL | BSF_FILE;
	      newsym->section = sec;

	      if (! generic_add_output_symbol (output_bfd, psymalloc,
					       newsym))
		return false;

	      break;
	    }
	}
    }

  /* Adjust the values of the globally visible symbols, and write out
     local symbols.  */
  sym_ptr = _bfd_generic_link_get_symbols (input_bfd);
  sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd);
  for (; sym_ptr < sym_end; sym_ptr++)
    {
      asymbol *sym;
      struct generic_link_hash_entry *h;

      h = NULL;
      sym = *sym_ptr;
      if ((sym->flags & (BSF_INDIRECT
			 | BSF_WARNING
			 | BSF_GLOBAL
			 | BSF_CONSTRUCTOR
			 | BSF_WEAK)) != 0
	  || bfd_is_und_section (bfd_asymbol_section (sym))
	  || bfd_is_com_section (bfd_asymbol_section (sym))
	  || bfd_is_ind_section (bfd_asymbol_section (sym)))
	{
	  if (sym->udata.p != NULL)
	    h = (struct generic_link_hash_entry *) sym->udata.p;
	  else if ((sym->flags & BSF_CONSTRUCTOR) != 0)
	    {
	      /* This case normally means that the main linker code
		 deliberately ignored this constructor symbol.  We
		 should just pass it through.  This will screw up if
		 the constructor symbol is from a different,
		 non-generic, object file format, but the case will
		 only arise when linking with -r, which will probably
		 fail anyhow, since there will be no way to represent
		 the relocs in the output format being used.  */
	      h = NULL;
	    }
	  else if (bfd_is_und_section (bfd_asymbol_section (sym)))
	    h = ((struct generic_link_hash_entry *)
		 bfd_wrapped_link_hash_lookup (output_bfd, info,
					       bfd_asymbol_name (sym),
					       false, false, true));
	  else
	    h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info),
					       bfd_asymbol_name (sym),
					       false, false, true);

	  if (h != NULL)
	    {
	      /* Force all references to this symbol to point to
		 the same area in memory.  It is possible that
		 this routine will be called with a hash table
		 other than a generic hash table, so we double
		 check that.  */
	      if (info->output_bfd->xvec == input_bfd->xvec)
		{
		  if (h->sym != NULL)
		    *sym_ptr = sym = h->sym;
		}

	      switch (h->root.type)
		{
		default:
		case bfd_link_hash_new:
		  abort ();
		case bfd_link_hash_undefined:
		  break;
		case bfd_link_hash_undefweak:
		  sym->flags |= BSF_WEAK;
		  break;
		case bfd_link_hash_indirect:
		  h = (struct generic_link_hash_entry *) h->root.u.i.link;
		  /* fall through */
		case bfd_link_hash_defined:
		  sym->flags |= BSF_GLOBAL;
		  sym->flags &=~ (BSF_WEAK | BSF_CONSTRUCTOR);
		  sym->value = h->root.u.def.value;
		  sym->section = h->root.u.def.section;
		  break;
		case bfd_link_hash_defweak:
		  sym->flags |= BSF_WEAK;
		  sym->flags &=~ BSF_CONSTRUCTOR;
		  sym->value = h->root.u.def.value;
		  sym->section = h->root.u.def.section;
		  break;
		case bfd_link_hash_common:
		  sym->value = h->root.u.c.size;
		  sym->flags |= BSF_GLOBAL;
		  if (! bfd_is_com_section (sym->section))
		    {
		      BFD_ASSERT (bfd_is_und_section (sym->section));
		      sym->section = bfd_com_section_ptr;
		    }
		  /* We do not set the section of the symbol to
		     h->root.u.c.p->section.  That value was saved so
		     that we would know where to allocate the symbol
		     if it was defined.  In this case the type is
		     still bfd_link_hash_common, so we did not define
		     it, so we do not want to use that section.  */
		  break;
		}
	    }
	}

      bool output = false;
      if ((sym->flags & BSF_KEEP) == 0
	  && (info->strip == strip_all
	      || (info->strip == strip_some
		  && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
				      false, false) == NULL)))
	;
      /* If this symbol is in a section which is not being included
	 in the output file, then we don't want to output the
	 symbol.  */
      else if (!bfd_is_abs_section (sym->section)
	       && bfd_section_removed_from_list (output_bfd,
						 sym->section->output_section))
	;
      else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0)
	{
	  /* If this symbol is marked as occurring now, rather
	     than at the end, output it now.  This is used for
	     COFF C_EXT FCN symbols.  FIXME: There must be a
	     better way.  */
	  if (bfd_asymbol_bfd (sym) == input_bfd
	      && (sym->flags & BSF_NOT_AT_END) != 0)
	    output = true;
	}
      else if ((sym->flags & BSF_KEEP) != 0)
	output = true;
      else if (bfd_is_ind_section (sym->section))
	;
      else if ((sym->flags & BSF_DEBUGGING) != 0)
	{
	  if (info->strip == strip_none)
	    output = true;
	}
      else if (bfd_is_und_section (sym->section)
	       || bfd_is_com_section (sym->section))
	;
      else if ((sym->flags & BSF_LOCAL) != 0)
	{
	  if ((sym->flags & BSF_WARNING) == 0)
	    {
	      switch (info->discard)
		{
		default:
		case discard_all:
		  break;
		case discard_sec_merge:
		  output = true;
		  if (bfd_link_relocatable (info)
		      || ! (sym->section->flags & SEC_MERGE))
		    break;
		  /* FALLTHROUGH */
		case discard_l:
		  if (!bfd_is_local_label (input_bfd, sym))
		    output = true;
		  break;
		case discard_none:
		  output = true;
		  break;
		}
	    }
	}
      else if ((sym->flags & BSF_CONSTRUCTOR))
	{
	  if (info->strip != strip_all)
	    output = true;
	}
      else if (sym->flags == 0)
	/* LTO doesn't set symbol information.  We get here with the
	   generic linker for a symbol that was "common" but no longer
	   needs to be global.  We also get here on fuzzed ELF objects
	   with bogus symbol type and binding.  */
	;
      else
	BFD_FAIL ();

      if (output)
	{
	  if (! generic_add_output_symbol (output_bfd, psymalloc, sym))
	    return false;
	  if (h != NULL)
	    h->written = true;
	}
    }

  return true;
}

/* Set the section and value of a generic BFD symbol based on a linker
   hash table entry.  */

static void
set_symbol_from_hash (bfd *output_bfd,
		      asymbol *sym,
		      struct bfd_link_hash_entry *h)
{
  switch (h->type)
    {
    default:
      abort ();
      break;
    case bfd_link_hash_new:
      /* This can happen when a constructor symbol is seen but we are
	 not building constructors.  */
      if (sym->section != NULL)
	{
	  BFD_ASSERT ((sym->flags & BSF_CONSTRUCTOR) != 0);
	}
      else
	{
	  sym->flags |= BSF_CONSTRUCTOR;
	  sym->section = bfd_abs_section_ptr;
	  sym->value = 0;
	}
      break;
    case bfd_link_hash_undefined:
      sym->section = bfd_und_section_ptr;
      sym->value = 0;
      break;
    case bfd_link_hash_undefweak:
      sym->section = bfd_und_section_ptr;
      sym->value = 0;
      sym->flags |= BSF_WEAK;
      break;
    case bfd_link_hash_defined:
      sym->flags |= BSF_GLOBAL;
      sym->section = h->u.def.section;
      sym->value = h->u.def.value;
      if (sym->section->sec_info_type == SEC_INFO_TYPE_MERGE)
	{
	  sym->value =
	    _bfd_merged_section_offset (output_bfd, &sym->section, sym->value);
	  sym->flags |= BSF_MERGE_RESOLVED;
	}
      break;
    case bfd_link_hash_defweak:
      sym->flags |= BSF_WEAK;
      sym->section = h->u.def.section;
      sym->value = h->u.def.value;
      if (sym->section->sec_info_type == SEC_INFO_TYPE_MERGE)
	{
	  sym->value =
	    _bfd_merged_section_offset (output_bfd, &sym->section, sym->value);
	  sym->flags |= BSF_MERGE_RESOLVED;
	}
      break;
    case bfd_link_hash_common:
      sym->value = h->u.c.size;
      if (sym->section == NULL)
	sym->section = bfd_com_section_ptr;
      else if (! bfd_is_com_section (sym->section))
	{
	  BFD_ASSERT (bfd_is_und_section (sym->section));
	  sym->section = bfd_com_section_ptr;
	}
      /* Do not set the section; see _bfd_generic_link_output_symbols.  */
      break;
    case bfd_link_hash_indirect:
    case bfd_link_hash_warning:
      /* FIXME: What should we do here?  */
      break;
    }
}

/* Write out a global symbol, if it hasn't already been written out.
   This is called for each symbol in the hash table.  */

static bool
_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h,
				       void *data)
{
  struct generic_write_global_symbol_info *wginfo = data;
  asymbol *sym;

  if (h->written)
    return true;

  h->written = true;

  if (wginfo->info->strip == strip_all
      || (wginfo->info->strip == strip_some
	  && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string,
			      false, false) == NULL))
    return true;

  if (h->sym != NULL)
    sym = h->sym;
  else
    {
      sym = bfd_make_empty_symbol (wginfo->output_bfd);
      if (!sym)
	{
	  wginfo->failed = true;
	  return false;
	}
      sym->name = h->root.root.string;
      sym->flags = 0;
    }

  set_symbol_from_hash (wginfo->output_bfd, sym, &h->root);

  sym->flags |= BSF_GLOBAL;

  if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc,
				   sym))
    {
      wginfo->failed = true;
      return false;
    }

  return true;
}

/* Create a relocation.  */

bool
_bfd_generic_reloc_link_order (bfd *abfd,
			       struct bfd_link_info *info,
			       asection *sec,
			       struct bfd_link_order *link_order)
{
  arelent *r;

  if (! bfd_link_relocatable (info))
    abort ();
  if (sec->orelocation == NULL)
    abort ();

  r = (arelent *) bfd_alloc (abfd, sizeof (arelent));
  if (r == NULL)
    return false;

  r->address = link_order->offset;
  r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
  if (r->howto == 0)
    {
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  /* Get the symbol to use for the relocation.  */
  if (link_order->type == bfd_section_reloc_link_order)
    r->sym_ptr_ptr = &link_order->u.reloc.p->u.section->symbol;
  else
    {
      struct generic_link_hash_entry *h;

      h = ((struct generic_link_hash_entry *)
	   bfd_wrapped_link_hash_lookup (abfd, info,
					 link_order->u.reloc.p->u.name,
					 false, false, true));
      if (h == NULL
	  || ! h->written)
	{
	  (*info->callbacks->unattached_reloc)
	    (info, link_order->u.reloc.p->u.name, NULL, NULL, 0);
	  bfd_set_error (bfd_error_bad_value);
	  return false;
	}
      r->sym_ptr_ptr = &h->sym;
    }

  /* If this is an inplace reloc, write the addend to the object file.
     Otherwise, store it in the reloc addend.  */
  if (! r->howto->partial_inplace)
    r->addend = link_order->u.reloc.p->addend;
  else
    {
      bfd_size_type size;
      bfd_reloc_status_type rstat;
      bfd_byte *buf;
      bool ok;
      file_ptr loc;

      size = bfd_get_reloc_size (r->howto);
      buf = (bfd_byte *) bfd_zmalloc (size);
      if (buf == NULL && size != 0)
	return false;
      rstat = _bfd_relocate_contents (r->howto, abfd,
				      (bfd_vma) link_order->u.reloc.p->addend,
				      buf);
      switch (rstat)
	{
	case bfd_reloc_ok:
	  break;
	default:
	case bfd_reloc_outofrange:
	  abort ();
	case bfd_reloc_overflow:
	  (*info->callbacks->reloc_overflow)
	    (info, NULL,
	     (link_order->type == bfd_section_reloc_link_order
	      ? bfd_section_name (link_order->u.reloc.p->u.section)
	      : link_order->u.reloc.p->u.name),
	     r->howto->name, link_order->u.reloc.p->addend,
	     NULL, NULL, 0);
	  break;
	}
      loc = link_order->offset * bfd_octets_per_byte (abfd, sec);
      ok = bfd_set_section_contents (abfd, sec, buf, loc, size);
      free (buf);
      if (! ok)
	return false;

      r->addend = 0;
    }

  sec->orelocation[sec->reloc_count] = r;
  ++sec->reloc_count;

  return true;
}

/* Allocate a new link_order for a section.  */

struct bfd_link_order *
bfd_new_link_order (bfd *abfd, asection *section)
{
  size_t amt = sizeof (struct bfd_link_order);
  struct bfd_link_order *new_lo;

  new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt);
  if (!new_lo)
    return NULL;

  new_lo->type = bfd_undefined_link_order;

  if (section->map_tail.link_order != NULL)
    section->map_tail.link_order->next = new_lo;
  else
    section->map_head.link_order = new_lo;
  section->map_tail.link_order = new_lo;

  return new_lo;
}

/* Default link order processing routine.  Note that we can not handle
   the reloc_link_order types here, since they depend upon the details
   of how the particular backends generates relocs.  */

bool
_bfd_default_link_order (bfd *abfd,
			 struct bfd_link_info *info,
			 asection *sec,
			 struct bfd_link_order *link_order)
{
  switch (link_order->type)
    {
    case bfd_undefined_link_order:
    case bfd_section_reloc_link_order:
    case bfd_symbol_reloc_link_order:
    default:
      abort ();
    case bfd_indirect_link_order:
      return default_indirect_link_order (abfd, info, sec, link_order,
					  false);
    case bfd_data_link_order:
      return default_data_link_order (abfd, info, sec, link_order);
    }
}

/* Default routine to handle a bfd_data_link_order.  */

static bool
default_data_link_order (bfd *abfd,
			 struct bfd_link_info *info,
			 asection *sec,
			 struct bfd_link_order *link_order)
{
  bfd_size_type size;
  size_t fill_size;
  bfd_byte *fill;
  file_ptr loc;
  bool result;

  BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0);

  size = link_order->size;
  if (size == 0)
    return true;

  fill = link_order->u.data.contents;
  fill_size = link_order->u.data.size;
  if (fill_size == 0)
    {
      fill = abfd->arch_info->fill (size, info->big_endian,
				    (sec->flags & SEC_CODE) != 0);
      if (fill == NULL)
	return false;
    }
  else if (fill_size < size)
    {
      bfd_byte *p;
      fill = (bfd_byte *) bfd_malloc (size);
      if (fill == NULL)
	return false;
      p = fill;
      if (fill_size == 1)
	memset (p, (int) link_order->u.data.contents[0], (size_t) size);
      else
	{
	  do
	    {
	      memcpy (p, link_order->u.data.contents, fill_size);
	      p += fill_size;
	      size -= fill_size;
	    }
	  while (size >= fill_size);
	  if (size != 0)
	    memcpy (p, link_order->u.data.contents, (size_t) size);
	  size = link_order->size;
	}
    }

  loc = link_order->offset * bfd_octets_per_byte (abfd, sec);
  result = bfd_set_section_contents (abfd, sec, fill, loc, size);

  if (fill != link_order->u.data.contents)
    free (fill);
  return result;
}

/* Default routine to handle a bfd_indirect_link_order.  */

static bool
default_indirect_link_order (bfd *output_bfd,
			     struct bfd_link_info *info,
			     asection *output_section,
			     struct bfd_link_order *link_order,
			     bool generic_linker)
{
  asection *input_section;
  bfd *input_bfd;
  bfd_byte *alloced = NULL;
  bfd_byte *new_contents;
  file_ptr loc;

  BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);

  input_section = link_order->u.indirect.section;
  input_bfd = input_section->owner;
  if (input_section->size == 0)
    return true;

  BFD_ASSERT (input_section->output_section == output_section);
  BFD_ASSERT (input_section->output_offset == link_order->offset);
  BFD_ASSERT (input_section->size == link_order->size);

  if (bfd_link_relocatable (info)
      && input_section->reloc_count > 0
      && output_section->orelocation == NULL)
    {
      /* Space has not been allocated for the output relocations.
	 This can happen when we are called by a specific backend
	 because somebody is attempting to link together different
	 types of object files.  Handling this case correctly is
	 difficult, and sometimes impossible.  */
      _bfd_error_handler
	/* xgettext:c-format */
	(_("attempt to do relocatable link with %s input and %s output"),
	 bfd_get_target (input_bfd), bfd_get_target (output_bfd));
      bfd_set_error (bfd_error_wrong_format);
      return false;
    }

  if (! generic_linker)
    {
      asymbol **sympp;
      asymbol **symppend;

      /* Get the canonical symbols.  The generic linker will always
	 have retrieved them by this point, but we are being called by
	 a specific linker, presumably because we are linking
	 different types of object files together.  */
      if (!bfd_generic_link_read_symbols (input_bfd))
	return false;

      /* Since we have been called by a specific linker, rather than
	 the generic linker, the values of the symbols will not be
	 right.  They will be the values as seen in the input file,
	 not the values of the final link.  We need to fix them up
	 before we can relocate the section.  */
      sympp = _bfd_generic_link_get_symbols (input_bfd);
      symppend = sympp + _bfd_generic_link_get_symcount (input_bfd);
      for (; sympp < symppend; sympp++)
	{
	  asymbol *sym;
	  struct bfd_link_hash_entry *h = NULL;

	  sym = *sympp;

	  if ((sym->flags & (BSF_INDIRECT
			     | BSF_WARNING
			     | BSF_GLOBAL
			     | BSF_CONSTRUCTOR
			     | BSF_WEAK)) != 0
	      || bfd_is_und_section (bfd_asymbol_section (sym))
	      || bfd_is_com_section (bfd_asymbol_section (sym))
	      || bfd_is_ind_section (bfd_asymbol_section (sym)))
	    {
	      /* sym->udata may have been set by
		 generic_link_add_symbol_list.  */
	      if (sym->udata.p != NULL)
		h = (struct bfd_link_hash_entry *) sym->udata.p;
	      else if (bfd_is_und_section (bfd_asymbol_section (sym)))
		h = bfd_wrapped_link_hash_lookup (output_bfd, info,
						  bfd_asymbol_name (sym),
						  false, false, true);
	      else
		h = bfd_link_hash_lookup (info->hash,
					  bfd_asymbol_name (sym),
					  false, false, true);
	      if (h != NULL)
		set_symbol_from_hash (output_bfd, sym, h);
	    }

	  if (h == NULL
	      && sym->section->sec_info_type == SEC_INFO_TYPE_MERGE
	      && !(sym->flags & (BSF_SECTION_SYM | BSF_MERGE_RESOLVED)))
	    {
	      sym->value = _bfd_merged_section_offset (output_bfd,
						       &sym->section,
						       sym->value);
	      sym->flags |= BSF_MERGE_RESOLVED;
	    }
	}

      if (input_section->sec_info_type == SEC_INFO_TYPE_MERGE)
	return _bfd_write_merged_section (output_bfd, input_section);
    }

  if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP
      && input_section->size != 0)
    {
      /* Group section contents are set by bfd_elf_set_group_contents.  */
      if (!output_bfd->output_has_begun)
	{
	  /* FIXME: This hack ensures bfd_elf_set_group_contents is called.  */
	  if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1))
	    goto error_return;
	}
      new_contents = output_section->contents;
      BFD_ASSERT (new_contents != NULL);
      BFD_ASSERT (input_section->output_offset == 0);
    }
  else
    {
      /* Get and relocate the section contents.  */
      new_contents = (bfd_get_relocated_section_contents
		      (output_bfd, info, link_order, NULL,
		       bfd_link_relocatable (info),
		       _bfd_generic_link_get_symbols (input_bfd)));
      alloced = new_contents;
      if (!new_contents)
	goto error_return;
    }

  /* Output the section contents.  */
  loc = (input_section->output_offset
	 * bfd_octets_per_byte (output_bfd, output_section));
  if (! bfd_set_section_contents (output_bfd, output_section,
				  new_contents, loc, input_section->size))
    goto error_return;

  free (alloced);
  return true;

 error_return:
  free (alloced);
  return false;
}

/* A little routine to count the number of relocs in a link_order
   list.  */

unsigned int
_bfd_count_link_order_relocs (struct bfd_link_order *link_order)
{
  register unsigned int c;
  register struct bfd_link_order *l;

  c = 0;
  for (l = link_order; l != NULL; l = l->next)
    {
      if (l->type == bfd_section_reloc_link_order
	  || l->type == bfd_symbol_reloc_link_order)
	++c;
    }

  return c;
}

/*
FUNCTION
	bfd_link_split_section

SYNOPSIS
	bool bfd_link_split_section (bfd *abfd, asection *sec);

DESCRIPTION
	Return nonzero if @var{sec} should be split during a
	reloceatable or final link.

.#define bfd_link_split_section(abfd, sec) \
.	BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
.

*/

bool
_bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED,
				 asection *sec ATTRIBUTE_UNUSED)
{
  return false;
}

/*
FUNCTION
	bfd_section_already_linked

SYNOPSIS
	bool bfd_section_already_linked (bfd *abfd,
					 asection *sec,
					 struct bfd_link_info *info);

DESCRIPTION
	Check if @var{data} has been already linked during a reloceatable
	or final link.  Return TRUE if it has.

.#define bfd_section_already_linked(abfd, sec, info) \
.	BFD_SEND (abfd, _section_already_linked, (abfd, sec, info))
.

*/

/* Sections marked with the SEC_LINK_ONCE flag should only be linked
   once into the output.  This routine checks each section, and
   arrange to discard it if a section of the same name has already
   been linked.  This code assumes that all relevant sections have the
   SEC_LINK_ONCE flag set; that is, it does not depend solely upon the
   section name.  bfd_section_already_linked is called via
   bfd_map_over_sections.  */

/* The hash table.  */

static struct bfd_hash_table _bfd_section_already_linked_table;

/* Support routines for the hash table used by section_already_linked,
   initialize the table, traverse, lookup, fill in an entry and remove
   the table.  */

void
bfd_section_already_linked_table_traverse
  (bool (*func) (struct bfd_section_already_linked_hash_entry *, void *),
   void *info)
{
  bfd_hash_traverse (&_bfd_section_already_linked_table,
		     (bool (*) (struct bfd_hash_entry *, void *)) func,
		     info);
}

struct bfd_section_already_linked_hash_entry *
bfd_section_already_linked_table_lookup (const char *name)
{
  return ((struct bfd_section_already_linked_hash_entry *)
	  bfd_hash_lookup (&_bfd_section_already_linked_table, name,
			   true, false));
}

bool
bfd_section_already_linked_table_insert
  (struct bfd_section_already_linked_hash_entry *already_linked_list,
   asection *sec)
{
  struct bfd_section_already_linked *l;

  /* Allocate the memory from the same obstack as the hash table is
     kept in.  */
  l = (struct bfd_section_already_linked *)
      bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
  if (l == NULL)
    return false;
  l->sec = sec;
  l->next = already_linked_list->entry;
  already_linked_list->entry = l;
  return true;
}

static struct bfd_hash_entry *
already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
			struct bfd_hash_table *table,
			const char *string ATTRIBUTE_UNUSED)
{
  struct bfd_section_already_linked_hash_entry *ret =
    (struct bfd_section_already_linked_hash_entry *)
      bfd_hash_allocate (table, sizeof *ret);

  if (ret == NULL)
    return NULL;

  ret->entry = NULL;

  return &ret->root;
}

bool
bfd_section_already_linked_table_init (void)
{
  return bfd_hash_table_init_n (&_bfd_section_already_linked_table,
				already_linked_newfunc,
				sizeof (struct bfd_section_already_linked_hash_entry),
				42);
}

void
bfd_section_already_linked_table_free (void)
{
  bfd_hash_table_free (&_bfd_section_already_linked_table);
}

/* Report warnings as appropriate for duplicate section SEC.
   Return FALSE if we decide to keep SEC after all.  */

bool
_bfd_handle_already_linked (asection *sec,
			    struct bfd_section_already_linked *l,
			    struct bfd_link_info *info)
{
  switch (sec->flags & SEC_LINK_DUPLICATES)
    {
    default:
      abort ();

    case SEC_LINK_DUPLICATES_DISCARD:
      /* If we found an LTO IR match for this comdat group on
	 the first pass, replace it with the LTO output on the
	 second pass.  We can't simply choose real object
	 files over IR because the first pass may contain a
	 mix of LTO and normal objects and we must keep the
	 first match, be it IR or real.  */
      if (sec->owner->lto_output
	  && (l->sec->owner->flags & BFD_PLUGIN) != 0)
	{
	  l->sec = sec;
	  return false;
	}
      break;

    case SEC_LINK_DUPLICATES_ONE_ONLY:
      info->callbacks->einfo
	/* xgettext:c-format */
	(_("%pB: ignoring duplicate section `%pA'\n"),
	 sec->owner, sec);
      break;

    case SEC_LINK_DUPLICATES_SAME_SIZE:
      if ((l->sec->owner->flags & BFD_PLUGIN) != 0)
	;
      else if (sec->size != l->sec->size)
	info->callbacks->einfo
	  /* xgettext:c-format */
	  (_("%pB: duplicate section `%pA' has different size\n"),
	   sec->owner, sec);
      break;

    case SEC_LINK_DUPLICATES_SAME_CONTENTS:
      if ((l->sec->owner->flags & BFD_PLUGIN) != 0)
	;
      else if (sec->size != l->sec->size)
	info->callbacks->einfo
	  /* xgettext:c-format */
	  (_("%pB: duplicate section `%pA' has different size\n"),
	   sec->owner, sec);
      else if (sec->size != 0)
	{
	  bfd_byte *sec_contents, *l_sec_contents;

	  if ((sec->flags & SEC_HAS_CONTENTS) == 0
	      && (l->sec->flags & SEC_HAS_CONTENTS) == 0)
	    ;
	  else if ((sec->flags & SEC_HAS_CONTENTS) == 0
		   || !bfd_malloc_and_get_section (sec->owner, sec,
						   &sec_contents))
	    info->callbacks->einfo
	      /* xgettext:c-format */
	      (_("%pB: could not read contents of section `%pA'\n"),
	       sec->owner, sec);
	  else if ((l->sec->flags & SEC_HAS_CONTENTS) == 0
		   || !bfd_malloc_and_get_section (l->sec->owner, l->sec,
						   &l_sec_contents))
	    {
	      info->callbacks->einfo
		/* xgettext:c-format */
		(_("%pB: could not read contents of section `%pA'\n"),
		 l->sec->owner, l->sec);
	      free (sec_contents);
	    }
	  else
	    {
	      if (memcmp (sec_contents, l_sec_contents, sec->size) != 0)
		info->callbacks->einfo
		  /* xgettext:c-format */
		  (_("%pB: duplicate section `%pA' has different contents\n"),
		   sec->owner, sec);
	      free (l_sec_contents);
	      free (sec_contents);
	    }
	}
      break;
    }

  /* Set the output_section field so that lang_add_section
     does not create a lang_input_section structure for this
     section.  Since there might be a symbol in the section
     being discarded, we must retain a pointer to the section
     which we are really going to use.  */
  sec->output_section = bfd_abs_section_ptr;
  sec->kept_section = l->sec;
  return true;
}

/* This is used on non-ELF inputs.  */

bool
_bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED,
				     asection *sec,
				     struct bfd_link_info *info)
{
  const char *name;
  struct bfd_section_already_linked *l;
  struct bfd_section_already_linked_hash_entry *already_linked_list;

  if ((sec->flags & SEC_LINK_ONCE) == 0)
    return false;

  /* The generic linker doesn't handle section groups.  */
  if ((sec->flags & SEC_GROUP) != 0)
    return false;

  /* FIXME: When doing a relocatable link, we may have trouble
     copying relocations in other sections that refer to local symbols
     in the section being discarded.  Those relocations will have to
     be converted somehow; as of this writing I'm not sure that any of
     the backends handle that correctly.

     It is tempting to instead not discard link once sections when
     doing a relocatable link (technically, they should be discarded
     whenever we are building constructors).  However, that fails,
     because the linker winds up combining all the link once sections
     into a single large link once section, which defeats the purpose
     of having link once sections in the first place.  */

  name = bfd_section_name (sec);

  already_linked_list = bfd_section_already_linked_table_lookup (name);
  if (!already_linked_list)
    goto bad;

  l = already_linked_list->entry;
  if (l != NULL)
    {
      /* The section has already been linked.  See if we should
	 issue a warning.  */
      return _bfd_handle_already_linked (sec, l, info);
    }

  /* This is the first section with this name.  Record it.  */
  if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
    {
    bad:
      info->callbacks->fatal (_("%P: already_linked_table: %E\n"));
    }
  return false;
}

/* Convert symbols in excluded output sections to use a kept section.  */

static bool
fix_syms (struct bfd_link_hash_entry *h, void *data)
{
  struct bfd_link_info *info = data;
  bfd *obfd = info->output_bfd;

  if (h->type == bfd_link_hash_defined
      || h->type == bfd_link_hash_defweak)
    {
      asection *s = h->u.def.section;
      if (s != NULL
	  && s->output_section != NULL
	  && (s->output_section->flags & SEC_EXCLUDE) != 0
	  && bfd_section_removed_from_list (obfd, s->output_section))
	{
	  asection *op;

	  h->u.def.value += s->output_offset + s->output_section->vma;
	  op = info->callbacks->nearby_section (obfd, s->output_section,
						h->u.def.value);
	  h->u.def.value -= op->vma;
	  h->u.def.section = op;
	}
    }

  return true;
}

void
bfd_fix_excluded_sec_syms (struct bfd_link_info *info)
{
  bfd_link_hash_traverse (info->hash, fix_syms, info);
}

/*
FUNCTION
	bfd_generic_define_common_symbol

SYNOPSIS
	bool bfd_generic_define_common_symbol
	  (bfd *output_bfd, struct bfd_link_info *info,
	   struct bfd_link_hash_entry *h);

DESCRIPTION
	Convert common symbol @var{h} into a defined symbol.
	Return TRUE on success and FALSE on failure.

.#define bfd_define_common_symbol(output_bfd, info, h) \
.	BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h))
.
*/

bool
bfd_generic_define_common_symbol (bfd *output_bfd,
				  struct bfd_link_info *info ATTRIBUTE_UNUSED,
				  struct bfd_link_hash_entry *h)
{
  unsigned int power_of_two;
  bfd_vma alignment, size;
  asection *section;

  BFD_ASSERT (h != NULL && h->type == bfd_link_hash_common);

  size = h->u.c.size;
  power_of_two = h->u.c.p->alignment_power;
  section = h->u.c.p->section;

  /* Increase the size of the section to align the common symbol.
     The alignment must be a power of two.  But if the section does
     not have any alignment requirement then do not increase the
     alignment unnecessarily.  */
  if (power_of_two)
    alignment = bfd_octets_per_byte (output_bfd, section) << power_of_two;
  else
    alignment = 1;
  BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment);
  section->size += alignment - 1;
  section->size &= -alignment;

  /* Adjust the section's overall alignment if necessary.  */
  if (power_of_two > section->alignment_power)
    section->alignment_power = power_of_two;

  /* Change the symbol from common to defined.  */
  h->type = bfd_link_hash_defined;
  h->u.def.section = section;
  h->u.def.value = section->size;

  /* Increase the size of the section.  */
  section->size += size;

  /* Make sure the section is allocated in memory, and make sure that
     it is no longer a common section.  */
  section->flags |= SEC_ALLOC;
  section->flags &= ~(SEC_IS_COMMON | SEC_HAS_CONTENTS);
  return true;
}

/*
FUNCTION
	_bfd_generic_link_hide_symbol

SYNOPSIS
	void _bfd_generic_link_hide_symbol
	  (bfd *output_bfd, struct bfd_link_info *info,
	   struct bfd_link_hash_entry *h);

DESCRIPTION
	Hide symbol @var{h}.
	This is an internal function.  It should not be called from
	outside the BFD library.

.#define bfd_link_hide_symbol(output_bfd, info, h) \
.	BFD_SEND (output_bfd, _bfd_link_hide_symbol, (output_bfd, info, h))
.
*/

void
_bfd_generic_link_hide_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
			       struct bfd_link_info *info ATTRIBUTE_UNUSED,
			       struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED)
{
}

/*
FUNCTION
	bfd_generic_define_start_stop

SYNOPSIS
	struct bfd_link_hash_entry *bfd_generic_define_start_stop
	  (struct bfd_link_info *info,
	   const char *symbol, asection *sec);

DESCRIPTION
	Define a __start, __stop, .startof. or .sizeof. symbol.
	Return the symbol or NULL if no such undefined symbol exists.

.#define bfd_define_start_stop(output_bfd, info, symbol, sec) \
.	BFD_SEND (output_bfd, _bfd_define_start_stop, (info, symbol, sec))
.
*/

struct bfd_link_hash_entry *
bfd_generic_define_start_stop (struct bfd_link_info *info,
			       const char *symbol, asection *sec)
{
  struct bfd_link_hash_entry *h;

  h = bfd_link_hash_lookup (info->hash, symbol, false, false, true);
  if (h != NULL
      && !h->ldscript_def
      && (h->type == bfd_link_hash_undefined
	  || h->type == bfd_link_hash_undefweak))
    {
      h->type = bfd_link_hash_defined;
      h->u.def.section = sec;
      h->u.def.value = 0;
      return h;
    }
  return NULL;
}

/*
FUNCTION
	bfd_find_version_for_sym

SYNOPSIS
	struct bfd_elf_version_tree * bfd_find_version_for_sym
	  (struct bfd_elf_version_tree *verdefs,
	   const char *sym_name, bool *hide);

DESCRIPTION
	Search an elf version script tree for symbol versioning
	info and export / don't-export status for a given symbol.
	Return non-NULL on success and NULL on failure; also sets
	the output @samp{hide} boolean parameter.

*/

struct bfd_elf_version_tree *
bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs,
			  const char *sym_name,
			  bool *hide)
{
  struct bfd_elf_version_tree *t;
  struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
  struct bfd_elf_version_tree *star_local_ver, *star_global_ver;

  local_ver = NULL;
  global_ver = NULL;
  star_local_ver = NULL;
  star_global_ver = NULL;
  exist_ver = NULL;
  for (t = verdefs; t != NULL; t = t->next)
    {
      if (t->globals.list != NULL)
	{
	  struct bfd_elf_version_expr *d = NULL;

	  while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL)
	    {
	      if (d->literal || strcmp (d->pattern, "*") != 0)
		global_ver = t;
	      else
		star_global_ver = t;
	      if (d->symver)
		exist_ver = t;
	      d->script = 1;
	      /* If the match is a wildcard pattern, keep looking for
		 a more explicit, perhaps even local, match.  */
	      if (d->literal)
		break;
	    }

	  if (d != NULL)
	    break;
	}

      if (t->locals.list != NULL)
	{
	  struct bfd_elf_version_expr *d = NULL;

	  while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL)
	    {
	      if (d->literal || strcmp (d->pattern, "*") != 0)
		local_ver = t;
	      else
		star_local_ver = t;
	      /* If the match is a wildcard pattern, keep looking for
		 a more explicit, perhaps even global, match.  */
	      if (d->literal)
		{
		  /* An exact match overrides a global wildcard.  */
		  global_ver = NULL;
		  star_global_ver = NULL;
		  break;
		}
	    }

	  if (d != NULL)
	    break;
	}
    }

  if (global_ver == NULL && local_ver == NULL)
    global_ver = star_global_ver;

  if (global_ver != NULL)
    {
      /* If we already have a versioned symbol that matches the
	 node for this symbol, then we don't want to create a
	 duplicate from the unversioned symbol.  Instead hide the
	 unversioned symbol.  */
      *hide = exist_ver == global_ver;
      return global_ver;
    }

  if (local_ver == NULL)
    local_ver = star_local_ver;

  if (local_ver != NULL)
    {
      *hide = true;
      return local_ver;
    }

  return NULL;
}

/*
FUNCTION
	bfd_hide_sym_by_version

SYNOPSIS
	bool bfd_hide_sym_by_version
	  (struct bfd_elf_version_tree *verdefs, const char *sym_name);

DESCRIPTION
	Search an elf version script tree for symbol versioning
	info for a given symbol.  Return TRUE if the symbol is hidden.

*/

bool
bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs,
			 const char *sym_name)
{
  bool hidden = false;
  bfd_find_version_for_sym (verdefs, sym_name, &hidden);
  return hidden;
}

/*
FUNCTION
	bfd_link_check_relocs

SYNOPSIS
	bool bfd_link_check_relocs
	  (bfd *abfd, struct bfd_link_info *info);

DESCRIPTION
	Checks the relocs in ABFD for validity.
	Does not execute the relocs.
	Return TRUE if everything is OK, FALSE otherwise.
	This is the external entry point to this code.
*/

bool
bfd_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
{
  return BFD_SEND (abfd, _bfd_link_check_relocs, (abfd, info));
}

/*
FUNCTION
	_bfd_generic_link_check_relocs

SYNOPSIS
	bool _bfd_generic_link_check_relocs
	  (bfd *abfd, struct bfd_link_info *info);

DESCRIPTION
	Stub function for targets that do not implement reloc checking.
	Return TRUE.
	This is an internal function.  It should not be called from
	outside the BFD library.
*/

bool
_bfd_generic_link_check_relocs (bfd *abfd ATTRIBUTE_UNUSED,
				struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  return true;
}

/*
FUNCTION
	bfd_merge_private_bfd_data

DESCRIPTION
	Merge private BFD information from the BFD @var{ibfd} to the
	the output file BFD when linking.  Return <<TRUE>> on success,
	<<FALSE>> on error.  Possible error returns are:

	o <<bfd_error_no_memory>> -
	Not enough memory exists to create private data for @var{obfd}.

.#define bfd_merge_private_bfd_data(ibfd, info) \
.	BFD_SEND ((info)->output_bfd, _bfd_merge_private_bfd_data, \
.		  (ibfd, info))
.
*/

/*
INTERNAL_FUNCTION
	_bfd_generic_verify_endian_match

SYNOPSIS
	bool _bfd_generic_verify_endian_match
	  (bfd *ibfd, struct bfd_link_info *info);

DESCRIPTION
	Can be used from / for bfd_merge_private_bfd_data to check that
	endianness matches between input and output file.  Returns
	TRUE for a match, otherwise returns FALSE and emits an error.
*/

bool
_bfd_generic_verify_endian_match (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;

  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
    {
      if (bfd_big_endian (ibfd))
	_bfd_error_handler (_("%pB: compiled for a big endian system "
			      "and target is little endian"), ibfd);
      else
	_bfd_error_handler (_("%pB: compiled for a little endian system "
			      "and target is big endian"), ibfd);
      bfd_set_error (bfd_error_wrong_format);
      return false;
    }

  return true;
}

int
_bfd_nolink_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
			    struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  return 0;
}

bool
_bfd_nolink_bfd_relax_section (bfd *abfd,
			       asection *section ATTRIBUTE_UNUSED,
			       struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
			       bool *again ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

bfd_byte *
_bfd_nolink_bfd_get_relocated_section_contents
    (bfd *abfd,
     struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
     struct bfd_link_order *link_order ATTRIBUTE_UNUSED,
     bfd_byte *data ATTRIBUTE_UNUSED,
     bool relocatable ATTRIBUTE_UNUSED,
     asymbol **symbols ATTRIBUTE_UNUSED)
{
  return (bfd_byte *) _bfd_ptr_bfd_null_error (abfd);
}

bool
_bfd_nolink_bfd_lookup_section_flags
    (struct bfd_link_info *info ATTRIBUTE_UNUSED,
     struct flag_info *flaginfo ATTRIBUTE_UNUSED,
     asection *section)
{
  return _bfd_bool_bfd_false_error (section->owner);
}

bool
_bfd_nolink_bfd_is_group_section (bfd *abfd,
				  const asection *sec ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

const char *
_bfd_nolink_bfd_group_name (bfd *abfd,
			    const asection *sec ATTRIBUTE_UNUSED)
{
  return _bfd_ptr_bfd_null_error (abfd);
}

bool
_bfd_nolink_bfd_discard_group (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

struct bfd_link_hash_table *
_bfd_nolink_bfd_link_hash_table_create (bfd *abfd)
{
  return (struct bfd_link_hash_table *) _bfd_ptr_bfd_null_error (abfd);
}

void
_bfd_nolink_bfd_link_just_syms (asection *sec ATTRIBUTE_UNUSED,
				struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
}

void
_bfd_nolink_bfd_copy_link_hash_symbol_type
    (bfd *abfd ATTRIBUTE_UNUSED,
     struct bfd_link_hash_entry *from ATTRIBUTE_UNUSED,
     struct bfd_link_hash_entry *to ATTRIBUTE_UNUSED)
{
}

bool
_bfd_nolink_bfd_link_split_section (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

bool
_bfd_nolink_section_already_linked (bfd *abfd,
				    asection *sec ATTRIBUTE_UNUSED,
				    struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

bool
_bfd_nolink_bfd_define_common_symbol
    (bfd *abfd,
     struct bfd_link_info *info ATTRIBUTE_UNUSED,
     struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (abfd);
}

struct bfd_link_hash_entry *
_bfd_nolink_bfd_define_start_stop (struct bfd_link_info *info ATTRIBUTE_UNUSED,
				   const char *name ATTRIBUTE_UNUSED,
				   asection *sec)
{
  return (struct bfd_link_hash_entry *) _bfd_ptr_bfd_null_error (sec->owner);
}
