x86: Add _bfd_x86_elf_link_hash_table_create
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 30 Aug 2017 16:10:08 +0000 (09:10 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 30 Aug 2017 16:10:24 +0000 (09:10 -0700)
Share _bfd_x86_elf_link_hash_table_create in elf32-i386.c and
elf64-x86-64.c by:

1. Replace elf_i386_lazy_plt_layout, elf_i386_non_lazy_plt_layout,
elf_i386_plt_layout, elf_x86_64_lazy_plt_layout,
elf_x86_64_non_lazy_plt_layout and elf_x86_64_plt_layout with
elf_x86_lazy_plt_layout, elf_x86_non_lazy_plt_layout and
elf_x86_plt_layout.
2. Move plt, lazy_plt, non_lazy_plt, srelplt2 and next_tls_desc_index
from elf_i386_link_hash_table to elf_x86_link_hash_table.
3. Remove elf_i386_link_hash_table and elf_x86_64_link_hash_table.

* elf32-i386.c (ELF_DYNAMIC_INTERPRETER): Removed.
(elf_i386_lazy_plt_layout): Likewise.
(elf_i386_non_lazy_plt_layout): Likewise.
(elf_i386_plt_layout): Likewise.
(elf_i386_link_hash_table): Likewise.
(elf_i386_next_tls_desc_index): Likewise.
(elf_i386_srelplt2): Likewise.
(elf_i386_plt): Likewise.
(elf_i386_lazy_plt): Likewise.
(elf_i386_non_lazy_plt): Likewise.
(elf_i386_link_hash_table_create): Likewise.
(bfd_elf32_bfd_link_hash_table_create): Likewise.
(elf_i386_lazy_plt): Updated.
(elf_i386_non_lazy_plt): Likewise.
(elf_i386_lazy_ibt_plt): Likewise.
(elf_i386_non_lazy_ibt_plt): Likewise.
(elf_i386_allocate_dynrelocs): Likewise.
(elf_i386_size_dynamic_sections): Likewise.
(elf_i386_relocate_section): Likewise.
(elf_i386_finish_dynamic_symbol): Likewise.
(elf_i386_finish_dynamic_sections): Likewise.
(elf_i386_get_synthetic_symtab): Likewise.
(elf_i386_link_setup_gnu_properties): Likewise.
(elf_i386_nacl_plt): Likewise.
* elf64-x86-64.c (ABI_64_P): Removed.
(ELF64_DYNAMIC_INTERPRETER): Likewise.
(ELF32_DYNAMIC_INTERPRETER): Likewise.
(elf_x86_64_lazy_plt_layout): Likewise.
(elf_x86_64_non_lazy_plt_layout): Likewise.
(elf_x86_64_plt_layout): Likewise.
(elf_x86_64_link_hash_table): Likewise.
(elf_x86_64_plt): Likewise.
(elf_x86_64_lazy_plt): Likewise.
(elf_x86_64_non_lazy_plt): Likewise.
(elf_x86_64_link_hash_table_create): Likewise.
(bfd_elf64_bfd_link_hash_table_create): Likewise.
(bfd_elf32_bfd_link_hash_table_create): Likewise.
(elf_x86_64_lazy_plt): Updated.
(elf_x86_64_non_lazy_plt): Likewise.
(elf_x86_64_lazy_bnd_plt): Likewise.
(elf_x86_64_non_lazy_bnd_plt): Likewise.
(elf_x86_64_lazy_ibt_plt): Likewise.
(elf_x32_lazy_ibt_plt): Likewise.
(elf_x86_64_non_lazy_ibt_plt): Likewise.
(elf_x32_non_lazy_ibt_plt): Likewise.
(elf_x86_64_allocate_dynrelocs): Likewise.
(elf_x86_64_size_dynamic_sections): Likewise.
(elf_x86_64_relocate_section): Likewise.
(elf_x86_64_finish_dynamic_symbol): Likewise.
(elf_x86_64_finish_dynamic_sections): Likewise.
(elf_x86_64_get_synthetic_symtab): Likewise.
(elf_x86_64_link_setup_gnu_properties): Likewise.
(elf_x86_64_nacl_plt): Likewise.
* elfxx-x86.c: Include "objalloc.h", "elf/i386.h" and
"elf/x86-64.h".
(ELF32_DYNAMIC_INTERPRETER): New.
(ELF64_DYNAMIC_INTERPRETER): Likewise.
(ELFX32_DYNAMIC_INTERPRETER): Likewise.
(_bfd_x86_elf_link_hash_table_create): Likewise.
(_bfd_x86_elf_link_hash_table_free): Renamed to ...
(elf_x86_link_hash_table_free): This.  Make it static.
* elfxx-x86.h: Don't include "objalloc.h".
(ABI_64_P): New.
(elf_x86_lazy_plt_layout): Likewise.
(elf_x86_non_lazy_plt_layout): Likewise.
(elf_x86_plt_layout): Likewise.
(_bfd_x86_elf_link_hash_table_create): Likewise.
(bfd_elf64_bfd_link_hash_table_create): Likewise.
(bfd_elf32_bfd_link_hash_table_create): Likewise.
(elf_x86_link_hash_table): Add plt, lazy_plt, non_lazy_plt,
srelplt2 and next_tls_desc_index.
(_bfd_x86_elf_link_hash_table_free): Removed.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfxx-x86.c
bfd/elfxx-x86.h

index f52e75deb53aa4d75ec900e835f17e2746f79995..095373e6b3df5f1296b721a3b3c4bce0ef9c9c6d 100644 (file)
@@ -1,3 +1,78 @@
+2017-08-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elf32-i386.c (ELF_DYNAMIC_INTERPRETER): Removed.
+       (elf_i386_lazy_plt_layout): Likewise.
+       (elf_i386_non_lazy_plt_layout): Likewise.
+       (elf_i386_plt_layout): Likewise.
+       (elf_i386_link_hash_table): Likewise.
+       (elf_i386_next_tls_desc_index): Likewise.
+       (elf_i386_srelplt2): Likewise.
+       (elf_i386_plt): Likewise.
+       (elf_i386_lazy_plt): Likewise.
+       (elf_i386_non_lazy_plt): Likewise.
+       (elf_i386_link_hash_table_create): Likewise.
+       (bfd_elf32_bfd_link_hash_table_create): Likewise.
+       (elf_i386_lazy_plt): Updated.
+       (elf_i386_non_lazy_plt): Likewise.
+       (elf_i386_lazy_ibt_plt): Likewise.
+       (elf_i386_non_lazy_ibt_plt): Likewise.
+       (elf_i386_allocate_dynrelocs): Likewise.
+       (elf_i386_size_dynamic_sections): Likewise.
+       (elf_i386_relocate_section): Likewise.
+       (elf_i386_finish_dynamic_symbol): Likewise.
+       (elf_i386_finish_dynamic_sections): Likewise.
+       (elf_i386_get_synthetic_symtab): Likewise.
+       (elf_i386_link_setup_gnu_properties): Likewise.
+       (elf_i386_nacl_plt): Likewise.
+       * elf64-x86-64.c (ABI_64_P): Removed.
+       (ELF64_DYNAMIC_INTERPRETER): Likewise.
+       (ELF32_DYNAMIC_INTERPRETER): Likewise.
+       (elf_x86_64_lazy_plt_layout): Likewise.
+       (elf_x86_64_non_lazy_plt_layout): Likewise.
+       (elf_x86_64_plt_layout): Likewise.
+       (elf_x86_64_link_hash_table): Likewise.
+       (elf_x86_64_plt): Likewise.
+       (elf_x86_64_lazy_plt): Likewise.
+       (elf_x86_64_non_lazy_plt): Likewise.
+       (elf_x86_64_link_hash_table_create): Likewise.
+       (bfd_elf64_bfd_link_hash_table_create): Likewise.
+       (bfd_elf32_bfd_link_hash_table_create): Likewise.
+       (elf_x86_64_lazy_plt): Updated.
+       (elf_x86_64_non_lazy_plt): Likewise.
+       (elf_x86_64_lazy_bnd_plt): Likewise.
+       (elf_x86_64_non_lazy_bnd_plt): Likewise.
+       (elf_x86_64_lazy_ibt_plt): Likewise.
+       (elf_x32_lazy_ibt_plt): Likewise.
+       (elf_x86_64_non_lazy_ibt_plt): Likewise.
+       (elf_x32_non_lazy_ibt_plt): Likewise.
+       (elf_x86_64_allocate_dynrelocs): Likewise.
+       (elf_x86_64_size_dynamic_sections): Likewise.
+       (elf_x86_64_relocate_section): Likewise.
+       (elf_x86_64_finish_dynamic_symbol): Likewise.
+       (elf_x86_64_finish_dynamic_sections): Likewise.
+       (elf_x86_64_get_synthetic_symtab): Likewise.
+       (elf_x86_64_link_setup_gnu_properties): Likewise.
+       (elf_x86_64_nacl_plt): Likewise.
+       * elfxx-x86.c: Include "objalloc.h", "elf/i386.h" and
+       "elf/x86-64.h".
+       (ELF32_DYNAMIC_INTERPRETER): New.
+       (ELF64_DYNAMIC_INTERPRETER): Likewise.
+       (ELFX32_DYNAMIC_INTERPRETER): Likewise.
+       (_bfd_x86_elf_link_hash_table_create): Likewise.
+       (_bfd_x86_elf_link_hash_table_free): Renamed to ...
+       (elf_x86_link_hash_table_free): This.  Make it static.
+       * elfxx-x86.h: Don't include "objalloc.h".
+       (ABI_64_P): New.
+       (elf_x86_lazy_plt_layout): Likewise.
+       (elf_x86_non_lazy_plt_layout): Likewise.
+       (elf_x86_plt_layout): Likewise.
+       (_bfd_x86_elf_link_hash_table_create): Likewise.
+       (bfd_elf64_bfd_link_hash_table_create): Likewise.
+       (bfd_elf32_bfd_link_hash_table_create): Likewise.
+       (elf_x86_link_hash_table): Add plt, lazy_plt, non_lazy_plt,
+       srelplt2 and next_tls_desc_index.
+       (_bfd_x86_elf_link_hash_table_free): Removed.
+
 2017-08-30  Maciej W. Rozycki  <macro@imgtec.com>
 
        * elfxx-mips.c (mips_elf_perform_relocation): Correct microMIPS
index 4fcfff1bf225c0b92f454e8acba2cfd09ad60bea..8e41c6eef27ff4bedcbdebafe9195fe0e5afced3 100644 (file)
@@ -522,12 +522,6 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
    early in the link process, elf_i386_finish_dynamic_sections is
    one of the last functions.  */
 
-
-/* The name of the dynamic interpreter.  This is put in the .interp
-   section.  */
-
-#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
-
 /* The size in bytes of an entry in the lazy procedure linkage table.  */
 
 #define LAZY_PLT_ENTRY_SIZE 16
@@ -758,94 +752,21 @@ static const bfd_byte elf_i386_eh_frame_non_lazy_plt[] =
   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
 };
 
