Copy relocations against protected symbols
[deliverable/binutils-gdb.git] / bfd / elf64-sh64.c
index fe3195ca3a097b7d7066ea8989fc90e427dd67b6..74979293169ab70c1311ff266d9bbbbb62332abf 100644 (file)
@@ -1,11 +1,11 @@
 /* SuperH SH64-specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000-2014 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 #define SH64_ELF64
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
@@ -87,92 +88,18 @@ struct elf_sh64_link_hash_entry
   struct elf_sh64_pcrel_relocs_copied *pcrel_relocs_copied;
 };
 
-/* sh ELF linker hash table.  */
-
-struct elf_sh64_link_hash_table
-{
-  struct elf_link_hash_table root;
-};
-
 /* Traverse an sh ELF linker hash table.  */
 
-#define sh64_elf64_link_hash_traverse(table, func, info)               \
-  (elf_link_hash_traverse                                              \
-   (&(table)->root,                                                    \
-    (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+#define sh64_elf64_link_hash_traverse(table, func, info)       \
+  (elf_link_hash_traverse                                      \
+   ((table),                                                   \
+    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
     (info)))
 
-/* Get the sh ELF linker hash table from a link_info structure.  */
-
-#define sh64_elf64_hash_table(p) \
-  ((struct elf_sh64_link_hash_table *) ((p)->hash))
-
-static bfd_boolean sh_elf64_copy_private_data
-  PARAMS ((bfd *, bfd *));
-static bfd_boolean sh_elf64_copy_private_data_internal
-  PARAMS ((bfd *, bfd *));
-static bfd_boolean sh_elf64_merge_private_data
-  PARAMS ((bfd *, bfd *));
 static bfd_reloc_status_type sh_elf64_ignore_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type sh_elf64_reloc
-  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
-static reloc_howto_type *sh_elf64_reloc_type_lookup
-  PARAMS ((bfd *, bfd_reloc_code_real_type));
-static void sh_elf64_info_to_howto
-  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
-static bfd_boolean sh_elf64_relocate_section
-  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
-static bfd_byte *sh_elf64_get_relocated_section_contents
-  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
-          bfd_byte *, bfd_boolean, asymbol **));
-static bfd_boolean sh_elf64_set_mach_from_flags
-  PARAMS ((bfd *));
-static bfd_boolean sh_elf64_set_private_flags
-  PARAMS ((bfd *, flagword));
-static asection *sh_elf64_gc_mark_hook
-  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-          struct elf_link_hash_entry *, Elf_Internal_Sym *));
-static bfd_boolean sh_elf64_gc_sweep_hook
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-static bfd_boolean sh_elf64_check_relocs
-  PARAMS ((bfd *, struct bfd_link_info *, asection *,
-          const Elf_Internal_Rela *));
-static int sh64_elf64_get_symbol_type
-  PARAMS ((Elf_Internal_Sym *, int));
-static bfd_boolean sh64_elf64_add_symbol_hook
-  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
-          const char **, flagword *, asection **, bfd_vma *));
-static bfd_boolean sh64_elf64_link_output_symbol_hook
-  PARAMS ((bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
-          asection *));
-static bfd_boolean sh64_elf64_fake_sections
-  PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
-static void sh64_elf64_final_write_processing
-  PARAMS ((bfd *, bfd_boolean));
-static struct bfd_hash_entry *sh64_elf64_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
-static struct bfd_link_hash_table *sh64_elf64_link_hash_table_create
-  PARAMS ((bfd *));
-inline static void movi_shori_putval
-  PARAMS ((bfd *, unsigned long, char *));
-inline static void movi_3shori_putval
-  PARAMS ((bfd *, bfd_vma, char *));
-static bfd_boolean sh64_elf64_create_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean sh64_elf64_adjust_dynamic_symbol
-  PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *));
-static bfd_boolean sh64_elf64_discard_copies
-  PARAMS ((struct elf_sh64_link_hash_entry *, PTR));
-static bfd_boolean sh64_elf64_size_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
-static bfd_boolean sh64_elf64_finish_dynamic_symbol
-  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-          Elf_Internal_Sym *));
-static bfd_boolean sh64_elf64_finish_dynamic_sections
-  PARAMS ((bfd *, struct bfd_link_info *));
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 
 static reloc_howto_type sh_elf64_howto_table[] = {
   /* No relocation.  */
@@ -1300,15 +1227,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
    which the linker should otherwise ignore.  */
 
 static bfd_reloc_status_type
-sh_elf64_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
-                    output_bfd, error_message)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *reloc_entry;
-     asymbol *symbol ATTRIBUTE_UNUSED;
-     PTR data ATTRIBUTE_UNUSED;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+sh_elf64_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+                      asymbol *symbol ATTRIBUTE_UNUSED,
+                      void *data ATTRIBUTE_UNUSED, asection *input_section,
+                      bfd *output_bfd,
+                      char **error_message ATTRIBUTE_UNUSED)
 {
   if (output_bfd != NULL)
     reloc_entry->address += input_section->output_offset;
@@ -1321,15 +1244,9 @@ sh_elf64_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
    See sh_elf_reloc in elf32-sh.c for the original.  */
 
 static bfd_reloc_status_type
-sh_elf64_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
-         error_message)
-     bfd *abfd;
-     arelent *reloc_entry;
-     asymbol *symbol_in;
-     PTR data;
-     asection *input_section;
-     bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+sh_elf64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
+               void *data, asection *input_section, bfd *output_bfd,
+               char **error_message ATTRIBUTE_UNUSED)
 {
   unsigned long insn;
   bfd_vma sym_value;
@@ -1449,9 +1366,8 @@ static const struct elf_reloc_map sh64_reloc_map[] =
    corresponding SH ELf reloc.  */
 
 static reloc_howto_type *
-sh_elf64_reloc_type_lookup (abfd, code)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     bfd_reloc_code_real_type code;
+sh_elf64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                           bfd_reloc_code_real_type code)
 {
   unsigned int i;
 
@@ -1464,15 +1380,29 @@ sh_elf64_reloc_type_lookup (abfd, code)
   return NULL;
 }
 
+static reloc_howto_type *
+sh_elf64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                           const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (sh_elf64_howto_table) / sizeof (sh_elf64_howto_table[0]);
+       i++)
+    if (sh_elf64_howto_table[i].name != NULL
+       && strcasecmp (sh_elf64_howto_table[i].name, r_name) == 0)
+      return &sh_elf64_howto_table[i];
+
+  return NULL;
+}
+
 /* Given an ELF reloc, fill in the howto field of a relent.
 
    See sh_elf_info_to_howto in elf32-sh.c for the original.  */
 
 static void
-sh_elf64_info_to_howto (abfd, cache_ptr, dst)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *cache_ptr;
-     Elf_Internal_Rela *dst;
+sh_elf64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+                       Elf_Internal_Rela *dst)
 {
   unsigned int r;
 
@@ -1492,16 +1422,12 @@ sh_elf64_info_to_howto (abfd, cache_ptr, dst)
    See sh_elf_info_to_howto in elf32-sh.c for the original.  */
 
 static bfd_boolean
-sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
-                          contents, relocs, local_syms, local_sections)
-     bfd *output_bfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info;
-     bfd *input_bfd;
-     asection *input_section;
-     bfd_byte *contents;
-     Elf_Internal_Rela *relocs;
-     Elf_Internal_Sym *local_syms;
-     asection **local_sections;
+sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+                          struct bfd_link_info *info, bfd *input_bfd,
+                          asection *input_section, bfd_byte *contents,
+                          Elf_Internal_Rela *relocs,
+                          Elf_Internal_Sym *local_syms,
+                          asection **local_sections)
 {
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
@@ -1551,8 +1477,10 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
              && r_type <= (int) R_SH_LAST_INVALID_RELOC)
          || (r_type >= (int) R_SH_DIR8WPN
-             && r_type <= (int) R_SH_LAST_INVALID_RELOC_2)
-         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
+             && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+         || (r_type >= (int) R_SH_GNU_VTINHERIT
+             && r_type <= (int) R_SH_PSHL)
+         || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
              && r_type <= R_SH_GOTPLT32)
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
              && r_type <= (int) R_SH_LAST_INVALID_RELOC_4))
