2001-02-14 Bo Thorsen <bo@suse.de>
authorAndreas Jaeger <aj@suse.de>
Wed, 14 Feb 2001 10:57:47 +0000 (10:57 +0000)
committerAndreas Jaeger <aj@suse.de>
Wed, 14 Feb 2001 10:57:47 +0000 (10:57 +0000)
* elf64-x86-64.c: Small formatting fixes and rearrangements of code.
(elf64_86_64_size_info): Struct added to fix a problem
with the hashtable string entries.
(elf64_x86_64_adjust_dynamic_symbol): Add generation of .got.plt.
(elf64_x86_64_size_dynamic_sections): A FIXME removed.
(elf64_x86_64_size_dynamic_sections): Fix a dynamic entry and
remove the FIXME for this.
(elf64_x86_64_adjust_dynamic_symbol): Fix check for unneeded .plt
section. Also removed the FIXME for it.
(x86_64_elf_howto_table): Use bfd_elf_generic_reloc.
(ELF_DYNAMIC_INTERPRETER): Fix the name of the dynamic linker.
(elf64_x86_64_finish_dynamic_sections): Enable .got.plt writing.

bfd/ChangeLog
bfd/elf64-x86-64.c

index ae04d073982433171ccfc6b3f3e753702035a5db..9a0da2a172a0b15439e51c7b36bdf9d68387d24b 100644 (file)
@@ -1,3 +1,18 @@
+2001-02-14  Bo Thorsen  <bo@suse.de>
+
+       * elf64-x86-64.c: Small formatting fixes and rearrangements of code.
+       (elf64_86_64_size_info): Struct added to fix a problem
+       with the hashtable string entries.
+       (elf64_x86_64_adjust_dynamic_symbol): Add generation of .got.plt.
+       (elf64_x86_64_size_dynamic_sections): A FIXME removed.
+       (elf64_x86_64_size_dynamic_sections): Fix a dynamic entry and
+       remove the FIXME for this.
+       (elf64_x86_64_adjust_dynamic_symbol): Fix check for unneeded .plt
+       section. Also removed the FIXME for it.
+       (x86_64_elf_howto_table): Use bfd_elf_generic_reloc.
+       (ELF_DYNAMIC_INTERPRETER): Fix the name of the dynamic linker.
+       (elf64_x86_64_finish_dynamic_sections): Enable .got.plt writing.
+
 2001-02-13  Richard Henderson  <rth@redhat.com>
 
        * elfxx-ia64.c (elfNN_ia64_final_link): Set __gp if required
