/* linker.c -- BFD linker routines
   Copyright (C) 1993-2018 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)>>.
*/

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

/* 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.  */

bfd_boolean
_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)
{
  bfd_boolean 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;
      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.  */

struct bfd_link_hash_entry *
bfd_link_hash_lookup (struct bfd_link_hash_table *table,
		      const char *string,
		      bfd_boolean create,
		      bfd_boolean copy,
		      bfd_boolean 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,
			      bfd_boolean create,
			      bfd_boolean copy,
			      bfd_boolean follow)
{
  bfd_size_type amt;

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

      l = string;
      if (*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);
	  free (n);
	  return h;
	}

#undef  REAL
#define REAL "__real_"

      if (*l == '_'
	  && CONST_STRNEQ (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);
	  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 == bfd_get_symbol_leading_char (input_bfd)
      || *l == info->wrap_char)
    ++l;

  if (CONST_STRNEQ (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,
   bfd_boolean (*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.  */

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;
  bfd_size_type 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_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.  */

bfd_boolean
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;
      bfd_get_outsymbols (abfd) = (struct bfd_symbol **) 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;
      bfd_get_symcount (abfd) = 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.  */

bfd_boolean
_bfd_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
  bfd_boolean 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 bfd_boolean
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.  */

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

  if (! bfd_has_map (abfd))
    {
      /* An empty archive is a special case.  */
      if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
	return TRUE;
      bfd_set_error (bfd_error_no_armap);
      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;
      file_ptr last_ar_offset = -1;
      bfd_boolean 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 && arsym->file_offset == last_ar_offset)
	    {
	      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
	      && CONST_STRNEQ (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 (last_ar_offset != arsym->file_offset)
	    {
	      last_ar_offset = arsym->file_offset;
	      element = _bfd_get_elt_at_filepos (abfd, last_ar_offset);
	      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 (arsyms[mark].file_offset == last_ar_offset);

	      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 bfd_boolean
generic_link_check_archive_element (bfd *abfd,
				    struct bfd_link_info *info,
				    struct bfd_link_hash_entry *h,
				    const char *name ATTRIBUTE_UNUSED,
				    bfd_boolean *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 bfd_boolean
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_get_section (p))
	  || bfd_is_com_section (bfd_get_section (p))
	  || bfd_is_ind_section (bfd_get_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_get_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_get_section (p))
		      && (! bfd_is_com_section (bfd_get_section (p))
			  || bfd_is_und_section (bfd_get_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_get_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,  MDEF,  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*/
}

/* 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.  */

bfd_boolean
_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,
				  bfd_boolean copy,
				  bfd_boolean collect,
				  struct bfd_link_hash_entry **hashp)
{
  enum link_row row;
  struct bfd_link_hash_entry *h;
  struct bfd_link_hash_entry *inh = NULL;
  bfd_boolean 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[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' && CONST_STRNEQ (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 (strcmp (h->u.i.link->root.string, string) == 0)
	    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);
	      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;
}

/* Generic final link routine.  */

bfd_boolean
_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;

  bfd_get_outsymbols (abfd) = NULL;
  bfd_get_symcount (abfd) = 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;
  _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info),
				   _bfd_generic_link_write_global_symbol,
				   &wginfo);

  /* 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 bfd_boolean
generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym)
{
  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;
      bfd_get_outsymbols (output_bfd) = newsyms;
    }

  bfd_get_outsymbols (output_bfd) [bfd_get_symcount (output_bfd)] = sym;
  if (sym != NULL)
    ++ bfd_get_symcount (output_bfd);

  return TRUE;
}

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

bfd_boolean
_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 = input_bfd->filename;
	      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;
      bfd_boolean output;

      h = NULL;
      sym = *sym_ptr;
      if ((sym->flags & (BSF_INDIRECT
			 | BSF_WARNING
			 | BSF_GLOBAL
			 | BSF_CONSTRUCTOR
			 | BSF_WEAK)) != 0
	  || bfd_is_und_section (bfd_get_section (sym))
	  || bfd_is_com_section (bfd_get_section (sym))
	  || bfd_is_ind_section (bfd_get_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_get_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;
		}
	    }
	}

      /* This switch is straight from the old code in
	 write_file_locals in ldsym.c.  */
      if (info->strip == strip_all
	  || (info->strip == strip_some
	      && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym),
				  FALSE, FALSE) == NULL))
	output = FALSE;
      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
	    output = FALSE;
	}
      else if (bfd_is_ind_section (sym->section))
	output = FALSE;
      else if ((sym->flags & BSF_DEBUGGING) != 0)
	{
	  if (info->strip == strip_none)
	    output = TRUE;
	  else
	    output = FALSE;
	}
      else if (bfd_is_und_section (sym->section)
	       || bfd_is_com_section (sym->section))
	output = FALSE;
      else if ((sym->flags & BSF_LOCAL) != 0)
	{
	  if ((sym->flags & BSF_WARNING) != 0)
	    output = FALSE;
	  else
	    {
	      switch (info->discard)
		{
		default:
		case discard_all:
		  output = FALSE;
		  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 = FALSE;
		  else
		    output = TRUE;
		  break;
		case discard_none:
		  output = TRUE;
		  break;
		}
	    }
	}
      else if ((sym->flags & BSF_CONSTRUCTOR))
	{
	  if (info->strip != strip_all)
	    output = TRUE;
	  else
	    output = FALSE;
	}
      else if (sym->flags == 0
	       && (sym->section->owner->flags & BFD_PLUGIN) != 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.  */
	output = FALSE;
      else
	abort ();

      /* 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.  */
      if (!bfd_is_abs_section (sym->section)
	  && bfd_section_removed_from_list (output_bfd,
					    sym->section->output_section))
	output = FALSE;

      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 (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->section = h->u.def.section;
      sym->value = h->u.def.value;
      break;
    case bfd_link_hash_defweak:
      sym->flags |= BSF_WEAK;
      sym->section = h->u.def.section;
      sym->value = h->u.def.value;
      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.  */

bfd_boolean
_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h,
				       void *data)
{
  struct generic_write_global_symbol_info *wginfo =
      (struct generic_write_global_symbol_info *) 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)
	return FALSE;
      sym->name = h->root.root.string;
      sym->flags = 0;
    }

  set_symbol_from_hash (sym, &h->root);

  sym->flags |= BSF_GLOBAL;

  if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc,
				   sym))
    {
      /* FIXME: No way to return failure.  */
      abort ();
    }

  return TRUE;
}