-struct elf_i386_lazy_plt_layout
-{
-  /* The first entry in an absolute lazy procedure linkage table looks
-     like this.  */
-  const bfd_byte *plt0_entry;
-  unsigned int plt0_entry_size;
-
-  /* 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;
-
-  /* Later entries in an absolute lazy procedure linkage table look
-     like this.  */
-  const bfd_byte *plt_entry;
-  unsigned int plt_entry_size;
-
-  /* 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. */
-
-  /* Offset into plt_entry where the initial value of the GOT entry
-     points.  */
-  unsigned int plt_lazy_offset;
-
-  /* The first entry in a PIC lazy procedure linkage table looks like
-     this.  */
-  const bfd_byte *pic_plt0_entry;
-
-  /* Subsequent entries in a PIC lazy procedure linkage table look
-     like this.  */
-  const bfd_byte *pic_plt_entry;
-
-  /* .eh_frame covering the lazy .plt section.  */
-  const bfd_byte *eh_frame_plt;
-  unsigned int eh_frame_plt_size;
-};
-
-struct elf_i386_non_lazy_plt_layout
-{
-  /* Entries in an absolute non-lazy procedure linkage table look like
-     this.  */
-  const bfd_byte *plt_entry;
-  /* Entries in a PIC non-lazy procedure linkage table look like this.  */
-  const bfd_byte *pic_plt_entry;
-
-  unsigned int plt_entry_size;
-
-  /* Offsets into plt_entry that are to be replaced with...  */
-  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
-
-  /* .eh_frame covering the non-lazy .plt section.  */
-  const bfd_byte *eh_frame_plt;
-  unsigned int eh_frame_plt_size;
-};
-
-struct elf_i386_plt_layout
-{
-  /* The first entry in a lazy procedure linkage table looks like this.  */
-  const bfd_byte *plt0_entry;
-  /* Entries in a procedure linkage table look like this.  */
-  const bfd_byte *plt_entry;
-  unsigned int plt_entry_size;
-
-  /* 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. */
-
-  /* .eh_frame covering the .plt section.  */
-  const bfd_byte *eh_frame_plt;
-  unsigned int eh_frame_plt_size;
-};
-
 /* These are the standard parameters.  */