index 288377c734e31fd432c059ba009c7e35dbd981d5..9e10c917f0d50542046371d7463685d4053003f7 100644 (file)
@@ -32,26 +32,42 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define MINUS_ONE (~ (bfd_vma) 0)
 
 /* The relocation "howto" table.  Order of fields:
-   type, size, bitsize, pc_relative, complain_on_overflow, special_function,
-   name, partial_inplace, src_mask, dst_pack, pcrel_offset  */
+   type, size, bitsize, pc_relative, complain_on_overflow,
+   special_function, name, partial_inplace, src_mask, dst_pack, pcrel_offset.  */
 static reloc_howto_type x86_64_elf_howto_table[] =
 {
-  HOWTO(R_X86_64_NONE,          0,0, 0,false,0,complain_overflow_dont,    0, "R_X86_64_NONE",   false,0x00000000,0x00000000,false),
-  HOWTO(R_X86_64_64,    0,4,64,false,0,complain_overflow_bitfield,0, "R_X86_64_64",     false,MINUS_ONE ,MINUS_ONE ,false),
-  HOWTO(R_X86_64_PC32,          0,4,32,true ,0,complain_overflow_signed  ,0, "R_X86_64_PC32",   false,0xffffffff,0xffffffff,true),
-  HOWTO(R_X86_64_GOT32,         0,4,32,false,0,complain_overflow_signed  ,0, "R_X86_64_GOT32",  false,0xffffffff,0xffffffff,false),
-  HOWTO(R_X86_64_PLT32,         0,4,32,true ,0,complain_overflow_signed  ,0, "R_X86_64_PLT32",  false,0xffffffff,0xffffffff,true),
-  HOWTO(R_X86_64_COPY,     0,4,32,false,0,complain_overflow_bitfield,0, "R_X86_64_COPY",   false,0xffffffff,0xffffffff,false),
-  HOWTO(R_X86_64_GLOB_DAT, 0,4,64,false,0,complain_overflow_bitfield,0,"R_X86_64_GLOB_DAT",false,MINUS_ONE ,MINUS_ONE ,false),
-  HOWTO(R_X86_64_RELATIVE ,0,4,64,false,0,complain_overflow_bitfield,0,"R_X86_64_RELATIVE",false,MINUS_ONE ,MINUS_ONE ,false),
-  HOWTO(R_X86_64_JUMP_SLOT,0,4,64,false,0,complain_overflow_bitfield,0,"R_X86_64_JUMP_SLOT",false,MINUS_ONE,MINUS_ONE ,false),
-  HOWTO(R_X86_64_GOTPCREL, 0,4,32,true, 0,complain_overflow_signed  ,0, "R_X86_64_GOTPCREL",false,0xffffffff,0xffffffff,true),
-  HOWTO(R_X86_64_32,    0,4,32,false,0,complain_overflow_unsigned,0, "R_X86_64_32",     false,0xffffffff,0xffffffff,false),
-  HOWTO(R_X86_64_32S,   0,4,32,false,0,complain_overflow_signed,  0, "R_X86_64_32S",    false,0xffffffff,0xffffffff,false),
-  HOWTO(R_X86_64_16,    0,1,16,false,0,complain_overflow_bitfield,0, "R_X86_64_16",     false,0xffff    ,0xffff,    false),
-  HOWTO(R_X86_64_PC16,          0,1,16,true ,0,complain_overflow_bitfield,0, "R_X86_64_PC16",   false,0xffff    ,0xffff,    true),
-  HOWTO(R_X86_64_8,     0,0, 8,false,0,complain_overflow_signed  ,0, "R_X86_64_8",      false,0xff      ,0xff,      false),
-  HOWTO(R_X86_64_PC8,   0,0, 8,true ,0,complain_overflow_signed  ,0, "R_X86_64_PC8",    false,0xff      ,0xff,      true),
+  HOWTO(R_X86_64_NONE, 0, 0, 0, false, 0, complain_overflow_dont,
+       bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0x00000000, 0x00000000, false),
+  HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_64", false, MINUS_ONE, MINUS_ONE, false),
+  HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0xffffffff, 0xffffffff, true),
+  HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0xffffffff, 0xffffffff, false),
+  HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0xffffffff, 0xffffffff, true),
+  HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0xffffffff, 0xffffffff, false),
+  HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, MINUS_ONE, MINUS_ONE, false),
+  HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, MINUS_ONE, MINUS_ONE, false),
+  HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, MINUS_ONE, MINUS_ONE, false),
+  HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true,0 , complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0xffffffff, 0xffffffff, true),
+  HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned,
+       bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff, false),
+  HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_32S", false, 0xffffffff, 0xffffffff, false),
+  HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false),
+  HOWTO(R_X86_64_PC16,0, 1, 16, true, 0, complain_overflow_bitfield,
+       bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true),
+  HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false),
+  HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed,
+       bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0xff, 0xff, true)
 };
 
 /* Map BFD relocs to the x86_64 elf relocs.  */
@@ -97,7 +113,7 @@ static boolean elf64_x86_64_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static boolean elf64_x86_64_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-         Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+        Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
 static boolean elf64_x86_64_finish_dynamic_symbol
   PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
           Elf_Internal_Sym *sym));
@@ -137,12 +153,12 @@ elf64_x86_64_info_to_howto (abfd, cache_ptr, dst)
   BFD_ASSERT (r_type == cache_ptr->howto->type);
 }
 \f
-/* Functions for the x86-64 ELF linker.  */
+/* Functions for the x86-64 ELF linker.         */
 
