x86: Add _bfd_x86_elf_gc_mark_hook
[deliverable/binutils-gdb.git] / bfd / elf64-x86-64.c
index be8bf569bf40f2a741ebcfca964868c876e92bff..63aff4630f5f00a7ac9e3d9be5473c0ae3e59d7e 100644 (file)
@@ -40,9 +40,6 @@
    relocation type.  We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
    since they are the same.  */
 
-#define ABI_64_P(abfd) \
-  (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
-
 /* The relocation "howto" table.  Order of fields:
    type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
    special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset.  */
@@ -521,12 +518,6 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 \f
 /* Functions for the x86-64 ELF linker.         */
 
-/* The name of the dynamic interpreter.         This is put in the .interp
-   section.  */
-
-#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
-#define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
-
 /* The size in bytes of an entry in the global offset table.  */
 
 #define GOT_ENTRY_SIZE 8
@@ -823,77 +814,6 @@ static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] =
   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
 };
 
-struct elf_x86_64_lazy_plt_layout
-{
-  /* Templates for the initial PLT entry and for subsequent entries.  */
-  const bfd_byte *plt0_entry;
-  const bfd_byte *plt_entry;
-  unsigned int plt_entry_size;          /* Size of each PLT entry.  */
-
-  /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2].  */
-  unsigned int plt0_got1_offset;
-  unsigned int plt0_got2_offset;
-
-  /* Offset of the end of the PC-relative instruction containing
-     plt0_got2_offset.  */
-  unsigned int plt0_got2_insn_end;
-
-  /* Offsets into plt_entry that are to be replaced with...  */
-  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
-  unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
-  unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
-
-  /* Length of the PC-relative instruction containing plt_got_offset.  */
-  unsigned int plt_got_insn_size;
-
-  /* Offset of the end of the PC-relative jump to plt0_entry.  */
-  unsigned int plt_plt_insn_end;
-
-  /* Offset into plt_entry where the initial value of the GOT entry points.  */
-  unsigned int plt_lazy_offset;
-
-  /* .eh_frame covering the lazy .plt section.  */
-  const bfd_byte *eh_frame_plt;
-  unsigned int eh_frame_plt_size;
-};
-
-struct elf_x86_64_non_lazy_plt_layout
-{
-  /* Template for the lazy PLT entries.  */
-  const bfd_byte *plt_entry;
-  unsigned int plt_entry_size;          /* Size of each PLT entry.  */
-
-  /* Offsets into plt_entry that are to be replaced with...  */
-  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
-
-  /* Length of the PC-relative instruction containing plt_got_offset.  */
-  unsigned int plt_got_insn_size;
-
-  /* .eh_frame covering the non-lazy .plt section.  */
-  const bfd_byte *eh_frame_plt;
-  unsigned int eh_frame_plt_size;
-};
-
-struct elf_x86_64_plt_layout
-{
-  /* Template for the PLT entries.  */
-  const bfd_byte *plt_entry;
-  unsigned int plt_entry_size;          /* Size of each PLT entry.  */
-
-  /* 1 has PLT0.  */
-   unsigned int has_plt0;
-
-  /* Offsets into plt_entry that are to be replaced with...  */
-  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
-
-  /* Length of the PC-relative instruction containing plt_got_offset.  */
-  unsigned int plt_got_insn_size;
-
-  /* .eh_frame covering the .plt section.  */
-  const bfd_byte *eh_frame_plt;
-  unsigned int eh_frame_plt_size;
-};
-
 /* Architecture-specific backend data for x86-64.  */
 
 struct elf_x86_64_backend_data
@@ -913,9 +833,10 @@ struct elf_x86_64_backend_data
   get_elf_x86_64_arch_data (get_elf_backend_data (abfd))
 
 /* These are the standard parameters.  */