-static const struct elf_i386_lazy_plt_layout elf_i386_lazy_plt =
+static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt =
   {
     elf_i386_lazy_plt0_entry,           /* plt0_entry */
     sizeof (elf_i386_lazy_plt0_entry),  /* plt0_entry_size */
-    2,                                  /* plt0_got1_offset */
-    8,                                  /* plt0_got2_offset */
     elf_i386_lazy_plt_entry,            /* plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
+    2,                                  /* plt0_got1_offset */
+    8,                                  /* plt0_got2_offset */
+    0,                                  /* plt0_got2_insn_end */
     2,                                  /* plt_got_offset */
     7,                                  /* plt_reloc_offset */
     12,                                 /* plt_plt_offset */
+    0,                                  /* plt_got_insn_size */
+    0,                                  /* plt_plt_insn_end */
     6,                                  /* plt_lazy_offset */
     elf_i386_pic_lazy_plt0_entry,       /* pic_plt0_entry */
     elf_i386_pic_lazy_plt_entry,        /* pic_plt_entry */
@@ -853,27 +774,31 @@ static const struct elf_i386_lazy_plt_layout elf_i386_lazy_plt =
     sizeof (elf_i386_eh_frame_lazy_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_i386_non_lazy_plt_layout elf_i386_non_lazy_plt =
+static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_plt =
   {
     elf_i386_non_lazy_plt_entry,        /* plt_entry */
     elf_i386_pic_non_lazy_plt_entry,    /* pic_plt_entry */
     NON_LAZY_PLT_ENTRY_SIZE,            /* plt_entry_size */
     2,                                  /* plt_got_offset */
+    0,                                  /* plt_got_insn_size */
     elf_i386_eh_frame_non_lazy_plt,     /* eh_frame_plt */
     sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_i386_lazy_plt_layout elf_i386_lazy_ibt_plt =
+static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt =
   {
     elf_i386_lazy_ibt_plt0_entry,       /* plt0_entry */
     sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
-    2,                                  /* plt0_got1_offset */
-    8,                                  /* plt0_got2_offset */
     elf_i386_lazy_ibt_plt_entry,        /* plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
+    2,                                  /* plt0_got1_offset */
+    8,                                  /* plt0_got2_offset */
+    0,                                  /* plt0_got2_insn_end */
     4+2,                                /* plt_got_offset */
     4+1,                                /* plt_reloc_offset */
     4+6,                                /* plt_plt_offset */
+    0,                                  /* plt_got_insn_size */
+    0,                                  /* plt_plt_insn_end */
     0,                                  /* plt_lazy_offset */
     elf_i386_pic_lazy_ibt_plt0_entry,   /* pic_plt0_entry */
     elf_i386_lazy_ibt_plt_entry,        /* pic_plt_entry */
@@ -881,12 +806,13 @@ static const struct elf_i386_lazy_plt_layout elf_i386_lazy_ibt_plt =
     sizeof (elf_i386_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_i386_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
+static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
   {
     elf_i386_non_lazy_ibt_plt_entry,    /* plt_entry */
     elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     4+2,                                /* plt_got_offset */
+    0,                                  /* plt_got_insn_size */
     elf_i386_eh_frame_non_lazy_plt,     /* eh_frame_plt */
     sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
   };
@@ -955,88 +881,9 @@ elf_i386_mkobject (bfd *abfd)
                                  I386_ELF_DATA);
 }
 
-/* i386 ELF linker hash table.  */
-
-struct elf_i386_link_hash_table
-{
-  struct elf_x86_link_hash_table x86;
-
-  /* Parameters describing PLT generation, lazy or non-lazy.  */
-  struct elf_i386_plt_layout plt;
-
-  /* Parameters describing lazy PLT generation.  */
-  const struct elf_i386_lazy_plt_layout *lazy_plt;
-
-  /* Parameters describing non-lazy PLT generation.  */
-  const struct elf_i386_non_lazy_plt_layout *non_lazy_plt;
-
-  /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
-  asection *srelplt2;
-
-  /* The index of the next unused R_386_TLS_DESC slot in .rel.plt.  */
-  bfd_vma next_tls_desc_index;
-};
-
-#define elf_i386_next_tls_desc_index(htab) \
-  ((struct elf_i386_link_hash_table *) (htab))->next_tls_desc_index
-
-#define elf_i386_srelplt2(htab) \
-  ((struct elf_i386_link_hash_table *) (htab))->srelplt2
-
-#define elf_i386_plt(htab) \
-  ((struct elf_i386_link_hash_table *) (htab))->plt
-
-#define elf_i386_lazy_plt(htab) \
-  ((struct elf_i386_link_hash_table *) (htab))->lazy_plt
-
-#define elf_i386_non_lazy_plt(htab) \
-  ((struct elf_i386_link_hash_table *) (htab))->non_lazy_plt
-
 #define elf_i386_compute_jump_table_size(htab) \
   ((htab)->elf.srelplt->reloc_count * 4)
 
-/* Create an i386 ELF linker hash table.  */
-
-static struct bfd_link_hash_table *
-elf_i386_link_hash_table_create (bfd *abfd)
-{
-  struct elf_x86_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf_i386_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),
-                                     I386_ELF_DATA))
-    {
-      free (ret);
-      return NULL;
-    }
-
-  ret->r_info = elf32_r_info;
-  ret->r_sym = elf32_r_sym;
-  ret->pointer_r_type = R_386_32;
-  ret->dynamic_interpreter_size = sizeof ELF_DYNAMIC_INTERPRETER;
-  ret->dynamic_interpreter = ELF_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;
-}
-
 /* Return TRUE if the TLS access code sequence support transition
    from R_TYPE.  */
 
@@ -2362,8 +2209,6 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   unsigned plt_entry_size;
   bfd_boolean resolved_to_zero;
   const struct elf_i386_backend_data *bed;
-  const struct elf_i386_plt_layout *plt_layout;
-  const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout;
 
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -2377,9 +2222,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
   bed = get_elf_i386_backend_data (info->output_bfd);
 
-  plt_layout = &elf_i386_plt (htab);
-  non_lazy_plt_layout = elf_i386_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,
                                                      I386_ELF_DATA,
@@ -2417,7 +2260,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
                                              &htab->readonly_dynrelocs_against_ifunc,
                                              plt_entry_size,
