/* x86 specific support for ELF
   Copyright (C) 2017-2022 Free Software Foundation, Inc.

   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 "elfxx-x86.h"
#include "elf-vxworks.h"
#include "objalloc.h"

/* The name of the dynamic interpreter.  This is put in the .interp
   section.  */

#define ELF32_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
#define ELFX32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"

bool
_bfd_x86_elf_mkobject (bfd *abfd)
{
  return bfd_elf_allocate_object (abfd,
				  sizeof (struct elf_x86_obj_tdata),
				  get_elf_backend_data (abfd)->target_id);
}

/* _TLS_MODULE_BASE_ needs to be treated especially when linking
   executables.  Rather than setting it to the beginning of the TLS
   section, we have to set it to the end.    This function may be called
   multiple times, it is idempotent.  */

void
_bfd_x86_elf_set_tls_module_base (struct bfd_link_info *info)
{
  struct elf_x86_link_hash_table *htab;
  struct bfd_link_hash_entry *base;
  const struct elf_backend_data *bed;

  if (!bfd_link_executable (info))
    return;

  bed = get_elf_backend_data (info->output_bfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return;

  base = htab->tls_module_base;
  if (base == NULL)
    return;

  base->u.def.value = htab->elf.tls_size;
}

/* Return the base VMA address which should be subtracted from real addresses
   when resolving @dtpoff relocation.
   This is PT_TLS segment p_vaddr.  */

bfd_vma
_bfd_x86_elf_dtpoff_base (struct bfd_link_info *info)
{
  /* If tls_sec is NULL, we should have signalled an error already.  */
  if (elf_hash_table (info)->tls_sec == NULL)
    return 0;
  return elf_hash_table (info)->tls_sec->vma;
}

/* Allocate space in .plt, .got and associated reloc sections for
   dynamic relocs.  */

static bool
elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
  struct bfd_link_info *info;
  struct elf_x86_link_hash_table *htab;
  struct elf_x86_link_hash_entry *eh;
  struct elf_dyn_relocs *p;
  unsigned int plt_entry_size;
  bool resolved_to_zero;
  const struct elf_backend_data *bed;

  if (h->root.type == bfd_link_hash_indirect)
    return true;

  eh = (struct elf_x86_link_hash_entry *) h;

  info = (struct bfd_link_info *) inf;
  bed = get_elf_backend_data (info->output_bfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return false;

  plt_entry_size = htab->plt.plt_entry_size;

  resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);

  /* We can't use the GOT PLT if pointer equality is needed since
     finish_dynamic_symbol won't clear symbol value and the dynamic
     linker won't update the GOT slot.  We will get into an infinite
     loop at run-time.  */
  if (htab->plt_got != NULL
      && h->type != STT_GNU_IFUNC
      && !h->pointer_equality_needed
      && h->plt.refcount > 0
      && h->got.refcount > 0)
    {
      /* Don't use the regular PLT if there are both GOT and GOTPLT
	 reloctions.  */
      h->plt.offset = (bfd_vma) -1;

      /* Use the GOT PLT.  */
      eh->plt_got.refcount = 1;
    }

  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
     here if it is defined and referenced in a non-shared object.  */
  if (h->type == STT_GNU_IFUNC
      && h->def_regular)
    {
      /* GOTOFF relocation needs PLT.  */
      if (eh->gotoff_ref)
	h->plt.refcount = 1;

      if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs,
					      plt_entry_size,
					      (htab->plt.has_plt0
					       * plt_entry_size),
					       htab->got_entry_size,
					       true))
	{
	  asection *s = htab->plt_second;
	  if (h->plt.offset != (bfd_vma) -1 && s != NULL)
	    {
	      /* Use the second PLT section if it is created.  */
	      eh->plt_second.offset = s->size;

	      /* Make room for this entry in the second PLT section.  */
	      s->size += htab->non_lazy_plt->plt_entry_size;
	    }

	  return true;
	}
      else
	return false;
    }
  /* Don't create the PLT entry if there are only function pointer
     relocations which can be resolved at run-time.  */
  else if (htab->elf.dynamic_sections_created
	   && (h->plt.refcount > 0
	       || eh->plt_got.refcount > 0))
    {
      bool use_plt_got = eh->plt_got.refcount > 0;

      /* Make sure this symbol is output as a dynamic symbol.
	 Undefined weak syms won't yet be marked as dynamic.  */
      if (h->dynindx == -1
	  && !h->forced_local
	  && !resolved_to_zero
	  && h->root.type == bfd_link_hash_undefweak)
	{
	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
	    return false;
	}

      if (bfd_link_pic (info)
	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
	{
	  asection *s = htab->elf.splt;
	  asection *second_s = htab->plt_second;
	  asection *got_s = htab->plt_got;
	  bool use_plt;

	  /* If this is the first .plt entry, make room for the special
	     first entry.  The .plt section is used by prelink to undo
	     prelinking for dynamic relocations.  */
	  if (s->size == 0)
	    s->size = htab->plt.has_plt0 * plt_entry_size;

	  if (use_plt_got)
	    eh->plt_got.offset = got_s->size;
	  else
	    {
	      h->plt.offset = s->size;
	      if (second_s)
		eh->plt_second.offset = second_s->size;
	    }

	  /* If this symbol is not defined in a regular file, and we are
	     generating PDE, then set the symbol to this location in the
	     .plt.  This is required to make function pointers compare
	     as equal between PDE and the shared library.

	     NB: If PLT is PC-relative, we can use the .plt in PIE for
	     function address. */
	  if (h->def_regular)
	    use_plt = false;
	  else if (htab->pcrel_plt)
	    use_plt = ! bfd_link_dll (info);
	  else
	    use_plt = bfd_link_pde (info);
	  if (use_plt)
	    {
	      if (use_plt_got)
		{
		  /* We need to make a call to the entry of the GOT PLT
		     instead of regular PLT entry.  */
		  h->root.u.def.section = got_s;
		  h->root.u.def.value = eh->plt_got.offset;
		}
	      else
		{
		  if (second_s)
		    {
		      /* We need to make a call to the entry of the
			 second PLT instead of regular PLT entry.  */
		      h->root.u.def.section = second_s;
		      h->root.u.def.value = eh->plt_second.offset;
		    }
		  else
		    {
		      h->root.u.def.section = s;
		      h->root.u.def.value = h->plt.offset;
		    }
		}
	    }

	  /* Make room for this entry.  */
	  if (use_plt_got)
	    got_s->size += htab->non_lazy_plt->plt_entry_size;
	  else
	    {
	      s->size += plt_entry_size;
	      if (second_s)
		second_s->size += htab->non_lazy_plt->plt_entry_size;

	      /* We also need to make an entry in the .got.plt section,
		 which will be placed in the .got section by the linker
		 script.  */
	      htab->elf.sgotplt->size += htab->got_entry_size;

	      /* There should be no PLT relocation against resolved
		 undefined weak symbol in executable.  */
	      if (!resolved_to_zero)
		{
		  /* We also need to make an entry in the .rel.plt
		     section.  */
		  htab->elf.srelplt->size += htab->sizeof_reloc;
		  htab->elf.srelplt->reloc_count++;
		}
	    }

	  if (htab->elf.target_os == is_vxworks && !bfd_link_pic (info))
	    {
	      /* VxWorks has a second set of relocations for each PLT entry
		 in executables.  They go in a separate relocation section,
		 which is processed by the kernel loader.  */

	      /* There are two relocations for the initial PLT entry: an
		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */

	      asection *srelplt2 = htab->srelplt2;
	      if (h->plt.offset == plt_entry_size)
		srelplt2->size += (htab->sizeof_reloc * 2);

	      /* There are two extra relocations for each subsequent PLT entry:
		 an R_386_32 relocation for the GOT entry, and an R_386_32
		 relocation for the PLT entry.  */

	      srelplt2->size += (htab->sizeof_reloc * 2);
	    }
	}
      else
	{
	  eh->plt_got.offset = (bfd_vma) -1;
	  h->plt.offset = (bfd_vma) -1;
	  h->needs_plt = 0;
	}
    }
  else
    {
      eh->plt_got.offset = (bfd_vma) -1;
      h->plt.offset = (bfd_vma) -1;
      h->needs_plt = 0;
    }

  eh->tlsdesc_got = (bfd_vma) -1;

  /* For i386, if R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the
     binary, make it a R_386_TLS_LE_32 requiring no TLS entry.  For
     x86-64, if R_X86_64_GOTTPOFF symbol is now local to the binary,
     make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
  if (h->got.refcount > 0
      && bfd_link_executable (info)
      && h->dynindx == -1
      && (elf_x86_hash_entry (h)->tls_type & GOT_TLS_IE))
    h->got.offset = (bfd_vma) -1;
  else if (h->got.refcount > 0)
    {
      asection *s;
      bool dyn;
      int tls_type = elf_x86_hash_entry (h)->tls_type;

      /* Make sure this symbol is output as a dynamic symbol.
	 Undefined weak syms won't yet be marked as dynamic.  */
      if (h->dynindx == -1
	  && !h->forced_local
	  && !resolved_to_zero
	  && h->root.type == bfd_link_hash_undefweak)
	{
	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
	    return false;
	}

      s = htab->elf.sgot;
      if (GOT_TLS_GDESC_P (tls_type))
	{
	  eh->tlsdesc_got = htab->elf.sgotplt->size
	    - elf_x86_compute_jump_table_size (htab);
	  htab->elf.sgotplt->size += 2 * htab->got_entry_size;
	  h->got.offset = (bfd_vma) -2;
	}
      if (! GOT_TLS_GDESC_P (tls_type)
	  || GOT_TLS_GD_P (tls_type))
	{
	  h->got.offset = s->size;
	  s->size += htab->got_entry_size;
	  /* R_386_TLS_GD and R_X86_64_TLSGD need 2 consecutive GOT
	     slots.  */
	  if (GOT_TLS_GD_P (tls_type) || tls_type == GOT_TLS_IE_BOTH)
	    s->size += htab->got_entry_size;
	}
      dyn = htab->elf.dynamic_sections_created;
      /* R_386_TLS_IE_32 needs one dynamic relocation,
	 R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
	 (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we
	 need two), R_386_TLS_GD and R_X86_64_TLSGD need one if local
	 symbol and two if global.  No dynamic relocation against
	 resolved undefined weak symbol in executable.  No dynamic
	 relocation against non-preemptible absolute symbol.  */
      if (tls_type == GOT_TLS_IE_BOTH)
	htab->elf.srelgot->size += 2 * htab->sizeof_reloc;
      else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
	       || (tls_type & GOT_TLS_IE))
	htab->elf.srelgot->size += htab->sizeof_reloc;
      else if (GOT_TLS_GD_P (tls_type))
	htab->elf.srelgot->size += 2 * htab->sizeof_reloc;
      else if (! GOT_TLS_GDESC_P (tls_type)
	       && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
		    && !resolved_to_zero)
		   || h->root.type != bfd_link_hash_undefweak)
	       && ((bfd_link_pic (info)
		    && !(h->dynindx == -1
			 && ABS_SYMBOL_P (h)))
		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
	htab->elf.srelgot->size += htab->sizeof_reloc;
      if (GOT_TLS_GDESC_P (tls_type))
	{
	  htab->elf.srelplt->size += htab->sizeof_reloc;
	  if (bed->target_id == X86_64_ELF_DATA)
	    htab->elf.tlsdesc_plt = (bfd_vma) -1;
	}
    }
  else
    h->got.offset = (bfd_vma) -1;

  if (h->dyn_relocs == NULL)
    return true;

  /* In the shared -Bsymbolic case, discard space allocated for
     dynamic pc-relative relocs against symbols which turn out to be
     defined in regular objects.  For the normal shared case, discard
     space for pc-relative relocs that have become local due to symbol
     visibility changes.  */

  if (bfd_link_pic (info))
    {
      /* Relocs that use pc_count are those that appear on a call
	 insn, or certain REL relocs that can generated via assembly.
	 We want calls to protected symbols to resolve directly to the
	 function rather than going via the plt.  If people want
	 function pointer comparisons to work as expected then they
	 should avoid writing weird assembly.  */
      if (SYMBOL_CALLS_LOCAL (info, h))
	{
	  struct elf_dyn_relocs **pp;

	  for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
	    {
	      p->count -= p->pc_count;
	      p->pc_count = 0;
	      if (p->count == 0)
		*pp = p->next;
	      else
		pp = &p->next;
	    }
	}

      if (htab->elf.target_os == is_vxworks)
	{
	  struct elf_dyn_relocs **pp;
	  for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
	    {
	      if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
		*pp = p->next;
	      else
		pp = &p->next;
	    }
	}

      /* Also discard relocs on undefined weak syms with non-default
	 visibility or in PIE.  */
      if (h->dyn_relocs != NULL)
	{
	  if (h->root.type == bfd_link_hash_undefweak)
	    {
	      /* Undefined weak symbol is never bound locally in shared
		 library.  */
	      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
		  || resolved_to_zero)
		{
		  if (bed->target_id == I386_ELF_DATA
		      && h->non_got_ref)
		    {
		      /* Keep dynamic non-GOT/non-PLT relocation so
			 that we can branch to 0 without PLT.  */
		      struct elf_dyn_relocs **pp;

		      for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
			if (p->pc_count == 0)
			  *pp = p->next;
			else
			  {
			    /* Remove non-R_386_PC32 relocation.  */
			    p->count = p->pc_count;
			    pp = &p->next;
			  }

		      /* Make sure undefined weak symbols are output
			 as dynamic symbols in PIEs for dynamic non-GOT
			 non-PLT reloations.  */
		      if (h->dyn_relocs != NULL
			  && !bfd_elf_link_record_dynamic_symbol (info, h))
			return false;
		    }
		  else
		    h->dyn_relocs = NULL;
		}
	      else if (h->dynindx == -1
		       && !h->forced_local
		       && !bfd_elf_link_record_dynamic_symbol (info, h))
		return false;
	    }
	  else if (bfd_link_executable (info)
		   && (h->needs_copy || eh->needs_copy)
		   && h->def_dynamic
		   && !h->def_regular)
	    {
	      /* NB: needs_copy is set only for x86-64.  For PIE,
		 discard space for pc-relative relocs against symbols
		 which turn out to need copy relocs.  */
	      struct elf_dyn_relocs **pp;

	      for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
		{
		  if (p->pc_count != 0)
		    *pp = p->next;
		  else
		    pp = &p->next;
		}
	    }
	}
    }
  else if (ELIMINATE_COPY_RELOCS)
    {
      /* For the non-shared case, discard space for relocs against
	 symbols which turn out to need copy relocs or are not
	 dynamic.  Keep dynamic relocations for run-time function
	 pointer initialization.  */

      if ((!h->non_got_ref
	   || (h->root.type == bfd_link_hash_undefweak
	       && !resolved_to_zero))
	  && ((h->def_dynamic
	       && !h->def_regular)
	      || (htab->elf.dynamic_sections_created
		  && (h->root.type == bfd_link_hash_undefweak
		      || h->root.type == bfd_link_hash_undefined))))
	{
	  /* Make sure this symbol is output as a dynamic symbol.
	     Undefined weak syms won't yet be marked as dynamic.  */
	  if (h->dynindx == -1
	      && !h->forced_local
	      && !resolved_to_zero
	      && h->root.type == bfd_link_hash_undefweak
	      && ! bfd_elf_link_record_dynamic_symbol (info, h))
	    return false;

	  /* If that succeeded, we know we'll be keeping all the
	     relocs.  */
	  if (h->dynindx != -1)
	    goto keep;
	}

      h->dyn_relocs = NULL;

    keep: ;
    }

  /* Finally, allocate space.  */
  for (p = h->dyn_relocs; p != NULL; p = p->next)
    {
      asection *sreloc;

      if (eh->def_protected
	  && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
	{
	  /* Disallow copy relocation against non-copyable protected
	     symbol.  */
	  asection *s = p->sec->output_section;
	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
	    {
	      info->callbacks->einfo
		/* xgettext:c-format */
		(_("%F%P: %pB: copy relocation against non-copyable "
		   "protected symbol `%s' in %pB\n"),
		 p->sec->owner, h->root.root.string,
		 h->root.u.def.section->owner);
	      return false;
	    }
	}

      sreloc = elf_section_data (p->sec)->sreloc;

      BFD_ASSERT (sreloc != NULL);
      sreloc->size += p->count * htab->sizeof_reloc;
    }

  return true;
}

/* Allocate space in .plt, .got and associated reloc sections for
   local dynamic relocs.  */