-static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_plt =
+static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt =
   {
     elf_x86_64_lazy_plt0_entry,         /* plt0_entry */
+    LAZY_PLT_ENTRY_SIZE,                /* plt0_entry_size */
     elf_x86_64_lazy_plt_entry,          /* plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     2,                                  /* plt0_got1_offset */
@@ -927,13 +848,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_plt =
     6,                                  /* plt_got_insn_size */
     LAZY_PLT_ENTRY_SIZE,                /* plt_plt_insn_end */
     6,                                  /* plt_lazy_offset */
+    elf_x86_64_lazy_plt0_entry,         /* pic_plt0_entry */
+    elf_x86_64_lazy_plt_entry,          /* pic_plt_entry */
     elf_x86_64_eh_frame_lazy_plt,       /* eh_frame_plt */
     sizeof (elf_x86_64_eh_frame_lazy_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_plt =
+static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt =
   {
     elf_x86_64_non_lazy_plt_entry,      /* plt_entry */
+    elf_x86_64_non_lazy_plt_entry,      /* pic_plt_entry */
     NON_LAZY_PLT_ENTRY_SIZE,            /* plt_entry_size */
     2,                                  /* plt_got_offset */
     6,                                  /* plt_got_insn_size */
@@ -941,9 +865,10 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_plt =
     sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_bnd_plt =
+static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt =
   {
     elf_x86_64_lazy_bnd_plt0_entry,     /* plt0_entry */
+    LAZY_PLT_ENTRY_SIZE,                /* plt0_entry_size */
     elf_x86_64_lazy_bnd_plt_entry,      /* plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     2,                                  /* plt0_got1_offset */
@@ -955,13 +880,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_bnd_plt =
     1+6,                                /* plt_got_insn_size */
     11,                                 /* plt_plt_insn_end */
     0,                                  /* plt_lazy_offset */
+    elf_x86_64_lazy_bnd_plt0_entry,     /* pic_plt0_entry */
+    elf_x86_64_lazy_bnd_plt_entry,      /* pic_plt_entry */
     elf_x86_64_eh_frame_lazy_bnd_plt,   /* eh_frame_plt */
     sizeof (elf_x86_64_eh_frame_lazy_bnd_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt =
+static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt =
   {
     elf_x86_64_non_lazy_bnd_plt_entry,  /* plt_entry */
+    elf_x86_64_non_lazy_bnd_plt_entry,  /* pic_plt_entry */
     NON_LAZY_PLT_ENTRY_SIZE,            /* plt_entry_size */
     1+2,                                /* plt_got_offset */
     1+6,                                /* plt_got_insn_size */
@@ -969,9 +897,10 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt =
     sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
+static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
   {
     elf_x86_64_lazy_bnd_plt0_entry,     /* plt0_entry */
+    LAZY_PLT_ENTRY_SIZE,                /* plt0_entry_size */
     elf_x86_64_lazy_ibt_plt_entry,      /* plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     2,                                  /* plt0_got1_offset */
@@ -983,13 +912,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_lazy_ibt_plt =
     4+1+6,                              /* plt_got_insn_size */
     4+1+5+5,                            /* plt_plt_insn_end */
     0,                                  /* plt_lazy_offset */
+    elf_x86_64_lazy_bnd_plt0_entry,     /* pic_plt0_entry */
+    elf_x86_64_lazy_ibt_plt_entry,      /* pic_plt_entry */
     elf_x86_64_eh_frame_lazy_ibt_plt,   /* eh_frame_plt */
     sizeof (elf_x86_64_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_lazy_plt_layout elf_x32_lazy_ibt_plt =
+static const struct elf_x86_lazy_plt_layout elf_x32_lazy_ibt_plt =
   {
     elf_x86_64_lazy_plt0_entry,         /* plt0_entry */
+    LAZY_PLT_ENTRY_SIZE,                /* plt0_entry_size */
     elf_x32_lazy_ibt_plt_entry,         /* plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     2,                                  /* plt0_got1_offset */
@@ -1001,13 +933,16 @@ static const struct elf_x86_64_lazy_plt_layout elf_x32_lazy_ibt_plt =
     4+6,                                /* plt_got_insn_size */
     4+5+5,                              /* plt_plt_insn_end */
     0,                                  /* plt_lazy_offset */
+    elf_x86_64_lazy_plt0_entry,         /* pic_plt0_entry */
+    elf_x32_lazy_ibt_plt_entry,         /* pic_plt_entry */
     elf_x32_eh_frame_lazy_ibt_plt,      /* eh_frame_plt */
     sizeof (elf_x32_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt =
+static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt =
   {
     elf_x86_64_non_lazy_ibt_plt_entry,  /* plt_entry */
+    elf_x86_64_non_lazy_ibt_plt_entry,  /* pic_plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     4+1+2,                              /* plt_got_offset */
     4+1+6,                              /* plt_got_insn_size */
@@ -1015,9 +950,10 @@ static const struct elf_x86_64_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt =
     sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_64_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt =
+static const struct elf_x86_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt =
   {
     elf_x32_non_lazy_ibt_plt_entry,     /* plt_entry */
+    elf_x32_non_lazy_ibt_plt_entry,     /* pic_plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     4+2,                                /* plt_got_offset */
     4+6,                                /* plt_got_insn_size */
@@ -1049,101 +985,9 @@ static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
    && elf_tdata (bfd) != NULL                          \
    && elf_object_id (bfd) == X86_64_ELF_DATA)
 
-static bfd_boolean
-elf_x86_64_mkobject (bfd *abfd)
-{
-  return bfd_elf_allocate_object (abfd, sizeof (struct elf_x86_obj_tdata),
-                                 X86_64_ELF_DATA);
-}
-
-/* x86-64 ELF linker hash table.  */
-
-struct elf_x86_64_link_hash_table
-{
-  struct elf_x86_link_hash_table x86;
-
-  /* Parameters describing PLT generation, lazy or non-lazy.  */
-  struct elf_x86_64_plt_layout plt;
-
-  /* Parameters describing lazy PLT generation.  */
-  const struct elf_x86_64_lazy_plt_layout *lazy_plt;
-
-  /* Parameters describing non-lazy PLT generation.  */
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt;
-};
-
-#define elf_x86_64_next_tls_desc_index(htab) \
-  ((struct elf_x86_64_link_hash_table *) (htab))->next_tls_desc_index
-
-#define elf_x86_64_srelplt2(htab) \
-  ((struct elf_x86_64_link_hash_table *) (htab))->srelplt2
-
-#define elf_x86_64_plt(htab) \
-  ((struct elf_x86_64_link_hash_table *) (htab))->plt
-
-#define elf_x86_64_lazy_plt(htab) \
-  ((struct elf_x86_64_link_hash_table *) (htab))->lazy_plt
-
-#define elf_x86_64_non_lazy_plt(htab) \
-  ((struct elf_x86_64_link_hash_table *) (htab))->non_lazy_plt
-
 #define elf_x86_64_compute_jump_table_size(htab) \
   ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
 
-/* Create an X86-64 ELF linker hash table.  */
-
-static struct bfd_link_hash_table *
-elf_x86_64_link_hash_table_create (bfd *abfd)
-{
-  struct elf_x86_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table);
-
-  ret = (struct elf_x86_link_hash_table *) bfd_zmalloc (amt);
-  if (ret == NULL)
-    return NULL;
-
-  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
-                                     _bfd_x86_elf_link_hash_newfunc,
-                                     sizeof (struct elf_x86_link_hash_entry),
-                                     X86_64_ELF_DATA))
-    {
-      free (ret);
-      return NULL;
-    }
-
-  if (ABI_64_P (abfd))
-    {
-      ret->r_info = elf64_r_info;
-      ret->r_sym = elf64_r_sym;
-      ret->pointer_r_type = R_X86_64_64;
-      ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
-      ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
-    }
-  else
-    {
-      ret->r_info = elf32_r_info;
-      ret->r_sym = elf32_r_sym;
-      ret->pointer_r_type = R_X86_64_32;
-      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)
-    {
-      _bfd_x86_elf_link_hash_table_free (abfd);
-      return NULL;
-    }
-  ret->elf.root.hash_table_free = _bfd_x86_elf_link_hash_table_free;
-
-  return &ret->elf.root;
-}
-
 static bfd_boolean
 elf64_x86_64_elf_object_p (bfd *abfd)
 {
@@ -2570,220 +2414,6 @@ error_return:
   return FALSE;
 }
 
-/* Return the section that should be marked against GC for a given
-   relocation. */
-
-static asection *
-elf_x86_64_gc_mark_hook (asection *sec,
-                        struct bfd_link_info *info,
-                        Elf_Internal_Rela *rel,
-                        struct elf_link_hash_entry *h,
-                        Elf_Internal_Sym *sym)
-{
-  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);
-}
-
-/* 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. */
-
-static bfd_boolean
-elf_x86_64_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;
-
-  /* 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 = &eh->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;
-               }
-           }
-       }
-
-      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_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;
-
-  eh = (struct elf_x86_link_hash_entry *) h;
-
-  /* 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->u.weakdef != NULL)
-    {
-      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
-                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->u.weakdef->root.u.def.section;
-      h->root.u.def.value = h->u.weakdef->root.u.def.value;
-      if (ELIMINATE_COPY_RELOCS
-         || info->nocopyreloc
-         || SYMBOL_NO_COPYRELOC (info, eh))
-       {
-         h->non_got_ref = h->u.weakdef->non_got_ref;
-         eh->needs_copy = h->u.weakdef->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, we don't need to generate a copy reloc.  */
-  if (!h->non_got_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;
-    }
-
-  if (ELIMINATE_COPY_RELOCS)
-    {
-      eh = (struct elf_x86_link_hash_entry *) h;
-      for (p = eh->dyn_relocs; p != NULL; p = p->next)
-       {
-         s = p->sec->output_section;
-         if (s != NULL && (s->flags & SEC_READONLY) != 0)
-           break;
-       }
-
-      /* If we didn't find any dynamic relocs in read-only sections, then
-        we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
-      if (p == NULL)
-       {
-         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.  */
-
-  htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
-  if (htab == NULL)
-    return FALSE;
-
-  /* We must generate a 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)
-    {
-      const struct elf_backend_data *bed;
-      bed = get_elf_backend_data (info->output_bfd);
-      srel->size += bed->s->sizeof_rela;
-      h->needs_copy = 1;
-    }
-
-  return _bfd_elf_adjust_dynamic_copy (info, h, s);
-}
-
 /* Allocate space in .plt, .got and associated reloc sections for
    dynamic relocs.  */
 
@@ -2797,8 +2427,6 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   const struct elf_backend_data *bed;
   unsigned int plt_entry_size;
   bfd_boolean resolved_to_zero;
-  const struct elf_x86_64_plt_layout *plt_layout;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout;
 
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -2811,9 +2439,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
     return FALSE;
   bed = get_elf_backend_data (info->output_bfd);
 
-  plt_layout = &elf_x86_64_plt (htab);
-  non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab);
-  plt_entry_size = plt_layout->plt_entry_size;
+  plt_entry_size = htab->plt.plt_entry_size;
 
   resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
                                                      X86_64_ELF_DATA,
@@ -2852,7 +2478,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
                                              &eh->dyn_relocs,
                                              &htab->readonly_dynrelocs_against_ifunc,
                                              plt_entry_size,
-                                             (plt_layout->has_plt0
+                                             (htab->plt.has_plt0
                                               * plt_entry_size),
                                              GOT_ENTRY_SIZE, TRUE))
        {
@@ -2863,7 +2489,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
              eh->plt_second.offset = s->size;
 
              /* Make room for this entry in the second PLT section.  */
-             s->size += non_lazy_plt_layout->plt_entry_size;
+             s->size += htab->non_lazy_plt->plt_entry_size;
            }
 
          return TRUE;
@@ -2905,7 +2531,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
             first entry.  The .plt section is used by prelink to undo
             prelinking for dynamic relocations.  */
          if (s->size == 0)
-           s->size = plt_layout->has_plt0 * plt_entry_size;
+           s->size = htab->plt.has_plt0 * plt_entry_size;
 
          if (use_plt_got)
            eh->plt_got.offset = got_s->size;
@@ -2950,12 +2576,12 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 
          /* Make room for this entry.  */
          if (use_plt_got)
-           got_s->size += non_lazy_plt_layout->plt_entry_size;
+           got_s->size += htab->non_lazy_plt->plt_entry_size;
          else
            {
              s->size += plt_entry_size;
              if (second_s)
-               second_s->size += non_lazy_plt_layout->plt_entry_size;
+               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
@@ -3338,8 +2964,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
   bfd_boolean relocs;
   bfd *ibfd;
   const struct elf_backend_data *bed;
-  const struct elf_x86_64_plt_layout *plt_layout;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout;
 
   htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
   if (htab == NULL)
@@ -3350,9 +2974,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
   if (dynobj == NULL)
     abort ();
 
-  plt_layout = &elf_x86_64_plt (htab);
-  non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab);
-
   /* Set up .got offsets for local syms, and space for local dynamic
      relocs.  */
   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
@@ -3509,9 +3130,9 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          /* 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 = plt_layout->plt_entry_size;
+           htab->elf.splt->size = htab->plt.plt_entry_size;
          htab->tlsdesc_plt = htab->elf.splt->size;
-         htab->elf.splt->size += plt_layout->plt_entry_size;
+         htab->elf.splt->size += htab->plt.plt_entry_size;
        }
     }
 
@@ -3540,14 +3161,14 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          && htab->elf.splt != NULL
          && htab->elf.splt->size != 0
          && !bfd_is_abs_section (htab->elf.splt->output_section))
-       htab->plt_eh_frame->size = plt_layout->eh_frame_plt_size;
+       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
-         = non_lazy_plt_layout->eh_frame_plt_size;
+         = htab->non_lazy_plt->eh_frame_plt_size;
 
       /* Unwind info for the second PLT and .plt.got sections are
         identical.  */
@@ -3556,7 +3177,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          && htab->plt_second->size != 0
          && !bfd_is_abs_section (htab->plt_second->output_section))
        htab->plt_second_eh_frame->size
-         = non_lazy_plt_layout->eh_frame_plt_size;
+         = htab->non_lazy_plt->eh_frame_plt_size;
     }
 
   /* We now have determined the sizes of the various dynamic sections.
@@ -3632,7 +3253,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
       && htab->plt_eh_frame->contents != NULL)
     {
       memcpy (htab->plt_eh_frame->contents,
-             plt_layout->eh_frame_plt, htab->plt_eh_frame->size);
+             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);
     }
@@ -3641,7 +3262,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
       && htab->plt_got_eh_frame->contents != NULL)
     {
       memcpy (htab->plt_got_eh_frame->contents,
-             non_lazy_plt_layout->eh_frame_plt,
+             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
@@ -3652,7 +3273,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
       && htab->plt_second_eh_frame->contents != NULL)
     {
       memcpy (htab->plt_second_eh_frame->contents,
-             non_lazy_plt_layout->eh_frame_plt,
+             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
@@ -3798,7 +3419,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
   htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
   if (htab == NULL)
     return FALSE;
-  plt_entry_size = elf_x86_64_plt (htab).plt_entry_size;
+  plt_entry_size = htab->plt.plt_entry_size;
   symtab_hdr = &elf_symtab_hdr (input_bfd);
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_offsets = elf_local_got_offsets (input_bfd);
@@ -3976,7 +3597,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
                  if (htab->elf.splt != NULL)
                    {
                      plt_index = (h->plt.offset / plt_entry_size
-                                  - elf_x86_64_plt (htab).has_plt0);
+                                  - htab->plt.has_plt0);
                      off = (plt_index + 3) * GOT_ENTRY_SIZE;
                      base_got = htab->elf.sgotplt;
                    }
@@ -4207,7 +3828,7 @@ do_ifunc_pointer:
                     finish_dynamic_symbol would use that as offset into
                     .got.  */
                  bfd_vma plt_index = (h->plt.offset / plt_entry_size
-                                      - elf_x86_64_plt (htab).has_plt0);
+                                      - htab->plt.has_plt0);
                  off = (plt_index + 3) * GOT_ENTRY_SIZE;
                  base_got = htab->elf.sgotplt;
                }
@@ -5362,9 +4983,6 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
   bfd_boolean use_plt_second;
   struct elf_x86_link_hash_entry *eh;
   bfd_boolean local_undefweak;
-  const struct elf_x86_64_plt_layout *plt_layout;
-  const struct elf_x86_64_lazy_plt_layout *lazy_plt_layout;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout;
 
   htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
   if (htab == NULL)
@@ -5377,10 +4995,6 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
   if (eh->no_finish_dynamic_symbol)
     abort ();
 
-  plt_layout = &elf_x86_64_plt (htab);
-  lazy_plt_layout = elf_x86_64_lazy_plt (htab);
-  non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab);
-
   /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
      resolved undefined weak symbols in executable so that their
      references have value 0 at run-time.  */
@@ -5439,24 +5053,24 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
 
       if (plt == htab->elf.splt)
        {
-         got_offset = (h->plt.offset / plt_layout->plt_entry_size
-                       - plt_layout->has_plt0);
+         got_offset = (h->plt.offset / htab->plt.plt_entry_size
+                       - htab->plt.has_plt0);
          got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
        }
       else
        {
-         got_offset = h->plt.offset / plt_layout->plt_entry_size;
+         got_offset = h->plt.offset / htab->plt.plt_entry_size;
          got_offset = got_offset * GOT_ENTRY_SIZE;
        }
 
       /* Fill in the entry in the procedure linkage table.  */
-      memcpy (plt->contents + h->plt.offset, plt_layout->plt_entry,
-             plt_layout->plt_entry_size);
+      memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
+             htab->plt.plt_entry_size);
       if (use_plt_second)
        {
          memcpy (htab->plt_second->contents + eh->plt_second.offset,
-                 non_lazy_plt_layout->plt_entry,
-                 non_lazy_plt_layout->plt_entry_size);
+                 htab->non_lazy_plt->plt_entry,
+                 htab->non_lazy_plt->plt_entry_size);
 
          resolved_plt = htab->plt_second;
          plt_offset = eh->plt_second.offset;