@@ -1563,10 +1491,10 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
 
       howto = sh_elf64_howto_table + r_type;
 
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
+      relocation = 0;
       if (r_symndx < symtab_hdr->sh_info)
        {
          sym = local_syms + r_symndx;
@@ -1585,13 +1513,15 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
              _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
              input_bfd, input_section, rel->r_offset));
 
-         if (info->relocateable)
+         if (sec != NULL && discarded_section (sec))
+           /* Handled below.  */
+           ;
+         else if (info->relocatable)
            {
-             /* This is a relocateable link.  We don't have to change
+             /* This is a relocatable link.  We don't have to change
                 anything, unless the reloc is against a section symbol,
                 in which case we have to adjust according to where the
                 section symbol winds up in the output section.  */
-             sym = local_syms + r_symndx;
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
                goto final_link_relocate;
 
@@ -1599,7 +1529,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          else if (! howto->partial_inplace)
            {
-             relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+             relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
              relocation |= ((sym->st_other & STO_SH5_ISA32) != 0);
            }
          else if ((sec->flags & SEC_MERGE)
@@ -1610,9 +1540,8 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
              if (howto->rightshift || howto->src_mask != 0xffffffff)
                {
                  (*_bfd_error_handler)
-                   (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"),
-                    bfd_archive_filename (input_bfd),
-                    bfd_get_section_name (input_bfd, input_section),
+                   (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+                    input_bfd, input_section,
                     (long) rel->r_offset, howto->name);
                  return FALSE;
                }
@@ -1629,11 +1558,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
        }
       else
        {
-         /* Section symbols are never (?) placed in the hash table, so
-            we can just ignore hash relocations when creating a
-            relocateable object file.  */
-         if (info->relocateable)
-           continue;
+         /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ?  */
 
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
          while (h->root.type == bfd_link_hash_indirect
@@ -1669,8 +1594,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                      && elf_hash_table (info)->dynamic_sections_created
                      && (! info->shared
                          || (! info->symbolic && h->dynindx != -1)
-                         || (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) == 0))
+                         || !h->def_regular))
                  /* The cases above are those in which relocation is
                     overwritten in the switch block below.  The cases
                     below are those in which we must defer relocation
@@ -1678,8 +1602,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                     addresses when creating a shared library.  */
                  || (info->shared
                      && ((! info->symbolic && h->dynindx != -1)
-                         || (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) == 0)
+                         || !h->def_regular)
                      && ((r_type == R_SH_64
                           && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
                                || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN))
@@ -1695,18 +1618,9 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                     thus ld.so will not process them.  */
                  || (sec->output_section == NULL
                      && ((input_section->flags & SEC_DEBUGGING) != 0
-                         && (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))
-               relocation = 0;
-             else if (sec->output_section == NULL)
-               {
-                 (*_bfd_error_handler)
-                   (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
-                    bfd_get_filename (input_bfd), h->root.root.string,
-                    bfd_get_section_name (input_bfd, input_section));
-                 relocation = 0;
-               }
-             else
+                         && h->def_dynamic)))
+               ;
+             else if (sec->output_section != NULL)
                relocation = ((h->root.u.def.value
                               + sec->output_section->vma
                               + sec->output_offset)
@@ -1715,21 +1629,44 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                                 STT_DATALABEL on the way to it.  */
                              | ((h->other & STO_SH5_ISA32) != 0
                                 && ! seen_stt_datalabel));
+             else if (!info->relocatable
+                      && (_bfd_elf_section_offset (output_bfd, info,
+                                                   input_section,
+                                                   rel->r_offset)
+                          != (bfd_vma) -1))
+               {
+                 (*_bfd_error_handler)
+                   (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+                    input_bfd,
+                    input_section,
+                    (long) rel->r_offset,
+                    howto->name,
+                    h->root.root.string);
+               }
            }
          else if (h->root.type == bfd_link_hash_undefweak)
-           relocation = 0;
-         else if (info->shared && !info->symbolic && !info->no_undefined)
-           relocation = 0;
-         else
+           ;
+         else if (info->unresolved_syms_in_objects == RM_IGNORE
+                  && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+           ;
+         else if (!info->relocatable)
            {
              if (! ((*info->callbacks->undefined_symbol)
                     (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset, TRUE)))
+                     input_section, rel->r_offset,
+                     (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+                      || ELF_ST_VISIBILITY (h->other)))))
                return FALSE;
-             relocation = 0;
            }
        }
 
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
+
+      if (info->relocatable)
+       continue;
+
       disp = (relocation
              - input_section->output_section->vma
              - input_section->output_offset
@@ -1760,8 +1697,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                  || (h != NULL
                      && h->dynindx != -1
                      && (! info->symbolic
-                         || (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                         || !h->def_regular))))
            {
              Elf_Internal_Rela outrel;
              bfd_byte *loc;
@@ -1773,22 +1709,10 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
 
              if (sreloc == NULL)
                {
-                 const char *name;
-
-                 name = (bfd_elf_string_from_elf_section
-                         (input_bfd,
-                          elf_elfheader (input_bfd)->e_shstrndx,
-                          elf_section_data (input_section)->rel_hdr.sh_name));
-                 if (name == NULL)
+                 sreloc = _bfd_elf_get_dynamic_reloc_section
+                   (input_bfd, input_section, /*rela?*/ TRUE);
+                 if (sreloc == NULL)
                    return FALSE;
-
-                 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
-                             && strcmp (bfd_get_section_name (input_bfd,
-                                                              input_section),
-                                        name + 5) == 0);
-
-                 sreloc = bfd_get_section_by_name (dynobj, name);
-                 BFD_ASSERT (sreloc != NULL);
                }
 
              skip = FALSE;