-                                             (plt_layout->has_plt0
+                                             (htab->plt.has_plt0
                                               * plt_entry_size),
                                               4, TRUE))
        {
@@ -2428,7 +2271,7 @@ elf_i386_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;
@@ -2470,7 +2313,7 @@ elf_i386_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;
@@ -2515,12 +2358,12 @@ elf_i386_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
@@ -2548,7 +2391,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
                 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
                 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
 
-             asection *srelplt2 = elf_i386_srelplt2 (htab);
+             asection *srelplt2 = htab->srelplt2;
              if (h->plt.offset == plt_entry_size)
                srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
 
@@ -3096,10 +2939,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
      so that R_386_IRELATIVE entries come last.  */
   if (htab->elf.srelplt)
     {
-      elf_i386_next_tls_desc_index(htab)
-       = htab->elf.srelplt->reloc_count;
-      htab->sgotplt_jump_table_size
-       = elf_i386_next_tls_desc_index(htab) * 4;
+      htab->next_tls_desc_index = htab->elf.srelplt->reloc_count;
+      htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;
       htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
     }
   else if (htab->elf.irelplt)
@@ -3131,14 +2972,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
          && htab->elf.splt != NULL
          && htab->elf.splt->size != 0
          && !bfd_is_abs_section (htab->elf.splt->output_section))
-       htab->plt_eh_frame->size = elf_i386_plt (htab).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
-         = elf_i386_non_lazy_plt (htab)->eh_frame_plt_size;
+         = htab->non_lazy_plt->eh_frame_plt_size;
 
       /* Unwind info for the second PLT and .plt.got sections are
         identical.  */
@@ -3147,7 +2988,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
          && htab->plt_second->size != 0
          && !bfd_is_abs_section (htab->plt_second->output_section))
        htab->plt_second_eh_frame->size
-         = elf_i386_non_lazy_plt (htab)->eh_frame_plt_size;
+         = htab->non_lazy_plt->eh_frame_plt_size;
     }
 
   /* We now have determined the sizes of the various dynamic sections.
@@ -3189,7 +3030,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
        {
          if (s->size != 0
              && s != htab->elf.srelplt
-             && s != elf_i386_srelplt2 (htab))
+             && s != htab->srelplt2)
            relocs = TRUE;
 
          /* We use the reloc_count field as a counter if we need
@@ -3235,7 +3076,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       && htab->plt_eh_frame->contents != NULL)
     {
       memcpy (htab->plt_eh_frame->contents,
-             elf_i386_plt (htab).eh_frame_plt,
+             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);
@@ -3245,7 +3086,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       && htab->plt_got_eh_frame->contents != NULL)
     {
       memcpy (htab->plt_got_eh_frame->contents,
-             elf_i386_non_lazy_plt (htab)->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
@@ -3256,7 +3097,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       && htab->plt_second_eh_frame->contents != NULL)
     {
       memcpy (htab->plt_second_eh_frame->contents,
-             elf_i386_non_lazy_plt (htab)->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
@@ -3431,7 +3272,7 @@ elf_i386_relocate_section (bfd *output_bfd,
 
   _bfd_x86_elf_set_tls_module_base (info);
 
-  plt_entry_size = elf_i386_plt (htab).plt_entry_size;
+  plt_entry_size = htab->plt.plt_entry_size;
 
   rel = wrel = relocs;
   relend = relocs + input_section->reloc_count;
@@ -3676,7 +3517,7 @@ elf_i386_relocate_section (bfd *output_bfd,
                  if (htab->elf.splt != NULL)
                    {
                      plt_index = (h->plt.offset / plt_entry_size
-                                  - elf_i386_plt (htab).has_plt0);
+                                  - htab->plt.has_plt0);
                      off = (plt_index + 3) * 4;
                      base_got = htab->elf.sgotplt;
                    }
@@ -3894,7 +3735,7 @@ do_ifunc_pointer:
          else
            /* Use GOTPLT entry.  */
            relocation = (h->plt.offset / plt_entry_size
-                         - elf_i386_plt (htab).has_plt0 + 3) * 4;
+                         - htab->plt.has_plt0 + 3) * 4;
 
          if (!bfd_link_pic (info))
            {
@@ -4523,7 +4364,7 @@ disallow_got32:
                                     + htab->sgotplt_jump_table_size);
                  sreloc = htab->elf.srelplt;
                  loc = sreloc->contents;
-                 loc += (elf_i386_next_tls_desc_index (htab)++
+                 loc += (htab->next_tls_desc_index++
                          * sizeof (Elf32_External_Rel));
                  BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
                              <= sreloc->contents + sreloc->size);
@@ -4983,19 +4824,13 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
   struct elf_x86_link_hash_entry *eh;
   bfd_boolean local_undefweak;
   bfd_boolean use_plt_second;
-  const struct elf_i386_plt_layout *plt_layout;
-  const struct elf_i386_lazy_plt_layout *lazy_plt_layout;
-  const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout;
 
   htab = elf_x86_hash_table (info, I386_ELF_DATA);
   if (htab == NULL)
     return FALSE;
 
   abed = get_elf_i386_backend_data (output_bfd);
-  plt_layout = &elf_i386_plt (htab);
-  lazy_plt_layout = elf_i386_lazy_plt (htab);
-  non_lazy_plt_layout = elf_i386_non_lazy_plt (htab);
-  plt_entry_size = plt_layout->plt_entry_size;
+  plt_entry_size = htab->plt.plt_entry_size;
 
   /* Use the second PLT section only if there is .plt section.  */
   use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL;
@@ -5061,7 +4896,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
       if (plt == htab->elf.splt)
        {
          got_offset = (h->plt.offset / plt_entry_size
-                       - plt_layout->has_plt0);
+                       - htab->plt.has_plt0);
          got_offset = (got_offset + 3) * 4;
        }
       else
@@ -5072,18 +4907,18 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
 
       /* Fill in the entry in the procedure linkage table and update
         the first slot.  */
-      memcpy (plt->contents + h->plt.offset, plt_layout->plt_entry,
+      memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
              plt_entry_size);
 
       if (use_plt_second)
        {
          const bfd_byte *plt_entry;
          if (bfd_link_pic (info))
-           plt_entry = non_lazy_plt_layout->pic_plt_entry;
+           plt_entry = htab->non_lazy_plt->pic_plt_entry;
          else
-           plt_entry = non_lazy_plt_layout->plt_entry;
+           plt_entry = htab->non_lazy_plt->plt_entry;
          memcpy (htab->plt_second->contents + eh->plt_second.offset,
-                 plt_entry, non_lazy_plt_layout->plt_entry_size);
+                 plt_entry, htab->non_lazy_plt->plt_entry_size);
 
          resolved_plt = htab->plt_second;
          plt_offset = eh->plt_second.offset;
@@ -5101,7 +4936,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
                       + gotplt->output_offset
                       + got_offset),
                      resolved_plt->contents + plt_offset