@@ -5477,7 +5091,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
                              - resolved_plt->output_section->vma
                              - resolved_plt->output_offset
                              - plt_offset
-                             - plt_layout->plt_got_insn_size);
+                             - htab->plt.plt_got_insn_size);
 
       /* Check PC-relative offset overflow in PLT entry.  */
       if ((plt_got_pcrel_offset + 0x80000000) > 0xffffffff)
@@ -5487,7 +5101,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
 
       bfd_put_32 (output_bfd, plt_got_pcrel_offset,
                  (resolved_plt->contents + plt_offset
-                  + plt_layout->plt_got_offset));
+                  + htab->plt.plt_got_offset));
 
       /* Fill in the entry in the global offset table, initially this
         points to the second part of the PLT entry.  Leave the entry
@@ -5495,11 +5109,11 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
         against undefined weak symbol in PIE.  */
       if (!local_undefweak)
        {
-         if (plt_layout->has_plt0)
+         if (htab->plt.has_plt0)
            bfd_put_64 (output_bfd, (plt->output_section->vma
                                     + plt->output_offset
                                     + h->plt.offset
-                                    + lazy_plt_layout->plt_lazy_offset),
+                                    + htab->lazy_plt->plt_lazy_offset),
                        gotplt->contents + got_offset);
 
          /* Fill in the entry in the .rela.plt section.  */