-/* The name of the dynamic interpreter.  This is put in the .interp
+/* The name of the dynamic interpreter.         This is put in the .interp
    section.  */
 
-#define ELF_DYNAMIC_INTERPRETER "/lib/libd64.so.1"
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
 
 /* The size in bytes of an entry in the global offset table.  */
 
@@ -159,7 +175,7 @@ static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
 {
   0xff, 0xb3, 8, 0, 0, 0,      /* pushq GOT+8(%rip) */
   0xff, 0xa3, 16, 0, 0, 0,     /* jmp GOT+16(%rip) */
-  0, 0, 0, 0                   /* pad out to 16 bytes.  */
+  0, 0, 0, 0                   /* pad out to 16 bytes.  */
 };
 
 /* Subsequent entries in a procedure linkage table look like this.  */
@@ -167,7 +183,7 @@ static const bfd_byte elf64_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
 static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] =
 {
   0xff, 0xa3,  /* jmp *name@GOTPC(%rip) */
-  0, 0, 0, 0,  /* replaced with offset to this symbol in .got.  */
+  0, 0, 0, 0,  /* replaced with offset to this symbol in .got.  */
   0x68,        /* pushq immediate */
   0, 0, 0, 0,  /* replaced with index into relocation table.  */
   0xe9,                /* jmp relative */
@@ -175,10 +191,10 @@ static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] =
 };
 
 /* The x86-64 linker needs to keep track of the number of relocs that
-   it decides to copy in check_relocs for each symbol.  This is so
+   it decides to copy in check_relocs for each symbol. This is so
    that it can discard PC relative relocs if it doesn't need them when
    linking with -Bsymbolic.  We store the information in a field
-   extending the regular ELF linker hash table.  */
+   extending the regular ELF linker hash table.         */
 
 /* This structure keeps track of the number of PC relative relocs we
    have copied for a given symbol.  */
@@ -205,7 +221,8 @@ struct elf64_x86_64_link_hash_entry
 
 /* x86-64  ELF linker hash table.  */
 
-struct elf64_x86_64_link_hash_table {
+struct elf64_x86_64_link_hash_table
+{
   struct elf_link_hash_table root;
 };
 
@@ -227,7 +244,7 @@ static boolean elf64_x86_64_discard_copies
 #define elf64_x86_64_hash_table(p) \
   ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
 
-/* Create an entry in an x86-64 ELF linker hash table.  */
+/* Create an entry in an x86-64 ELF linker hash table. */
 
 static struct bfd_hash_entry *
 elf64_x86_64_link_hash_newfunc (entry, table, string)
@@ -239,7 +256,7 @@ elf64_x86_64_link_hash_newfunc (entry, table, string)
     (struct elf64_x86_64_link_hash_entry *) entry;
 
   /* Allocate the structure if it has not already been allocated by a
-     subclass.  */
+     subclass. */
   if (ret == (struct elf64_x86_64_link_hash_entry *) NULL)
     ret = ((struct elf64_x86_64_link_hash_entry *)
           bfd_hash_allocate (table,
@@ -351,7 +368,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
        {
        case R_X86_64_GOTPCREL:
        case R_X86_64_GOT32:
-         /* This symbol requires a global offset table entry.  */
+         /* This symbol requires a global offset table entry.  */
 
          if (sgot == NULL)
            {
@@ -432,14 +449,14 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
 
        case R_X86_64_PLT32:
          /* This symbol requires a procedure linkage table entry.  We
-             actually build the entry in adjust_dynamic_symbol,
-             because this might be a case of linking PIC code which is
-             never referenced by a dynamic object, in which case we
-             don't need to generate a procedure linkage table entry
-             after all.  */
+            actually build the entry in adjust_dynamic_symbol,
+            because this might be a case of linking PIC code which is
+            never referenced by a dynamic object, in which case we
+            don't need to generate a procedure linkage table entry
+            after all.  */
 
          /* If this is a local symbol, we resolve it directly without
-             creating a procedure linkage table entry.  */
+            creating a procedure linkage table entry.  */
          if (h == NULL)
            continue;
 
@@ -464,7 +481,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
             into the shared library.  However, if we are linking with
             -Bsymbolic, we do not need to copy a reloc against a
             global symbol which is defined in an object we are
-            including in the link (i.e., DEF_REGULAR is set).  At
+            including in the link (i.e., DEF_REGULAR is set).  At
             this point we have not seen all the input files, so it is
             possible that DEF_REGULAR is not set now but will be set
             later (it is never cleared).  We account for that
@@ -558,7 +575,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
 }
 
 /* Return the section that should be marked against GC for a given
-   relocation.  */
+   relocation. */
 
 static asection *
 elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym)
@@ -597,7 +614,7 @@ elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym)
   return NULL;
 }
 
-/* Update the got entry reference counts for the section being removed.  */
+/* Update the got entry reference counts for the section being removed.         */
 
 static boolean
 elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)