static int
elf_x86_allocate_local_dynreloc (void **slot, void *inf)
{
  struct elf_link_hash_entry *h
    = (struct elf_link_hash_entry *) *slot;

  if (h->type != STT_GNU_IFUNC
      || !h->def_regular
      || !h->ref_regular
      || !h->forced_local
      || h->root.type != bfd_link_hash_defined)
    abort ();

  return elf_x86_allocate_dynrelocs (h, inf);
}

/* Find and/or create a hash entry for local symbol.  */

struct elf_link_hash_entry *
_bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab,
				 bfd *abfd, const Elf_Internal_Rela *rel,
				 bool create)
{
  struct elf_x86_link_hash_entry e, *ret;
  asection *sec = abfd->sections;
  hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
				       htab->r_sym (rel->r_info));
  void **slot;

  e.elf.indx = sec->id;
  e.elf.dynstr_index = htab->r_sym (rel->r_info);
  slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
				   create ? INSERT : NO_INSERT);

  if (!slot)
    return NULL;

  if (*slot)
    {
      ret = (struct elf_x86_link_hash_entry *) *slot;
      return &ret->elf;
    }

  ret = (struct elf_x86_link_hash_entry *)
	objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
			sizeof (struct elf_x86_link_hash_entry));
  if (ret)
    {
      memset (ret, 0, sizeof (*ret));
      ret->elf.indx = sec->id;
      ret->elf.dynstr_index = htab->r_sym (rel->r_info);
      ret->elf.dynindx = -1;
      ret->plt_got.offset = (bfd_vma) -1;
      *slot = ret;
    }
  return &ret->elf;
}

/* Create an entry in a x86 ELF linker hash table.  NB: THIS MUST BE IN
   SYNC WITH _bfd_elf_link_hash_newfunc.  */

struct bfd_hash_entry *
_bfd_x86_elf_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 elf_x86_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 != NULL)
    {
      struct elf_x86_link_hash_entry *eh
       = (struct elf_x86_link_hash_entry *) entry;
      struct elf_link_hash_table *htab
	= (struct elf_link_hash_table *) table;

      memset (&eh->elf.size, 0,
	      (sizeof (struct elf_x86_link_hash_entry)
	       - offsetof (struct elf_link_hash_entry, size)));
      /* Set local fields.  */
      eh->elf.indx = -1;
      eh->elf.dynindx = -1;
      eh->elf.got = htab->init_got_refcount;
      eh->elf.plt = htab->init_plt_refcount;
      /* Assume that we have been called by a non-ELF symbol reader.
	 This flag is then reset by the code which reads an ELF input
	 file.  This ensures that a symbol created by a non-ELF symbol
	 reader will have the flag set correctly.  */
      eh->elf.non_elf = 1;
      eh->plt_second.offset = (bfd_vma) -1;
      eh->plt_got.offset = (bfd_vma) -1;
      eh->tlsdesc_got = (bfd_vma) -1;
      eh->zero_undefweak = 1;
    }

  return entry;
}

/* Compute a hash of a local hash entry.  We use elf_link_hash_entry
  for local symbol so that we can handle local STT_GNU_IFUNC symbols
  as global symbol.  We reuse indx and dynstr_index for local symbol
  hash since they aren't used by global symbols in this backend.  */

hashval_t
_bfd_x86_elf_local_htab_hash (const void *ptr)
{
  struct elf_link_hash_entry *h
    = (struct elf_link_hash_entry *) ptr;
  return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
}

/* Compare local hash entries.  */

int
_bfd_x86_elf_local_htab_eq (const void *ptr1, const void *ptr2)
{
  struct elf_link_hash_entry *h1
     = (struct elf_link_hash_entry *) ptr1;
  struct elf_link_hash_entry *h2
    = (struct elf_link_hash_entry *) ptr2;

  return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
}

/* Destroy an x86 ELF linker hash table.  */

static void
elf_x86_link_hash_table_free (bfd *obfd)
{
  struct elf_x86_link_hash_table *htab
    = (struct elf_x86_link_hash_table *) obfd->link.hash;

  if (htab->loc_hash_table)
    htab_delete (htab->loc_hash_table);
  if (htab->loc_hash_memory)
    objalloc_free ((struct objalloc *) htab->loc_hash_memory);
  _bfd_elf_link_hash_table_free (obfd);
}

static bool
elf_i386_is_reloc_section (const char *secname)
{
  return startswith (secname, ".rel");
}

static bool
elf_x86_64_is_reloc_section (const char *secname)
{
  return startswith (secname, ".rela");
}

/* Create an x86 ELF linker hash table.  */

struct bfd_link_hash_table *
_bfd_x86_elf_link_hash_table_create (bfd *abfd)
{
  struct elf_x86_link_hash_table *ret;
  const struct elf_backend_data *bed;
  size_t amt = sizeof (struct elf_x86_link_hash_table);

  ret = (struct elf_x86_link_hash_table *) bfd_zmalloc (amt);
  if (ret == NULL)
    return NULL;

  bed = get_elf_backend_data (abfd);
  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
				      _bfd_x86_elf_link_hash_newfunc,
				      sizeof (struct elf_x86_link_hash_entry),
				      bed->target_id))
    {
      free (ret);
      return NULL;
    }

  if (bed->target_id == X86_64_ELF_DATA)
    {
      ret->is_reloc_section = elf_x86_64_is_reloc_section;
      ret->got_entry_size = 8;
      ret->pcrel_plt = true;
      ret->tls_get_addr = "__tls_get_addr";
      ret->relative_r_type = R_X86_64_RELATIVE;
      ret->relative_r_name = "R_X86_64_RELATIVE";
      ret->elf_append_reloc = elf_append_rela;
      ret->elf_write_addend_in_got = _bfd_elf64_write_addend;
    }
  if (ABI_64_P (abfd))
    {
      ret->sizeof_reloc = sizeof (Elf64_External_Rela);
      ret->pointer_r_type = R_X86_64_64;
      ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
      ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
      ret->elf_write_addend = _bfd_elf64_write_addend;
    }
  else
    {
      if (bed->target_id == X86_64_ELF_DATA)
	{
	  ret->sizeof_reloc = sizeof (Elf32_External_Rela);
	  ret->pointer_r_type = R_X86_64_32;
	  ret->dynamic_interpreter = ELFX32_DYNAMIC_INTERPRETER;
	  ret->dynamic_interpreter_size
	    = sizeof ELFX32_DYNAMIC_INTERPRETER;
	  ret->elf_write_addend = _bfd_elf32_write_addend;
	}
      else
	{
	  ret->is_reloc_section = elf_i386_is_reloc_section;
	  ret->sizeof_reloc = sizeof (Elf32_External_Rel);
	  ret->got_entry_size = 4;
	  ret->pcrel_plt = false;
	  ret->pointer_r_type = R_386_32;
	  ret->relative_r_type = R_386_RELATIVE;
	  ret->relative_r_name = "R_386_RELATIVE";
	  ret->elf_append_reloc = elf_append_rel;
	  ret->elf_write_addend = _bfd_elf32_write_addend;
	  ret->elf_write_addend_in_got = _bfd_elf32_write_addend;
	  ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
	  ret->dynamic_interpreter_size
	    = sizeof ELF32_DYNAMIC_INTERPRETER;
	  ret->tls_get_addr = "___tls_get_addr";
	}
    }

  ret->loc_hash_table = htab_try_create (1024,
					 _bfd_x86_elf_local_htab_hash,
					 _bfd_x86_elf_local_htab_eq,
					 NULL);
  ret->loc_hash_memory = objalloc_create ();
  if (!ret->loc_hash_table || !ret->loc_hash_memory)
    {
      elf_x86_link_hash_table_free (abfd);
      return NULL;
    }
  ret->elf.root.hash_table_free = elf_x86_link_hash_table_free;

  return &ret->elf.root;
}

/* Sort relocs into address order.  */

int
_bfd_x86_elf_compare_relocs (const void *ap, const void *bp)
{
  const arelent *a = * (const arelent **) ap;
  const arelent *b = * (const arelent **) bp;

  if (a->address > b->address)
    return 1;
  else if (a->address < b->address)
    return -1;
  else
    return 0;
}

/* Mark symbol, NAME, as locally defined by linker if it is referenced
   and not defined in a relocatable object file.  */

static void
elf_x86_linker_defined (struct bfd_link_info *info, const char *name)
{
  struct elf_link_hash_entry *h;

  h = elf_link_hash_lookup (elf_hash_table (info), name,
			    false, false, false);
  if (h == NULL)
    return;

  while (h->root.type == bfd_link_hash_indirect)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (h->root.type == bfd_link_hash_new
      || h->root.type == bfd_link_hash_undefined
      || h->root.type == bfd_link_hash_undefweak
      || h->root.type == bfd_link_hash_common
      || (!h->def_regular && h->def_dynamic))
    {
      elf_x86_hash_entry (h)->local_ref = 2;
      elf_x86_hash_entry (h)->linker_def = 1;
    }
}

/* Hide a linker-defined symbol, NAME, with hidden visibility.  */

static void
elf_x86_hide_linker_defined (struct bfd_link_info *info,
			     const char *name)
{
  struct elf_link_hash_entry *h;

  h = elf_link_hash_lookup (elf_hash_table (info), name,
			    false, false, false);
  if (h == NULL)
    return;

  while (h->root.type == bfd_link_hash_indirect)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
      || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
    _bfd_elf_link_hash_hide_symbol (info, h, true);
}

bool
_bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
{
  if (!bfd_link_relocatable (info))
    {
      /* Check for __tls_get_addr reference.  */
      struct elf_x86_link_hash_table *htab;
      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
      htab = elf_x86_hash_table (info, bed->target_id);
      if (htab)
	{
	  struct elf_link_hash_entry *h;

	  h = elf_link_hash_lookup (elf_hash_table (info),
				    htab->tls_get_addr,
				    false, false, false);
	  if (h != NULL)
	    {
	      elf_x86_hash_entry (h)->tls_get_addr = 1;

	      /* Check the versioned __tls_get_addr symbol.  */
	      while (h->root.type == bfd_link_hash_indirect)
		{
		  h = (struct elf_link_hash_entry *) h->root.u.i.link;
		  elf_x86_hash_entry (h)->tls_get_addr = 1;
		}
	    }

	  /* "__ehdr_start" will be defined by linker as a hidden symbol
	     later if it is referenced and not defined.  */
	  elf_x86_linker_defined (info, "__ehdr_start");

	  if (bfd_link_executable (info))
	    {
	      /* References to __bss_start, _end and _edata should be
		 locally resolved within executables.  */
	      elf_x86_linker_defined (info, "__bss_start");
	      elf_x86_linker_defined (info, "_end");
	      elf_x86_linker_defined (info, "_edata");
	    }
	  else
	    {
	      /* Hide hidden __bss_start, _end and _edata in shared
		 libraries.  */
	      elf_x86_hide_linker_defined (info, "__bss_start");
	      elf_x86_hide_linker_defined (info, "_end");
	      elf_x86_hide_linker_defined (info, "_edata");
	    }
	}
    }

  /* Invoke the regular ELF backend linker to do all the work.  */
  return _bfd_elf_link_check_relocs (abfd, info);
}

/* Look through the relocs for a section before allocation to make the
   dynamic reloc section.  */

bool
_bfd_x86_elf_check_relocs (bfd *abfd,
			   struct bfd_link_info *info,
			   asection *sec,
			   const Elf_Internal_Rela *relocs)
{
  struct elf_x86_link_hash_table *htab;
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;
  asection *sreloc;
  const struct elf_backend_data *bed;
  bool is_x86_64;

  if (bfd_link_relocatable (info))
    return true;

  bed = get_elf_backend_data (abfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    {
      sec->check_relocs_failed = 1;
      return false;
    }

  is_x86_64 = bed->target_id == X86_64_ELF_DATA;

  symtab_hdr = &elf_symtab_hdr (abfd);
  sym_hashes = elf_sym_hashes (abfd);

  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; rel++)
    {
      unsigned int r_type;
      unsigned int r_symndx;
      struct elf_link_hash_entry *h;

      r_symndx = htab->r_sym (rel->r_info);
      r_type = ELF32_R_TYPE (rel->r_info);

      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
	{
	  /* xgettext:c-format */
	  _bfd_error_handler (_("%pB: bad symbol index: %d"),
			      abfd, r_symndx);
	  goto error_return;
	}

      if (r_symndx < symtab_hdr->sh_info)
	h = NULL;
      else
	{
	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
	  while (h->root.type == bfd_link_hash_indirect
		 || h->root.type == bfd_link_hash_warning)
	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
	}

      if (X86_NEED_DYNAMIC_RELOC_TYPE_P (is_x86_64, r_type)
	  && NEED_DYNAMIC_RELOCATION_P (is_x86_64, info, true, h, sec,
					r_type, htab->pointer_r_type))
	{
	  /* We may copy these reloc types into the output file.
	     Create a reloc section in dynobj and make room for
	     this reloc.  */
	  sreloc = _bfd_elf_make_dynamic_reloc_section
	    (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2,
	     abfd, sec->use_rela_p);

	  if (sreloc != NULL)
	    return true;

  error_return:
	  sec->check_relocs_failed = 1;
	  return false;
	}
    }

  return true;
}

/* Add an entry to the relative reloc record.  */

static bool
elf_x86_relative_reloc_record_add
  (struct bfd_link_info *info,
   struct elf_x86_relative_reloc_data *relative_reloc,
   Elf_Internal_Rela *rel, asection *sec,
   asection *sym_sec, struct elf_link_hash_entry *h,
   Elf_Internal_Sym *sym, bfd_vma offset)
{
  bfd_size_type newidx;

  if (relative_reloc->data == NULL)
    {
      relative_reloc->data = bfd_malloc
	(sizeof (struct elf_x86_relative_reloc_record));
      relative_reloc->count = 0;
      relative_reloc->size = 1;
    }

  newidx = relative_reloc->count++;

  if (relative_reloc->count > relative_reloc->size)
    {
      relative_reloc->size <<= 1;
      relative_reloc->data = bfd_realloc
	(relative_reloc->data,
	 (relative_reloc->size
	  * sizeof (struct elf_x86_relative_reloc_record)));
    }

  if (relative_reloc->data == NULL)
    {
      info->callbacks->einfo
	/* xgettext:c-format */
	(_("%F%P: %pB: failed to allocate relative reloc record\n"),
	 info->output_bfd);
      return false;
    }

  relative_reloc->data[newidx].rel = *rel;
  relative_reloc->data[newidx].sec = sec;
  if (h != NULL)
    {
      /* Set SYM to NULL to indicate a global symbol.  */
      relative_reloc->data[newidx].sym = NULL;
      relative_reloc->data[newidx].u.h = h;
    }
  else
    {
      relative_reloc->data[newidx].sym = sym;
      relative_reloc->data[newidx].u.sym_sec = sym_sec;
    }
  relative_reloc->data[newidx].offset = offset;
  relative_reloc->data[newidx].address = 0;
  return true;
}

/* After input sections have been mapped to output sections and
   addresses of output sections are set initiallly, scan input
   relocations with the same logic in relocate_section to determine
   if a relative relocation should be generated.  Save the relative
   relocation candidate information for sizing the DT_RELR section
   later after all symbols addresses can be determined.  */