@@ -5534,15 +5148,15 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
 
          /* Don't fill the second and third slots in PLT entry for
             static executables nor without PLT0.  */
-         if (plt == htab->elf.splt && plt_layout->has_plt0)
+         if (plt == htab->elf.splt && htab->plt.has_plt0)
            {
              bfd_vma plt0_offset
-               = h->plt.offset + lazy_plt_layout->plt_plt_insn_end;
+               = h->plt.offset + htab->lazy_plt->plt_plt_insn_end;
 
              /* Put relocation index.  */
              bfd_put_32 (output_bfd, plt_index,
                          (plt->contents + h->plt.offset
-                          + lazy_plt_layout->plt_reloc_offset));
+                          + htab->lazy_plt->plt_reloc_offset));
 
              /* Put offset for jmp .PLT0 and check for overflow.  We don't
                 check relocation index for overflow since branch displacement
@@ -5553,7 +5167,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
                                        output_bfd, h->root.root.string);
              bfd_put_32 (output_bfd, - plt0_offset,
                          (plt->contents + h->plt.offset
-                          + lazy_plt_layout->plt_plt_offset));
+                          + htab->lazy_plt->plt_plt_offset));
            }
 
          bed = get_elf_backend_data (output_bfd);
@@ -5584,8 +5198,8 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
       /* Fill in the entry in the GOT procedure linkage table.  */
       plt_offset = eh->plt_got.offset;
       memcpy (plt->contents + plt_offset,
-             non_lazy_plt_layout->plt_entry,
-             non_lazy_plt_layout->plt_entry_size);
+             htab->non_lazy_plt->plt_entry,
+             htab->non_lazy_plt->plt_entry_size);
 
       /* Put offset the PC-relative instruction referring to the GOT
         entry, subtracting the size of that instruction.  */