-                      + plt_layout->plt_got_offset);
+                      + htab->plt.plt_got_offset);
 
          if (abed->os == is_vxworks)
            {
@@ -5111,8 +4946,8 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
                 for this PLT entry.  */
 
              /* S: Current slot number (zero-based).  */
-             s = ((h->plt.offset - plt_layout->plt_entry_size)
-                   / plt_layout->plt_entry_size);
+             s = ((h->plt.offset - htab->plt.plt_entry_size)
+                   / htab->plt.plt_entry_size);
              /* K: Number of relocations for PLTResolve. */
              if (bfd_link_pic (info))
                k = PLTRESOLVE_RELOCS_SHLIB;
@@ -5121,7 +4956,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
              /* Skip the PLTresolve relocations, and the relocations for
                 the other PLT slots. */
              reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS;
-             loc = (elf_i386_srelplt2 (htab)->contents + reloc_index
+             loc = (htab->srelplt2->contents + reloc_index
                     * sizeof (Elf32_External_Rel));
 
              rel.r_offset = (plt->output_section->vma
@@ -5144,7 +4979,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
        {
          bfd_put_32 (output_bfd, got_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.  Leave the entry
@@ -5152,12 +4987,12 @@ elf_i386_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_32 (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 .rel.plt section.  */
@@ -5197,17 +5032,17 @@ elf_i386_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_put_32 (output_bfd,
                          plt_index * sizeof (Elf32_External_Rel),
                          plt->contents + h->plt.offset
-                         + lazy_plt_layout->plt_reloc_offset);
+                         + htab->lazy_plt->plt_reloc_offset);
              bfd_put_32 (output_bfd,
                          - (h->plt.offset
-                            + lazy_plt_layout->plt_plt_offset + 4),
+                            + htab->lazy_plt->plt_plt_offset + 4),
                          (plt->contents + h->plt.offset
-                          + lazy_plt_layout->plt_plt_offset));
+                          + htab->lazy_plt->plt_plt_offset));
            }
        }
     }
@@ -5232,12 +5067,12 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
       /* Fill in the entry in the GOT procedure linkage table.  */
       if (! bfd_link_pic (info))
        {
-         got_plt_entry = non_lazy_plt_layout->plt_entry;
+         got_plt_entry = htab->non_lazy_plt->plt_entry;
          got_offset += got->output_section->vma + got->output_offset;
        }
       else
        {
-         got_plt_entry = non_lazy_plt_layout->pic_plt_entry;
+         got_plt_entry = htab->non_lazy_plt->pic_plt_entry;
          got_offset += (got->output_section->vma
                         + got->output_offset
                         - gotplt->output_section->vma
@@ -5246,10 +5081,10 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
 
       plt_offset = eh->plt_got.offset;
       memcpy (plt->contents + plt_offset, got_plt_entry,
-             non_lazy_plt_layout->plt_entry_size);
+             htab->non_lazy_plt->plt_entry_size);
       bfd_put_32 (output_bfd, got_offset,
                  (plt->contents + plt_offset
-                  + non_lazy_plt_layout->plt_got_offset));
+                  + htab->non_lazy_plt->plt_got_offset));
     }
 
   if (!local_undefweak
@@ -5505,9 +5340,6 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
   if (htab->elf.dynamic_sections_created)
     {
       Elf32_External_Dyn *dyncon, *dynconend;
-      const struct elf_i386_plt_layout *plt_layout;
-      const struct elf_i386_lazy_plt_layout *lazy_plt_layout;
-      const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout;
 
       if (sdyn == NULL || htab->elf.sgot == NULL)
        abort ();
@@ -5548,10 +5380,6 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
          bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
        }
 
-      plt_layout = &elf_i386_plt (htab);
-      lazy_plt_layout = elf_i386_lazy_plt (htab);
-      non_lazy_plt_layout =  elf_i386_non_lazy_plt (htab);
-
       if (htab->elf.splt && htab->elf.splt->size > 0)
        {
          /* UnixWare sets the entsize of .plt to 4, although that doesn't
@@ -5559,15 +5387,15 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
          elf_section_data (htab->elf.splt->output_section)
            ->this_hdr.sh_entsize = 4;
 
-         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, plt_layout->plt0_entry,
-                     lazy_plt_layout->plt0_entry_size);
-             memset (htab->elf.splt->contents + lazy_plt_layout->plt0_entry_size,
+             memcpy (htab->elf.splt->contents, htab->plt.plt0_entry,
+                     htab->lazy_plt->plt0_entry_size);
+             memset (htab->elf.splt->contents + htab->lazy_plt->plt0_entry_size,
                      abed->plt0_pad_byte,
-                     plt_layout->plt_entry_size - lazy_plt_layout->plt0_entry_size);
+                     htab->plt.plt_entry_size - htab->lazy_plt->plt0_entry_size);
              if (!bfd_link_pic (info))
                {
                  bfd_put_32 (output_bfd,
@@ -5575,28 +5403,28 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
                               + htab->elf.sgotplt->output_offset
                               + 4),
                              htab->elf.splt->contents
-                             + lazy_plt_layout->plt0_got1_offset);
+                             + htab->lazy_plt->plt0_got1_offset);
                  bfd_put_32 (output_bfd,
                              (htab->elf.sgotplt->output_section->vma
                               + htab->elf.sgotplt->output_offset
                               + 8),
                              htab->elf.splt->contents
-                             + lazy_plt_layout->plt0_got2_offset);
+                             + htab->lazy_plt->plt0_got2_offset);
 
                  if (abed->os == is_vxworks)
                    {
                      Elf_Internal_Rela rel;
                      int num_plts = (htab->elf.splt->size
-                                     / plt_layout->plt_entry_size) - 1;
+                                     / htab->plt.plt_entry_size) - 1;
                      unsigned char *p;
-                     asection *srelplt2 = elf_i386_srelplt2 (htab);
+                     asection *srelplt2 = htab->srelplt2;
 
                      /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
                         + 4.  On IA32 we use REL relocations so the
                         addend goes in the PLT directly.  */
                      rel.r_offset = (htab->elf.splt->output_section->vma
                                      + htab->elf.splt->output_offset
-                                     + lazy_plt_layout->plt0_got1_offset);
+                                     + htab->lazy_plt->plt0_got1_offset);
                      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
                                                 R_386_32);
                      bfd_elf32_swap_reloc_out (output_bfd, &rel,
@@ -5605,7 +5433,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
                         + 8.  */
                      rel.r_offset = (htab->elf.splt->output_section->vma
                                      + htab->elf.splt->output_offset
-                                     + lazy_plt_layout->plt0_got2_offset);
+                                     + htab->lazy_plt->plt0_got2_offset);
                      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
                                                 R_386_32);
                      bfd_elf32_swap_reloc_out (output_bfd, &rel,
@@ -5639,11 +5467,11 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
 
       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;
     }
 
   /* Fill in the first three entries in the global offset table.  */
@@ -5811,7 +5639,7 @@ struct elf_i386_plt
 };
 
 /* Forward declaration.  */