bool
_bfd_x86_elf_link_relax_section (bfd *abfd ATTRIBUTE_UNUSED,
				 asection *input_section,
				 struct bfd_link_info *info,
				 bool *again)
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Rela *internal_relocs;
  Elf_Internal_Rela *irel, *irelend;
  Elf_Internal_Sym *isymbuf = NULL;
  struct elf_link_hash_entry **sym_hashes;
  const struct elf_backend_data *bed;
  struct elf_x86_link_hash_table *htab;
  bfd_vma *local_got_offsets;
  bool is_x86_64;
  bool unaligned_section;

  if (bfd_link_relocatable (info))
    return true;

  /* Assume we're not going to change any sizes, and we'll only need
     one pass.  */
  *again = false;

  bed = get_elf_backend_data (abfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return true;

  /* Nothing to do if there are no relocations or relative relocations
     have been packed.  */
  if (input_section == htab->elf.srelrdyn
      || input_section->relative_reloc_packed
      || ((input_section->flags & (SEC_RELOC | SEC_ALLOC))
	  != (SEC_RELOC | SEC_ALLOC))
      || (input_section->flags & SEC_DEBUGGING) != 0
      || input_section->reloc_count == 0)
    return true;

  /* Skip if the section isn't aligned.  */
  unaligned_section = input_section->alignment_power == 0;

  is_x86_64 = bed->target_id == X86_64_ELF_DATA;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  local_got_offsets = elf_local_got_offsets (abfd);

  /* Load the relocations for this section.  */
  internal_relocs =
    _bfd_elf_link_read_relocs (abfd, input_section, NULL,
			       (Elf_Internal_Rela *) NULL,
			       info->keep_memory);
  if (internal_relocs == NULL)
    return false;

  irelend = internal_relocs + input_section->reloc_count;
  for (irel = internal_relocs; irel < irelend; irel++)
    {
      unsigned int r_type;
      unsigned int r_symndx;
      Elf_Internal_Sym *isym;
      struct elf_link_hash_entry *h;
      struct elf_x86_link_hash_entry *eh;
      bfd_vma offset;
      bool resolved_to_zero;
      bool need_copy_reloc_in_pie;
      bool pc32_reloc;
      asection *sec;
      /* Offset must be a multiple of 2.  */
      bool unaligned_offset = (irel->r_offset & 1) != 0;
      /* True if there is a relative relocation against a dynamic
	 symbol.  */
      bool dynamic_relative_reloc_p;

      /* Get the value of the symbol referred to by the reloc.  */
      r_symndx = htab->r_sym (irel->r_info);

      r_type = ELF32_R_TYPE (irel->r_info);
      /* Clear the R_X86_64_converted_reloc_bit bit.  */
      r_type &= ~R_X86_64_converted_reloc_bit;

      sec = NULL;
      h = NULL;
      dynamic_relative_reloc_p = false;

      if (r_symndx < symtab_hdr->sh_info)
	{
	  /* Read this BFD's local symbols.  */
	  if (isymbuf == NULL)
	    {
	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
	      if (isymbuf == NULL)
		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
						symtab_hdr->sh_info, 0,
						NULL, NULL, NULL);
	      if (isymbuf == NULL)
		goto error_return;
	    }

	  isym = isymbuf + r_symndx;
	  switch (isym->st_shndx)
	    {
	    case SHN_ABS:
	      sec = bfd_abs_section_ptr;
	      break;
	    case SHN_COMMON:
	      sec = bfd_com_section_ptr;
	      break;
	    case SHN_X86_64_LCOMMON:
	      if (!is_x86_64)
		abort ();
	      sec = &_bfd_elf_large_com_section;
	      break;
	    default:
	      sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
	      break;
	    }

	  /* Skip relocation against local STT_GNU_IFUNC symbol.  */
	  if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
	    continue;

	  eh = (struct elf_x86_link_hash_entry *) h;
	  resolved_to_zero = false;
	}
      else
	{
	  /* Get H and SEC for GENERATE_DYNAMIC_RELOCATION_P below.  */
	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
	  while (h->root.type == bfd_link_hash_indirect
		 || h->root.type == bfd_link_hash_warning)
	    h = (struct elf_link_hash_entry *) h->root.u.i.link;

	  if (h->root.type == bfd_link_hash_defined
	      || h->root.type == bfd_link_hash_defweak)
	    sec = h->root.u.def.section;

	  /* Skip relocation against STT_GNU_IFUNC symbol.  */
	  if (h->type == STT_GNU_IFUNC)
	    continue;

	  eh = (struct elf_x86_link_hash_entry *) h;
	  resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);

	  /* NB: See how elf_backend_finish_dynamic_symbol is called
	     from elf_link_output_extsym.  */
	  if ((h->dynindx != -1 || h->forced_local)
	      && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
		   || h->root.type != bfd_link_hash_undefweak)
		  || !h->forced_local)
	      && h->got.offset != (bfd_vma) -1
	      && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h)->tls_type)
	      && elf_x86_hash_entry (h)->tls_type != GOT_TLS_IE
	      && !resolved_to_zero
	      && SYMBOL_REFERENCES_LOCAL_P (info, h)
	      && SYMBOL_DEFINED_NON_SHARED_P (h))
	    dynamic_relative_reloc_p = true;

	  isym = NULL;
	}

      if (X86_GOT_TYPE_P (is_x86_64, r_type))
	{
	  /* Pack GOT relative relocations.  There should be only a
	     single R_*_RELATIVE relocation in GOT.  */
	  if (eh != NULL)
	    {
	      if (eh->got_relative_reloc_done)
		continue;

	      if (!(dynamic_relative_reloc_p
		    || (RESOLVED_LOCALLY_P (info, h, htab)
			&& GENERATE_RELATIVE_RELOC_P (info, h))))
		continue;

	      if (!dynamic_relative_reloc_p)
		eh->no_finish_dynamic_symbol = 1;
	      eh->got_relative_reloc_done = 1;
	      offset = h->got.offset;
	    }
	  else
	    {
	      if (elf_x86_relative_reloc_done (abfd)[r_symndx])
		continue;

	      if (!X86_LOCAL_GOT_RELATIVE_RELOC_P (is_x86_64, info,
						   isym))
		continue;

	      elf_x86_relative_reloc_done (abfd)[r_symndx] = 1;
	      offset = local_got_offsets[r_symndx];
	    }

	  if (!elf_x86_relative_reloc_record_add (info,
						  &htab->relative_reloc,
						  irel, htab->elf.sgot,
						  sec, h, isym, offset))
	    goto error_return;

	  continue;
	}

      if (is_x86_64
	  && irel->r_addend == 0
	  && !ABI_64_P (info->output_bfd))
	{
	  /* For x32, if addend is zero, treat R_X86_64_64 like
	     R_X86_64_32 and R_X86_64_SIZE64 like R_X86_64_SIZE32.  */
	  if (r_type == R_X86_64_64)
	    r_type = R_X86_64_32;
	  else if (r_type == R_X86_64_SIZE64)
	    r_type = R_X86_64_SIZE32;
	}

      if (!X86_RELATIVE_RELOC_TYPE_P (is_x86_64, r_type))
	continue;

      /* Pack non-GOT relative relocations.  */
      if (is_x86_64)
	{
	  need_copy_reloc_in_pie =
	    (bfd_link_pie (info)
	     && h != NULL
	     && (h->needs_copy
		 || eh->needs_copy
		 || (h->root.type == bfd_link_hash_undefined))
	     && (X86_PCREL_TYPE_P (true, r_type)
		 || X86_SIZE_TYPE_P (true, r_type)));
	  pc32_reloc = false;
	}
      else
	{
	  need_copy_reloc_in_pie = false;
	  pc32_reloc = r_type == R_386_PC32;
	}

      if (GENERATE_DYNAMIC_RELOCATION_P (is_x86_64, info, eh, r_type,
					 sec, need_copy_reloc_in_pie,
					 resolved_to_zero, pc32_reloc))
	{
	  /* When generating a shared object, these relocations
	     are copied into the output file to be resolved at run
	     time.	*/
	  offset = _bfd_elf_section_offset (info->output_bfd, info,
					    input_section,
					    irel->r_offset);
	  if (offset == (bfd_vma) -1
	      || offset == (bfd_vma) -2
	      || COPY_INPUT_RELOC_P (is_x86_64, info, h, r_type))
	    continue;

	  /* This symbol is local, or marked to become local.  When
	     relocation overflow check is disabled, we convert
	     R_X86_64_32 to dynamic R_X86_64_RELATIVE.  */
	  if (is_x86_64
	      && !(r_type == htab->pointer_r_type
		   || (r_type == R_X86_64_32
		       && htab->params->no_reloc_overflow_check)))
	    continue;

	  if (!elf_x86_relative_reloc_record_add
	        (info,
		 ((unaligned_section || unaligned_offset)
		  ? &htab->unaligned_relative_reloc
		  : &htab->relative_reloc),
		 irel, input_section, sec, h, isym, offset))
	    goto error_return;
	}
    }

  input_section->relative_reloc_packed = 1;

  return true;

error_return:
  if ((unsigned char *) isymbuf != symtab_hdr->contents)
    free (isymbuf);
  if (elf_section_data (input_section)->relocs != internal_relocs)
    free (internal_relocs);
  return false;
}

/* Add an entry to the 64-bit DT_RELR bitmap.  */

static void
elf64_dt_relr_bitmap_add
  (struct bfd_link_info *info, struct elf_dt_relr_bitmap *bitmap,
   uint64_t entry)
{
  bfd_size_type newidx;

  if (bitmap->u.elf64 == NULL)
    {
      bitmap->u.elf64 = bfd_malloc (sizeof (uint64_t));
      bitmap->count = 0;
      bitmap->size = 1;
    }

  newidx = bitmap->count++;

  if (bitmap->count > bitmap->size)
    {
      bitmap->size <<= 1;
      bitmap->u.elf64 = bfd_realloc (bitmap->u.elf64,
				     (bitmap->size * sizeof (uint64_t)));
    }

  if (bitmap->u.elf64 == NULL)
    {
      info->callbacks->einfo
	/* xgettext:c-format */
	(_("%F%P: %pB: failed to allocate 64-bit DT_RELR bitmap\n"),
	 info->output_bfd);
    }

  bitmap->u.elf64[newidx] = entry;
}

/* Add an entry to the 32-bit DT_RELR bitmap.  */

static void
elf32_dt_relr_bitmap_add
  (struct bfd_link_info *info, struct elf_dt_relr_bitmap *bitmap,
   uint32_t entry)
{
  bfd_size_type newidx;

  if (bitmap->u.elf32 == NULL)
    {
      bitmap->u.elf32 = bfd_malloc (sizeof (uint32_t));
      bitmap->count = 0;
      bitmap->size = 1;
    }

  newidx = bitmap->count++;

  if (bitmap->count > bitmap->size)
    {
      bitmap->size <<= 1;
      bitmap->u.elf32 = bfd_realloc (bitmap->u.elf32,
				     (bitmap->size * sizeof (uint32_t)));
    }

  if (bitmap->u.elf32 == NULL)
    {
      info->callbacks->einfo
	/* xgettext:c-format */
	(_("%F%P: %pB: failed to allocate 32-bit DT_RELR bitmap\n"),
	 info->output_bfd);
    }

  bitmap->u.elf32[newidx] = entry;
}

void
_bfd_elf32_write_addend (bfd *abfd, uint64_t value, void *addr)
{
  bfd_put_32 (abfd, value, addr);
}

void
_bfd_elf64_write_addend (bfd *abfd, uint64_t value, void *addr)
{
  bfd_put_64 (abfd, value, addr);
}

/* Size or finish relative relocations to determine the run-time
   addresses for DT_RELR bitmap computation later.  OUTREL is set
   to NULL in the sizing phase and non-NULL in the finising phase
   where the regular relative relocations will be written out.  */

static void
elf_x86_size_or_finish_relative_reloc
  (bool is_x86_64, struct bfd_link_info *info,
   struct elf_x86_link_hash_table *htab, bool unaligned,
   Elf_Internal_Rela *outrel)
{
  unsigned int align_mask;
  bfd_size_type i, count;
  asection *sec, *srel;
  struct elf_link_hash_entry *h;
  bfd_vma offset;
  Elf_Internal_Sym *sym;
  asection *sym_sec;
  asection *sgot = htab->elf.sgot;
  asection *srelgot = htab->elf.srelgot;
  struct elf_x86_relative_reloc_data *relative_reloc;

  if (unaligned)
    {
      align_mask = 0;
      relative_reloc = &htab->unaligned_relative_reloc;
    }
  else
    {
      align_mask = 1;
      relative_reloc = &htab->relative_reloc;
    }

  count = relative_reloc->count;
  for (i = 0; i < count; i++)
    {
      sec = relative_reloc->data[i].sec;
      sym = relative_reloc->data[i].sym;

      /* If SYM is NULL, it must be a global symbol.  */
      if (sym == NULL)
	h = relative_reloc->data[i].u.h;
      else
	h = NULL;

      if (is_x86_64)
	{
	  bfd_vma relocation;
	  /* This function may be called more than once and REL may be
	     updated by _bfd_elf_rela_local_sym below.  */
	  Elf_Internal_Rela rel = relative_reloc->data[i].rel;

	  if (h != NULL)
	    {
	      if (h->root.type == bfd_link_hash_defined
		  || h->root.type == bfd_link_hash_defweak)
		{
		  sym_sec = h->root.u.def.section;
		  relocation = (h->root.u.def.value
				+ sym_sec->output_section->vma
				+ sym_sec->output_offset);
		}
	      else
		{
		  /* Allow undefined symbol only at the sizing phase.
		     Otherwise skip undefined symbol here.  Undefined
		     symbol will be reported by relocate_section.  */
		  if (outrel == NULL)
		    relocation = 0;
		  else
		    continue;
		}
	    }
	  else
	    {
	      sym_sec = relative_reloc->data[i].u.sym_sec;
	      relocation = _bfd_elf_rela_local_sym
		(info->output_bfd, sym, &sym_sec, &rel);
	    }

	  if (outrel != NULL)
	    {
	      outrel->r_addend = relocation;
	      if (sec == sgot)
		{
		  if (h != NULL && h->needs_plt)
		    abort ();
		}
	      else
		outrel->r_addend += rel.r_addend;

	      /* Write the implicit addend if ALIGN_MASK isn't 0.  */
	      if (align_mask)
		{
		  if (sec == sgot)
		    {
		      if (relative_reloc->data[i].offset >= sec->size)
			abort ();
		      htab->elf_write_addend_in_got
			(info->output_bfd, outrel->r_addend,
			 sec->contents + relative_reloc->data[i].offset);
		    }
		  else
		    {
		      if (rel.r_offset >= sec->size)
			abort ();
		      htab->elf_write_addend
			(info->output_bfd, outrel->r_addend,
			 (elf_section_data (sec)->this_hdr.contents
			  + rel.r_offset));
		    }
		}
	    }
	}

      if (sec == sgot)
	srel = srelgot;
      else
	srel = elf_section_data (sec)->sreloc;
      offset = (sec->output_section->vma + sec->output_offset
		+ relative_reloc->data[i].offset);
      relative_reloc->data[i].address = offset;
      if (outrel != NULL)
	{
	  outrel->r_offset = offset;

	  if ((outrel->r_offset & align_mask) != 0)
	    abort ();

	  if (htab->params->report_relative_reloc)
	    _bfd_x86_elf_link_report_relative_reloc
	      (info, sec, h, sym, htab->relative_r_name, outrel);

	  /* Generate regular relative relocation if ALIGN_MASK is 0.  */
	  if (align_mask == 0)
	    htab->elf_append_reloc (info->output_bfd, srel, outrel);
	}
    }
}

/* Compute the DT_RELR section size.  Set NEED_PLAYOUT to true if
   the DT_RELR section size has been increased.  */