@@ -1820,8 +1744,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                     become local.  */
                  if (h == NULL
                      || ((info->symbolic || h->dynindx == -1)
-                         && (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) != 0))
+                         && h->def_regular))
                    {
                      relocate = TRUE;
                      outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
@@ -1873,7 +1796,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
             offset table extension for the procedure linkage table.  */
          if (sgotplt == NULL)
            {
-             sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+             sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
              BFD_ASSERT (sgotplt != NULL);
            }
 
@@ -1896,7 +1819,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
             offset table.  */
          if (sgot == NULL)
            {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
+             sgot = bfd_get_linker_section (dynobj, ".got");
              BFD_ASSERT (sgot != NULL);
            }
 
@@ -1919,7 +1842,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                      && (info->symbolic || h->dynindx == -1
                          || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
                          || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
-                     && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+                     && h->def_regular))
                {
                  /* This is actually a static link, or it is a
                     -Bsymbolic link and the symbol is defined
@@ -1990,7 +1913,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                      Elf_Internal_Rela outrel;
                      bfd_byte *loc;
 
-                     s = bfd_get_section_by_name (dynobj, ".rela.got");
+                     s = bfd_get_linker_section (dynobj, ".rela.got");
                      BFD_ASSERT (s != NULL);
 
                      outrel.r_offset = (sgot->output_section->vma
@@ -2025,7 +1948,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
 
          if (sgot == NULL)
            {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
+             sgot = bfd_get_linker_section (dynobj, ".got");
              BFD_ASSERT (sgot != NULL);
            }
 
@@ -2050,7 +1973,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
 
          if (sgot == NULL)
            {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
+             sgot = bfd_get_linker_section (dynobj, ".got");
              BFD_ASSERT (sgot != NULL);
            }
 
@@ -2088,7 +2011,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
 
          if (splt == NULL)
            {
-             splt = bfd_get_section_by_name (dynobj, ".plt");
+             splt = bfd_get_linker_section (dynobj, ".plt");
              BFD_ASSERT (splt != NULL);
            }
 
@@ -2148,7 +2071,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                const char *name;
 
                if (h != NULL)
-                 name = h->root.root.string;
+                 name = NULL;
                else
                  {
                    name = (bfd_elf_string_from_elf_section
@@ -2159,8 +2082,9 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
                      name = bfd_section_name (input_bfd, sec);
                  }
                if (! ((*info->callbacks->reloc_overflow)
-                      (info, name, howto->name, (bfd_vma) 0,
-                       input_bfd, input_section, rel->r_offset)))
+                      (info, (h ? &h->root : NULL), name, howto->name,
+                       (bfd_vma) 0, input_bfd, input_section,
+                       rel->r_offset)))
                  return FALSE;
              }
              break;
@@ -2177,14 +2101,12 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section,
    See sh_elf_relocate_section in elf32-sh.c for the original.  */
 
 static bfd_byte *
-sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
-                                        data, relocateable, symbols)
-     bfd *output_bfd;
-     struct bfd_link_info *link_info;
-     struct bfd_link_order *link_order;
-     bfd_byte *data;
-     bfd_boolean relocateable;
-     asymbol **symbols;
+sh_elf64_get_relocated_section_contents (bfd *output_bfd,
+                                        struct bfd_link_info *link_info,
+                                        struct bfd_link_order *link_order,
+                                        bfd_byte *data,
+                                        bfd_boolean relocatable,
+                                        asymbol **symbols)
 {
   Elf_Internal_Shdr *symtab_hdr;
   asection *input_section = link_order->u.indirect.section;
@@ -2195,17 +2117,17 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
 
   /* We only need to handle the case of relaxing, or of having a
      particular set of section contents, specially.  */
-  if (relocateable
+  if (relocatable
       || elf_section_data (input_section)->this_hdr.contents == NULL)
     return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
                                                       link_order, data,
-                                                      relocateable,
+                                                      relocatable,
                                                       symbols);
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
-         input_section->_raw_size);
+         input_section->size);
 
   if ((input_section->flags & SEC_RELOC) != 0
       && input_section->reloc_count > 0)
@@ -2227,7 +2149,7 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
        }
 
       internal_relocs = (_bfd_elf_link_read_relocs
-                        (input_bfd, input_section, (PTR) NULL,
+                        (input_bfd, input_section, NULL,
                          (Elf_Internal_Rela *) NULL, FALSE));
       if (internal_relocs == NULL)
        goto error_return;
@@ -2245,17 +2167,12 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
 
          if (isymp->st_shndx == SHN_UNDEF)
            isec = bfd_und_section_ptr;
-         else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
-           isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
          else if (isymp->st_shndx == SHN_ABS)
            isec = bfd_abs_section_ptr;
          else if (isymp->st_shndx == SHN_COMMON)
            isec = bfd_com_section_ptr;
          else
-           {
-             /* Who knows?  */
-             isec = NULL;
-           }
+           isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
 
          *secpp = isec;
        }
@@ -2290,11 +2207,10 @@ sh_elf64_get_relocated_section_contents (output_bfd, link_info, link_order,
 
 /* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections.  */
 
-bfd_boolean
-sh64_elf64_fake_sections (output_bfd, elf_section_hdr, asect)
-     bfd *output_bfd ATTRIBUTE_UNUSED;
-     Elf_Internal_Shdr *elf_section_hdr;
-     asection *asect;
+static bfd_boolean
+sh64_elf64_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+                         Elf_Internal_Shdr *elf_section_hdr,
+                         asection *asect)
 {
   /* Code sections can only contain SH64 code, so mark them as such.  */
   if (bfd_get_section_flags (output_bfd, asect) & SEC_CODE)
@@ -2304,8 +2220,7 @@ sh64_elf64_fake_sections (output_bfd, elf_section_hdr, asect)
 }
 
 static bfd_boolean
-sh_elf64_set_mach_from_flags (abfd)
-     bfd *abfd;
+sh_elf64_set_mach_from_flags (bfd *abfd)
 {
   flagword flags = elf_elfheader (abfd)->e_flags;
 
@@ -2328,9 +2243,7 @@ sh_elf64_set_mach_from_flags (abfd)
    See sh64_elf_set_private_flags in elf32-sh64.c for the original.  */
 
 static bfd_boolean
-sh_elf64_set_private_flags (abfd, flags)
-     bfd *    abfd;
-     flagword flags;
+sh_elf64_set_private_flags (bfd *abfd, flagword flags)
 {
   BFD_ASSERT (! elf_flags_init (abfd)
              || elf_elfheader (abfd)->e_flags == flags);
@@ -2344,9 +2257,7 @@ sh_elf64_set_private_flags (abfd, flags)
    code, to keep attributes the same as for SHmedia in 32-bit ELF.  */
 
 static bfd_boolean
-sh_elf64_copy_private_data_internal (ibfd, obfd)
-     bfd * ibfd;
-     bfd * obfd;
+sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd)
 {
   Elf_Internal_Shdr **o_shdrp;
   asection *isec;
@@ -2373,21 +2284,20 @@ sh_elf64_copy_private_data_internal (ibfd, obfd)
        }
     }
 
+  /* Copy object attributes.  */
+  _bfd_elf_copy_private_bfd_data (ibfd, obfd);
+  
   return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
 }
 
 static bfd_boolean
-sh_elf64_copy_private_data (ibfd, obfd)
-     bfd * ibfd;
-     bfd * obfd;
+sh_elf64_copy_private_data (bfd *ibfd, bfd *obfd)
 {
   return sh_elf64_copy_private_data_internal (ibfd, obfd);
 }
 
 static bfd_boolean