@@ -5595,7 +5209,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
                          - plt->output_section->vma
                          - plt->output_offset
                          - plt_offset
-                         - non_lazy_plt_layout->plt_got_insn_size);
+                         - htab->non_lazy_plt->plt_got_insn_size);
 
       /* Check PC-relative offset overflow in GOT PLT entry.  */
       got_after_plt = got->output_section->vma > plt->output_section->vma;
@@ -5607,7 +5221,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
 
       bfd_put_32 (output_bfd, got_pcrel_offset,
                  (plt->contents + plt_offset
-                  + non_lazy_plt_layout->plt_got_offset));
+                  + htab->non_lazy_plt->plt_got_offset));
     }
 
   if (!local_undefweak
@@ -5871,9 +5485,6 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
       bfd_byte *dyncon, *dynconend;
       const struct elf_backend_data *bed;
       bfd_size_type sizeof_dyn;
-      const struct elf_x86_64_plt_layout *plt_layout;
-      const struct elf_x86_64_lazy_plt_layout *lazy_plt_layout;
-      const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout;
 
       if (sdyn == NULL || htab->elf.sgot == NULL)
        abort ();
@@ -5924,22 +5535,18 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
          (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
        }
 
-      plt_layout = &elf_x86_64_plt (htab);
-      lazy_plt_layout = elf_x86_64_lazy_plt (htab);
-      non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab);
-
       if (htab->elf.splt && htab->elf.splt->size > 0)
        {
          elf_section_data (htab->elf.splt->output_section)
-           ->this_hdr.sh_entsize = plt_layout->plt_entry_size;
+           ->this_hdr.sh_entsize = htab->plt.plt_entry_size;
 
-         if (plt_layout->has_plt0)
+         if (htab->plt.has_plt0)
            {
              /* Fill in the special first entry in the procedure linkage
                 table.  */
              memcpy (htab->elf.splt->contents,
-                     lazy_plt_layout->plt0_entry,
-                     lazy_plt_layout->plt_entry_size);
+                     htab->lazy_plt->plt0_entry,
+                     htab->lazy_plt->plt0_entry_size);
              /* Add offset for pushq GOT+8(%rip), since the instruction
                 uses 6 bytes subtract this value.  */
              bfd_put_32 (output_bfd,
@@ -5950,7 +5557,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                           - htab->elf.splt->output_offset
                           - 6),
                          (htab->elf.splt->contents
-                          + lazy_plt_layout->plt0_got1_offset));
+                          + htab->lazy_plt->plt0_got1_offset));
              /* Add offset for the PC-relative instruction accessing
                 GOT+16, subtracting the offset to the end of that
                 instruction.  */
@@ -5960,9 +5567,9 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                           + 16
                           - htab->elf.splt->output_section->vma
                           - htab->elf.splt->output_offset
-                          - lazy_plt_layout->plt0_got2_insn_end),
+                          - htab->lazy_plt->plt0_got2_insn_end),
                          (htab->elf.splt->contents
-                          + lazy_plt_layout->plt0_got2_offset));
+                          + htab->lazy_plt->plt0_got2_offset));
 
              if (htab->tlsdesc_plt)
                {
@@ -5970,8 +5577,8 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                              htab->elf.sgot->contents + htab->tlsdesc_got);
 
                  memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
-                         lazy_plt_layout->plt0_entry,
-                         lazy_plt_layout->plt_entry_size);
+                         htab->lazy_plt->plt0_entry,
+                         htab->lazy_plt->plt0_entry_size);
 
                  /* Add offset for pushq GOT+8(%rip), since the
                     instruction uses 6 bytes subtract this value.  */