static void
elf_x86_compute_dl_relr_bitmap
  (struct bfd_link_info *info, struct elf_x86_link_hash_table *htab,
   bool *need_layout)
{
  bfd_vma base;
  bfd_size_type i, count, new_count;
  struct elf_x86_relative_reloc_data *relative_reloc =
    &htab->relative_reloc;
  /* Save the old DT_RELR bitmap count.  Don't shrink the DT_RELR bitmap
     if the new DT_RELR bitmap count is smaller than the old one.  Pad
     with trailing 1s which won't be decoded to more relocations.  */
  bfd_size_type dt_relr_bitmap_count = htab->dt_relr_bitmap.count;

  /* Clear the DT_RELR bitmap count.  */
  htab->dt_relr_bitmap.count = 0;

  count = relative_reloc->count;

  if (ABI_64_P (info->output_bfd))
    {
      /* Compute the 64-bit DT_RELR bitmap.  */
      i = 0;
      while (i < count)
	{
	  if ((relative_reloc->data[i].address % 1) != 0)
	    abort ();

	  elf64_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap,
				    relative_reloc->data[i].address);

	  base = relative_reloc->data[i].address + 8;
	  i++;

	  while (i < count)
	    {
	      uint64_t bitmap = 0;
	      for (; i < count; i++)
		{
		  bfd_vma delta = (relative_reloc->data[i].address
				   - base);
		  /* Stop if it is too far from base.  */
		  if (delta >= 63 * 8)
		    break;
		  /* Stop if it isn't a multiple of 8.  */
		  if ((delta % 8) != 0)
		    break;
		  bitmap |= 1ULL << (delta / 8);
		}

	      if (bitmap == 0)
		break;

	      elf64_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap,
					(bitmap << 1) | 1);

	      base += 63 * 8;
	    }
	}

      new_count = htab->dt_relr_bitmap.count;
      if (dt_relr_bitmap_count > new_count)
	{
	  /* Don't shrink the DT_RELR section size to avoid section
	     layout oscillation.  Instead, pad the DT_RELR bitmap with
	     1s which do not decode to more relocations.  */

	  htab->dt_relr_bitmap.count = dt_relr_bitmap_count;
	  count = dt_relr_bitmap_count - new_count;
	  for (i = 0; i < count; i++)
	    htab->dt_relr_bitmap.u.elf64[new_count + i] = 1;
	}
    }
  else
    {
      /* Compute the 32-bit DT_RELR bitmap.  */
      i = 0;
      while (i < count)
	{
	  if ((relative_reloc->data[i].address % 1) != 0)
	    abort ();

	  elf32_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap,
				    relative_reloc->data[i].address);

	  base = relative_reloc->data[i].address + 4;
	  i++;

	  while (i < count)
	    {
	      uint32_t bitmap = 0;
	      for (; i < count; i++)
		{
		  bfd_vma delta = (relative_reloc->data[i].address
				   - base);
		  /* Stop if it is too far from base.  */
		  if (delta >= 31 * 4)
		    break;
		  /* Stop if it isn't a multiple of 4.  */
		  if ((delta % 4) != 0)
		    break;
		  bitmap |= 1ULL << (delta / 4);
		}

	      if (bitmap == 0)
		break;

	      elf32_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap,
					(bitmap << 1) | 1);

	      base += 31 * 4;
	    }
	}

      new_count = htab->dt_relr_bitmap.count;
      if (dt_relr_bitmap_count > new_count)
	{
	  /* Don't shrink the DT_RELR section size to avoid section
	     layout oscillation.  Instead, pad the DT_RELR bitmap with
	     1s which do not decode to more relocations.  */

	  htab->dt_relr_bitmap.count = dt_relr_bitmap_count;
	  count = dt_relr_bitmap_count - new_count;
	  for (i = 0; i < count; i++)
	    htab->dt_relr_bitmap.u.elf32[new_count + i] = 1;
	}
    }

  if (htab->dt_relr_bitmap.count != dt_relr_bitmap_count)
    {
      if (need_layout)
	{
	  /* The .relr.dyn section size is changed.  Update the section
	     size and tell linker to layout sections again.  */
	  htab->elf.srelrdyn->size =
	    (htab->dt_relr_bitmap.count
	     * (ABI_64_P (info->output_bfd) ? 8 : 4));

	  *need_layout = true;
	}
      else
	info->callbacks->einfo
	  /* xgettext:c-format */
	  (_("%F%P: %pB: size of compact relative reloc section is "
	     "changed: new (%lu) != old (%lu)\n"),
	   info->output_bfd, htab->dt_relr_bitmap.count,
	   dt_relr_bitmap_count);
    }
}

/* Write out the DT_RELR section.  */

static void
elf_x86_write_dl_relr_bitmap (struct bfd_link_info *info,
			      struct elf_x86_link_hash_table *htab)
{
  asection *sec = htab->elf.srelrdyn;
  bfd_size_type size = sec->size;
  bfd_size_type i;
  unsigned char *contents;

  contents = (unsigned char *) bfd_alloc (sec->owner, size);
  if (contents == NULL)
    info->callbacks->einfo
      /* xgettext:c-format */
      (_("%F%P: %pB: failed to allocate compact relative reloc section\n"),
       info->output_bfd);

  /* Cache the section contents for elf_link_input_bfd.  */
  sec->contents = contents;

  if (ABI_64_P (info->output_bfd))
    for (i = 0; i < htab->dt_relr_bitmap.count; i++, contents += 8)
      bfd_put_64 (info->output_bfd, htab->dt_relr_bitmap.u.elf64[i],
		  contents);
  else
    for (i = 0; i < htab->dt_relr_bitmap.count; i++, contents += 4)
      bfd_put_32 (info->output_bfd, htab->dt_relr_bitmap.u.elf32[i],
		  contents);
}

/* Sort relative relocations by address.  */

static int
elf_x86_relative_reloc_compare (const void *pa, const void *pb)
{
  struct elf_x86_relative_reloc_record *a =
    (struct elf_x86_relative_reloc_record *) pa;
  struct elf_x86_relative_reloc_record *b =
    (struct elf_x86_relative_reloc_record *) pb;
  if (a->address < b->address)
    return -1;
  if (a->address > b->address)
    return 1;
  return 0;
}

bool
_bfd_elf_x86_size_relative_relocs (struct bfd_link_info *info,
				   bool *need_layout)
{
  struct elf_x86_link_hash_table *htab;
  const struct elf_backend_data *bed;
  bool is_x86_64;
  bfd_size_type i, count, unaligned_count;
  asection *sec, *srel;

  /* Do nothing for ld -r.  */
  if (bfd_link_relocatable (info))
    return true;

  bed = get_elf_backend_data (info->output_bfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return false;

  count = htab->relative_reloc.count;
  unaligned_count = htab->unaligned_relative_reloc.count;
  if (count == 0)
    {
      if (htab->generate_relative_reloc_pass == 0
	  && htab->elf.srelrdyn != NULL)
	{
	  /* Remove the empty .relr.dyn sections now.  */
	  if (!bfd_is_abs_section (htab->elf.srelrdyn->output_section))
	    {
	      bfd_section_list_remove
		(info->output_bfd, htab->elf.srelrdyn->output_section);
	      info->output_bfd->section_count--;
	    }
	  bfd_section_list_remove (htab->elf.srelrdyn->owner,
				   htab->elf.srelrdyn);
	  htab->elf.srelrdyn->owner->section_count--;
	}
      if (unaligned_count == 0)
	{
	  htab->generate_relative_reloc_pass++;
	  return true;
	}
    }

  is_x86_64 = bed->target_id == X86_64_ELF_DATA;

  /* Size relative relocations.  */
  if (htab->generate_relative_reloc_pass)
    {
      /* Reset the regular relative relocation count.  */
      for (i = 0; i < unaligned_count; i++)
	{
	  sec = htab->unaligned_relative_reloc.data[i].sec;
	  srel = elf_section_data (sec)->sreloc;
	  srel->reloc_count = 0;
	}
    }
  else
    {
      /* Remove the reserved space for compact relative relocations.  */
      if (count)
	{
	  asection *sgot = htab->elf.sgot;
	  asection *srelgot = htab->elf.srelgot;

	  for (i = 0; i < count; i++)
	    {
	      sec = htab->relative_reloc.data[i].sec;
	      if (sec == sgot)
		srel = srelgot;
	      else
		srel = elf_section_data (sec)->sreloc;
	      srel->size -= htab->sizeof_reloc;
	    }
	}
    }

  /* Size unaligned relative relocations.  */
  if (unaligned_count)
    elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab,
					   true, NULL);

  if (count)
    {
      elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab,
					     false, NULL);

      /* Sort relative relocations by addresses.  We only need to
	 sort them in the first pass since the relative positions
	 won't change.  */
      if (htab->generate_relative_reloc_pass == 0)
	qsort (htab->relative_reloc.data, count,
	       sizeof (struct elf_x86_relative_reloc_record),
	       elf_x86_relative_reloc_compare);

      elf_x86_compute_dl_relr_bitmap (info, htab, need_layout);
    }

  htab->generate_relative_reloc_pass++;

  return true;
}

bool
_bfd_elf_x86_finish_relative_relocs (struct bfd_link_info *info)
{
  struct elf_x86_link_hash_table *htab;
  const struct elf_backend_data *bed;
  Elf_Internal_Rela outrel;
  bool is_x86_64;
  bfd_size_type count;

  /* Do nothing for ld -r.  */
  if (bfd_link_relocatable (info))
    return true;

  bed = get_elf_backend_data (info->output_bfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return false;

  is_x86_64 = bed->target_id == X86_64_ELF_DATA;

  outrel.r_info = htab->r_info (0, htab->relative_r_type);

  if (htab->unaligned_relative_reloc.count)
    elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab,
					   true, &outrel);

  count = htab->relative_reloc.count;
  if (count)
    {
      elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab,
					     false, &outrel);

      elf_x86_compute_dl_relr_bitmap (info, htab, NULL);

      elf_x86_write_dl_relr_bitmap (info, htab);
    }

  return true;
}

bool
_bfd_elf_x86_valid_reloc_p (asection *input_section,
			    struct bfd_link_info *info,
			    struct elf_x86_link_hash_table *htab,
			    const Elf_Internal_Rela *rel,
			    struct elf_link_hash_entry *h,
			    Elf_Internal_Sym *sym,
			    Elf_Internal_Shdr *symtab_hdr,
			    bool *no_dynreloc_p)
{
  bool valid_p = true;

  *no_dynreloc_p = false;

  /* Check If relocation against non-preemptible absolute symbol is
     valid in PIC.  FIXME: Can't use SYMBOL_REFERENCES_LOCAL_P since
     it may call _bfd_elf_link_hide_sym_by_version and result in
     ld-elfvers/ vers21 test failure.  */
  if (bfd_link_pic (info)
      && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, h)))
    {
      const struct elf_backend_data *bed;
      unsigned int r_type;
      Elf_Internal_Rela irel;

      /* Skip non-absolute symbol.  */
      if (h)
	{
	  if (!ABS_SYMBOL_P (h))
	    return valid_p;
	}
      else if (sym->st_shndx != SHN_ABS)
	return valid_p;

      bed = get_elf_backend_data (input_section->owner);
      r_type = ELF32_R_TYPE (rel->r_info);
      irel = *rel;

      /* Only allow relocations against absolute symbol, which can be
	 resolved as absolute value + addend.  GOTPCREL and GOT32
	 relocations are allowed since absolute value + addend is
	 stored in the GOT slot.  */
      if (bed->target_id == X86_64_ELF_DATA)
	{
	  r_type &= ~R_X86_64_converted_reloc_bit;
	  valid_p = (r_type == R_X86_64_64
		     || r_type == R_X86_64_32
		     || r_type == R_X86_64_32S
		     || r_type == R_X86_64_16
		     || r_type == R_X86_64_8
		     || r_type == R_X86_64_GOTPCREL
		     || r_type == R_X86_64_GOTPCRELX
		     || r_type == R_X86_64_REX_GOTPCRELX);
	  if (!valid_p)
	    {
	      unsigned int r_symndx = htab->r_sym (rel->r_info);
	      irel.r_info = htab->r_info (r_symndx, r_type);
	    }
	}
      else
	valid_p = (r_type == R_386_32
		   || r_type == R_386_16
		   || r_type == R_386_8
		   || r_type == R_386_GOT32
		   || r_type == R_386_GOT32X);

      if (valid_p)
	*no_dynreloc_p = true;
      else
	{
	  const char *name;
	  arelent internal_reloc;

	  if (!bed->elf_info_to_howto (input_section->owner,
				       &internal_reloc, &irel)
	      || internal_reloc.howto == NULL)
	    abort ();

	  if (h)
	    name = h->root.root.string;
	  else
	    name = bfd_elf_sym_name (input_section->owner, symtab_hdr,
				     sym, NULL);
	  info->callbacks->einfo
	    /* xgettext:c-format */
	    (_("%F%P: %pB: relocation %s against absolute symbol "
	       "`%s' in section `%pA' is disallowed\n"),
	     input_section->owner, internal_reloc.howto->name, name,
	     input_section);
	  bfd_set_error (bfd_error_bad_value);
	}
    }

  return valid_p;
}

/* Set the sizes of the dynamic sections.  */

bool
_bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
				    struct bfd_link_info *info)
{
  struct elf_x86_link_hash_table *htab;
  bfd *dynobj;
  asection *s;
  bool relocs;
  bfd *ibfd;
  const struct elf_backend_data *bed
    = get_elf_backend_data (output_bfd);

  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return false;
  dynobj = htab->elf.dynobj;
  if (dynobj == NULL)
    abort ();