/* Create a relocation.  */

bfd_boolean
_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_ptr_ptr;
  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;
      bfd_boolean 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 (abfd, 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);
      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)
{
  bfd_size_type 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.  */

bfd_boolean
_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 bfd_boolean
default_data_link_order (bfd *abfd,
			 struct bfd_link_info *info ATTRIBUTE_UNUSED,
			 asection *sec,
			 struct bfd_link_order *link_order)
{
  bfd_size_type size;
  size_t fill_size;
  bfd_byte *fill;
  file_ptr loc;
  bfd_boolean 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, bfd_big_endian (abfd),
				    (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);
  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 bfd_boolean
default_indirect_link_order (bfd *output_bfd,
			     struct bfd_link_info *info,
			     asection *output_section,
			     struct bfd_link_order *link_order,
			     bfd_boolean generic_linker)
{
  asection *input_section;
  bfd *input_bfd;
  bfd_byte *contents = NULL;
  bfd_byte *new_contents;
  bfd_size_type sec_size;
  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;

	  sym = *sympp;

	  if ((sym->flags & (BSF_INDIRECT
			     | BSF_WARNING
			     | BSF_GLOBAL
			     | BSF_CONSTRUCTOR
			     | BSF_WEAK)) != 0
	      || bfd_is_und_section (bfd_get_section (sym))
	      || bfd_is_com_section (bfd_get_section (sym))
	      || bfd_is_ind_section (bfd_get_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_get_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 (sym, h);
	    }
	}
    }

  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.  */
      sec_size = (input_section->rawsize > input_section->size
		  ? input_section->rawsize
		  : input_section->size);
      contents = (bfd_byte *) bfd_malloc (sec_size);
      if (contents == NULL && sec_size != 0)
	goto error_return;
      new_contents = (bfd_get_relocated_section_contents
		      (output_bfd, info, link_order, contents,
		       bfd_link_relocatable (info),
		       _bfd_generic_link_get_symbols (input_bfd)));
      if (!new_contents)
	goto error_return;
    }

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

  if (contents != NULL)
    free (contents);
  return TRUE;

 error_return:
  if (contents != NULL)
    free (contents);
  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
	bfd_boolean 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))
.

*/

bfd_boolean
_bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED,
				 asection *sec ATTRIBUTE_UNUSED)
{
  return FALSE;
}

/*
FUNCTION
	bfd_section_already_linked

SYNOPSIS
	bfd_boolean 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
  (bfd_boolean (*func) (struct bfd_section_already_linked_hash_entry *,
			void *), void *info)
{
  bfd_hash_traverse (&_bfd_section_already_linked_table,
		     (bfd_boolean (*) (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));
}

bfd_boolean
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;
}

bfd_boolean
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.  */