@@ -5985,7 +5592,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                               - 6),
                              (htab->elf.splt->contents
                               + htab->tlsdesc_plt
-                              + lazy_plt_layout->plt0_got1_offset));
+                              + htab->lazy_plt->plt0_got1_offset));
                  /* Add offset for the PC-relative instruction accessing
                     GOT+TDG, where TDG stands for htab->tlsdesc_got,
                     subtracting the offset to the end of that
@@ -5997,21 +5604,21 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                               - htab->elf.splt->output_section->vma
                               - htab->elf.splt->output_offset
                               - htab->tlsdesc_plt
-                              - lazy_plt_layout->plt0_got2_insn_end),
+                              - htab->lazy_plt->plt0_got2_insn_end),
                              (htab->elf.splt->contents
                               + htab->tlsdesc_plt
-                              + lazy_plt_layout->plt0_got2_offset));
+                              + htab->lazy_plt->plt0_got2_offset));
                }
            }
        }
 
       if (htab->plt_got != NULL && htab->plt_got->size > 0)
        elf_section_data (htab->plt_got->output_section)
-         ->this_hdr.sh_entsize = non_lazy_plt_layout->plt_entry_size;
+         ->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 = non_lazy_plt_layout->plt_entry_size;
+         ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
     }
 
   /* GOT is always created in setup_gnu_properties.  But it may not be
@@ -6167,28 +5774,8 @@ elf_x86_64_output_arch_local_syms
   return TRUE;
 }
 
-enum elf_x86_64_plt_type
-{
-  plt_non_lazy = 0,
-  plt_lazy = 1 << 0,
-  plt_second = 1 << 1,
-  plt_unknown = -1
-};
-
-struct elf_x86_64_plt
-{
-  const char *name;
-  asection *sec;
-  bfd_byte *contents;
-  enum elf_x86_64_plt_type type;
-  unsigned int plt_got_offset;
-  unsigned int plt_got_insn_size;
-  unsigned int plt_entry_size;
-  long count;
-};
-
 /* Forward declaration.  */
-static const struct elf_x86_64_lazy_plt_layout elf_x86_64_nacl_plt;
+static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt;
 
 /* Similar to _bfd_elf_get_synthetic_symtab.  Support PLTs with all
    dynamic relocations.   */
@@ -6201,23 +5788,19 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
                                 asymbol **dynsyms,
                                 asymbol **ret)
 {
-  long size, count, i, n, len;
+  long count, i, n;
   int j;
-  unsigned int plt_got_offset, plt_entry_size, plt_got_insn_size;
-  asymbol *s;
   bfd_byte *plt_contents;
-  long dynrelcount, relsize;
-  arelent **dynrelbuf, *p;
-  const struct elf_x86_64_lazy_plt_layout *lazy_plt;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt;
-  const struct elf_x86_64_lazy_plt_layout *lazy_bnd_plt;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_bnd_plt;
-  const struct elf_x86_64_lazy_plt_layout *lazy_ibt_plt;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_ibt_plt;
+  long relsize;
+  const struct elf_x86_lazy_plt_layout *lazy_plt;
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
+  const struct elf_x86_lazy_plt_layout *lazy_bnd_plt;
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_plt;
+  const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
   asection *plt;
-  char *names;
-  enum elf_x86_64_plt_type plt_type;
-  struct elf_x86_64_plt plts[] =
+  enum elf_x86_plt_type plt_type;
+  struct elf_x86_plt plts[] =
     {
       { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
       { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
@@ -6385,159 +5968,9 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
       plts[j].contents = plt_contents;
     }
 
-  if (count == 0)
-    return -1;
-
-  dynrelbuf = (arelent **) bfd_malloc (relsize);
-  if (dynrelbuf == NULL)
-    return -1;
-
-  dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf,
-                                               dynsyms);
-
-  /* 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;
-
-  /* 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;
-
-       plt_got_offset = plts[j].plt_got_offset;
-       plt_got_insn_size = plts[j].plt_got_insn_size;
-       plt_entry_size = plts[j].plt_entry_size;
-
-       plt = plts[j].sec;
-
-       if ((plts[j].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 < plts[j].count; k++)
-         {
-           int off;
-           bfd_vma got_vma;
-           long min, max, mid;
-
-           /* Get the PC-relative offset, a signed 32-bit integer.  */
-           off = H_GET_32 (abfd, (plt_contents + offset
-                                  + plt_got_offset));
-           got_vma = plt->vma + offset + off + plt_got_insn_size;
-
-           /* 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
-               && (p->howto->type == R_X86_64_JUMP_SLOT
-                   || p->howto->type == R_X86_64_GLOB_DAT
-                   || p->howto->type == R_X86_64_IRELATIVE))
-             {
-               *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++;
-             }
-           offset += plt_entry_size;
-         }
-      }
-
-  /* PLT entries with R_X86_64_TLSDESC relocations are skipped.  */
-  if (n == 0)
-    {
-bad_return:
-      count = -1;
-    }
-  else
-    count = n;
-
-  for (j = 0; plts[j].name != NULL; j++)
-    if (plts[j].contents != NULL)
-      free (plts[j].contents);
-
-  free (dynrelbuf);
-
-  return count;
+  return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize,
+                                           (bfd_vma) 0, plts, dynsyms,
+                                           ret);
 }
 
 /* Handle an x86-64 specific section when reading an object file.  This
@@ -6726,398 +6159,44 @@ elf_x86_64_relocs_compatible (const bfd_target *input,
 static bfd *
 elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
 {
-  bfd_boolean normal_target;
-  bfd_boolean lazy_plt;
-  asection *sec, *pltsec;
-  bfd *dynobj;
-  bfd_boolean use_ibt_plt;
-  unsigned int plt_alignment, features;
-  struct elf_x86_link_hash_table *htab;
-  bfd *pbfd;
-  bfd *ebfd = NULL;
-  elf_property *prop;
-  struct elf_x86_64_plt_layout *plt_layout;
-  const struct elf_x86_64_lazy_plt_layout *lazy_plt_layout;
-  const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt_layout;
-
-  features = 0;
-  if (info->ibt)
-    features = GNU_PROPERTY_X86_FEATURE_1_IBT;
-  if (info->shstk)
-    features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
-
-  /* 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;
-      }
+  struct elf_x86_plt_layout_table plt_layout;
 
-  if (ebfd != NULL && features)
+  plt_layout.is_vxworks = FALSE;
+  if (get_elf_x86_64_backend_data (info->output_bfd)->os == is_normal)
     {
-      /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
-        GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
-      prop = _bfd_elf_get_property (ebfd,
-                                   GNU_PROPERTY_X86_FEATURE_1_AND,
-                                   4);
-      prop->u.number |= features;
-      prop->pr_kind = property_number;
-
-      /* Create the GNU property note section if needed.  */
-      if (pbfd == NULL)
+      if (info->bndplt)
        {
-         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: failed to create GNU property section\n"));
-
-         if (!bfd_set_section_alignment (ebfd, sec,
-                                         ABI_64_P (ebfd) ? 3 : 2))
-           {
-error_alignment:
-             info->callbacks->einfo (_("%F%A: failed to align section\n"),
-                                     sec);
-           }
-
-         elf_section_type (sec) = SHT_NOTE;
-       }
-    }
-
-  pbfd = _bfd_elf_link_setup_gnu_properties (info);
-
-  if (bfd_link_relocatable (info))
-    return pbfd;
-
-  htab = elf_x86_hash_table (info, X86_64_ELF_DATA);
-  if (htab == NULL)
-    return pbfd;
-
-  use_ibt_plt = info->ibtplt || info->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;
+         plt_layout.lazy_plt = &elf_x86_64_lazy_bnd_plt;
+         plt_layout.non_lazy_plt = &elf_x86_64_non_lazy_bnd_plt;
        }
       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)