  /* Set up .got offsets for local syms, and space for local dynamic
     relocs.  */
  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
    {
      bfd_signed_vma *local_got;
      bfd_signed_vma *end_local_got;
      char *local_tls_type;
      bfd_vma *local_tlsdesc_gotent;
      bfd_size_type locsymcount;
      Elf_Internal_Shdr *symtab_hdr;
      asection *srel;

      if (! is_x86_elf (ibfd, htab))
	continue;

      for (s = ibfd->sections; s != NULL; s = s->next)
	{
	  struct elf_dyn_relocs *p;

	  for (p = ((struct elf_dyn_relocs *)
		     elf_section_data (s)->local_dynrel);
	       p != NULL;
	       p = p->next)
	    {
	      if (!bfd_is_abs_section (p->sec)
		  && bfd_is_abs_section (p->sec->output_section))
		{
		  /* Input section has been discarded, either because
		     it is a copy of a linkonce section or due to
		     linker script /DISCARD/, so we'll be discarding
		     the relocs too.  */
		}
	      else if (htab->elf.target_os == is_vxworks
		       && strcmp (p->sec->output_section->name,
				  ".tls_vars") == 0)
		{
		  /* Relocations in vxworks .tls_vars sections are
		     handled specially by the loader.  */
		}
	      else if (p->count != 0)
		{
		  srel = elf_section_data (p->sec)->sreloc;
		  srel->size += p->count * htab->sizeof_reloc;
		  if ((p->sec->output_section->flags & SEC_READONLY) != 0
		      && (info->flags & DF_TEXTREL) == 0)
		    {
		      info->flags |= DF_TEXTREL;
		      if (bfd_link_textrel_check (info))
			/* xgettext:c-format */
			info->callbacks->einfo
			  (_("%P: %pB: warning: relocation "
			     "in read-only section `%pA'\n"),
			   p->sec->owner, p->sec);
		    }
		}
	    }
	}

      local_got = elf_local_got_refcounts (ibfd);
      if (!local_got)
	continue;

      symtab_hdr = &elf_symtab_hdr (ibfd);
      locsymcount = symtab_hdr->sh_info;
      end_local_got = local_got + locsymcount;
      local_tls_type = elf_x86_local_got_tls_type (ibfd);
      local_tlsdesc_gotent = elf_x86_local_tlsdesc_gotent (ibfd);
      s = htab->elf.sgot;
      srel = htab->elf.srelgot;
      for (; local_got < end_local_got;
	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
	{
	  *local_tlsdesc_gotent = (bfd_vma) -1;
	  if (*local_got > 0)
	    {
	      if (GOT_TLS_GDESC_P (*local_tls_type))
		{
		  *local_tlsdesc_gotent = htab->elf.sgotplt->size
		    - elf_x86_compute_jump_table_size (htab);
		  htab->elf.sgotplt->size += 2 * htab->got_entry_size;
		  *local_got = (bfd_vma) -2;
		}
	      if (! GOT_TLS_GDESC_P (*local_tls_type)
		  || GOT_TLS_GD_P (*local_tls_type))
		{
		  *local_got = s->size;
		  s->size += htab->got_entry_size;
		  if (GOT_TLS_GD_P (*local_tls_type)
		      || *local_tls_type == GOT_TLS_IE_BOTH)
		    s->size += htab->got_entry_size;
		}
	      if ((bfd_link_pic (info) && *local_tls_type != GOT_ABS)
		  || GOT_TLS_GD_ANY_P (*local_tls_type)
		  || (*local_tls_type & GOT_TLS_IE))
		{
		  if (*local_tls_type == GOT_TLS_IE_BOTH)
		    srel->size += 2 * htab->sizeof_reloc;
		  else if (GOT_TLS_GD_P (*local_tls_type)
			   || ! GOT_TLS_GDESC_P (*local_tls_type))
		    srel->size += htab->sizeof_reloc;
		  if (GOT_TLS_GDESC_P (*local_tls_type))
		    {
		      htab->elf.srelplt->size += htab->sizeof_reloc;
		      if (bed->target_id == X86_64_ELF_DATA)
			htab->elf.tlsdesc_plt = (bfd_vma) -1;
		    }
		}
	    }
	  else
	    *local_got = (bfd_vma) -1;
	}
    }

  if (htab->tls_ld_or_ldm_got.refcount > 0)
    {
      /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
	 or R_X86_64_TLSLD relocs.  */
      htab->tls_ld_or_ldm_got.offset = htab->elf.sgot->size;
      htab->elf.sgot->size += 2 * htab->got_entry_size;
      htab->elf.srelgot->size += htab->sizeof_reloc;
    }
  else
    htab->tls_ld_or_ldm_got.offset = -1;

  /* Allocate global sym .plt and .got entries, and space for global
     sym dynamic relocs.  */
  elf_link_hash_traverse (&htab->elf, elf_x86_allocate_dynrelocs,
			  info);

  /* Allocate .plt and .got entries, and space for local symbols.  */
  htab_traverse (htab->loc_hash_table, elf_x86_allocate_local_dynreloc,
		 info);

  /* For every jump slot reserved in the sgotplt, reloc_count is
     incremented.  However, when we reserve space for TLS descriptors,
     it's not incremented, so in order to compute the space reserved
     for them, it suffices to multiply the reloc count by the jump
     slot size.

     PR ld/13302: We start next_irelative_index at the end of .rela.plt
     so that R_{386,X86_64}_IRELATIVE entries come last.  */
  if (htab->elf.srelplt)
    {
      htab->next_tls_desc_index = htab->elf.srelplt->reloc_count;
      htab->sgotplt_jump_table_size
	= elf_x86_compute_jump_table_size (htab);
      htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
    }
  else if (htab->elf.irelplt)
    htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;

  if (htab->elf.tlsdesc_plt)
    {
      /* NB: tlsdesc_plt is set only for x86-64.  If we're not using
	 lazy TLS relocations, don't generate the PLT and GOT entries
	 they require.  */
      if ((info->flags & DF_BIND_NOW))
	htab->elf.tlsdesc_plt = 0;
      else
	{
	  htab->elf.tlsdesc_got = htab->elf.sgot->size;
	  htab->elf.sgot->size += htab->got_entry_size;
	  /* Reserve room for the initial entry.
	     FIXME: we could probably do away with it in this case.  */
	  if (htab->elf.splt->size == 0)
	    htab->elf.splt->size = htab->plt.plt_entry_size;
	  htab->elf.tlsdesc_plt = htab->elf.splt->size;
	  htab->elf.splt->size += htab->plt.plt_entry_size;
	}
    }

  if (htab->elf.sgotplt)
    {
      /* Don't allocate .got.plt section if there are no GOT nor PLT
	 entries and there is no reference to _GLOBAL_OFFSET_TABLE_.  */
      if ((htab->elf.hgot == NULL
	   || !htab->got_referenced)
	  && (htab->elf.sgotplt->size == bed->got_header_size)
	  && (htab->elf.splt == NULL
	      || htab->elf.splt->size == 0)
	  && (htab->elf.sgot == NULL
	      || htab->elf.sgot->size == 0)
	  && (htab->elf.iplt == NULL
	      || htab->elf.iplt->size == 0)
	  && (htab->elf.igotplt == NULL
	      || htab->elf.igotplt->size == 0))
	{
	  htab->elf.sgotplt->size = 0;
	  /* Solaris requires to keep _GLOBAL_OFFSET_TABLE_ even if it
	     isn't used.  */
	  if (htab->elf.hgot != NULL
	      && htab->elf.target_os != is_solaris)
	    {
	      /* Remove the unused _GLOBAL_OFFSET_TABLE_ from symbol
		 table. */
	      htab->elf.hgot->root.type = bfd_link_hash_undefined;
	      htab->elf.hgot->root.u.undef.abfd
		= htab->elf.hgot->root.u.def.section->owner;
	      htab->elf.hgot->root.linker_def = 0;
	      htab->elf.hgot->ref_regular = 0;
	      htab->elf.hgot->def_regular = 0;
	    }
	}
    }

  if (_bfd_elf_eh_frame_present (info))
    {
      if (htab->plt_eh_frame != NULL
	  && htab->elf.splt != NULL
	  && htab->elf.splt->size != 0
	  && !bfd_is_abs_section (htab->elf.splt->output_section))
	htab->plt_eh_frame->size = htab->plt.eh_frame_plt_size;

      if (htab->plt_got_eh_frame != NULL
	  && htab->plt_got != NULL
	  && htab->plt_got->size != 0
	  && !bfd_is_abs_section (htab->plt_got->output_section))
	htab->plt_got_eh_frame->size
	  = htab->non_lazy_plt->eh_frame_plt_size;

      /* Unwind info for the second PLT and .plt.got sections are
	 identical.  */
      if (htab->plt_second_eh_frame != NULL
	  && htab->plt_second != NULL
	  && htab->plt_second->size != 0
	  && !bfd_is_abs_section (htab->plt_second->output_section))
	htab->plt_second_eh_frame->size
	  = htab->non_lazy_plt->eh_frame_plt_size;
    }

  /* We now have determined the sizes of the various dynamic sections.
     Allocate memory for them.  */
  relocs = false;
  for (s = dynobj->sections; s != NULL; s = s->next)
    {
      bool strip_section = true;

      if ((s->flags & SEC_LINKER_CREATED) == 0)
	continue;

      /* The .relr.dyn section for compact relative relocation will
	 be filled later.  */
      if (s == htab->elf.srelrdyn)
	continue;

      if (s == htab->elf.splt
	  || s == htab->elf.sgot)
	{
	  /* Strip this section if we don't need it; see the
	     comment below.  */
	  /* We'd like to strip these sections if they aren't needed, but if
	     we've exported dynamic symbols from them we must leave them.
	     It's too late to tell BFD to get rid of the symbols.  */

	  if (htab->elf.hplt != NULL)
	    strip_section = false;
	}
      else if (s == htab->elf.sgotplt
	       || s == htab->elf.iplt
	       || s == htab->elf.igotplt
	       || s == htab->plt_second
	       || s == htab->plt_got
	       || s == htab->plt_eh_frame
	       || s == htab->plt_got_eh_frame
	       || s == htab->plt_second_eh_frame
	       || s == htab->elf.sdynbss
	       || s == htab->elf.sdynrelro)
	{
	  /* Strip these too.  */
	}
      else if (htab->is_reloc_section (bfd_section_name (s)))
	{
	  if (s->size != 0
	      && s != htab->elf.srelplt
	      && s != htab->srelplt2)
	    relocs = true;

	  /* We use the reloc_count field as a counter if we need
	     to copy relocs into the output file.  */
	  if (s != htab->elf.srelplt)
	    s->reloc_count = 0;
	}
      else
	{
	  /* It's not one of our sections, so don't allocate space.  */
	  continue;
	}

      if (s->size == 0)
	{
	  /* If we don't need this section, strip it from the
	     output file.  This is mostly to handle .rel.bss and
	     .rel.plt.  We must create both sections in
	     create_dynamic_sections, because they must be created
	     before the linker maps input sections to output
	     sections.  The linker does that before
	     adjust_dynamic_symbol is called, and it is that
	     function which decides whether anything needs to go
	     into these sections.  */
	  if (strip_section)
	    s->flags |= SEC_EXCLUDE;
	  continue;
	}

      if ((s->flags & SEC_HAS_CONTENTS) == 0)
	continue;

      /* NB: Initially, the iplt section has minimal alignment to
	 avoid moving dot of the following section backwards when
	 it is empty.  Update its section alignment now since it
	 is non-empty.  */
      if (s == htab->elf.iplt)
	bfd_set_section_alignment (s, htab->plt.iplt_alignment);

      /* Allocate memory for the section contents.  We use bfd_zalloc
	 here in case unused entries are not reclaimed before the
	 section's contents are written out.  This should not happen,
	 but this way if it does, we get a R_386_NONE or R_X86_64_NONE
	 reloc instead of garbage.  */
      s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
      if (s->contents == NULL)
	return false;
    }

  if (htab->plt_eh_frame != NULL
      && htab->plt_eh_frame->contents != NULL)
    {
      memcpy (htab->plt_eh_frame->contents,
	      htab->plt.eh_frame_plt,
	      htab->plt_eh_frame->size);
      bfd_put_32 (dynobj, htab->elf.splt->size,
		  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
    }

  if (htab->plt_got_eh_frame != NULL
      && htab->plt_got_eh_frame->contents != NULL)
    {
      memcpy (htab->plt_got_eh_frame->contents,
	      htab->non_lazy_plt->eh_frame_plt,
	      htab->plt_got_eh_frame->size);
      bfd_put_32 (dynobj, htab->plt_got->size,
		  (htab->plt_got_eh_frame->contents
		   + PLT_FDE_LEN_OFFSET));
    }

  if (htab->plt_second_eh_frame != NULL
      && htab->plt_second_eh_frame->contents != NULL)
    {
      memcpy (htab->plt_second_eh_frame->contents,
	      htab->non_lazy_plt->eh_frame_plt,
	      htab->plt_second_eh_frame->size);
      bfd_put_32 (dynobj, htab->plt_second->size,
		  (htab->plt_second_eh_frame->contents
		   + PLT_FDE_LEN_OFFSET));
    }

  return _bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info,
						  relocs);
}

/* Finish up the x86 dynamic sections.  */

struct elf_x86_link_hash_table *
_bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
				      struct bfd_link_info *info)
{
  struct elf_x86_link_hash_table *htab;
  const struct elf_backend_data *bed;
  bfd *dynobj;
  asection *sdyn;
  bfd_byte *dyncon, *dynconend;
  bfd_size_type sizeof_dyn;

  bed = get_elf_backend_data (output_bfd);
  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return htab;

  dynobj = htab->elf.dynobj;
  sdyn = bfd_get_linker_section (dynobj, ".dynamic");

  /* GOT is always created in setup_gnu_properties.  But it may not be
     needed.  .got.plt section may be needed for static IFUNC.  */
  if (htab->elf.sgotplt && htab->elf.sgotplt->size > 0)
    {
      bfd_vma dynamic_addr;

      if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
	{
	  _bfd_error_handler
	    (_("discarded output section: `%pA'"), htab->elf.sgotplt);
	  return NULL;
	}

      elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize
	= htab->got_entry_size;

      dynamic_addr = (sdyn == NULL
		      ? (bfd_vma) 0
		      : sdyn->output_section->vma + sdyn->output_offset);

      /* Set the first entry in the global offset table to the address
	 of the dynamic section.  Write GOT[1] and GOT[2], needed for
	 the dynamic linker.  */
      if (htab->got_entry_size == 8)
	{
	  bfd_put_64 (output_bfd, dynamic_addr,
		      htab->elf.sgotplt->contents);
	  bfd_put_64 (output_bfd, (bfd_vma) 0,
		      htab->elf.sgotplt->contents + 8);
	  bfd_put_64 (output_bfd, (bfd_vma) 0,
		      htab->elf.sgotplt->contents + 8*2);
	}
      else
	{
	  bfd_put_32 (output_bfd, dynamic_addr,
		      htab->elf.sgotplt->contents);
	  bfd_put_32 (output_bfd, 0,
		      htab->elf.sgotplt->contents + 4);
	  bfd_put_32 (output_bfd, 0,
		      htab->elf.sgotplt->contents + 4*2);
	}
    }

  if (!htab->elf.dynamic_sections_created)
    return htab;

  if (sdyn == NULL || htab->elf.sgot == NULL)
    abort ();

  sizeof_dyn = bed->s->sizeof_dyn;
  dyncon = sdyn->contents;
  dynconend = sdyn->contents + sdyn->size;
  for (; dyncon < dynconend; dyncon += sizeof_dyn)
    {
      Elf_Internal_Dyn dyn;
      asection *s;

      (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn);

      switch (dyn.d_tag)
	{
	default:
	  if (htab->elf.target_os == is_vxworks
	      && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
	    break;
	  continue;

	case DT_PLTGOT:
	  s = htab->elf.sgotplt;
	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
	  break;

	case DT_JMPREL:
	  dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
	  break;

	case DT_PLTRELSZ:
	  s = htab->elf.srelplt->output_section;
	  dyn.d_un.d_val = s->size;
	  break;

	case DT_TLSDESC_PLT:
	  s = htab->elf.splt;
	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
	    + htab->elf.tlsdesc_plt;
	  break;

	case DT_TLSDESC_GOT:
	  s = htab->elf.sgot;
	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
	    + htab->elf.tlsdesc_got;
	  break;
	}

      (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
    }

  if (htab->plt_got != NULL && htab->plt_got->size > 0)
    elf_section_data (htab->plt_got->output_section)
      ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;

  if (htab->plt_second != NULL && htab->plt_second->size > 0)
    elf_section_data (htab->plt_second->output_section)
      ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;

  /* Adjust .eh_frame for .plt section.  */
  if (htab->plt_eh_frame != NULL
      && htab->plt_eh_frame->contents != NULL)
    {
      if (htab->elf.splt != NULL
	  && htab->elf.splt->size != 0
	  && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
	  && htab->elf.splt->output_section != NULL
	  && htab->plt_eh_frame->output_section != NULL)
	{
	  bfd_vma plt_start = htab->elf.splt->output_section->vma;
	  bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
				   + htab->plt_eh_frame->output_offset
				   + PLT_FDE_START_OFFSET;
	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
			     htab->plt_eh_frame->contents
			     + PLT_FDE_START_OFFSET);
	}

      if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
	{
	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
						 htab->plt_eh_frame,
						 htab->plt_eh_frame->contents))
	    return NULL;
	}
    }

  /* Adjust .eh_frame for .plt.got section.  */
  if (htab->plt_got_eh_frame != NULL
      && htab->plt_got_eh_frame->contents != NULL)
    {
      if (htab->plt_got != NULL
	  && htab->plt_got->size != 0
	  && (htab->plt_got->flags & SEC_EXCLUDE) == 0
	  && htab->plt_got->output_section != NULL
	  && htab->plt_got_eh_frame->output_section != NULL)
	{
	  bfd_vma plt_start = htab->plt_got->output_section->vma;
	  bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma
				   + htab->plt_got_eh_frame->output_offset
				   + PLT_FDE_START_OFFSET;
	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
			     htab->plt_got_eh_frame->contents
			     + PLT_FDE_START_OFFSET);
	}
      if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
	{
	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
						 htab->plt_got_eh_frame,
						 htab->plt_got_eh_frame->contents))
	    return NULL;
	}
    }

  /* Adjust .eh_frame for the second PLT section.  */
  if (htab->plt_second_eh_frame != NULL
      && htab->plt_second_eh_frame->contents != NULL)
    {
      if (htab->plt_second != NULL
	  && htab->plt_second->size != 0
	  && (htab->plt_second->flags & SEC_EXCLUDE) == 0
	  && htab->plt_second->output_section != NULL
	  && htab->plt_second_eh_frame->output_section != NULL)
	{
	  bfd_vma plt_start = htab->plt_second->output_section->vma;
	  bfd_vma eh_frame_start
	    = (htab->plt_second_eh_frame->output_section->vma
	       + htab->plt_second_eh_frame->output_offset
	       + PLT_FDE_START_OFFSET);
	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
			     htab->plt_second_eh_frame->contents
			     + PLT_FDE_START_OFFSET);
	}
      if (htab->plt_second_eh_frame->sec_info_type
	  == SEC_INFO_TYPE_EH_FRAME)
	{
	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
						 htab->plt_second_eh_frame,
						 htab->plt_second_eh_frame->contents))
	    return NULL;
	}
    }

  if (htab->elf.sgot && htab->elf.sgot->size > 0)
    elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
      = htab->got_entry_size;

  return htab;
}


bool
_bfd_x86_elf_always_size_sections (bfd *output_bfd,
				   struct bfd_link_info *info)
{
  asection *tls_sec = elf_hash_table (info)->tls_sec;

  if (tls_sec)
    {
      struct elf_link_hash_entry *tlsbase;

      tlsbase = elf_link_hash_lookup (elf_hash_table (info),
				      "_TLS_MODULE_BASE_",
				      false, false, false);

      if (tlsbase && tlsbase->type == STT_TLS)
	{
	  struct elf_x86_link_hash_table *htab;
	  struct bfd_link_hash_entry *bh = NULL;
	  const struct elf_backend_data *bed
	    = get_elf_backend_data (output_bfd);

	  htab = elf_x86_hash_table (info, bed->target_id);
	  if (htab == NULL)
	    return false;

	  if (!(_bfd_generic_link_add_one_symbol
		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
		 tls_sec, 0, NULL, false,
		 bed->collect, &bh)))
	    return false;

	  htab->tls_module_base = bh;

	  tlsbase = (struct elf_link_hash_entry *)bh;
	  tlsbase->def_regular = 1;
	  tlsbase->other = STV_HIDDEN;
	  tlsbase->root.linker_def = 1;
	  (*bed->elf_backend_hide_symbol) (info, tlsbase, true);
	}
    }

  return true;
}

void
_bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
				     unsigned int st_other,
				     bool definition,
				     bool dynamic ATTRIBUTE_UNUSED)
{
  if (definition)
    {
      struct elf_x86_link_hash_entry *eh
	= (struct elf_x86_link_hash_entry *) h;
      eh->def_protected = ELF_ST_VISIBILITY (st_other) == STV_PROTECTED;
    }
}