-static const struct elf_i386_lazy_plt_layout elf_i386_nacl_plt;
+static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt;
 
 /* Similar to _bfd_elf_get_synthetic_symtab.  Support PLTs with all
    dynamic relocations.   */
@@ -5831,10 +5659,10 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
   bfd_byte *plt_contents;
   long dynrelcount, relsize;
   arelent **dynrelbuf, *p;
-  const struct elf_i386_lazy_plt_layout *lazy_plt;
-  const struct elf_i386_non_lazy_plt_layout *non_lazy_plt;
-  const struct elf_i386_lazy_plt_layout *lazy_ibt_plt;
-  const struct elf_i386_non_lazy_plt_layout *non_lazy_ibt_plt;
+  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_ibt_plt;
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
   asection *plt;
   bfd_vma got_addr;
   char *names;
@@ -6198,9 +6026,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
   bfd *pbfd;
   bfd *ebfd = NULL;
   elf_property *prop;
-  struct elf_i386_plt_layout *plt_layout;
-  const struct elf_i386_lazy_plt_layout *lazy_plt_layout;
-  const struct elf_i386_non_lazy_plt_layout *non_lazy_plt_layout;
 
   features = 0;
   if (info->ibt)
@@ -6316,12 +6141,10 @@ error_alignment:
        }
     }
 
-  plt_layout = &elf_i386_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;
+  htab->plt.has_plt0 = 1;
   normal_target = FALSE;
 
   switch (get_elf_i386_backend_data (info->output_bfd)->os)
@@ -6329,82 +6152,70 @@ error_alignment:
     case is_normal:
       if (use_ibt_plt)
        {
-         elf_i386_lazy_plt (htab) = &elf_i386_lazy_ibt_plt;
-         elf_i386_non_lazy_plt (htab) = &elf_i386_non_lazy_ibt_plt;
+         htab->lazy_plt = &elf_i386_lazy_ibt_plt;
+         htab->non_lazy_plt = &elf_i386_non_lazy_ibt_plt;
        }
       else
        {
-         elf_i386_lazy_plt (htab) = &elf_i386_lazy_plt;
-         elf_i386_non_lazy_plt (htab) = &elf_i386_non_lazy_plt;
+         htab->lazy_plt = &elf_i386_lazy_plt;
+         htab->non_lazy_plt = &elf_i386_non_lazy_plt;
        }
       normal_target = TRUE;
       break;
     case is_vxworks:
-      elf_i386_lazy_plt (htab) = &elf_i386_lazy_plt;
-      elf_i386_non_lazy_plt (htab) = NULL;
+      htab->lazy_plt = &elf_i386_lazy_plt;
+      htab->non_lazy_plt = NULL;
       if (!elf_vxworks_create_dynamic_sections (dynobj, info,
-                                               &elf_i386_srelplt2 (htab)))
+                                               &htab->srelplt2))
        info->callbacks->einfo (_("%F: failed to create VxWorks dynamic sections\n"));
       break;
     case is_nacl:
-      elf_i386_lazy_plt (htab) = &elf_i386_nacl_plt;
-      elf_i386_non_lazy_plt (htab) = NULL;
+      htab->lazy_plt = &elf_i386_nacl_plt;
+      htab->non_lazy_plt = NULL;
       break;
     }
 
-  lazy_plt_layout = elf_i386_lazy_plt (htab);
-  non_lazy_plt_layout = elf_i386_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))
+  if (htab->non_lazy_plt != NULL
+      && (!htab->plt.has_plt0 || pltsec == NULL))
     {
       lazy_plt = FALSE;
       if (bfd_link_pic (info))
-       plt_layout->plt_entry
-         = non_lazy_plt_layout->pic_plt_entry;
+       htab->plt.plt_entry = htab->non_lazy_plt->pic_plt_entry;
       else
-       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->eh_frame_plt_size
-       = non_lazy_plt_layout->eh_frame_plt_size;
-      plt_layout->eh_frame_plt
-       = non_lazy_plt_layout->eh_frame_plt;
+       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.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))
        {
-         plt_layout->plt0_entry
-           = lazy_plt_layout->pic_plt0_entry;
-         plt_layout->plt_entry
-           = lazy_plt_layout->pic_plt_entry;
+         htab->plt.plt0_entry = htab->lazy_plt->pic_plt0_entry;
+         htab->plt.plt_entry = htab->lazy_plt->pic_plt_entry;
        }
       else
        {
-         plt_layout->plt0_entry
-           = lazy_plt_layout->plt0_entry;
-         plt_layout->plt_entry
-           = lazy_plt_layout->plt_entry;
+         htab->plt.plt0_entry = htab->lazy_plt->plt0_entry;
+         htab->plt.plt_entry = htab->lazy_plt->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->eh_frame_plt_size
-       = lazy_plt_layout->eh_frame_plt_size;
-      plt_layout->eh_frame_plt
-       = lazy_plt_layout->eh_frame_plt;
+
+      htab->plt.plt_entry_size = htab->lazy_plt->plt_entry_size;
+      htab->plt.plt_got_offset = htab->lazy_plt->plt_got_offset;
+      htab->plt.eh_frame_plt_size = htab->lazy_plt->eh_frame_plt_size;
+      htab->plt.eh_frame_plt = htab->lazy_plt->eh_frame_plt;
     }
 
+  /* This is unused for i386.  */
+  htab->plt.plt_got_insn_size = 0;
+
   /* Return if there are no normal input files.  */
   if (dynobj == NULL)
     return pbfd;
@@ -6421,7 +6232,7 @@ error_alignment:
   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);
+  plt_alignment = bfd_log2 (htab->plt.plt_entry_size);
 
   if (pltsec != NULL)
     {
@@ -6450,7 +6261,7 @@ error_alignment:
                               | SEC_LOAD
                               | SEC_READONLY);
          unsigned int non_lazy_plt_alignment