-             {
-               htab->elf.dynobj = abfd;
-               dynobj = abfd;
-               break;
-             }
+         plt_layout.lazy_plt = &elf_x86_64_lazy_plt;
+         plt_layout.non_lazy_plt = &elf_x86_64_non_lazy_plt;
        }
-    }
 
-  plt_layout = &elf_x86_64_plt (htab);
-
-  /* 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.  */
-  plt_layout->has_plt0 = 1;
-
-  if (get_elf_x86_64_backend_data (info->output_bfd)->os
-      == is_normal)
-    {
-      if (use_ibt_plt)
-       {
-         if (ABI_64_P (dynobj))
-           {
-             elf_x86_64_lazy_plt (htab)
-               = &elf_x86_64_lazy_ibt_plt;
-             elf_x86_64_non_lazy_plt (htab)
-               = &elf_x86_64_non_lazy_ibt_plt;
-           }
-         else
-           {
-             elf_x86_64_lazy_plt (htab)
-               = &elf_x32_lazy_ibt_plt;
-             elf_x86_64_non_lazy_plt (htab)
-               = &elf_x32_non_lazy_ibt_plt;
-           }
-       }
-      else if (info->bndplt)
+      if (ABI_64_P (info->output_bfd))
        {
-         elf_x86_64_lazy_plt (htab) = &elf_x86_64_lazy_bnd_plt;
-         elf_x86_64_non_lazy_plt (htab) = &elf_x86_64_non_lazy_bnd_plt;
+         plt_layout.lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
+         plt_layout.non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
        }
       else
        {
-         elf_x86_64_lazy_plt (htab) = &elf_x86_64_lazy_plt;
-         elf_x86_64_non_lazy_plt (htab) = &elf_x86_64_non_lazy_plt;
+         plt_layout.lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
+         plt_layout.non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
        }
-      normal_target = TRUE;
-    }
-  else
-    {
-      elf_x86_64_lazy_plt (htab) = &elf_x86_64_nacl_plt;
-      elf_x86_64_non_lazy_plt (htab) = NULL;
-      normal_target = FALSE;
-    }
-
-  lazy_plt_layout = elf_x86_64_lazy_plt (htab);
-  non_lazy_plt_layout = elf_x86_64_non_lazy_plt (htab);
-
-  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 (non_lazy_plt_layout != NULL
-      && (!plt_layout->has_plt0 || pltsec == NULL))
-    {
-      lazy_plt = FALSE;
-      plt_layout->plt_entry
-       = non_lazy_plt_layout->plt_entry;
-      plt_layout->plt_entry_size
-       = non_lazy_plt_layout->plt_entry_size;
-      plt_layout->plt_got_offset
-       = non_lazy_plt_layout->plt_got_offset;
-      plt_layout->plt_got_insn_size
-       = non_lazy_plt_layout->plt_got_insn_size;
-      plt_layout->eh_frame_plt_size
-       = non_lazy_plt_layout->eh_frame_plt_size;
-      plt_layout->eh_frame_plt
-       = non_lazy_plt_layout->eh_frame_plt;
+      plt_layout.normal_target = TRUE;
     }
   else
     {
-      lazy_plt = TRUE;
-      plt_layout->plt_entry
-       = lazy_plt_layout->plt_entry;
-      plt_layout->plt_entry_size
-       = lazy_plt_layout->plt_entry_size;
-      plt_layout->plt_got_offset
-       = lazy_plt_layout->plt_got_offset;
-      plt_layout->plt_got_insn_size
-       = lazy_plt_layout->plt_got_insn_size;
-      plt_layout->eh_frame_plt_size
-       = lazy_plt_layout->eh_frame_plt_size;
-      plt_layout->eh_frame_plt
-       = lazy_plt_layout->eh_frame_plt;
-    }
-
-  /* Return if there are no normal input files.  */
-  if (dynobj == NULL)
-    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: failed to create GOT sections\n"));
-
-  /* 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 (dynobj, sec, 3))
-    goto error_alignment;
-
-  sec = htab->elf.sgotplt;
-  if (!bfd_set_section_alignment (dynobj, sec, 3))
-    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: failed to create ifunc sections\n"));
-
-  plt_alignment = bfd_log2 (plt_layout->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;
-       }
-
-      /* Don't change PLT section alignment for NaCl since it uses
-        64-byte PLT entry and sets PLT section alignment to 32
-        bytes.  Don't create additional PLT sections for NaCl.  */
-      if (normal_target)
-       {
-         const struct elf_backend_data *bed
-           = get_elf_backend_data (dynobj);
-         flagword pltflags = (bed->dynamic_sec_flags
-                              | SEC_ALLOC
-                              | SEC_CODE
-                              | SEC_LOAD
-                              | SEC_READONLY);
-         unsigned int non_lazy_plt_alignment
-           = bfd_log2 (non_lazy_plt_layout->plt_entry_size);
-
-         sec = pltsec;
-         if (!bfd_set_section_alignment (sec->owner, 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: failed to create GOT PLT section\n"));
-
-         if (!bfd_set_section_alignment (dynobj, 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 supported only for non-NaCl target and is
-                    is needed only for lazy binding.  */
-                 sec = bfd_make_section_anyway_with_flags (dynobj,
-                                                           ".plt.sec",
-                                                           pltflags);
-                 if (sec == NULL)
-                   info->callbacks->einfo (_("%F: failed to create IBT-enabled PLT section\n"));
-
-                 if (!bfd_set_section_alignment (dynobj, sec,
-                                                 plt_alignment))
-                   goto error_alignment;
-               }
-             else if (info->bndplt && ABI_64_P (dynobj))
-               {
-                 /* Create the second PLT for Intel MPX support.  MPX
-                    PLT is supported only for non-NaCl target 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: failed to create BND PLT section\n"));
-
-                 if (!bfd_set_section_alignment (dynobj, 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: failed to create PLT .eh_frame section\n"));
-
-         if (!bfd_set_section_alignment (dynobj, sec,
-                                         ABI_64_P (dynobj) ? 3 : 2))
-           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: failed to create GOT PLT .eh_frame section\n"));
-
-             if (!bfd_set_section_alignment (dynobj, sec,
-                                             ABI_64_P (dynobj) ? 3 : 2))
-               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: failed to create BND PLT .eh_frame section\n"));
-
-             if (!bfd_set_section_alignment (dynobj, sec, 3))
-               goto error_alignment;
-
-             htab->plt_second_eh_frame = sec;
-           }
-       }
-    }
-
-  if (normal_target)
-    {
-      /* The .iplt section is used for IFUNC symbols in static
-        executables.  */
-      sec = htab->elf.iplt;
-      if (sec != NULL
-         && !bfd_set_section_alignment (sec->owner, sec,
-                                        plt_alignment))
-       goto error_alignment;
+      plt_layout.lazy_plt = &elf_x86_64_nacl_plt;
+      plt_layout.non_lazy_plt = NULL;
+      plt_layout.lazy_ibt_plt = NULL;
+      plt_layout.non_lazy_ibt_plt = NULL;
+      plt_layout.normal_target = FALSE;
     }
 
-  return pbfd;
+  return _bfd_x86_elf_link_setup_gnu_properties (info, &plt_layout);
 }
 
 static const struct bfd_elf_special_section
@@ -7156,20 +6235,16 @@ elf_x86_64_special_sections[]=
 
 #define elf_info_to_howto                  elf_x86_64_info_to_howto
 
-#define bfd_elf64_bfd_link_hash_table_create \
-  elf_x86_64_link_hash_table_create
 #define bfd_elf64_bfd_reloc_type_lookup            elf_x86_64_reloc_type_lookup
 #define bfd_elf64_bfd_reloc_name_lookup \
   elf_x86_64_reloc_name_lookup
 
-#define elf_backend_adjust_dynamic_symbol   elf_x86_64_adjust_dynamic_symbol
 #define elf_backend_relocs_compatible      elf_x86_64_relocs_compatible
 #define elf_backend_check_relocs           elf_x86_64_check_relocs
 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
 #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
 #define elf_backend_finish_dynamic_symbol   elf_x86_64_finish_dynamic_symbol
 #define elf_backend_output_arch_local_syms  elf_x86_64_output_arch_local_syms
-#define elf_backend_gc_mark_hook           elf_x86_64_gc_mark_hook
 #define elf_backend_grok_prstatus          elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo                    elf_x86_64_grok_psinfo
 #ifdef CORE_HEADER
@@ -7180,7 +6255,6 @@ elf_x86_64_special_sections[]=
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
 #define elf_backend_init_index_section     _bfd_elf_init_1_index_section
 #define elf_backend_object_p               elf64_x86_64_elf_object_p
-#define bfd_elf64_mkobject                 elf_x86_64_mkobject
 #define bfd_elf64_get_synthetic_symtab     elf_x86_64_get_synthetic_symtab
 
 #define elf_backend_section_from_shdr \
@@ -7407,9 +6481,10 @@ static const bfd_byte elf_x86_64_nacl_eh_frame_plt[] =
     DW_CFA_nop, DW_CFA_nop
   };
 
-static const struct elf_x86_64_lazy_plt_layout elf_x86_64_nacl_plt =
+static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt =
   {
     elf_x86_64_nacl_plt0_entry,              /* plt0_entry */
+    NACL_PLT_ENTRY_SIZE,                     /* plt0_entry_size */
     elf_x86_64_nacl_plt_entry,               /* plt_entry */
     NACL_PLT_ENTRY_SIZE,                     /* plt_entry_size */
     2,                                       /* plt0_got1_offset */
@@ -7421,6 +6496,8 @@ static const struct elf_x86_64_lazy_plt_layout elf_x86_64_nacl_plt =
     7,                                       /* plt_got_insn_size */
     42,                                      /* plt_plt_insn_end */
     32,                                      /* plt_lazy_offset */
+    elf_x86_64_nacl_plt0_entry,              /* pic_plt0_entry */
+    elf_x86_64_nacl_plt_entry,               /* pic_plt_entry */
     elf_x86_64_nacl_eh_frame_plt,            /* eh_frame_plt */
     sizeof (elf_x86_64_nacl_eh_frame_plt)    /* eh_frame_plt_size */
   };
@@ -7461,14 +6538,10 @@ elf32_x86_64_nacl_elf_object_p (bfd *abfd)
 #undef elf32_bed
 #define        elf32_bed                       elf32_x86_64_nacl_bed
 
-#define bfd_elf32_bfd_link_hash_table_create \
-  elf_x86_64_link_hash_table_create
 #define bfd_elf32_bfd_reloc_type_lookup        \
   elf_x86_64_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup \
   elf_x86_64_reloc_name_lookup
-#define bfd_elf32_mkobject \
-  elf_x86_64_mkobject
 #define bfd_elf32_get_synthetic_symtab \
   elf_x86_64_get_synthetic_symtab
 
This page took 0.043775 seconds and 4 git commands to generate.