/* Copy the extra info we tack onto an elf_link_hash_entry.  */

void
_bfd_x86_elf_copy_indirect_symbol (struct bfd_link_info *info,
				   struct elf_link_hash_entry *dir,
				   struct elf_link_hash_entry *ind)
{
  struct elf_x86_link_hash_entry *edir, *eind;

  edir = (struct elf_x86_link_hash_entry *) dir;
  eind = (struct elf_x86_link_hash_entry *) ind;

  if (ind->root.type == bfd_link_hash_indirect
      && dir->got.refcount <= 0)
    {
      edir->tls_type = eind->tls_type;
      eind->tls_type = GOT_UNKNOWN;
    }

  /* Copy gotoff_ref so that elf_i386_adjust_dynamic_symbol will
     generate a R_386_COPY reloc.  */
  edir->gotoff_ref |= eind->gotoff_ref;

  edir->zero_undefweak |= eind->zero_undefweak;

  if (ELIMINATE_COPY_RELOCS
      && ind->root.type != bfd_link_hash_indirect
      && dir->dynamic_adjusted)
    {
      /* If called to transfer flags for a weakdef during processing
	 of elf_adjust_dynamic_symbol, don't copy non_got_ref.
	 We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
      if (dir->versioned != versioned_hidden)
	dir->ref_dynamic |= ind->ref_dynamic;
      dir->ref_regular |= ind->ref_regular;
      dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
      dir->needs_plt |= ind->needs_plt;
      dir->pointer_equality_needed |= ind->pointer_equality_needed;
    }
  else
    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}

/* Remove undefined weak symbol from the dynamic symbol table if it
   is resolved to 0.   */

bool
_bfd_x86_elf_fixup_symbol (struct bfd_link_info *info,
			   struct elf_link_hash_entry *h)
{
  if (h->dynindx != -1
      && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, elf_x86_hash_entry (h)))
    {
      h->dynindx = -1;
      _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
			      h->dynstr_index);
    }
  return true;
}

/* Change the STT_GNU_IFUNC symbol defined in position-dependent
   executable into the normal function symbol and set its address
   to its PLT entry, which should be resolved by R_*_IRELATIVE at
   run-time.  */

void
_bfd_x86_elf_link_fixup_ifunc_symbol (struct bfd_link_info *info,
				      struct elf_x86_link_hash_table *htab,
				      struct elf_link_hash_entry *h,
				      Elf_Internal_Sym *sym)
{
  if (bfd_link_pde (info)
      && h->def_regular
      && h->dynindx != -1
      && h->plt.offset != (bfd_vma) -1
      && h->type == STT_GNU_IFUNC)
    {
      asection *plt_s;
      bfd_vma plt_offset;
      bfd *output_bfd = info->output_bfd;

      if (htab->plt_second)
	{
	  struct elf_x86_link_hash_entry *eh
	    = (struct elf_x86_link_hash_entry *) h;

	  plt_s = htab->plt_second;
	  plt_offset = eh->plt_second.offset;
	}
      else
	{
	  plt_s = htab->elf.splt;
	  plt_offset = h->plt.offset;
	}

      sym->st_size = 0;
      sym->st_info = ELF_ST_INFO (ELF_ST_BIND (sym->st_info), STT_FUNC);
      sym->st_shndx
	= _bfd_elf_section_from_bfd_section (output_bfd,
					     plt_s->output_section);
      sym->st_value = (plt_s->output_section->vma
		       + plt_s->output_offset + plt_offset);
    }
}

/* Report relative relocation.  */

void
_bfd_x86_elf_link_report_relative_reloc
  (struct bfd_link_info *info, asection *asect,
   struct elf_link_hash_entry *h, Elf_Internal_Sym *sym,
   const char *reloc_name, const void *reloc)
{
  const char *name;
  bfd *abfd;
  const Elf_Internal_Rela *rel = (const Elf_Internal_Rela *) reloc;

  /* Use the output BFD for linker created sections.  */
  if ((asect->flags & SEC_LINKER_CREATED) != 0)
    abfd = info->output_bfd;
  else
    abfd = asect->owner;

  if (h != NULL && h->root.root.string != NULL)
    name = h->root.root.string;
  else
    name = bfd_elf_sym_name (abfd, &elf_symtab_hdr (abfd), sym, NULL);

  if (asect->use_rela_p)
    info->callbacks->einfo
      (_("%pB: %s (offset: 0x%v, info: 0x%v, addend: 0x%v) against "
	 "'%s' " "for section '%pA' in %pB\n"),
       info->output_bfd, reloc_name, rel->r_offset, rel->r_info,
       rel->r_addend, name, asect, abfd);
  else
    info->callbacks->einfo
      (_("%pB: %s (offset: 0x%v, info: 0x%v) against '%s' for section "
	 "'%pA' in %pB\n"),
       info->output_bfd, reloc_name, rel->r_offset, rel->r_info, name,
       asect, abfd);
}

/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */

bool
_bfd_x86_elf_hash_symbol (struct elf_link_hash_entry *h)
{
  if (h->plt.offset != (bfd_vma) -1
      && !h->def_regular
      && !h->pointer_equality_needed)
    return false;

  return _bfd_elf_hash_symbol (h);
}

/* Adjust a symbol defined by a dynamic object and referenced by a
   regular object.  The current definition is in some section of the
   dynamic object, but we're not including those sections.  We have to
   change the definition to something the rest of the link can
   understand.  */

bool
_bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
				    struct elf_link_hash_entry *h)
{
  struct elf_x86_link_hash_table *htab;
  asection *s, *srel;
  struct elf_x86_link_hash_entry *eh;
  struct elf_dyn_relocs *p;
  const struct elf_backend_data *bed
    = get_elf_backend_data (info->output_bfd);

  eh = (struct elf_x86_link_hash_entry *) h;

  /* Clear GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS if it is turned
     on by an input relocatable file and there is a non-GOT/non-PLT
     reference from another relocatable file without it.
     NB: There can be non-GOT reference in data sections in input with
     GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.  */
  if (eh->non_got_ref_without_indirect_extern_access
      && info->indirect_extern_access == 1
      && bfd_link_executable (info))
    {
      unsigned int needed_1;
      info->indirect_extern_access = 0;
      /* Turn off nocopyreloc if implied by indirect_extern_access.  */
      if (info->nocopyreloc == 2)
	info->nocopyreloc = 0;
      needed_1 = bfd_h_get_32 (info->output_bfd, info->needed_1_p);
      needed_1 &= ~GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
      bfd_h_put_32 (info->output_bfd, needed_1, info->needed_1_p);
    }

  /* STT_GNU_IFUNC symbol must go through PLT. */
  if (h->type == STT_GNU_IFUNC)
    {
      /* All local STT_GNU_IFUNC references must be treate as local
	 calls via local PLT.  */
      if (h->ref_regular
	  && SYMBOL_CALLS_LOCAL (info, h))
	{
	  bfd_size_type pc_count = 0, count = 0;
	  struct elf_dyn_relocs **pp;

	  eh = (struct elf_x86_link_hash_entry *) h;
	  for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
	    {
	      pc_count += p->pc_count;
	      p->count -= p->pc_count;
	      p->pc_count = 0;
	      count += p->count;
	      if (p->count == 0)
		*pp = p->next;
	      else
		pp = &p->next;
	    }

	  if (pc_count || count)
	    {
	      h->non_got_ref = 1;
	      if (pc_count)
		{
		  /* Increment PLT reference count only for PC-relative
		     references.  */
		  h->needs_plt = 1;
		  if (h->plt.refcount <= 0)
		    h->plt.refcount = 1;
		  else
		    h->plt.refcount += 1;
		}
	    }

	  /* GOTOFF relocation needs PLT.  */
	  if (eh->gotoff_ref)
	    h->plt.refcount = 1;
	}

      if (h->plt.refcount <= 0)
	{
	  h->plt.offset = (bfd_vma) -1;
	  h->needs_plt = 0;
	}
      return true;
    }

  /* If this is a function, put it in the procedure linkage table.  We
     will fill in the contents of the procedure linkage table later,
     when we know the address of the .got section.  */
  if (h->type == STT_FUNC
      || h->needs_plt)
    {
      if (h->plt.refcount <= 0
	  || SYMBOL_CALLS_LOCAL (info, h)
	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
	      && h->root.type == bfd_link_hash_undefweak))
	{
	  /* This case can occur if we saw a PLT32 reloc in an input
	     file, but the symbol was never referred to by a dynamic
	     object, or if all references were garbage collected.  In
	     such a case, we don't actually need to build a procedure
	     linkage table, and we can just do a PC32 reloc instead.  */
	  h->plt.offset = (bfd_vma) -1;
	  h->needs_plt = 0;
	}

      return true;
    }
  else
    /* It's possible that we incorrectly decided a .plt reloc was needed
     * for an R_386_PC32/R_X86_64_PC32 reloc to a non-function sym in
       check_relocs.  We can't decide accurately between function and
       non-function syms in check-relocs;  Objects loaded later in
       the link may change h->type.  So fix it now.  */
    h->plt.offset = (bfd_vma) -1;

  /* If this is a weak symbol, and there is a real definition, the
     processor independent code will have arranged for us to see the
     real definition first, and we can just use the same value.  */
  if (h->is_weakalias)
    {
      struct elf_link_hash_entry *def = weakdef (h);
      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
      h->root.u.def.section = def->root.u.def.section;
      h->root.u.def.value = def->root.u.def.value;
      if (ELIMINATE_COPY_RELOCS
	  || info->nocopyreloc
	  || SYMBOL_NO_COPYRELOC (info, eh))
	{
	  /* NB: needs_copy is always 0 for i386.  */
	  h->non_got_ref = def->non_got_ref;
	  eh->needs_copy = def->needs_copy;
	}
      return true;
    }

  /* This is a reference to a symbol defined by a dynamic object which
     is not a function.  */

  /* If we are creating a shared library, we must presume that the
     only references to the symbol are via the global offset table.
     For such cases we need not do anything here; the relocations will
     be handled correctly by relocate_section.  */
  if (!bfd_link_executable (info))
    return true;

  /* If there are no references to this symbol that do not use the
     GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
     reloc.  NB: gotoff_ref is always 0 for x86-64.  */
  if (!h->non_got_ref && !eh->gotoff_ref)
    return true;

  /* If -z nocopyreloc was given, we won't generate them either.  */
  if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
    {
      h->non_got_ref = 0;
      return true;
    }

  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return false;

  /* If there aren't any dynamic relocs in read-only sections nor
     R_386_GOTOFF relocation, then we can keep the dynamic relocs and
     avoid the copy reloc.  This doesn't work on VxWorks, where we can
     not have dynamic relocations (other than copy and jump slot
     relocations) in an executable.  */
  if (ELIMINATE_COPY_RELOCS
      && (bed->target_id == X86_64_ELF_DATA
	  || (!eh->gotoff_ref
	      && htab->elf.target_os != is_vxworks)))
    {
      /* If we don't find any dynamic relocs in read-only sections,
	 then we'll be keeping the dynamic relocs and avoiding the copy
	 reloc.  */
      if (!_bfd_elf_readonly_dynrelocs (h))
	{
	  h->non_got_ref = 0;
	  return true;
	}
    }

  /* We must allocate the symbol in our .dynbss section, which will
     become part of the .bss section of the executable.  There will be
     an entry for this symbol in the .dynsym section.  The dynamic
     object will contain position independent code, so all references
     from the dynamic object to this symbol will go through the global
     offset table.  The dynamic linker will use the .dynsym entry to
     determine the address it must put in the global offset table, so
     both the dynamic object and the regular object will refer to the
     same memory location for the variable.  */

  /* We must generate a R_386_COPY/R_X86_64_COPY reloc to tell the
     dynamic linker to copy the initial value out of the dynamic object
     and into the runtime process image.  */
  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
    {
      s = htab->elf.sdynrelro;
      srel = htab->elf.sreldynrelro;
    }
  else
    {
      s = htab->elf.sdynbss;
      srel = htab->elf.srelbss;
    }
  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
    {
      srel->size += htab->sizeof_reloc;
      h->needs_copy = 1;
    }

  return _bfd_elf_adjust_dynamic_copy (info, h, s);
}

void
_bfd_x86_elf_hide_symbol (struct bfd_link_info *info,
			  struct elf_link_hash_entry *h,
			  bool force_local)
{
  if (h->root.type == bfd_link_hash_undefweak
      && info->nointerp
      && bfd_link_pie (info))
    {
      /* When there is no dynamic interpreter in PIE, make the undefined
	 weak symbol dynamic so that PC relative branch to the undefined
	 weak symbol will land to address 0.  */
      struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
      if (h->plt.refcount > 0
	  || eh->plt_got.refcount > 0)
	return;
    }

  _bfd_elf_link_hash_hide_symbol (info, h, force_local);
}

/* Return TRUE if a symbol is referenced locally.  It is similar to
   SYMBOL_REFERENCES_LOCAL, but it also checks version script.  It
   works in check_relocs.  */

bool
_bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
					   struct elf_link_hash_entry *h)
{
  struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
  struct elf_x86_link_hash_table *htab
    = (struct elf_x86_link_hash_table *) info->hash;

  if (eh->local_ref > 1)
    return true;

  if (eh->local_ref == 1)
    return false;

  /* Unversioned symbols defined in regular objects can be forced local
     by linker version script.  A weak undefined symbol is forced local
     if
     1. It has non-default visibility.  Or
     2. When building executable, there is no dynamic linker.  Or
     3. or "-z nodynamic-undefined-weak" is used.
   */
  if (SYMBOL_REFERENCES_LOCAL (info, h)
      || (h->root.type == bfd_link_hash_undefweak
	  && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
	      || (bfd_link_executable (info)
		  && htab->interp == NULL)
	      || info->dynamic_undefined_weak == 0))
      || ((h->def_regular || ELF_COMMON_DEF_P (h))
	  && info->version_info != NULL
	  && _bfd_elf_link_hide_sym_by_version (info, h)))
    {
      eh->local_ref = 2;
      return true;
    }

  eh->local_ref = 1;
  return false;
}

/* Return the section that should be marked against GC for a given
   relocation.	*/

asection *
_bfd_x86_elf_gc_mark_hook (asection *sec,
			   struct bfd_link_info *info,
			   Elf_Internal_Rela *rel,
			   struct elf_link_hash_entry *h,
			   Elf_Internal_Sym *sym)
{
  /* Compiler should optimize this out.  */
  if (((unsigned int) R_X86_64_GNU_VTINHERIT
       != (unsigned int) R_386_GNU_VTINHERIT)
      || ((unsigned int) R_X86_64_GNU_VTENTRY
	  != (unsigned int) R_386_GNU_VTENTRY))
    abort ();

  if (h != NULL)
    switch (ELF32_R_TYPE (rel->r_info))
      {
      case R_X86_64_GNU_VTINHERIT:
      case R_X86_64_GNU_VTENTRY:
	return NULL;
      }

  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
}

static bfd_vma
elf_i386_get_plt_got_vma (struct elf_x86_plt *plt_p ATTRIBUTE_UNUSED,
			  bfd_vma off,
			  bfd_vma offset ATTRIBUTE_UNUSED,
			  bfd_vma got_addr)
{
  return got_addr + off;
}

static bfd_vma
elf_x86_64_get_plt_got_vma (struct elf_x86_plt *plt_p,
			    bfd_vma off,
			    bfd_vma offset,
			    bfd_vma got_addr ATTRIBUTE_UNUSED)
{
  return plt_p->sec->vma + offset + off + plt_p->plt_got_insn_size;
}

static bool
elf_i386_valid_plt_reloc_p (unsigned int type)
{
  return (type == R_386_JUMP_SLOT
	  || type == R_386_GLOB_DAT
	  || type == R_386_IRELATIVE);
}

static bool
elf_x86_64_valid_plt_reloc_p (unsigned int type)
{
  return (type == R_X86_64_JUMP_SLOT
	  || type == R_X86_64_GLOB_DAT
	  || type == R_X86_64_IRELATIVE);
}