-           = bfd_log2 (non_lazy_plt_layout->plt_entry_size);
+           = bfd_log2 (htab->non_lazy_plt->plt_entry_size);
 
          sec = pltsec;
          if (!bfd_set_section_alignment (sec->owner, sec,
@@ -6567,7 +6378,6 @@ error_alignment:
 #define bfd_elf32_mkobject                   elf_i386_mkobject
 
 #define bfd_elf32_bfd_is_local_label_name     elf_i386_is_local_label_name
-#define bfd_elf32_bfd_link_hash_table_create  elf_i386_link_hash_table_create
 #define bfd_elf32_bfd_reloc_type_lookup              elf_i386_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup              elf_i386_reloc_name_lookup
 #define bfd_elf32_get_synthetic_symtab       elf_i386_get_synthetic_symtab
@@ -6919,17 +6729,20 @@ static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
     DW_CFA_nop, DW_CFA_nop
   };
 
-static const struct elf_i386_lazy_plt_layout elf_i386_nacl_plt =
+static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt =
   {
     elf_i386_nacl_plt0_entry,          /* plt0_entry */
     sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */
-    2,                                 /* plt0_got1_offset */
-    8,                                 /* plt0_got2_offset */
     elf_i386_nacl_plt_entry,           /* plt_entry */
     NACL_PLT_ENTRY_SIZE,               /* plt_entry_size */
+    2,                                 /* plt0_got1_offset */
+    8,                                 /* plt0_got2_offset */
+    0,                                 /* plt0_got2_insn_end */
     2,                                 /* plt_got_offset */
     33,                                        /* plt_reloc_offset */
     38,                                        /* plt_plt_offset */
+    0,                                 /* plt_got_insn_size */
+    0,                                 /* plt_plt_insn_end */
     32,                                        /* plt_lazy_offset */
     elf_i386_nacl_pic_plt0_entry,      /* pic_plt0_entry */
     elf_i386_nacl_pic_plt_entry,       /* pic_plt_entry */
index 985f7f6d5cd370c0502fa13f5d07bfd65a2a8f8d..3bf465b46fa83c2f228ecd24495133dbac85cf8f 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 */
+    NULL,                               /* pic_plt0_entry */
+    NULL,                               /* 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 */
+    NULL,                               /* 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 */
+    NULL,                               /* pic_plt0_entry */
+    NULL,                               /* 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 */
+    NULL,                               /* 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 */
+    NULL,                               /* pic_plt0_entry */
+    NULL,                               /* 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 */
+    NULL,                               /* pic_plt0_entry */
+    NULL,                               /* 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 */
+    NULL,                               /* 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 */
+    NULL,                               /* pic_plt_entry */
     LAZY_PLT_ENTRY_SIZE,                /* plt_entry_size */
     4+2,                                /* plt_got_offset */
     4+6,                                /* plt_got_insn_size */
@@ -1056,88 +992,9 @@ elf_x86_64_mkobject (bfd *abfd)
                                  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_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)
 {
@@ -2791,8 +2648,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;
@@ -2805,9 +2660,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,
@@ -2846,7 +2699,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))
        {
@@ -2857,7 +2710,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;
@@ -2899,7 +2752,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;
@@ -2944,12 +2797,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
@@ -3332,8 +3185,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)
@@ -3344,9 +3195,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)
@@ -3503,9 +3351,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;
        }
     }
 
@@ -3534,14 +3382,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.  */
@@ -3550,7 +3398,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.
@@ -3626,7 +3474,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);
     }
@@ -3635,7 +3483,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
@@ -3646,7 +3494,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
@@ -3792,7 +3640,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);
@@ -3970,7 +3818,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;
                    }
@@ -4201,7 +4049,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;
                }
@@ -5356,9 +5204,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)
@@ -5371,10 +5216,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.  */
@@ -5433,24 +5274,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;
@@ -5471,7 +5312,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)
@@ -5481,7 +5322,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
@@ -5489,11 +5330,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.  */
@@ -5528,15 +5369,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
@@ -5547,7 +5388,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);
@@ -5578,8 +5419,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.  */
@@ -5589,7 +5430,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;
@@ -5601,7 +5442,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
@@ -5865,9 +5706,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 ();
@@ -5918,22 +5756,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,
@@ -5944,7 +5778,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.  */
@@ -5954,9 +5788,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)
                {
@@ -5964,8 +5798,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.  */
@@ -5979,7 +5813,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
@@ -5991,21 +5825,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
@@ -6182,7 +6016,7 @@ struct elf_x86_64_plt
 };
 
 /* 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.   */
@@ -6202,12 +6036,12 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
   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;
+  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;
@@ -6730,9 +6564,6 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info)
   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)
@@ -6849,12 +6680,10 @@ error_alignment:
        }
     }
 
-  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;
+  htab->plt.has_plt0 = 1;
 
   if (get_elf_x86_64_backend_data (info->output_bfd)->os
       == is_normal)
@@ -6863,79 +6692,71 @@ error_alignment:
        {
          if (ABI_64_P (dynobj))
            {
-             elf_x86_64_lazy_plt (htab)
+             htab->lazy_plt
                = &elf_x86_64_lazy_ibt_plt;
-             elf_x86_64_non_lazy_plt (htab)
+             htab->non_lazy_plt
                = &elf_x86_64_non_lazy_ibt_plt;
            }
          else
            {
-             elf_x86_64_lazy_plt (htab)
+             htab->lazy_plt
                = &elf_x32_lazy_ibt_plt;
-             elf_x86_64_non_lazy_plt (htab)
+             htab->non_lazy_plt
                = &elf_x32_non_lazy_ibt_plt;
            }
        }
       else if (info->bndplt)
        {
-         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;
+         htab->lazy_plt = &elf_x86_64_lazy_bnd_plt;
+         htab->non_lazy_plt = &elf_x86_64_non_lazy_bnd_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;
+         htab->lazy_plt = &elf_x86_64_lazy_plt;
+         htab->non_lazy_plt = &elf_x86_64_non_lazy_plt;
        }
       normal_target = TRUE;
     }
   else
     {
-      elf_x86_64_lazy_plt (htab) = &elf_x86_64_nacl_plt;
-      elf_x86_64_non_lazy_plt (htab) = NULL;
+      htab->lazy_plt = &elf_x86_64_nacl_plt;
+      htab->non_lazy_plt = 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))
+  if (htab->non_lazy_plt != NULL
+      && (!htab->plt.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;
+      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;
-      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;
+      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;
     }
 
+  /* This is unused for x86-64.  */
+  htab->plt.plt0_entry = NULL;
+
   /* Return if there are no normal input files.  */
   if (dynobj == NULL)
     return pbfd;
@@ -6963,7 +6784,7 @@ error_alignment:
   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);
+  plt_alignment = bfd_log2 (htab->plt.plt_entry_size);
 
   if (pltsec != NULL)
     {
@@ -6992,7 +6813,7 @@ error_alignment:
                               | SEC_LOAD
                               | SEC_READONLY);
          unsigned int non_lazy_plt_alignment