bfd_boolean
_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 = NULL;

	  if (!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 (!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);
	  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);

	  if (sec_contents)
	    free (sec_contents);
	  if (l_sec_contents)
	    free (l_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.  */

bfd_boolean
_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_get_section_name (abfd, sec);

  already_linked_list = bfd_section_already_linked_table_lookup (name);

  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))
    info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
  return FALSE;
}

/* Choose a neighbouring section to S in OBFD that will be output, or
   the absolute section if ADDR is out of bounds of the neighbours.  */

asection *
_bfd_nearby_section (bfd *obfd, asection *s, bfd_vma addr)
{
  asection *next, *prev, *best;

  /* Find preceding kept section.  */
  for (prev = s->prev; prev != NULL; prev = prev->prev)
    if ((prev->flags & SEC_EXCLUDE) == 0
	&& !bfd_section_removed_from_list (obfd, prev))
      break;

  /* Find following kept section.  Start at prev->next because
     other sections may have been added after S was removed.  */
  if (s->prev != NULL)
    next = s->prev->next;
  else
    next = s->owner->sections;
  for (; next != NULL; next = next->next)
    if ((next->flags & SEC_EXCLUDE) == 0
	&& !bfd_section_removed_from_list (obfd, next))
      break;

  /* Choose better of two sections, based on flags.  The idea
     is to choose a section that will be in the same segment
     as S would have been if it was kept.  */
  best = next;
  if (prev == NULL)
    {
      if (next == NULL)
	best = bfd_abs_section_ptr;
    }
  else if (next == NULL)
    best = prev;
  else if (((prev->flags ^ next->flags)
	    & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
    {
      if (((next->flags ^ s->flags)
	   & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
	  /* We prefer to choose a loaded section.  Section S
	     doesn't have SEC_LOAD set (it being excluded, that
	     part of the flag processing didn't happen) so we
	     can't compare that flag to those of NEXT and PREV.  */
	  || ((prev->flags & SEC_LOAD) != 0
	      && (next->flags & SEC_LOAD) == 0))
	best = prev;
    }
  else if (((prev->flags ^ next->flags) & SEC_READONLY) != 0)
    {
      if (((next->flags ^ s->flags) & SEC_READONLY) != 0)
	best = prev;
    }
  else if (((prev->flags ^ next->flags) & SEC_CODE) != 0)
    {
      if (((next->flags ^ s->flags) & SEC_CODE) != 0)
	best = prev;
    }
  else
    {
      /* Flags we care about are the same.  Prefer the following
	 section if that will result in a positive valued sym.  */
      if (addr < next->vma)
	best = prev;
    }

  return best;
}

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

static bfd_boolean
fix_syms (struct bfd_link_hash_entry *h, void *data)
{
  bfd *obfd = (bfd *) data;

  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 = _bfd_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 (bfd *obfd, struct bfd_link_info *info)
{
  bfd_link_hash_traverse (info->hash, fix_syms, obfd);
}

/*
FUNCTION
	bfd_generic_define_common_symbol

SYNOPSIS
	bfd_boolean 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))
.
*/

bfd_boolean
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.  */
  alignment = bfd_octets_per_byte (output_bfd) << power_of_two;
  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;
  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->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, bfd_boolean *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,
			  bfd_boolean *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
	bfd_boolean 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.

*/

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

/*
FUNCTION
	bfd_link_check_relocs

SYNOPSIS
	bfd_boolean 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.
*/

bfd_boolean
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
	bfd_boolean _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.
*/

bfd_boolean
_bfd_generic_link_check_relocs (bfd *abfd ATTRIBUTE_UNUSED,
				struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  return TRUE;
}

/*
FUNCTION
	bfd_merge_private_bfd_data

SYNOPSIS
	bfd_boolean bfd_merge_private_bfd_data
	  (bfd *ibfd, struct bfd_link_info *info);

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
	bfd_boolean _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.
*/

bfd_boolean
_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;
}

bfd_boolean
_bfd_nolink_bfd_relax_section (bfd *abfd,
			       asection *section ATTRIBUTE_UNUSED,
			       struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
			       bfd_boolean *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,
     bfd_boolean relocatable ATTRIBUTE_UNUSED,
     asymbol **symbols ATTRIBUTE_UNUSED)
{
  return (bfd_byte *) _bfd_ptr_bfd_null_error (abfd);
}

bfd_boolean
_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);
}

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

bfd_boolean
_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)
{
}

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

bfd_boolean
_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);
}

bfd_boolean
_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);
}