long
_bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
				   long count,
				   long relsize,
				   bfd_vma got_addr,
				   struct elf_x86_plt plts[],
				   asymbol **dynsyms,
				   asymbol **ret)
{
  long size, i, n, len;
  int j;
  unsigned int plt_got_offset, plt_entry_size;
  asymbol *s;
  bfd_byte *plt_contents;
  long dynrelcount;
  arelent **dynrelbuf, *p;
  char *names;
  const struct elf_backend_data *bed;
  bfd_vma (*get_plt_got_vma) (struct elf_x86_plt *, bfd_vma, bfd_vma,
			      bfd_vma);
  bool (*valid_plt_reloc_p) (unsigned int);

  dynrelbuf = NULL;
  if (count == 0)
    goto bad_return;

  dynrelbuf = (arelent **) bfd_malloc (relsize);
  if (dynrelbuf == NULL)
    goto bad_return;

  dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf,
						dynsyms);
  if (dynrelcount <= 0)
    goto bad_return;

  /* Sort the relocs by address.  */
  qsort (dynrelbuf, dynrelcount, sizeof (arelent *),
	 _bfd_x86_elf_compare_relocs);

  size = count * sizeof (asymbol);

  /* Allocate space for @plt suffixes.  */
  n = 0;
  for (i = 0; i < dynrelcount; i++)
    {
      p = dynrelbuf[i];
      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
      if (p->addend != 0)
	size += sizeof ("+0x") - 1 + 8 + 8 * ABI_64_P (abfd);
    }

  s = *ret = (asymbol *) bfd_zmalloc (size);
  if (s == NULL)
    goto bad_return;

  bed = get_elf_backend_data (abfd);

  if (bed->target_id == X86_64_ELF_DATA)
    {
      get_plt_got_vma = elf_x86_64_get_plt_got_vma;
      valid_plt_reloc_p = elf_x86_64_valid_plt_reloc_p;
    }
  else
    {
      get_plt_got_vma = elf_i386_get_plt_got_vma;
      valid_plt_reloc_p = elf_i386_valid_plt_reloc_p;
      if (got_addr)
	{
	  /* Check .got.plt and then .got to get the _GLOBAL_OFFSET_TABLE_
	     address.  */
	  asection *sec = bfd_get_section_by_name (abfd, ".got.plt");
	  if (sec != NULL)
	    got_addr = sec->vma;
	  else
	    {
	      sec = bfd_get_section_by_name (abfd, ".got");
	      if (sec != NULL)
		got_addr = sec->vma;
	    }

	  if (got_addr == (bfd_vma) -1)
	    goto bad_return;
	}
    }

  /* Check for each PLT section.  */
  names = (char *) (s + count);
  size = 0;
  n = 0;
  for (j = 0; plts[j].name != NULL; j++)
    if ((plt_contents = plts[j].contents) != NULL)
      {
	long k;
	bfd_vma offset;
	asection *plt;
	struct elf_x86_plt *plt_p = &plts[j];

	plt_got_offset = plt_p->plt_got_offset;
	plt_entry_size = plt_p->plt_entry_size;

	plt = plt_p->sec;

	if ((plt_p->type & plt_lazy))
	  {
	    /* Skip PLT0 in lazy PLT.  */
	    k = 1;
	    offset = plt_entry_size;
	  }
	else
	  {
	    k = 0;
	    offset = 0;
	  }

	/* Check each PLT entry against dynamic relocations.  */
	for (; k < plt_p->count; k++)
	  {
	    int off;
	    bfd_vma got_vma;
	    long min, max, mid;

	    /* Get the GOT offset for i386 or the PC-relative offset
	       for x86-64, a signed 32-bit integer.  */
	    off = H_GET_32 (abfd, (plt_contents + offset
				   + plt_got_offset));
	    got_vma = get_plt_got_vma (plt_p, off, offset, got_addr);

	    /* Binary search.  */
	    p = dynrelbuf[0];
	    min = 0;
	    max = dynrelcount;
	    while ((min + 1) < max)
	      {
		arelent *r;

		mid = (min + max) / 2;
		r = dynrelbuf[mid];
		if (got_vma > r->address)
		  min = mid;
		else if (got_vma < r->address)
		  max = mid;
		else
		  {
		    p = r;
		    break;
		  }
	      }

	    /* Skip unknown relocation.  PR 17512: file: bc9d6cf5.  */
	    if (got_vma == p->address
		&& p->howto != NULL
		&& valid_plt_reloc_p (p->howto->type))
	      {
		*s = **p->sym_ptr_ptr;
		/* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL
		   set.  Since we are defining a symbol, ensure one
		   of them is set.  */
		if ((s->flags & BSF_LOCAL) == 0)
		  s->flags |= BSF_GLOBAL;
		s->flags |= BSF_SYNTHETIC;
		/* This is no longer a section symbol.  */
		s->flags &= ~BSF_SECTION_SYM;
		s->section = plt;
		s->the_bfd = plt->owner;
		s->value = offset;
		s->udata.p = NULL;
		s->name = names;
		len = strlen ((*p->sym_ptr_ptr)->name);
		memcpy (names, (*p->sym_ptr_ptr)->name, len);
		names += len;
		if (p->addend != 0)
		  {
		    char buf[30], *a;

		    memcpy (names, "+0x", sizeof ("+0x") - 1);
		    names += sizeof ("+0x") - 1;
		    bfd_sprintf_vma (abfd, buf, p->addend);
		    for (a = buf; *a == '0'; ++a)
		      ;
		    size = strlen (a);
		    memcpy (names, a, size);
		    names += size;
		  }
		memcpy (names, "@plt", sizeof ("@plt"));
		names += sizeof ("@plt");
		n++;
		s++;
		/* There should be only one entry in PLT for a given
		   symbol.  Set howto to NULL after processing a PLT
		   entry to guard against corrupted PLT.  */
		p->howto = NULL;
	      }
	    offset += plt_entry_size;
	  }
      }

  /* PLT entries with R_386_TLS_DESC relocations are skipped.  */
  if (n == 0)
    {
    bad_return:
      count = -1;
    }
  else
    count = n;

  for (j = 0; plts[j].name != NULL; j++)
    free (plts[j].contents);

  free (dynrelbuf);

  return count;
}

/* Parse x86 GNU properties.  */

enum elf_property_kind
_bfd_x86_elf_parse_gnu_properties (bfd *abfd, unsigned int type,
				   bfd_byte *ptr, unsigned int datasz)
{
  elf_property *prop;

  if (type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED
      || type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED
      || (type >= GNU_PROPERTY_X86_UINT32_AND_LO
	  && type <= GNU_PROPERTY_X86_UINT32_AND_HI)
      || (type >= GNU_PROPERTY_X86_UINT32_OR_LO
	  && type <= GNU_PROPERTY_X86_UINT32_OR_HI)
      || (type >= GNU_PROPERTY_X86_UINT32_OR_AND_LO
	  && type <= GNU_PROPERTY_X86_UINT32_OR_AND_HI))
    {
      if (datasz != 4)
	{
	  _bfd_error_handler
	    (_("error: %pB: <corrupt x86 property (0x%x) size: 0x%x>"),
	     abfd, type, datasz);
	  return property_corrupt;
	}
      prop = _bfd_elf_get_property (abfd, type, datasz);
      prop->u.number |= bfd_h_get_32 (abfd, ptr);
      prop->pr_kind = property_number;
      return property_number;
    }

  return property_ignored;
}

/* Merge x86 GNU property BPROP with APROP.  If APROP isn't NULL,
   return TRUE if APROP is updated.  Otherwise, return TRUE if BPROP
   should be merged with ABFD.  */