-sh_elf64_merge_private_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
 {
   flagword old_flags, new_flags;
 
@@ -2450,56 +2360,21 @@ sh_elf64_merge_private_data (ibfd, obfd)
    relocation.  */
 
 static asection *
-sh_elf64_gc_mark_hook (sec, info, rel, h, sym)
-     asection *sec;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     Elf_Internal_Rela *rel;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+sh_elf64_gc_mark_hook (asection *sec,
+                      struct bfd_link_info *info,
+                      Elf_Internal_Rela *rel,
+                      struct elf_link_hash_entry *h,
+                      Elf_Internal_Sym *sym)
 {
   if (h != NULL)
-    {
-      switch (ELF64_R_TYPE (rel->r_info))
-       {
-       case R_SH_GNU_VTINHERIT:
-       case R_SH_GNU_VTENTRY:
-         break;
-
-       default:
-         while (h->root.type == bfd_link_hash_indirect
-                && h->root.u.i.link)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-         switch (h->root.type)
-           {
-           case bfd_link_hash_defined:
-           case bfd_link_hash_defweak:
-             return h->root.u.def.section;
-
-           case bfd_link_hash_common:
-             return h->root.u.c.p->section;
-
-           default:
-             break;
-           }
-       }
-    }
-  else
-    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
-  return NULL;
-}
-
-/* Update the got entry reference counts for the section being removed.  */
+    switch (ELF64_R_TYPE (rel->r_info))
+      {
+      case R_SH_GNU_VTINHERIT:
+      case R_SH_GNU_VTENTRY:
+       return NULL;
+      }
 
-static bfd_boolean
-sh_elf64_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     asection *sec ATTRIBUTE_UNUSED;
-     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
-{
-  /* No got and plt entries for 64-bit SH at present.  */
-  return TRUE;
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
 /* Look through the relocs for a section during the first phase.
@@ -2507,14 +2382,11 @@ sh_elf64_gc_sweep_hook (abfd, info, sec, relocs)
    virtual table relocs for gc.  */
 
 static bfd_boolean
-sh_elf64_check_relocs (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
+                      asection *sec, const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   bfd *dynobj;
@@ -2527,14 +2399,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
   srelgot = NULL;
   sreloc = NULL;
 
-  if (info->relocateable)
+  if (info->relocatable)
     return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
 
   dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (abfd);
@@ -2549,7 +2418,16 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
       if (r_symndx < symtab_hdr->sh_info)
         h = NULL;
       else
-        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+       {
+         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+         /* PR15323, ref flags aren't set for references in the same
+            object.  */
+         h->root.non_ir_ref = 1;
+       }
 
       /* Some relocs require a global offset table.  */
       if (dynobj == NULL)
@@ -2591,14 +2469,16 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
         case R_SH_GNU_VTINHERIT:
-          if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
             return FALSE;
           break;
 
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
         case R_SH_GNU_VTENTRY:
-          if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+          BFD_ASSERT (h != NULL);
+          if (h != NULL
+              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
             return FALSE;
           break;
 
@@ -2613,25 +2493,23 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
 
          if (sgot == NULL)
            {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
+             sgot = bfd_get_linker_section (dynobj, ".got");
              BFD_ASSERT (sgot != NULL);
            }
 
          if (srelgot == NULL
              && (h != NULL || info->shared))
            {
-             srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+             srelgot = bfd_get_linker_section (dynobj, ".rela.got");
              if (srelgot == NULL)
                {
-                 srelgot = bfd_make_section (dynobj, ".rela.got");
+                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+                                   | SEC_IN_MEMORY | SEC_LINKER_CREATED
+                                   | SEC_READONLY);
+                 srelgot = bfd_make_section_anyway_with_flags (dynobj,
+                                                               ".rela.got",
+                                                               flags);
                  if (srelgot == NULL
-                     || ! bfd_set_section_flags (dynobj, srelgot,
-                                                 (SEC_ALLOC
-                                                  | SEC_LOAD
-                                                  | SEC_HAS_CONTENTS
-                                                  | SEC_IN_MEMORY
-                                                  | SEC_LINKER_CREATED
-                                                  | SEC_READONLY))
                      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
                    return FALSE;
                }
@@ -2648,7 +2526,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
                  if (hsh->datalabel_got_offset != (bfd_vma) -1)
                    break;
 
-                 hsh->datalabel_got_offset = sgot->_raw_size;
+                 hsh->datalabel_got_offset = sgot->size;
                }
              else
                {
@@ -2657,17 +2535,17 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
                      /* We have already allocated space in the .got.  */
                      break;
                    }
-                 h->got.offset = sgot->_raw_size;
+                 h->got.offset = sgot->size;
                }
 
              /* Make sure this symbol is output as a dynamic symbol.  */
              if (h->dynindx == -1)
                {
-                 if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+                 if (! bfd_elf_link_record_dynamic_symbol (info, h))
                    return FALSE;
                }
 
-             srelgot->_raw_size += sizeof (Elf64_External_Rela);
+             srelgot->size += sizeof (Elf64_External_Rela);
            }
          else
            {
@@ -2700,7 +2578,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
                      break;
                    }
                  local_got_offsets[symtab_hdr->sh_info
-                                   + r_symndx] = sgot->_raw_size;
+                                   + r_symndx] = sgot->size;
                }
              else
                {
@@ -2709,7 +2587,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
                      /* We have already allocated space in the .got.  */
                      break;
                    }
-                 local_got_offsets[r_symndx] = sgot->_raw_size;
+                 local_got_offsets[r_symndx] = sgot->size;
                }
 
              if (info->shared)
@@ -2717,11 +2595,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
                  /* If we are generating a shared object, we need to
                     output a R_SH_RELATIVE reloc so that the dynamic
                     linker can adjust this GOT entry.  */
-                 srelgot->_raw_size += sizeof (Elf64_External_Rela);
+                 srelgot->size += sizeof (Elf64_External_Rela);
                }
            }
 
-         sgot->_raw_size += 8;
+         sgot->size += 8;
 
          break;
 
@@ -2746,11 +2624,11 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
          /* Make sure this symbol is output as a dynamic symbol.  */
          if (h->dynindx == -1)
            {
-             if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+             if (! bfd_elf_link_record_dynamic_symbol (info, h))
                return FALSE;
            }
 
-         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 1;
 
          break;
 
@@ -2774,14 +2652,14 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
              || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
            break;
 
-         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->needs_plt = 1;
 
          break;
 
        case R_SH_64:
        case R_SH_64_PCREL:
          if (h != NULL)
-           h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+           h->non_got_ref = 1;
 
          /* If we are creating a shared library, and this is a reloc
             against a global symbol, or a non PC relative reloc
@@ -2800,45 +2678,21 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
              && (ELF32_R_TYPE (rel->r_info) != R_SH_64_PCREL
                  || (h != NULL
                      && (! info->symbolic
-                         || (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                         || !h->def_regular))))
            {
              /* When creating a shared object, we must copy these
                 reloc types into the output file.  We create a reloc
                 section in dynobj and make room for this reloc.  */
              if (sreloc == NULL)
                {
-                 const char *name;
-
-                 name = (bfd_elf_string_from_elf_section
-                         (abfd,
-                          elf_elfheader (abfd)->e_shstrndx,
-                          elf_section_data (sec)->rel_hdr.sh_name));
-                 if (name == NULL)
-                   return FALSE;
+                 sreloc = _bfd_elf_make_dynamic_reloc_section
+                   (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
 
-                 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
-                             && strcmp (bfd_get_section_name (abfd, sec),
-                                        name + 5) == 0);
-
-                 sreloc = bfd_get_section_by_name (dynobj, name);
                  if (sreloc == NULL)
-                   {
-                     flagword flags;
-
-                     sreloc = bfd_make_section (dynobj, name);
-                     flags = (SEC_HAS_CONTENTS | SEC_READONLY
-                              | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-                     if ((sec->flags & SEC_ALLOC) != 0)
-                       flags |= SEC_ALLOC | SEC_LOAD;
-                     if (sreloc == NULL
-                         || ! bfd_set_section_flags (dynobj, sreloc, flags)
-                         || ! bfd_set_section_alignment (dynobj, sreloc, 2))
-                       return FALSE;
-                   }
+                   return FALSE;
                }
 
-             sreloc->_raw_size += sizeof (Elf64_External_Rela);
+             sreloc->size += sizeof (Elf64_External_Rela);
 
              /* If we are linking with -Bsymbolic, and this is a
                 global symbol, we count the number of PC relative
@@ -2884,9 +2738,7 @@ sh_elf64_check_relocs (abfd, info, sec, relocs)
 }
 
 static int
-sh64_elf64_get_symbol_type (elf_sym, type)
-     Elf_Internal_Sym * elf_sym;
-     int type;
+sh64_elf64_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
 {
   if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
     return STT_DATALABEL;
@@ -2917,26 +2769,22 @@ sh64_elf64_get_symbol_type (elf_sym, type)
    (not so good).  */
 
 static bfd_boolean
-sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     const Elf_Internal_Sym *sym;
-     const char **namep;
-     flagword *flagsp ATTRIBUTE_UNUSED;
-     asection **secp;
-     bfd_vma *valp;
+sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+                           Elf_Internal_Sym *sym, const char **namep,
+                           flagword *flagsp ATTRIBUTE_UNUSED,
+                           asection **secp, bfd_vma *valp)
 {
   /* We want to do this for relocatable as well as final linking.  */
   if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
-      && info->hash->creator->flavour == bfd_target_elf_flavour)
+      && is_elf_hash_table (info->hash))
     {
       struct elf_link_hash_entry *h;
 
-      /* For relocateable links, we register the DataLabel sym in its own
+      /* For relocatable links, we register the DataLabel sym in its own
         right, and tweak the name when it's output.  Otherwise, we make
         an indirect symbol of it.  */
       flagword flags
-       = info->relocateable || info->emitrelocations
+       = info->relocatable || info->emitrelocations
        ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
 
       char *dl_name
@@ -2959,7 +2807,7 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
        {
          /* No previous datalabel symbol.  Make one.  */
          struct bfd_link_hash_entry *bh = NULL;
-         struct elf_backend_data *bed = get_elf_backend_data (abfd);
+         const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
          if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
                                                  flags, *secp, *valp,
@@ -2971,7 +2819,7 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
            }
 
          h = (struct elf_link_hash_entry *) bh;
-         h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+         h->non_elf = 0;
          h->type = STT_DATALABEL;
        }
       else