-           = bfd_log2 (non_lazy_plt_layout->plt_entry_size);
+           = bfd_log2 (htab->non_lazy_plt->plt_entry_size);
 
          sec = pltsec;
          if (!bfd_set_section_alignment (sec->owner, sec,
@@ -7150,8 +6971,6 @@ 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
@@ -7401,9 +7220,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 */
@@ -7415,6 +7235,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 */
+    NULL,                                    /* pic_plt0_entry */
+    NULL,                                    /* 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 */
   };
@@ -7455,8 +7277,6 @@ 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 \
index 1c8380ddf053cb8ed076ed0888030292001e3f57..ccd6e1058ae2f5f7d54badb96b939003b8739946 100644 (file)
    MA 02110-1301, USA.  */
 
 #include "elfxx-x86.h"
+#include "objalloc.h"
+#include "elf/i386.h"
+#include "elf/x86-64.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"
 
 /* _TLS_MODULE_BASE_ needs to be treated especially when linking
    executables.  Rather than setting it to the beginning of the TLS
@@ -217,8 +227,8 @@ _bfd_x86_elf_local_htab_eq (const void *ptr1, const void *ptr2)
 
 /* Destroy an x86 ELF linker hash table.  */
 
-void
-_bfd_x86_elf_link_hash_table_free (bfd *obfd)
+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;
@@ -230,6 +240,77 @@ _bfd_x86_elf_link_hash_table_free (bfd *obfd)
   _bfd_elf_link_hash_table_free (obfd);
 }
 
+/* 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;
+  bfd_size_type 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;
+    }
+
+#ifdef BFD64
+  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;
+      ret->tls_get_addr = "__tls_get_addr";
+    }
+  else
+#endif
+    {
+      ret->r_info = elf32_r_info;
+      ret->r_sym = elf32_r_sym;
+      if (bed->elf_machine_code == EM_X86_64)
+       {
+         ret->pointer_r_type = R_X86_64_32;
+         ret->dynamic_interpreter = ELFX32_DYNAMIC_INTERPRETER;
+         ret->dynamic_interpreter_size
+           = sizeof ELFX32_DYNAMIC_INTERPRETER;
+         ret->tls_get_addr = "__tls_get_addr";
+       }
+      else
+       {
+         ret->pointer_r_type = R_386_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)
+    {
+      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
index 480189bfd40eacb4ba773be16f517dd526f6bfa3..21e16a2f1011fae847892ef36baaa7e0da66d8d8 100644 (file)
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "bfd_stdint.h"
-#include "objalloc.h"
 #include "hashtab.h"
 
+#define ABI_64_P(abfd) \
+  (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
 /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
    copying dynamic variables from a shared lib into an app's dynbss
    section, and instead use a dynamic relocation to point into the
@@ -118,6 +120,105 @@ struct elf_x86_link_hash_entry
   bfd_vma tlsdesc_got;
 };
 
+struct elf_x86_lazy_plt_layout
+{
+  /* The first entry in an absolute lazy procedure linkage table looks
+     like this.  */
+  const bfd_byte *plt0_entry;
+  unsigned int plt0_entry_size;          /* Size of PLT0 entry.  */
+
+  /* Later entries in an absolute lazy procedure linkage table look
+     like this.  */
+  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.  This is for x86-64 only.  */
+  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.
+     This is used for x86-64 only.  */
+  unsigned int plt_got_insn_size;
+
+  /* Offset of the end of the PC-relative jump to plt0_entry.  This is
+     used for x86-64 only.  */
+  unsigned int plt_plt_insn_end;
+
+  /* Offset into plt_entry where the initial value of the GOT entry
+     points.  */
+  unsigned int plt_lazy_offset;
+
+  /* The first entry in a PIC lazy procedure linkage table looks like
+     this.  This is used for i386 only.  */
+  const bfd_byte *pic_plt0_entry;
+
+  /* Subsequent entries in a PIC lazy procedure linkage table look
+     like this.  This is used for i386 only.  */
+  const bfd_byte *pic_plt_entry;
+
+  /* .eh_frame covering the lazy .plt section.  */
+  const bfd_byte *eh_frame_plt;
+  unsigned int eh_frame_plt_size;
+};
+
+struct elf_x86_non_lazy_plt_layout
+{
+  /* Entries in an absolute non-lazy procedure linkage table look like
+     this.  */
+  const bfd_byte *plt_entry;
+  /* Entries in a PIC non-lazy procedure linkage table look like this.
+     This is used for i386 only.  */
+  const bfd_byte *pic_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.
+     This is used for x86-64 only.  */
+  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_plt_layout
+{
+  /* The first entry in a lazy procedure linkage table looks like this.
+     This is only used for i386 where absolute PLT0 and PIC PLT0 are
+     different.  */
+  const bfd_byte *plt0_entry;
+  /* Entries in a procedure linkage table look like this.  */
+  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.
+     This is only used for x86-64.  */
+  unsigned int plt_got_insn_size;
+
+  /* .eh_frame covering the .plt section.  */
+  const bfd_byte *eh_frame_plt;
+  unsigned int eh_frame_plt_size;
+};
+
 /* The first 3 values in tls_type of x86 ELF linker hash entry.  */
 #define GOT_UNKNOWN    0
 #define GOT_NORMAL     1
@@ -140,6 +241,15 @@ struct elf_x86_link_hash_table
   asection *plt_got;
   asection *plt_got_eh_frame;
 
+  /* Parameters describing PLT generation, lazy or non-lazy.  */
+  struct elf_x86_plt_layout plt;
+
+  /* Parameters describing lazy PLT generation.  */
+  const struct elf_x86_lazy_plt_layout *lazy_plt;
+
+  /* Parameters describing non-lazy PLT generation.  */
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
+
   union
   {
     bfd_signed_vma refcount;
@@ -178,6 +288,14 @@ struct elf_x86_link_hash_table
      to read-only sections.  */
   bfd_boolean readonly_dynrelocs_against_ifunc;
 
+  /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.
+     This is used for i386 only.  */
+  asection *srelplt2;
+
+  /* The index of the next unused R_386_TLS_DESC slot in .rel.plt.  This
+     is used for i386 only.  */
+  bfd_vma next_tls_desc_index;
+
   bfd_vma (*r_info) (bfd_vma, bfd_vma);
   bfd_vma (*r_sym) (bfd_vma);
   unsigned int pointer_r_type;
@@ -228,7 +346,7 @@ extern int _bfd_x86_elf_local_htab_eq
 extern struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc
   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 
-extern void _bfd_x86_elf_link_hash_table_free
+extern struct bfd_link_hash_table * _bfd_x86_elf_link_hash_table_create
   (bfd *);
 
 extern int _bfd_x86_elf_compare_relocs
@@ -260,6 +378,10 @@ extern enum elf_property_kind _bfd_x86_elf_parse_gnu_properties
 extern bfd_boolean _bfd_x86_elf_merge_gnu_properties
   (struct bfd_link_info *, bfd *, elf_property *, elf_property *);
 
+#define bfd_elf64_bfd_link_hash_table_create \
+  _bfd_x86_elf_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+  _bfd_x86_elf_link_hash_table_create
 #define bfd_elf64_bfd_link_check_relocs        \
   _bfd_x86_elf_link_check_relocs
 #define bfd_elf32_bfd_link_check_relocs \