@@ -683,7 +700,7 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
    change the definition to something the rest of the link can
-   understand.  */
+   understand. */
 
 static boolean
 elf64_x86_64_adjust_dynamic_symbol (info, h)
@@ -713,21 +730,16 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
   if (h->type == STT_FUNC
       || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
     {
-      if (! elf_hash_table (info)->dynamic_sections_created)
+      if ((! info->shared
+          && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+          && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+         || (info->shared && h->plt.refcount <= 0))
        {
-         /* FIXME: These are the sparc64 comment and then the i386 comment.
-            How we need to deal with this and why remains to be seen.  */
-         /* This case can occur if we saw a WPLT30 reloc in an input
-             file, but none of the input files were dynamic objects.
-             In such a case, we don't actually need to build a
-             procedure linkage table, and we can just do a WDISP30
-             reloc instead.  */
          /* This case can occur if we saw a PLT32 reloc in an input
             file, but the symbol was never referred to by a dynamic
             object, or if all references were garbage collected.  In
             such a case, we don't actually need to build a procedure
             linkage table, and we can just do a PC32 reloc instead.  */
-         /* i386 code: */
          h->plt.offset = (bfd_vma) -1;
          h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
          return true;
@@ -750,7 +762,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
 
       /* If this symbol is not defined in a regular file, and we are
         not generating a shared library, then set the symbol to this
-        location in the .plt.  This is required to make function
+        location in the .plt.  This is required to make function
         pointers compare as equal between the normal executable and
         the shared library.  */
       if (! info->shared
@@ -765,6 +777,12 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
       /* Make room for this entry.  */
       s->_raw_size += PLT_ENTRY_SIZE;
 
+      /* We also need to make an entry in the .got.plt section, which
+        will be placed in the .got section by the linker script.  */
+      s = bfd_get_section_by_name (dynobj, ".got.plt");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size += GOT_ENTRY_SIZE;
+
       /* We also need to make an entry in the .rela.plt section.  */
       s = bfd_get_section_by_name (dynobj, ".rela.plt");
       BFD_ASSERT (s != NULL);
@@ -775,7 +793,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
 
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
-     real definition first, and we can just use the same value.  */
+     real definition first, and we can just use the same value.         */
   if (h->weakdef != NULL)
     {
       BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
@@ -786,12 +804,12 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
     }
 
   /* This is a reference to a symbol defined by a dynamic object which
-     is not a function.  */
+     is not a function.         */
 
   /* If we are creating a shared library, we must presume that the
      only references to the symbol are via the global offset table.
      For such cases we need not do anything here; the relocations will
-     be handled correctly by relocate_section.  */
+     be handled correctly by relocate_section. */
   if (info->shared)
     return true;
 
@@ -801,7 +819,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
     return true;
 
   /* We must allocate the symbol in our .dynbss section, which will
-     become part of the .bss section of the executable.  There will be
+     become part of the .bss section of the executable.         There will be
      an entry for this symbol in the .dynsym section.  The dynamic
      object will contain position independent code, so all references
      from the dynamic object to this symbol will go through the global
@@ -828,7 +846,7 @@ elf64_x86_64_adjust_dynamic_symbol (info, h)
     }
 
   /* We need to figure out the alignment required for this symbol.  I
-     have no idea how ELF linkers handle this.  16-bytes is the size
+     have no idea how ELF linkers handle this. 16-bytes is the size
      of the largest type that requires hard alignment -- long double.  */
   /* FIXME: This is VERY ugly. Should be fixed for all architectures using
      this construct.  */
@@ -884,10 +902,10 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
   else
     {
       /* We may have created entries in the .rela.got section.
-         However, if we are not creating the dynamic sections, we will
-         not actually use these entries.  Reset the size of .rela.got,
-         which will cause it to get stripped from the output file
-         below.  */
+        However, if we are not creating the dynamic sections, we will
+        not actually use these entries.  Reset the size of .rela.got,
+        which will cause it to get stripped from the output file
+        below.  */
       s = bfd_get_section_by_name (dynobj, ".rela.got");
       if (s != NULL)
        s->_raw_size = 0;
@@ -924,7 +942,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
          if (s->_raw_size == 0)
            {
              /* Strip this section if we don't need it; see the
-                 comment below.  */
+                comment below.  */
              strip = true;
            }
          else
@@ -953,7 +971,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
              asection *target;
 
              /* Remember whether there are any reloc sections other
-                 than .rela.plt.  */
+                than .rela.plt.  */
              if (strcmp (name, ".rela.plt") != 0)
                {
                  const char *outname;
@@ -1006,7 +1024,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
       /* Add some entries to the .dynamic section.  We fill in the
         values later, in elf64_x86_64_finish_dynamic_sections, but we
         must add the entries now so that we get the correct size for
-        the .dynamic section.  The DT_DEBUG entry is filled in by the
+        the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
       if (! info->shared)
        {
@@ -1016,10 +1034,9 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info)
 
       if (plt)
        {
-         /* FIXME: Are all these needed?  */
          if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
              || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+             || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
              || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
            return false;
        }
@@ -1079,7 +1096,7 @@ elf64_x86_64_discard_copies (h, inf)
 
 static boolean
 elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
-                             contents, relocs, local_syms, local_sections)
+                            contents, relocs, local_syms, local_sections)
      bfd *output_bfd;
      struct bfd_link_info *info;
      bfd *input_bfd;
@@ -1155,7 +1172,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
          continue;
        }
 
-      /* This is a final link.  */
+      /* This is a final link. */
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -1228,15 +1245,15 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
                {
                  /* This is actually a static link, or it is a -Bsymbolic
                     link and the symbol is defined locally, or the symbol
-                    was forced to be local because of a version file.  We
+                    was forced to be local because of a version file.  We
                     must initialize this entry in the global offset table.
                     Since the offset must always be a multiple of 8, we
                     use the least significant bit to record whether we
                     have initialized it already.
 
                     When doing a dynamic link, we create a .rela.got
-                    relocation entry to initialize the value.  This is
-                    done in the finish_dynamic_symbol routine.  */
+                    relocation entry to initialize the value.  This is
+                    done in the finish_dynamic_symbol routine.  */
                  if ((off & 1) != 0)
                    off &= ~1;
                  else
@@ -1258,8 +1275,8 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
              off = local_got_offsets[r_symndx];
 
              /* The offset must always be a multiple of 8.  We use
-                 the least significant bit to record whether we have
-                 already generated the necessary reloc.  */
+                the least significant bit to record whether we have
+                already generated the necessary reloc.  */
              if ((off & 1) != 0)
                off &= ~1;
              else
@@ -1312,15 +1329,15 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
                {
                  /* This is actually a static link, or it is a -Bsymbolic
                     link and the symbol is defined locally, or the symbol
-                    was forced to be local because of a version file.  We
+                    was forced to be local because of a version file.  We
                     must initialize this entry in the global offset table.
                     Since the offset must always be a multiple of 8, we
                     use the least significant bit to record whether we
                     have initialized it already.
 
                     When doing a dynamic link, we create a .rela.got
-                    relocation entry to initialize the value.  This is
-                    done in the finish_dynamic_symbol routine.  */
+                    relocation entry to initialize the value.  This is
+                    done in the finish_dynamic_symbol routine.  */
                  if ((off & 1) != 0)
                    off &= ~1;
                  else
@@ -1342,8 +1359,8 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
              off = local_got_offsets[r_symndx];
 
              /* The offset must always be a multiple of 8.  We use
-                 the least significant bit to record whether we have
-                 already generated the necessary reloc.  */
+                the least significant bit to record whether we have
+                already generated the necessary reloc.  */
              if ((off & 1) != 0)
                off &= ~1;
              else
@@ -1384,15 +1401,15 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
             procedure linkage table.  */
 
          /* Resolve a PLT32 reloc against a local symbol directly,
-             without using the procedure linkage table.  */
+            without using the procedure linkage table.  */
          if (h == NULL)
            break;
 
          if (h->plt.offset == (bfd_vma) -1 || splt == NULL)
            {
              /* We didn't make a PLT entry for this symbol.  This
-                 happens when statically linking PIC code, or when
-                 using -Bsymbolic.  */
+                happens when statically linking PIC code, or when
+                using -Bsymbolic.  */
              break;
            }
 
@@ -1408,7 +1425,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_X86_64_PC16:
        case R_X86_64_PC32:
          /* FIXME: The abi says the linker should make sure the value is
-            the same when it's zeroextended to 64 bit.  */
+            the same when it's zeroextended to 64 bit.  */
          if (info->shared
              && (input_section->flags & SEC_ALLOC) != 0
              && ((r_type != R_X86_64_PC8 && r_type != R_X86_64_PC16
@@ -1424,7 +1441,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
 
              /* When generating a shared object, these relocations
                 are copied into the output file to be resolved at run
-                time.  */
+                time.  */
 
              if (sreloc == NULL)
                {
@@ -1483,7 +1500,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
              else
                {
                  /* h->dynindx may be -1 if this symbol was marked to
-                     become local.  */
+                    become local.  */
                  if (h == NULL
                      || ((info->symbolic || h->dynindx == -1)
                          && (h->elf_link_hash_flags
@@ -1586,7 +1603,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)
       Elf_Internal_Rela rela;
 
       /* This symbol has an entry in the procedure linkage table.  Set
-        it up.  */
+        it up.  */
 
       BFD_ASSERT (h->dynindx != -1);
 
@@ -1602,7 +1619,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)
       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 
       /* Get the offset into the .got table of the entry that
-        corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
+        corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
         bytes. The first three are reserved.  */
       got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
 
@@ -1619,7 +1636,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)
       bfd_put_64 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
                  splt->contents + h->plt.offset + 12);
 
-      /* Fill in the entry in the global offset table.  */
+      /* Fill in the entry in the global offset table. */
       bfd_put_64 (output_bfd, (splt->output_section->vma + splt->output_offset
                               + h->plt.offset + 6),
                  sgot->contents + got_offset);
@@ -1637,7 +1654,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)
       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
        {
          /* Mark the symbol as undefined, rather than as defined in
-            the .plt section.  Leave the value alone.  */
+            the .plt section.  Leave the value alone.  */
          sym->st_shndx = SHN_UNDEF;
        }
     }
@@ -1696,8 +1713,7 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
       asection *splt;
       Elf64_External_Dyn *dyncon, *dynconend;
 
-      splt = bfd_get_section_by_name (dynobj, ".plt");
-      BFD_ASSERT (splt != NULL && sdyn != NULL);
+      BFD_ASSERT (sdyn != NULL);
 
       dyncon = (Elf64_External_Dyn *) sdyn->contents;
       dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
@@ -1730,14 +1746,14 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
            case DT_RELASZ:
              /* FIXME: This comment and code is from elf64-alpha.c:  */
              /* My interpretation of the TIS v1.1 ELF document indicates
-                that RELASZ should not include JMPREL.  This is not what
+                that RELASZ should not include JMPREL.  This is not what
                 the rest of the BFD does.  It is, however, what the
                 glibc ld.so wants.  Do this fixup here until we found
                 out who is right.  */
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
              if (s)
                {
-                 /* Subtract JMPREL size from RELASZ.  */
+                 /* Subtract JMPREL size from RELASZ.  */
                  dyn.d_un.d_val -=
                    (s->_cooked_size ? s->_cooked_size : s->_raw_size);
                }
@@ -1755,9 +1771,11 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
        }
 
       /* Initialize the contents of the .plt section.  */
+      splt = bfd_get_section_by_name (dynobj, ".plt");
+      BFD_ASSERT (splt != NULL);
       if (splt->_raw_size > 0)
        {
-           memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE);
+         memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE);
        }
 
       elf_section_data (splt->output_section)->this_hdr.sh_entsize =
@@ -1766,7 +1784,7 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
 
   /* Set the first entry in the global offset table to the address of
      the dynamic section.  */
-  sgot = bfd_get_section_by_name (dynobj, ".got");
+  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
   BFD_ASSERT (sgot != NULL);
   if (sgot->_raw_size > 0)
     {
@@ -1787,12 +1805,49 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
   return true;
 }
 
+/*
+ * Why was the hash table entry size definition changed from
+ * ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
+ * this is the only reason for the elf64_x86_64_size_info structure.
+ */
+
+const struct elf_size_info elf64_86_64_size_info =
+{
+  sizeof (Elf64_External_Ehdr),
+  sizeof (Elf64_External_Phdr),
+  sizeof (Elf64_External_Shdr),
+  sizeof (Elf64_External_Rel),
+  sizeof (Elf64_External_Rela),
+  sizeof (Elf64_External_Sym),
+  sizeof (Elf64_External_Dyn),
+  sizeof (Elf_External_Note),
+  8,           /* hash-table entry size */
+  1,           /* internal relocations per external relocations */
+  64,          /* arch_size */
+  8,           /* file_align */
+  ELFCLASS64, EV_CURRENT,
+  bfd_elf64_write_out_phdrs,
+  bfd_elf64_write_shdrs_and_ehdr,
+  bfd_elf64_write_relocs,
+  bfd_elf64_swap_symbol_out,
+  bfd_elf64_slurp_reloc_table,
+  bfd_elf64_slurp_symbol_table,
+  bfd_elf64_swap_dyn_in,
+  bfd_elf64_swap_dyn_out,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
+
 #define TARGET_LITTLE_SYM                  bfd_elf64_x86_64_vec
 #define TARGET_LITTLE_NAME                 "elf64-x86-64"
 #define ELF_ARCH                           bfd_arch_i386
 #define ELF_MACHINE_CODE                   EM_X86_64
 #define ELF_MAXPAGESIZE                            0x100000
 
+#define elf_backend_size_info              elf64_86_64_size_info
+
 #define elf_backend_can_gc_sections        1
 #define elf_backend_want_got_plt           1
 #define elf_backend_plt_readonly           1
@@ -1801,13 +1856,11 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_plt_header_size        PLT_ENTRY_SIZE
 
 #define elf_info_to_howto                  elf64_x86_64_info_to_howto
-#define elf_backend_object_p               elf64_x86_64_elf_object_p
-#define elf_backend_relocate_section       elf64_x86_64_relocate_section
 
 #define bfd_elf64_bfd_final_link           _bfd_elf64_gc_common_final_link
 #define bfd_elf64_bfd_link_hash_table_create \
   elf64_x86_64_link_hash_table_create
-#define bfd_elf64_bfd_reloc_type_lookup     elf64_x86_64_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_type_lookup            elf64_x86_64_reloc_type_lookup
 
 #define elf_backend_adjust_dynamic_symbol   elf64_x86_64_adjust_dynamic_symbol
 #define elf_backend_check_relocs           elf64_x86_64_check_relocs
@@ -1819,5 +1872,6 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_gc_sweep_hook          elf64_x86_64_gc_sweep_hook
 #define elf_backend_relocate_section       elf64_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections
+#define elf_backend_object_p               elf64_x86_64_elf_object_p
 
 #include "elf64-target.h"