@@ -2980,9 +2828,9 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
        free (dl_name);
 
       if (h->type != STT_DATALABEL
-         || ((info->relocateable || info->emitrelocations)
+         || ((info->relocatable || info->emitrelocations)
              && h->root.type != bfd_link_hash_undefined)
-         || (! info->relocateable && !info->emitrelocations
+         || (! info->relocatable && !info->emitrelocations
              && h->root.type != bfd_link_hash_indirect))
        {
          /* Make sure we don't get confused on invalid input.  */
@@ -3017,23 +2865,22 @@ sh64_elf64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
    we don't need to look up and make sure to emit the main symbol for each
    DataLabel symbol.  */
 
-static bfd_boolean
-sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info;
-     const char *cname;
-     Elf_Internal_Sym *sym;
-     asection *input_sec ATTRIBUTE_UNUSED;
+static int
+sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info,
+                                   const char *cname,
+                                   Elf_Internal_Sym *sym,
+                                   asection *input_sec ATTRIBUTE_UNUSED,
+                                   struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
 {
   char *name = (char *) cname;
 
-  if (info->relocateable || info->emitrelocations)
+  if (info->relocatable || info->emitrelocations)
     {
       if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
        name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
     }
 
-  return TRUE;
+  return 1;
 }
 
 /* Set bit 0 on the entry address; it always points to SHmedia code.  This
@@ -3044,9 +2891,8 @@ sh64_elf64_link_output_symbol_hook (abfd, info, cname, sym, input_sec)
    before jumping to the program entry.  */
 
 static void
-sh64_elf64_final_write_processing (abfd, linker)
-     bfd *abfd;
-     bfd_boolean linker ATTRIBUTE_UNUSED;
+sh64_elf64_final_write_processing (bfd *abfd,
+                                  bfd_boolean linker ATTRIBUTE_UNUSED)
 {
   /* FIXME: Perhaps we shouldn't do this if the entry address was supplied
      numerically, but we currently lack the infrastructure to recognize
@@ -3190,10 +3036,9 @@ static const bfd_byte *elf_sh64_pic_plt_entry;
 /* Create an entry in an sh ELF linker hash table.  */
 
 static struct bfd_hash_entry *
-sh64_elf64_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+sh64_elf64_link_hash_newfunc (struct bfd_hash_entry *entry,
+                             struct bfd_hash_table *table,
+                             const char *string)
 {
   struct elf_sh64_link_hash_entry *ret =
     (struct elf_sh64_link_hash_entry *) entry;
@@ -3223,31 +3068,28 @@ sh64_elf64_link_hash_newfunc (entry, table, string)
 /* Create an sh64 ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
-sh64_elf64_link_hash_table_create (abfd)
-     bfd *abfd;
+sh64_elf64_link_hash_table_create (bfd *abfd)
 {
-  struct elf_sh64_link_hash_table *ret;
+  struct elf_link_hash_table *ret;
 
-  ret = ((struct elf_sh64_link_hash_table *)
-        bfd_malloc (sizeof (struct elf_sh64_link_hash_table)));
-  if (ret == (struct elf_sh64_link_hash_table *) NULL)
+  ret = (struct elf_link_hash_table *) bfd_zmalloc (sizeof (* ret));
+  if (ret == (struct elf_link_hash_table *) NULL)
     return NULL;
 
-  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
-                                      sh64_elf64_link_hash_newfunc))
+  if (!_bfd_elf_link_hash_table_init (ret, abfd,
+                                     sh64_elf64_link_hash_newfunc,
+                                     sizeof (struct elf_sh64_link_hash_entry),
+                                     GENERIC_ELF_DATA))
     {
       free (ret);
       return NULL;
     }
 
-  return &ret->root.root;
+  return &ret->root;
 }
 
 inline static void
-movi_shori_putval (output_bfd, value, addr)
-     bfd *output_bfd;
-     unsigned long value;
-     char *addr;
+movi_shori_putval (bfd *output_bfd, unsigned long value, bfd_byte *addr)
 {
   bfd_put_32 (output_bfd,
              bfd_get_32 (output_bfd, addr)
@@ -3260,10 +3102,7 @@ movi_shori_putval (output_bfd, value, addr)
 }
 
 inline static void
-movi_3shori_putval (output_bfd, value, addr)
-     bfd *output_bfd;
-     bfd_vma value;
-     char *addr;
+movi_3shori_putval (bfd *output_bfd, bfd_vma value, bfd_byte *addr)
 {
   bfd_put_32 (output_bfd,
              bfd_get_32 (output_bfd, addr)
@@ -3286,13 +3125,11 @@ movi_3shori_putval (output_bfd, value, addr)
 /* Create dynamic sections when linking against a dynamic object.  */
 
 static bfd_boolean
-sh64_elf64_create_dynamic_sections (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   flagword flags, pltflags;
   register asection *s;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   int ptralign = 0;
 
   switch (bed->s->arch_size)
@@ -3323,9 +3160,8 @@ sh64_elf64_create_dynamic_sections (abfd, info)
   if (bed->plt_readonly)
     pltflags |= SEC_READONLY;
 
-  s = bfd_make_section (abfd, ".plt");
+  s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
   if (s == NULL
-      || ! bfd_set_section_flags (abfd, s, pltflags)
       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
     return FALSE;
 
@@ -3342,48 +3178,26 @@ sh64_elf64_create_dynamic_sections (abfd, info)
        return FALSE;
 
       h = (struct elf_link_hash_entry *) bh;
-      h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+      h->def_regular = 1;
       h->type = STT_OBJECT;
+      elf_hash_table (info)->hplt = h;
 
       if (info->shared
-         && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+         && ! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
     }
 
-  s = bfd_make_section (abfd,
-                       bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
+  s = bfd_make_section_anyway_with_flags (abfd,
+                                         bed->default_use_rela_p
+                                         ? ".rela.plt" : ".rel.plt",
+                                         flags | SEC_READONLY);
   if (s == NULL
-      || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
       || ! bfd_set_section_alignment (abfd, s, ptralign))
     return FALSE;
 
   if (! _bfd_elf_create_got_section (abfd, info))
     return FALSE;
 
-  {
-    const char *secname;
-    char *relname;
-    flagword secflags;
-    asection *sec;
-
-    for (sec = abfd->sections; sec; sec = sec->next)
-      {
-       secflags = bfd_get_section_flags (abfd, sec);
-       if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
-           || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
-         continue;
-       secname = bfd_get_section_name (abfd, sec);
-       relname = (char *) bfd_malloc (strlen (secname) + 6);
-       strcpy (relname, ".rela");
-       strcat (relname, secname);
-       s = bfd_make_section (abfd, relname);
-       if (s == NULL
-           || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
-           || ! bfd_set_section_alignment (abfd, s, ptralign))
-         return FALSE;
-      }
-  }
-
   if (bed->want_dynbss)
     {
       /* The .dynbss section is a place to put symbols which are defined
@@ -3392,9 +3206,9 @@ sh64_elf64_create_dynamic_sections (abfd, info)
         image and use a R_*_COPY reloc to tell the dynamic linker to
         initialize them at run time.  The linker script puts the .dynbss
         section into the .bss section of the final image.  */
-      s = bfd_make_section (abfd, ".dynbss");
-      if (s == NULL
-         || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
+      s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
+                                             SEC_ALLOC | SEC_LINKER_CREATED);
+      if (s == NULL)
        return FALSE;
 
       /* The .rel[a].bss section holds copy relocs.  This section is not
@@ -3410,11 +3224,11 @@ sh64_elf64_create_dynamic_sections (abfd, info)
         copy relocs.  */
       if (! info->shared)
        {
-         s = bfd_make_section (abfd,
-                               (bed->default_use_rela_p
-                                ? ".rela.bss" : ".rel.bss"));
+         s = bfd_make_section_anyway_with_flags (abfd,
+                                                 (bed->default_use_rela_p
+                                                  ? ".rela.bss" : ".rel.bss"),
+                                                 flags | SEC_READONLY);
          if (s == NULL
-             || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
              || ! bfd_set_section_alignment (abfd, s, ptralign))
            return FALSE;
        }
@@ -3430,60 +3244,55 @@ sh64_elf64_create_dynamic_sections (abfd, info)
    understand.  */
 
 static bfd_boolean
-sh64_elf64_adjust_dynamic_symbol (info, h)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
+sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
+                                 struct elf_link_hash_entry *h)
 {
   bfd *dynobj;
   asection *s;
-  unsigned int power_of_two;
 
   dynobj = elf_hash_table (info)->dynobj;
 
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
-             && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
-                 || h->weakdef != NULL
-                 || ((h->elf_link_hash_flags
-                      & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_REF_REGULAR) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+             && (h->needs_plt
+                 || h->u.weakdef != NULL
+                 || (h->def_dynamic
+                     && h->ref_regular
+                     && !h->def_regular)));
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later,
      when we know the address of the .got section.  */
   if (h->type == STT_FUNC
-      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
+      || h->needs_plt)
     {
       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)
+         && !h->def_dynamic
+         && !h->ref_dynamic)
        {
          /* This case can occur if we saw a PLT reloc in an input
             file, but the symbol was never referred to by a dynamic
             object.  In such a case, we don't actually need to build
             a procedure linkage table, and we can just do a REL64
             reloc instead.  */
-         BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+         BFD_ASSERT (h->needs_plt);
          return TRUE;
        }
 
       /* Make sure this symbol is output as a dynamic symbol.  */
       if (h->dynindx == -1)
        {
-         if (! bfd_elf64_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
-      s = bfd_get_section_by_name (dynobj, ".plt");
+      s = bfd_get_linker_section (dynobj, ".plt");
       BFD_ASSERT (s != NULL);
 
       /* If this is the first .plt entry, make room for the special
         first entry.  */
-      if (s->_raw_size == 0)
-       s->_raw_size += PLT_ENTRY_SIZE;
+      if (s->size == 0)
+       s->size += PLT_ENTRY_SIZE;
 
       /* If this symbol is not defined in a regular file, and we are
         not generating a shared library, then set the symbol to this
@@ -3491,29 +3300,29 @@ sh64_elf64_adjust_dynamic_symbol (info, h)
         pointers compare as equal between the normal executable and
         the shared library.  */
       if (! info->shared
-         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+         && !h->def_regular)
        {
          h->root.u.def.section = s;
-         h->root.u.def.value = s->_raw_size;
+         h->root.u.def.value = s->size;
        }
 
-      h->plt.offset = s->_raw_size;
+      h->plt.offset = s->size;
 
       /* Make room for this entry.  */
-      s->_raw_size += elf_sh64_sizeof_plt (info);
+      s->size += elf_sh64_sizeof_plt (info);
 
       /* 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");
+      s = bfd_get_linker_section (dynobj, ".got.plt");
       BFD_ASSERT (s != NULL);
-      s->_raw_size += 8;
+      s->size += 8;
 
       /* We also need to make an entry in the .rela.plt section.  */
 
-      s = bfd_get_section_by_name (dynobj, ".rela.plt");
+      s = bfd_get_linker_section (dynobj, ".rela.plt");
       BFD_ASSERT (s != NULL);
-      s->_raw_size += sizeof (Elf64_External_Rela);
+      s->size += sizeof (Elf64_External_Rela);
 
       return TRUE;
     }
@@ -3521,12 +3330,12 @@ sh64_elf64_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.  */
-  if (h->weakdef != NULL)
+  if (h->u.weakdef != NULL)
     {
-      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
-                 || h->weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->weakdef->root.u.def.section;
-      h->root.u.def.value = h->weakdef->root.u.def.value;
+      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
       return TRUE;
     }
 
@@ -3542,7 +3351,7 @@ sh64_elf64_adjust_dynamic_symbol (info, h)
 
   /* If there are no references to this symbol that do not use the
      GOT, we don't need to generate a copy reloc.  */
-  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
+  if (!h->non_got_ref)
     return TRUE;
 
   /* We must allocate the symbol in our .dynbss section, which will
@@ -3555,46 +3364,24 @@ sh64_elf64_adjust_dynamic_symbol (info, h)
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
-  s = bfd_get_section_by_name (dynobj, ".dynbss");
+  s = bfd_get_linker_section (dynobj, ".dynbss");
   BFD_ASSERT (s != NULL);
 
   /* We must generate a R_SH_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
       asection *srel;
 
-      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+      srel = bfd_get_linker_section (dynobj, ".rela.bss");
       BFD_ASSERT (srel != NULL);
-      srel->_raw_size += sizeof (Elf64_External_Rela);
-      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
-    }
-
-  /* We need to figure out the alignment required for this symbol.  I
-     have no idea how ELF linkers handle this.  */
-  power_of_two = bfd_log2 (h->size);
-  if (power_of_two > 3)
-    power_of_two = 3;
-
-  /* Apply the required alignment.  */
-  s->_raw_size = BFD_ALIGN (s->_raw_size,
-                           (bfd_size_type) (1 << power_of_two));
-  if (power_of_two > bfd_get_section_alignment (dynobj, s))
-    {
-      if (! bfd_set_section_alignment (dynobj, s, power_of_two))
-       return FALSE;
+      srel->size += sizeof (Elf64_External_Rela);
+      h->needs_copy = 1;
     }
 
-  /* Define the symbol as being at this point in the section.  */
-  h->root.u.def.section = s;
-  h->root.u.def.value = s->_raw_size;
-
-  /* Increment the section size to make room for the symbol.  */
-  s->_raw_size += h->size;
-
-  return TRUE;
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* This function is called via sh_elf_link_hash_traverse if we are
@@ -3605,21 +3392,17 @@ sh64_elf64_adjust_dynamic_symbol (info, h)
    relocate_section routine.  */
 
 static bfd_boolean
-sh64_elf64_discard_copies (h, ignore)
-     struct elf_sh64_link_hash_entry *h;
-     PTR ignore ATTRIBUTE_UNUSED;
+sh64_elf64_discard_copies (struct elf_sh64_link_hash_entry *h,
+                          void *ignore ATTRIBUTE_UNUSED)
 {
   struct elf_sh64_pcrel_relocs_copied *s;
 
-  if (h->root.root.type == bfd_link_hash_warning)
-    h = (struct elf_sh64_link_hash_entry *) h->root.root.u.i.link;
-
   /* We only discard relocs for symbols defined in a regular object.  */
-  if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+  if (!h->root.def_regular)
     return TRUE;
 
   for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
-    s->section->_raw_size -= s->count * sizeof (Elf64_External_Rela);
+    s->section->size -= s->count * sizeof (Elf64_External_Rela);
 
   return TRUE;
 }
@@ -3627,9 +3410,8 @@ sh64_elf64_discard_copies (h, ignore)
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
-sh64_elf64_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+sh64_elf64_size_dynamic_sections (bfd *output_bfd,
+                                 struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *s;
@@ -3645,9 +3427,9 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
       /* Set the contents of the .interp section to the interpreter.  */
       if (info->executable)
        {
-         s = bfd_get_section_by_name (dynobj, ".interp");
+         s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
-         s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
        }
     }
@@ -3658,9 +3440,9 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
         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");
+      s = bfd_get_linker_section (dynobj, ".rela.got");
       if (s != NULL)
-       s->_raw_size = 0;
+       s->size = 0;
     }
 
   /* If this is a -Bsymbolic shared link, then we need to discard all
@@ -3668,9 +3450,8 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
      We allocated space for them in the check_relocs routine, but we
      will not fill them in in the relocate_section routine.  */
   if (info->shared && info->symbolic)
-    sh64_elf64_link_hash_traverse (sh64_elf64_hash_table (info),
-                                  sh64_elf64_discard_copies,
-                                  (PTR) NULL);
+    sh64_elf64_link_hash_traverse (elf_hash_table (info),
+                                  sh64_elf64_discard_copies, NULL);
 
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
@@ -3681,7 +3462,6 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char *name;
-      bfd_boolean strip;
 
       if ((s->flags & SEC_LINKER_CREATED) == 0)
        continue;
@@ -3690,38 +3470,14 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
         of the dynobj section names depend upon the input files.  */
       name = bfd_get_section_name (dynobj, s);
 
-      strip = FALSE;
-
       if (strcmp (name, ".plt") == 0)
        {
-         if (s->_raw_size == 0)
-           {
-             /* Strip this section if we don't need it; see the
-                comment below.  */
-             strip = TRUE;
-           }
-         else
-           {
-             /* Remember whether there is a PLT.  */
-             plt = TRUE;
-           }
+         /* Remember whether there is a PLT.  */
+         plt = s->size != 0;
        }
-      else if (strncmp (name, ".rela", 5) == 0)
+      else if (CONST_STRNEQ (name, ".rela"))
        {
-         if (s->_raw_size == 0)
-           {
-             /* If we don't need this section, strip it from the
-                output file.  This is mostly to handle .rela.bss and
-                .rela.plt.  We must create both sections in
-                create_dynamic_sections, because they must be created
-                before the linker maps input sections to output
-                sections.  The linker does that before
-                adjust_dynamic_symbol is called, and it is that
-                function which decides whether anything needs to go
-                into these sections.  */
-             strip = TRUE;
-           }
-         else
+         if (s->size != 0)
            {
              asection *target;
 
@@ -3752,21 +3508,34 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
              s->reloc_count = 0;
            }
        }
-      else if (strncmp (name, ".got", 4) != 0)
+      else if (! CONST_STRNEQ (name, ".got")
+              && strcmp (name, ".dynbss") != 0)
        {
          /* It's not one of our sections, so don't allocate space.  */
          continue;
        }
 
-      if (strip)
+      if (s->size == 0)
        {
-         _bfd_strip_section_from_output (info, s);
+         /* If we don't need this section, strip it from the
+            output file.  This is mostly to handle .rela.bss and
+            .rela.plt.  We must create both sections in
+            create_dynamic_sections, because they must be created
+            before the linker maps input sections to output
+            sections.  The linker does that before
+            adjust_dynamic_symbol is called, and it is that
+            function which decides whether anything needs to go
+            into these sections.  */
+         s->flags |= SEC_EXCLUDE;
          continue;
        }
 
+      if ((s->flags & SEC_HAS_CONTENTS) == 0)
+       continue;
+
       /* Allocate memory for the section contents.  */
-      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
-      if (s->contents == NULL && s->_raw_size != 0)
+      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+      if (s->contents == NULL)
        return FALSE;
     }
 
@@ -3779,31 +3548,31 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
         dynamic linker and used by the debugger.  */
       if (info->executable)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
            return FALSE;
        }
 
       if (plt)
        {
-         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_RELA)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+             || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
            return FALSE;
        }
 
       if (relocs)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
-             || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
-                                               sizeof (Elf64_External_Rela)))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+             || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+                                             sizeof (Elf64_External_Rela)))
            return FALSE;
        }
 
       if (reltext)
        {
-         if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+         if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
            return FALSE;
        }
     }