bool
_bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info,
				   bfd *abfd ATTRIBUTE_UNUSED,
				   bfd *bbfd ATTRIBUTE_UNUSED,
				   elf_property *aprop,
				   elf_property *bprop)
{
  unsigned int number, features;
  bool updated = false;
  const struct elf_backend_data *bed;
  struct elf_x86_link_hash_table *htab;
  unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;

  if (pr_type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED
      || (pr_type >= GNU_PROPERTY_X86_UINT32_OR_AND_LO
	  && pr_type <= GNU_PROPERTY_X86_UINT32_OR_AND_HI))
    {
      if (aprop == NULL || bprop == NULL)
	{
	  /* Only one of APROP and BPROP can be NULL.  */
	  if (aprop != NULL)
	    {
	      /* Remove this property since the other input file doesn't
		 have it.  */
	      aprop->pr_kind = property_remove;
	      updated = true;
	    }
	}
      else
	{
	  number = aprop->u.number;
	  aprop->u.number = number | bprop->u.number;
	  updated = number != (unsigned int) aprop->u.number;
	}
      return updated;
    }
  else if (pr_type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED
	   || (pr_type >= GNU_PROPERTY_X86_UINT32_OR_LO
	       && pr_type <= GNU_PROPERTY_X86_UINT32_OR_HI))
    {
      features = 0;
      if (pr_type == GNU_PROPERTY_X86_ISA_1_NEEDED)
	{
	  bed = get_elf_backend_data (info->output_bfd);
	  htab = elf_x86_hash_table (info, bed->target_id);
	  switch (htab->params->isa_level)
	    {
	    case 0:
	      break;
	    case 2:
	      features = GNU_PROPERTY_X86_ISA_1_V2;
	      break;
	    case 3:
	      features = GNU_PROPERTY_X86_ISA_1_V3;
	      break;
	    case 4:
	      features = GNU_PROPERTY_X86_ISA_1_V4;
	      break;
	    default:
	      abort ();
	    }
	}
      if (aprop != NULL && bprop != NULL)
	{
	  number = aprop->u.number;
	  aprop->u.number = number | bprop->u.number | features;
	  /* Remove the property if all bits are empty.  */
	  if (aprop->u.number == 0)
	    {
	      aprop->pr_kind = property_remove;
	      updated = true;
	    }
	  else
	    updated = number != (unsigned int) aprop->u.number;
	}
      else
	{
	  /* Only one of APROP and BPROP can be NULL.  */
	  if (aprop != NULL)
	    {
	      aprop->u.number |= features;
	      if (aprop->u.number == 0)
		{
		  /* Remove APROP if all bits are empty.  */
		  aprop->pr_kind = property_remove;
		  updated = true;
		}
	    }
	  else
	    {
	      /* Return TRUE if APROP is NULL and all bits of BPROP
		 aren't empty to indicate that BPROP should be added
		 to ABFD.  */
	      bprop->u.number |= features;
	      updated = bprop->u.number != 0;
	    }
	}
      return updated;
    }
  else if (pr_type >= GNU_PROPERTY_X86_UINT32_AND_LO
	   && pr_type <= GNU_PROPERTY_X86_UINT32_AND_HI)
    {
      /* Only one of APROP and BPROP can be NULL:
	 1. APROP & BPROP when both APROP and BPROP aren't NULL.
	 2. If APROP is NULL, remove x86 feature.
	 3. Otherwise, do nothing.
       */
      bed = get_elf_backend_data (info->output_bfd);
      htab = elf_x86_hash_table (info, bed->target_id);
      if (!htab)
	abort ();
      if (aprop != NULL && bprop != NULL)
	{
	  number = aprop->u.number;
	  aprop->u.number = number & bprop->u.number;
	  if (pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
	    {
	      features = 0;
	      if (htab->params->ibt)
		features = GNU_PROPERTY_X86_FEATURE_1_IBT;
	      if (htab->params->shstk)
		features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
	      if (htab->params->lam_u48)
		features |= (GNU_PROPERTY_X86_FEATURE_1_LAM_U48
			     | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
	      else if (htab->params->lam_u57)
		features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
	      /* Add GNU_PROPERTY_X86_FEATURE_1_IBT,
		 GNU_PROPERTY_X86_FEATURE_1_SHSTK,
		 GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and
		 GNU_PROPERTY_X86_FEATURE_1_LAM_U57.  */
	      aprop->u.number |= features;
	    }
	  updated = number != (unsigned int) aprop->u.number;
	  /* Remove the property if all feature bits are cleared.  */
	  if (aprop->u.number == 0)
	    aprop->pr_kind = property_remove;
	}
      else
	{
	  /* There should be no AND properties since some input doesn't
	     have them.  Set IBT and SHSTK properties for -z ibt and -z
	     shstk if needed.  */
	  features = 0;
	  if (pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
	    {
	      if (htab->params->ibt)
		features = GNU_PROPERTY_X86_FEATURE_1_IBT;
	      if (htab->params->shstk)
		features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
	      if (htab->params->lam_u48)
		features |= (GNU_PROPERTY_X86_FEATURE_1_LAM_U48
			     | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
	      else if (htab->params->lam_u57)
		features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
	    }
	  if (features)
	    {
	      if (aprop != NULL)
		{
		  updated = features != (unsigned int) aprop->u.number;
		  aprop->u.number = features;
		}
	      else
		{
		  updated = true;
		  bprop->u.number = features;
		}
	    }
	  else if (aprop != NULL)
	    {
	      aprop->pr_kind = property_remove;
	      updated = true;
	    }
	}
      return updated;
    }
  else
    {
      /* Never should happen.  */
      abort ();
    }

  return updated;
}

/* Set up x86 GNU properties.  Return the first relocatable ELF input
   with GNU properties if found.  Otherwise, return NULL.  */

bfd *
_bfd_x86_elf_link_setup_gnu_properties
  (struct bfd_link_info *info, struct elf_x86_init_table *init_table)
{
  bool normal_target;
  bool lazy_plt;
  asection *sec, *pltsec;
  bfd *dynobj;
  bool use_ibt_plt;
  unsigned int plt_alignment, features, isa_level;
  struct elf_x86_link_hash_table *htab;
  bfd *pbfd;
  bfd *ebfd = NULL;
  elf_property *prop;
  const struct elf_backend_data *bed;
  unsigned int class_align = ABI_64_P (info->output_bfd) ? 3 : 2;
  unsigned int got_align;

  /* Find a normal input file with GNU property note.  */
  for (pbfd = info->input_bfds;
       pbfd != NULL;
       pbfd = pbfd->link.next)
    if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
	&& bfd_count_sections (pbfd) != 0)
      {
	ebfd = pbfd;

	if (elf_properties (pbfd) != NULL)
	  break;
      }

  bed = get_elf_backend_data (info->output_bfd);

  htab = elf_x86_hash_table (info, bed->target_id);
  if (htab == NULL)
    return pbfd;

  features = 0;
  if (htab->params->ibt)
    {
      features = GNU_PROPERTY_X86_FEATURE_1_IBT;
      htab->params->cet_report &= ~prop_report_ibt;
    }
  if (htab->params->shstk)
    {
      features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
      htab->params->cet_report &= ~prop_report_shstk;
    }
  if (!(htab->params->cet_report & (prop_report_ibt | prop_report_shstk)))
    htab->params->cet_report = prop_report_none;
  if (htab->params->lam_u48)
    {
      features |= (GNU_PROPERTY_X86_FEATURE_1_LAM_U48
		   | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
      htab->params->lam_u48_report = prop_report_none;
      htab->params->lam_u57_report = prop_report_none;
    }
  else if (htab->params->lam_u57)
    {
      features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
      htab->params->lam_u57_report = prop_report_none;
    }

  switch (htab->params->isa_level)
    {
    case 0:
      isa_level = 0;
      break;
    case 1:
      isa_level = GNU_PROPERTY_X86_ISA_1_BASELINE;
      break;
    case 2:
      isa_level = GNU_PROPERTY_X86_ISA_1_V2;
      break;
    case 3:
      isa_level = GNU_PROPERTY_X86_ISA_1_V3;
      break;
    case 4:
      isa_level = GNU_PROPERTY_X86_ISA_1_V4;
      break;
    default:
      abort ();
    }

  if (ebfd != NULL)
    {
      prop = NULL;
      if (features)
	{
	  /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT,
	     GNU_PROPERTY_X86_FEATURE_1_SHSTK,
	     GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and
	     GNU_PROPERTY_X86_FEATURE_1_LAM_U57.  */
	  prop = _bfd_elf_get_property (ebfd,
					GNU_PROPERTY_X86_FEATURE_1_AND,
					4);
	  prop->u.number |= features;
	  prop->pr_kind = property_number;
	}

      if (isa_level)
	{
	  /* If ISA level is set, add GNU_PROPERTY_X86_ISA_1_NEEDED.  */
	  prop = _bfd_elf_get_property (ebfd,
					GNU_PROPERTY_X86_ISA_1_NEEDED,
					4);
	  prop->u.number |= isa_level;
	  prop->pr_kind = property_number;
	}

      /* Create the GNU property note section if needed.  */
      if (prop != NULL && pbfd == NULL)
	{
	  sec = bfd_make_section_with_flags (ebfd,
					     NOTE_GNU_PROPERTY_SECTION_NAME,
					     (SEC_ALLOC
					      | SEC_LOAD
					      | SEC_IN_MEMORY
					      | SEC_READONLY
					      | SEC_HAS_CONTENTS
					      | SEC_DATA));
	  if (sec == NULL)
	    info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));

	  if (!bfd_set_section_alignment (sec, class_align))
	    {
	    error_alignment:
	      info->callbacks->einfo (_("%F%pA: failed to align section\n"),
				      sec);
	    }

	  elf_section_type (sec) = SHT_NOTE;
	}
    }

  if (htab->params->cet_report
      || htab->params->lam_u48_report
      || htab->params->lam_u57_report)
    {
      /* Report missing IBT, SHSTK and LAM properties.  */
      bfd *abfd;
      const char *warning_msg = _("%P: %pB: warning: missing %s\n");
      const char *error_msg = _("%X%P: %pB: error: missing %s\n");
      const char *cet_msg = NULL;
      const char *lam_u48_msg = NULL;
      const char *lam_u57_msg = NULL;
      const char *missing;
      elf_property_list *p;
      bool missing_ibt, missing_shstk;
      bool missing_lam_u48, missing_lam_u57;
      bool check_ibt
	= (htab->params->cet_report
	   && (htab->params->cet_report & prop_report_ibt));
      bool check_shstk
	= (htab->params->cet_report
	   && (htab->params->cet_report & prop_report_shstk));

      if (htab->params->cet_report)
	{
	  if ((htab->params->cet_report & prop_report_warning))
	    cet_msg = warning_msg;
	  else
	    cet_msg = error_msg;
	}
      if (htab->params->lam_u48_report)
	{
	  if ((htab->params->lam_u48_report & prop_report_warning))
	    lam_u48_msg = warning_msg;
	  else
	    lam_u48_msg = error_msg;
	}
      if (htab->params->lam_u57_report)
	{
	  if ((htab->params->lam_u57_report & prop_report_warning))
	    lam_u57_msg = warning_msg;
	  else
	    lam_u57_msg = error_msg;
	}

      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
	if (!(abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED))
	    && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
	  {
	    for (p = elf_properties (abfd); p; p = p->next)
	      if (p->property.pr_type == GNU_PROPERTY_X86_FEATURE_1_AND)
		break;

	    missing_ibt = check_ibt;
	    missing_shstk = check_shstk;
	    missing_lam_u48 = !!lam_u48_msg;
	    missing_lam_u57 = !!lam_u57_msg;
	    if (p)
	      {
		missing_ibt &= !(p->property.u.number
				 & GNU_PROPERTY_X86_FEATURE_1_IBT);
		missing_shstk &= !(p->property.u.number
				   & GNU_PROPERTY_X86_FEATURE_1_SHSTK);
		missing_lam_u48 &= !(p->property.u.number
				     & GNU_PROPERTY_X86_FEATURE_1_LAM_U48);
		missing_lam_u57 &= !(p->property.u.number
				     & GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
	      }
	    if (missing_ibt || missing_shstk)
	      {
		if (missing_ibt && missing_shstk)
		  missing = _("IBT and SHSTK properties");
		else if (missing_ibt)
		  missing = _("IBT property");
		else
		  missing = _("SHSTK property");
		info->callbacks->einfo (cet_msg, abfd, missing);
	      }
	    if (missing_lam_u48)
	      {
		missing = _("LAM_U48 property");
		info->callbacks->einfo (lam_u48_msg, abfd, missing);
	      }
	    if (missing_lam_u57)
	      {
		missing = _("LAM_U57 property");
		info->callbacks->einfo (lam_u57_msg, abfd, missing);
	      }
	  }
    }

  pbfd = _bfd_elf_link_setup_gnu_properties (info);

  htab->r_info = init_table->r_info;
  htab->r_sym = init_table->r_sym;

  if (bfd_link_relocatable (info))
    return pbfd;

  htab->plt0_pad_byte = init_table->plt0_pad_byte;

  use_ibt_plt = htab->params->ibtplt || htab->params->ibt;
  if (!use_ibt_plt && pbfd != NULL)
    {
      /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on.  */
      elf_property_list *p;

      /* The property list is sorted in order of type.  */
      for (p = elf_properties (pbfd); p; p = p->next)
	{
	  if (GNU_PROPERTY_X86_FEATURE_1_AND == p->property.pr_type)
	    {
	      use_ibt_plt = !!(p->property.u.number
			       & GNU_PROPERTY_X86_FEATURE_1_IBT);
	      break;
	    }
	  else if (GNU_PROPERTY_X86_FEATURE_1_AND < p->property.pr_type)
	    break;
	}
    }

  dynobj = htab->elf.dynobj;

  /* Set htab->elf.dynobj here so that there is no need to check and
     set it in check_relocs.  */
  if (dynobj == NULL)
    {
      if (pbfd != NULL)
	{
	  htab->elf.dynobj = pbfd;
	  dynobj = pbfd;
	}
      else
	{
	  bfd *abfd;

	  /* Find a normal input file to hold linker created
	     sections.  */
	  for (abfd = info->input_bfds;
	       abfd != NULL;
	       abfd = abfd->link.next)
	    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
		&& (abfd->flags
		    & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0
		&& bed->relocs_compatible (abfd->xvec,
					   info->output_bfd->xvec))
	      {
		htab->elf.dynobj = abfd;
		dynobj = abfd;
		break;
	      }
	}
    }

  /* Return if there are no normal input files.  */
  if (dynobj == NULL)
    return pbfd;

  /* Even when lazy binding is disabled by "-z now", the PLT0 entry may
     still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for
     canonical function address.  */
  htab->plt.has_plt0 = 1;
  normal_target = htab->elf.target_os == is_normal;

  if (normal_target)
    {
      if (use_ibt_plt)
	{
	  htab->lazy_plt = init_table->lazy_ibt_plt;
	  htab->non_lazy_plt = init_table->non_lazy_ibt_plt;
	}
      else
	{
	  htab->lazy_plt = init_table->lazy_plt;
	  htab->non_lazy_plt = init_table->non_lazy_plt;
	}
    }
  else
    {
      htab->lazy_plt = init_table->lazy_plt;
      htab->non_lazy_plt = NULL;
    }

  pltsec = htab->elf.splt;

  /* If the non-lazy PLT is available, use it for all PLT entries if
     there are no PLT0 or no .plt section.  */
  if (htab->non_lazy_plt != NULL
      && (!htab->plt.has_plt0 || pltsec == NULL))
    {
      lazy_plt = false;
      if (bfd_link_pic (info))
	htab->plt.plt_entry = htab->non_lazy_plt->pic_plt_entry;
      else
	htab->plt.plt_entry = htab->non_lazy_plt->plt_entry;
      htab->plt.plt_entry_size = htab->non_lazy_plt->plt_entry_size;
      htab->plt.plt_got_offset = htab->non_lazy_plt->plt_got_offset;
      htab->plt.plt_got_insn_size
	= htab->non_lazy_plt->plt_got_insn_size;
      htab->plt.eh_frame_plt_size
	= htab->non_lazy_plt->eh_frame_plt_size;
      htab->plt.eh_frame_plt = htab->non_lazy_plt->eh_frame_plt;
    }
  else
    {
      lazy_plt = true;
      if (bfd_link_pic (info))
	{
	  htab->plt.plt0_entry = htab->lazy_plt->pic_plt0_entry;
	  htab->plt.plt_entry = htab->lazy_plt->pic_plt_entry;
	}
      else
	{
	  htab->plt.plt0_entry = htab->lazy_plt->plt0_entry;
	  htab->plt.plt_entry = htab->lazy_plt->plt_entry;
	}
      htab->plt.plt_entry_size = htab->lazy_plt->plt_entry_size;
      htab->plt.plt_got_offset = htab->lazy_plt->plt_got_offset;
      htab->plt.plt_got_insn_size
	= htab->lazy_plt->plt_got_insn_size;
      htab->plt.eh_frame_plt_size
	= htab->lazy_plt->eh_frame_plt_size;
      htab->plt.eh_frame_plt = htab->lazy_plt->eh_frame_plt;
    }

  if (htab->elf.target_os == is_vxworks
      && !elf_vxworks_create_dynamic_sections (dynobj, info,
					       &htab->srelplt2))
    {
      info->callbacks->einfo (_("%F%P: failed to create VxWorks dynamic sections\n"));
      return pbfd;
    }

  /* Since create_dynamic_sections isn't always called, but GOT
     relocations need GOT relocations, create them here so that we
     don't need to do it in check_relocs.  */
  if (htab->elf.sgot == NULL
      && !_bfd_elf_create_got_section (dynobj, info))
    info->callbacks->einfo (_("%F%P: failed to create GOT sections\n"));

  got_align = (bed->target_id == X86_64_ELF_DATA) ? 3 : 2;

  /* Align .got and .got.plt sections to their entry size.  Do it here
     instead of in create_dynamic_sections so that they are always
     properly aligned even if create_dynamic_sections isn't called.  */
  sec = htab->elf.sgot;
  if (!bfd_set_section_alignment (sec, got_align))
    goto error_alignment;

  sec = htab->elf.sgotplt;
  if (!bfd_set_section_alignment (sec, got_align))
    goto error_alignment;

  /* Create the ifunc sections here so that check_relocs can be
     simplified.  */
  if (!_bfd_elf_create_ifunc_sections (dynobj, info))
    info->callbacks->einfo (_("%F%P: failed to create ifunc sections\n"));

  plt_alignment = bfd_log2 (htab->plt.plt_entry_size);

  if (pltsec != NULL)
    {
      /* Whe creating executable, set the contents of the .interp
	 section to the interpreter.  */
      if (bfd_link_executable (info) && !info->nointerp)
	{
	  asection *s = bfd_get_linker_section (dynobj, ".interp");
	  if (s == NULL)
	    abort ();
	  s->size = htab->dynamic_interpreter_size;
	  s->contents = (unsigned char *) htab->dynamic_interpreter;
	  htab->interp = s;
	}

      if (normal_target)
	{
	  flagword pltflags = (bed->dynamic_sec_flags
			       | SEC_ALLOC
			       | SEC_CODE
			       | SEC_LOAD
			       | SEC_READONLY);
	  unsigned int non_lazy_plt_alignment
	    = bfd_log2 (htab->non_lazy_plt->plt_entry_size);

	  sec = pltsec;
	  if (!bfd_set_section_alignment (sec, plt_alignment))
	    goto error_alignment;

	  /* Create the GOT procedure linkage table.  */
	  sec = bfd_make_section_anyway_with_flags (dynobj,
						    ".plt.got",
						    pltflags);
	  if (sec == NULL)
	    info->callbacks->einfo (_("%F%P: failed to create GOT PLT section\n"));

	  if (!bfd_set_section_alignment (sec, non_lazy_plt_alignment))
	    goto error_alignment;

	  htab->plt_got = sec;

	  if (lazy_plt)
	    {
	      sec = NULL;

	      if (use_ibt_plt)
		{
		  /* Create the second PLT for Intel IBT support.  IBT
		     PLT is needed only for lazy binding.  */
		  sec = bfd_make_section_anyway_with_flags (dynobj,
							    ".plt.sec",
							    pltflags);
		  if (sec == NULL)
		    info->callbacks->einfo (_("%F%P: failed to create IBT-enabled PLT section\n"));

		  if (!bfd_set_section_alignment (sec, plt_alignment))
		    goto error_alignment;
		}
	      else if (htab->params->bndplt && ABI_64_P (dynobj))
		{
		  /* Create the second PLT for Intel MPX support.  MPX
		     PLT is supported only in 64-bit mode and is needed
		     only for lazy binding.  */
		  sec = bfd_make_section_anyway_with_flags (dynobj,
							    ".plt.sec",
							    pltflags);
		  if (sec == NULL)
		    info->callbacks->einfo (_("%F%P: failed to create BND PLT section\n"));

		  if (!bfd_set_section_alignment (sec, non_lazy_plt_alignment))
		    goto error_alignment;
		}

	      htab->plt_second = sec;
	    }
	}

      if (!info->no_ld_generated_unwind_info)
	{
	  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
			    | SEC_HAS_CONTENTS | SEC_IN_MEMORY
			    | SEC_LINKER_CREATED);

	  sec = bfd_make_section_anyway_with_flags (dynobj,
						    ".eh_frame",
						    flags);
	  if (sec == NULL)
	    info->callbacks->einfo (_("%F%P: failed to create PLT .eh_frame section\n"));

	  if (!bfd_set_section_alignment (sec, class_align))
	    goto error_alignment;

	  htab->plt_eh_frame = sec;

	  if (htab->plt_got != NULL)
	    {
	      sec = bfd_make_section_anyway_with_flags (dynobj,
							".eh_frame",
							flags);
	      if (sec == NULL)
		info->callbacks->einfo (_("%F%P: failed to create GOT PLT .eh_frame section\n"));

	      if (!bfd_set_section_alignment (sec, class_align))
		goto error_alignment;

	      htab->plt_got_eh_frame = sec;
	    }

	  if (htab->plt_second != NULL)
	    {
	      sec = bfd_make_section_anyway_with_flags (dynobj,
							".eh_frame",
							flags);
	      if (sec == NULL)
		info->callbacks->einfo (_("%F%P: failed to create the second PLT .eh_frame section\n"));

	      if (!bfd_set_section_alignment (sec, class_align))
		goto error_alignment;

	      htab->plt_second_eh_frame = sec;
	    }
	}
    }

  /* The .iplt section is used for IFUNC symbols in static
     executables.  */
  sec = htab->elf.iplt;
  if (sec != NULL)
    {
      /* NB: Delay setting its alignment until we know it is non-empty.
	 Otherwise an empty iplt section may change vma and lma of the
	 following sections, which triggers moving dot of the following
	 section backwards, resulting in a warning and section lma not
	 being set properly.  It later leads to a "File truncated"
	 error.  */
      if (!bfd_set_section_alignment (sec, 0))
	goto error_alignment;

      htab->plt.iplt_alignment = (normal_target
				  ? plt_alignment
				  : bed->plt_alignment);
    }

  if (bfd_link_executable (info)
      && !info->nointerp
      && !htab->params->has_dynamic_linker
      && htab->params->static_before_all_inputs)
    {
      /* Report error for dynamic input objects if -static is passed at
	 command-line before all input files without --dynamic-linker
	 unless --no-dynamic-linker is used.  */
      bfd *abfd;

      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
	if ((abfd->flags & DYNAMIC))
	  info->callbacks->einfo
	    (_("%X%P: attempted static link of dynamic object `%pB'\n"),
	     abfd);
    }

  return pbfd;
}

/* Fix up x86 GNU properties.  */

void
_bfd_x86_elf_link_fixup_gnu_properties
  (struct bfd_link_info *info, elf_property_list **listp)
{
  elf_property_list *p;

  for (p = *listp; p; p = p->next)
    {
      unsigned int type = p->property.pr_type;
      if (type == GNU_PROPERTY_X86_COMPAT_ISA_1_USED
	  || type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED
	  || (type >= GNU_PROPERTY_X86_UINT32_AND_LO
	      && type <= GNU_PROPERTY_X86_UINT32_AND_HI)
	  || (type >= GNU_PROPERTY_X86_UINT32_OR_LO
	      && type <= GNU_PROPERTY_X86_UINT32_OR_HI)
	  || (type >= GNU_PROPERTY_X86_UINT32_OR_AND_LO
	      && type <= GNU_PROPERTY_X86_UINT32_OR_AND_HI))
	{
	  if (p->property.u.number == 0
	      && (type == GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED
		  || (type >= GNU_PROPERTY_X86_UINT32_AND_LO
		      && type <= GNU_PROPERTY_X86_UINT32_AND_HI)
		  || (type >= GNU_PROPERTY_X86_UINT32_OR_LO
		      && type <= GNU_PROPERTY_X86_UINT32_OR_HI)))
	    {
	      /* Remove empty property.  */
	      *listp = p->next;
	      continue;
	    }

	  /* Keep LAM features only for 64-bit output.  */
	  if (type == GNU_PROPERTY_X86_FEATURE_1_AND
	      && !ABI_64_P (info->output_bfd))
	    p->property.u.number &= ~(GNU_PROPERTY_X86_FEATURE_1_LAM_U48
				      | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);

	  listp = &p->next;
	}
      else if (type > GNU_PROPERTY_HIPROC)
	{
	  /* The property list is sorted in order of type.  */
	  break;
	}
    }
}

void
_bfd_elf_linker_x86_set_options (struct bfd_link_info * info,
				 struct elf_linker_x86_params *params)
{
  const struct elf_backend_data *bed
    = get_elf_backend_data (info->output_bfd);
  struct elf_x86_link_hash_table *htab
    = elf_x86_hash_table (info, bed->target_id);
  if (htab != NULL)
    htab->params = params;
}