@@ -3815,11 +3584,10 @@ sh64_elf64_size_dynamic_sections (output_bfd, info)
    dynamic sections here.  */
 
 static bfd_boolean
-sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
+                                 struct bfd_link_info *info,
+                                 struct elf_link_hash_entry *h,
+                                 Elf_Internal_Sym *sym)
 {
   bfd *dynobj;
 
@@ -3841,9 +3609,9 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       BFD_ASSERT (h->dynindx != -1);
 
-      splt = bfd_get_section_by_name (dynobj, ".plt");
-      sgot = bfd_get_section_by_name (dynobj, ".got.plt");
-      srel = bfd_get_section_by_name (dynobj, ".rela.plt");
+      splt = bfd_get_linker_section (dynobj, ".plt");
+      sgot = bfd_get_linker_section (dynobj, ".got.plt");
+      srel = bfd_get_linker_section (dynobj, ".rela.plt");
       BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
 
       /* Get the index in the procedure linkage table which
@@ -3926,7 +3694,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
       loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
       bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
 
-      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+      if (!h->def_regular)
        {
          /* Mark the symbol as undefined, rather than as defined in
             the .plt section.  Leave the value alone.  */
@@ -3944,8 +3712,8 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
       /* This symbol has an entry in the global offset table.  Set it
         up.  */
 
-      sgot = bfd_get_section_by_name (dynobj, ".got");
-      srel = bfd_get_section_by_name (dynobj, ".rela.got");
+      sgot = bfd_get_linker_section (dynobj, ".got");
+      srel = bfd_get_linker_section (dynobj, ".rela.got");
       BFD_ASSERT (sgot != NULL && srel != NULL);
 
       rel.r_offset = (sgot->output_section->vma
@@ -3959,7 +3727,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
         initialized in the relocate_section function.  */
       if (info->shared
          && (info->symbolic || h->dynindx == -1)
-         && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+         && h->def_regular)
        {
          rel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
          rel.r_addend = (h->root.u.def.value
@@ -3978,7 +3746,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
       bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
     }
 
-  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
+  if (h->needs_copy)
     {
       asection *s;
       Elf_Internal_Rela rel;
@@ -3990,8 +3758,7 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = bfd_get_section_by_name (h->root.u.def.section->owner,
-                                  ".rela.bss");
+      s = bfd_get_linker_section (dynobj, ".rela.bss");
       BFD_ASSERT (s != NULL);
 
       rel.r_offset = (h->root.u.def.value
@@ -4005,8 +3772,8 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
-  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+  if (h == elf_hash_table (info)->hdynamic
+      || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -4015,9 +3782,8 @@ sh64_elf64_finish_dynamic_symbol (output_bfd, info, h, sym)
 /* Finish up the dynamic sections.  */
 
 static bfd_boolean
-sh64_elf64_finish_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
+                                   struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *sgot;
@@ -4025,9 +3791,9 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
 
   dynobj = elf_hash_table (info)->dynobj;
 
-  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+  sgot = bfd_get_linker_section (dynobj, ".got.plt");
   BFD_ASSERT (sgot != NULL);
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -4037,7 +3803,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
       BFD_ASSERT (sdyn != NULL);
 
       dyncon = (Elf64_External_Dyn *) sdyn->contents;
-      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
       for (; dyncon < dynconend; dyncon++)
        {
          Elf_Internal_Dyn dyn;
@@ -4087,10 +3853,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
            case DT_PLTRELSZ:
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
              BFD_ASSERT (s != NULL);
-             if (s->_cooked_size != 0)
-               dyn.d_un.d_val = s->_cooked_size;
-             else
-               dyn.d_un.d_val = s->_raw_size;
+             dyn.d_un.d_val = s->size;
              bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
@@ -4106,20 +3869,15 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
                 about changing the DT_RELA entry.  */
              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
              if (s != NULL)
-               {
-                 if (s->_cooked_size != 0)
-                   dyn.d_un.d_val -= s->_cooked_size;
-                 else
-                   dyn.d_un.d_val -= s->_raw_size;
-               }
+               dyn.d_un.d_val -= s->size;
              bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
            }
        }
 
       /* Fill in the first entry in the procedure linkage table.  */
-      splt = bfd_get_section_by_name (dynobj, ".plt");
-      if (splt && splt->_raw_size > 0)
+      splt = bfd_get_linker_section (dynobj, ".plt");
+      if (splt && splt->size > 0)
        {
          if (info->shared)
            {
@@ -4155,7 +3913,7 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
     }
 
   /* Fill in the first three entries in the global offset table.  */
-  if (sgot->_raw_size > 0)
+  if (sgot->size > 0)
     {
       if (sdyn == NULL)
        bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);
@@ -4172,9 +3930,36 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
   return TRUE;
 }
 
-#define TARGET_BIG_SYM         bfd_elf64_sh64_vec
+/* Merge non visibility st_other attribute when the symbol comes from
+   a dynamic object.  */
+static void
+sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
+                                  const Elf_Internal_Sym *isym,
+                                  bfd_boolean definition,
+                                  bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+  if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
+    {
+      unsigned char other;
+
+      /* Take the balance of OTHER from the definition.  */
+      other = (definition ? isym->st_other : h->other);
+      other &= ~ ELF_ST_VISIBILITY (-1);
+      h->other = other | ELF_ST_VISIBILITY (h->other);
+    }
+
+  return;
+}
+
+static const struct bfd_elf_special_section sh64_elf64_special_sections[]=
+{
+  { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
+  { NULL,                       0, 0, 0,            0 }
+};
+
+#define TARGET_BIG_SYM         sh64_elf64_vec
 #define TARGET_BIG_NAME                "elf64-sh64"
-#define TARGET_LITTLE_SYM      bfd_elf64_sh64l_vec
+#define TARGET_LITTLE_SYM      sh64_elf64_le_vec
 #define TARGET_LITTLE_NAME     "elf64-sh64l"
 #define ELF_ARCH               bfd_arch_sh
 #define ELF_MACHINE_CODE       EM_SH
@@ -4183,6 +3968,8 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
 #define elf_symbol_leading_char '_'
 
 #define bfd_elf64_bfd_reloc_type_lookup        sh_elf64_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup \
+                                       sh_elf64_reloc_name_lookup
 #define elf_info_to_howto              sh_elf64_info_to_howto
 
 /* Note: there's no relaxation at present.  */
@@ -4200,7 +3987,6 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_fake_sections      sh64_elf64_fake_sections
 
 #define elf_backend_gc_mark_hook        sh_elf64_gc_mark_hook
-#define elf_backend_gc_sweep_hook       sh_elf64_gc_sweep_hook
 #define elf_backend_check_relocs        sh_elf64_check_relocs
 
 #define elf_backend_can_gc_sections    1
@@ -4212,6 +3998,9 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
 #define elf_backend_link_output_symbol_hook \
        sh64_elf64_link_output_symbol_hook
 
+#define        elf_backend_merge_symbol_attribute \
+       sh64_elf64_merge_symbol_attribute
+
 #define elf_backend_final_write_processing \
        sh64_elf64_final_write_processing
 
@@ -4223,26 +4012,28 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
                                        sh64_elf64_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
                                        sh64_elf64_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_finish_dynamic_symbol \
                                        sh64_elf64_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections \
                                        sh64_elf64_finish_dynamic_sections
+#define elf_backend_special_sections   sh64_elf64_special_sections
 
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    24
-#define elf_backend_plt_header_size    PLT_ENTRY_SIZE
 
 #include "elf64-target.h"
 
 /* NetBSD support.  */
 #undef TARGET_BIG_SYM
-#define        TARGET_BIG_SYM                  bfd_elf64_sh64nbsd_vec
+#define        TARGET_BIG_SYM                  sh64_elf64_nbsd_vec
 #undef TARGET_BIG_NAME
 #define        TARGET_BIG_NAME                 "elf64-sh64-nbsd"
 #undef TARGET_LITTLE_SYM
-#define        TARGET_LITTLE_SYM               bfd_elf64_sh64lnbsd_vec
+#define        TARGET_LITTLE_SYM               sh64_elf64_nbsd_le_vec
 #undef TARGET_LITTLE_NAME
 #define        TARGET_LITTLE_NAME              "elf64-sh64l-nbsd"
 #undef ELF_MAXPAGESIZE
@@ -4256,13 +4047,14 @@ sh64_elf64_finish_dynamic_sections (output_bfd, info)
 
 /* Linux support.  */
 #undef TARGET_BIG_SYM
-#define        TARGET_BIG_SYM                  bfd_elf64_sh64blin_vec
+#define        TARGET_BIG_SYM                  sh64_elf64_linux_be_vec
 #undef TARGET_BIG_NAME
 #define        TARGET_BIG_NAME                 "elf64-sh64big-linux"
 #undef TARGET_LITTLE_SYM
-#define        TARGET_LITTLE_SYM               bfd_elf64_sh64lin_vec
+#define        TARGET_LITTLE_SYM               sh64_elf64_linux_vec
 #undef TARGET_LITTLE_NAME
 #define        TARGET_LITTLE_NAME              "elf64-sh64-linux"
+#undef elf64_bed
+#define        elf64_bed                       elf64_sh64_linux_bed
 
-#define        INCLUDED_TARGET_FILE
 #include "elf64-target.h"
This page took 0.054118 seconds and 4 git commands to generate.