Use %pA and %pB in messages rather than %A and %B
[deliverable/binutils-gdb.git] / bfd / elf64-sh64.c
index 16fbe5e5676e39fd56c71a874865a8fdbe4b4d2d..8d6404690226a9da8f5f06971ac7237f31542e0e 100644 (file)
@@ -1,12 +1,11 @@
 /* SuperH SH64-specific support for 64-bit ELF
-   Copyright 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2018 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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"
@@ -53,7 +53,7 @@
 #define elf_sh64_plt_symbol_offset(info) 0
 
 /* Return offset of the relocation in PLT entry.  */
-#define elf_sh64_plt_reloc_offset(info) (info->shared ? 52 : 44)
+#define elf_sh64_plt_reloc_offset(info) (bfd_link_pic (info) ? 52 : 44)
 
 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
 
@@ -88,26 +88,14 @@ 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,                                                    \
+#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_reloc_status_type sh_elf64_ignore_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type sh_elf64_reloc
@@ -117,7 +105,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
   /* No relocation.  */
   HOWTO (R_SH_NONE,            /* type */
         0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        3,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
@@ -281,33 +269,33 @@ static reloc_howto_type sh_elf64_howto_table[] = {
 
   /* GNU extension to record C++ vtable hierarchy */
   HOWTO (R_SH_GNU_VTINHERIT, /* type */
-         0,                     /* rightshift */
-         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-         0,                     /* bitsize */
-         FALSE,                 /* pc_relative */
-         0,                     /* bitpos */
-         complain_overflow_dont, /* complain_on_overflow */
-         NULL,                  /* special_function */
-         "R_SH_GNU_VTINHERIT", /* name */
-         FALSE,                 /* partial_inplace */
-         0,                     /* src_mask */
-         0,                     /* dst_mask */
-         FALSE),                /* pcrel_offset */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        NULL,                  /* special_function */
+        "R_SH_GNU_VTINHERIT", /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* GNU extension to record C++ vtable member usage */
   HOWTO (R_SH_GNU_VTENTRY,     /* type */
-         0,                     /* rightshift */
-         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-         0,                     /* bitsize */
-         FALSE,                 /* pc_relative */
-         0,                     /* bitpos */
-         complain_overflow_dont, /* complain_on_overflow */
-         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
-         "R_SH_GNU_VTENTRY",   /* name */
-         FALSE,                 /* partial_inplace */
-         0,                     /* src_mask */
-         0,                     /* dst_mask */
-         FALSE),                /* pcrel_offset */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
+        "R_SH_GNU_VTENTRY",   /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        FALSE),                /* pcrel_offset */
 
   /* For 32-bit sh, this is R_SH_LOOP_START.  */
   EMPTY_HOWTO (36),
@@ -336,7 +324,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xfc00,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in SHARI, SHLLI et al.  */
   HOWTO (R_SH_DIR6U,           /* type */
@@ -351,7 +339,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xfc00,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in BxxI, LDHI.L et al.  */
   HOWTO (R_SH_DIR6S,           /* type */
@@ -366,7 +354,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xfc00,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in ADDI, ANDI et al.  */
   HOWTO (R_SH_DIR10S,          /* type */
@@ -381,7 +369,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in LD.UW, ST.W et al.  */
   HOWTO (R_SH_DIR10SW, /* type */
@@ -396,7 +384,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in LD.L, FLD.S et al.  */
   HOWTO (R_SH_DIR10SL, /* type */
@@ -411,7 +399,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in FLD.D, FST.P et al.  */
   HOWTO (R_SH_DIR10SQ, /* type */
@@ -426,7 +414,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   EMPTY_HOWTO (52),
   EMPTY_HOWTO (53),
@@ -560,11 +548,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         10,                    /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_GOT_LOW16",      /* name */
+        "R_SH_GOT_LOW16",      /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
   HOWTO (R_SH_GOT_MEDLOW16,    /* type */
@@ -579,7 +567,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
   HOWTO (R_SH_GOT_MEDHI16,     /* type */
@@ -594,7 +582,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
   HOWTO (R_SH_GOT_HI16,                /* type */
@@ -609,7 +597,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (x & 65536).  */
   HOWTO (R_SH_GOTPLT_LOW16,    /* type */
@@ -624,7 +612,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
   HOWTO (R_SH_GOTPLT_MEDLOW16, /* type */
@@ -639,7 +627,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
   HOWTO (R_SH_GOTPLT_MEDHI16,  /* type */
@@ -654,7 +642,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
   HOWTO (R_SH_GOTPLT_HI16,     /* type */
@@ -669,7 +657,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (x & 65536).  */
   HOWTO (R_SH_PLT_LOW16,       /* type */
@@ -680,11 +668,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         10,                    /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_PLT_LOW16",      /* name */
+        "R_SH_PLT_LOW16",      /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
   HOWTO (R_SH_PLT_MEDLOW16,    /* type */
@@ -699,7 +687,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
   HOWTO (R_SH_PLT_MEDHI16,     /* type */
@@ -714,7 +702,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
   HOWTO (R_SH_PLT_HI16,                /* type */
@@ -729,7 +717,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI (x & 65536).  */
   HOWTO (R_SH_GOTOFF_LOW16,    /* type */
@@ -744,7 +732,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
   HOWTO (R_SH_GOTOFF_MEDLOW16, /* type */
@@ -759,7 +747,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
   HOWTO (R_SH_GOTOFF_MEDHI16,  /* type */
@@ -774,7 +762,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
   HOWTO (R_SH_GOTOFF_HI16,     /* type */
@@ -789,7 +777,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (x & 65536).  */
   HOWTO (R_SH_GOTPC_LOW16,     /* type */
@@ -804,7 +792,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 16) & 65536).  */
   HOWTO (R_SH_GOTPC_MEDLOW16,  /* type */
@@ -819,7 +807,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 32) & 65536).  */
   HOWTO (R_SH_GOTPC_MEDHI16,   /* type */
@@ -834,7 +822,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x >> 48) & 65536).  */
   HOWTO (R_SH_GOTPC_HI16,      /* type */
@@ -849,7 +837,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        TRUE),                 /* pcrel_offset */
+        TRUE),                 /* pcrel_offset */
 
   /* Used in LD.L, FLD.S et al.  */
   HOWTO (R_SH_GOT10BY4,                /* type */
@@ -864,7 +852,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in LD.L, FLD.S et al.  */
   HOWTO (R_SH_GOTPLT10BY4,     /* type */
@@ -879,7 +867,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in FLD.D, FST.P et al.  */
   HOWTO (R_SH_GOT10BY8,                /* type */
@@ -894,7 +882,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in FLD.D, FST.P et al.  */
   HOWTO (R_SH_GOTPLT10BY8,     /* type */
@@ -909,7 +897,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0xffc00,               /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   HOWTO (R_SH_COPY64,          /* type */
         0,                     /* rightshift */
@@ -919,11 +907,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_COPY64",         /* name */
+        "R_SH_COPY64",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         ((bfd_vma) 0) - 1,     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   HOWTO (R_SH_GLOB_DAT64,      /* type */
         0,                     /* rightshift */
@@ -933,11 +921,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_GLOB_DAT64",     /* name */
+        "R_SH_GLOB_DAT64",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         ((bfd_vma) 0) - 1,     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   HOWTO (R_SH_JMP_SLOT64,      /* type */
         0,                     /* rightshift */
@@ -947,11 +935,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_JMP_SLOT64",     /* name */
+        "R_SH_JMP_SLOT64",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         ((bfd_vma) 0) - 1,     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   HOWTO (R_SH_RELATIVE64,      /* type */
         0,                     /* rightshift */
@@ -961,11 +949,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_RELATIVE64",     /* name */
+        "R_SH_RELATIVE64",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         ((bfd_vma) 0) - 1,     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   EMPTY_HOWTO (197),
   EMPTY_HOWTO (198),
@@ -1066,7 +1054,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in SHORI.  */
   HOWTO (R_SH_IMMU16,          /* type */
@@ -1081,7 +1069,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (x & 65536).  */
   HOWTO (R_SH_IMM_LOW16,       /* type */
@@ -1092,11 +1080,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         10,                    /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_IMM_LOW16",      /* name */
+        "R_SH_IMM_LOW16",      /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI ((x - $) & 65536).  */
   HOWTO (R_SH_IMM_LOW16_PCREL, /* type */
@@ -1126,7 +1114,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (((x - $) >> 16) & 65536).  */
   HOWTO (R_SH_IMM_MEDLOW16_PCREL, /* type */
@@ -1156,7 +1144,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (((x - $) >> 32) & 65536).  */
   HOWTO (R_SH_IMM_MEDHI16_PCREL, /* type */
@@ -1186,7 +1174,7 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x3fffc00,             /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* Used in MOVI and SHORI (((x - $) >> 48) & 65536).  */
   HOWTO (R_SH_IMM_HI16_PCREL,  /* type */
@@ -1212,11 +1200,11 @@ static reloc_howto_type sh_elf64_howto_table[] = {
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_SH_64",             /* name */
+        "R_SH_64",             /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         ((bfd_vma) 0) - 1,     /* dst_mask */
-        FALSE),                /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
 
   /* For the .uaquad pseudo, (x - $).  */
   HOWTO (R_SH_64_PCREL,                /* type */
@@ -1392,6 +1380,22 @@ sh_elf64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   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.  */
@@ -1428,7 +1432,6 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
-  bfd *dynobj;
   bfd_vma *local_got_offsets;
   asection *sgot;
   asection *sgotplt;
@@ -1438,12 +1441,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
-  dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
-  sgot = NULL;
-  sgotplt = NULL;
-  splt = NULL;
   sreloc = NULL;
 
   rel = relocs;
@@ -1487,10 +1486,10 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       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;
@@ -1504,18 +1503,20 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
             datalabel processing here.  Make sure this does not change
             without notice.  */
          if ((sym->st_other & STO_SH5_ISA32) != 0)
-           ((*info->callbacks->reloc_dangerous)
-            (info,
-             _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
-             input_bfd, input_section, rel->r_offset));
-
-         if (info->relocatable)
+           (*info->callbacks->reloc_dangerous)
+             (info,
+              _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+              input_bfd, input_section, rel->r_offset);
+
+         if (sec != NULL && discarded_section (sec))
+           /* Handled below.  */
+           ;
+         else if (bfd_link_relocatable (info))
            {
              /* 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;
 
@@ -1533,16 +1534,17 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
              if (howto->rightshift || howto->src_mask != 0xffffffff)
                {
-                 (*_bfd_error_handler)
-                   (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB(%pA+%#Lx): %s relocation against SEC_MERGE section"),
                     input_bfd, input_section,
-                    (long) rel->r_offset, howto->name);
+                    rel->r_offset, howto->name);
                  return FALSE;
                }
 
-              addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
-              msec = sec;
-              addend =
+             addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
+             msec = sec;
+             addend =
                _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
                - relocation;
              addend += msec->output_section->vma + msec->output_offset;
@@ -1554,12 +1556,6 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        {
          /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ?  */
 
-         /* Section symbols are never (?) placed in the hash table, so
-            we can just ignore hash relocations when creating a
-            relocatable object file.  */
-         if (info->relocatable)
-           continue;
-
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
@@ -1592,7 +1588,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                       || r_type == R_SH_GOT_MEDHI16
                       || r_type == R_SH_GOT_HI16)
                      && elf_hash_table (info)->dynamic_sections_created
-                     && (! info->shared
+                     && (! bfd_link_pic (info)
                          || (! info->symbolic && h->dynindx != -1)
                          || !h->def_regular))
                  /* The cases above are those in which relocation is
@@ -1600,7 +1596,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                     below are those in which we must defer relocation
                     to run-time, because we can't resolve absolute
                     addresses when creating a shared library.  */
-                 || (info->shared
+                 || (bfd_link_pic (info)
                      && ((! info->symbolic && h->dynindx != -1)
                          || !h->def_regular)
                      && ((r_type == R_SH_64
@@ -1619,16 +1615,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                  || (sec->output_section == NULL
                      && ((input_section->flags & SEC_DEBUGGING) != 0
                          && h->def_dynamic)))
-               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
+               ;
+             else if (sec->output_section != NULL)
                relocation = ((h->root.u.def.value
                               + sec->output_section->vma
                               + sec->output_offset)
@@ -1637,24 +1625,42 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                                 STT_DATALABEL on the way to it.  */
                              | ((h->other & STO_SH5_ISA32) != 0
                                 && ! seen_stt_datalabel));
+             else if (!bfd_link_relocatable (info)
+                      && (_bfd_elf_section_offset (output_bfd, info,
+                                                   input_section,
+                                                   rel->r_offset)
+                          != (bfd_vma) -1))
+               {
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB(%pA+%#Lx): unresolvable %s relocation against symbol `%s'"),
+                    input_bfd,
+                    input_section,
+                    rel->r_offset,
+                    howto->name,
+                    h->root.root.string);
+               }
            }
          else if (h->root.type == bfd_link_hash_undefweak)
-           relocation = 0;
+           ;
          else if (info->unresolved_syms_in_objects == RM_IGNORE
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-           relocation = 0;
-         else
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset,
-                     (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-                      || ELF_ST_VISIBILITY (h->other)))))
-               return FALSE;
-             relocation = 0;
-           }
+           ;
+         else if (!bfd_link_relocatable (info))
+           (*info->callbacks->undefined_symbol)
+             (info, h->root.root.string, input_bfd,
+              input_section, rel->r_offset,
+              (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+               || ELF_ST_VISIBILITY (h->other)));
        }
 
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
+
+      if (bfd_link_relocatable (info))
+       continue;
+
       disp = (relocation
              - input_section->output_section->vma
              - input_section->output_offset
@@ -1669,9 +1675,11 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        }
       if (dropped != 0)
        {
-         (*_bfd_error_handler)
-           (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"),
-            bfd_get_filename (input_bfd), (int)r_type, (unsigned)rel->r_offset, (unsigned)relocation);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%pB: error: unaligned relocation type %d at %08Lx reloc %08Lx"),
+            input_bfd, (int) r_type, rel->r_offset,
+            relocation);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
@@ -1679,7 +1687,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        {
        case R_SH_64:
        case R_SH_64_PCREL:
-         if (info->shared
+         if (bfd_link_pic (info)
              && (input_section->flags & SEC_ALLOC) != 0
              && (r_type != R_SH_64_PCREL
                  || (h != NULL
@@ -1697,22 +1705,10 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
              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;
@@ -1785,7 +1781,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          if (h == NULL
              || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
              || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
-             || ! info->shared
+             || ! bfd_link_pic (info)
              || info->symbolic
              || h->dynindx == -1
              || h->plt.offset == (bfd_vma) -1
@@ -1794,11 +1790,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
 
          /* Relocation is to the entry for this symbol in the global
             offset table extension for the procedure linkage table.  */
-         if (sgotplt == NULL)
-           {
-             sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
-             BFD_ASSERT (sgotplt != NULL);
-           }
+         sgotplt = elf_hash_table (info)->sgotplt;
+         BFD_ASSERT (sgotplt != NULL);
 
          relocation = (sgotplt->output_offset
                        + ((h->plt.offset / elf_sh64_sizeof_plt (info)
@@ -1817,11 +1810,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        case R_SH_GOT10BY8:
          /* Relocation is to the entry for this symbol in the global
             offset table.  */
-         if (sgot == NULL)
-           {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
-             BFD_ASSERT (sgot != NULL);
-           }
+         sgot = elf_hash_table (info)->sgot;
+         BFD_ASSERT (sgot != NULL);
 
          if (h != NULL)
            {
@@ -1838,7 +1828,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              BFD_ASSERT (off != (bfd_vma) -1);
 
              if (! elf_hash_table (info)->dynamic_sections_created
-                 || (info->shared
+                 || (bfd_link_pic (info)
                      && (info->symbolic || h->dynindx == -1
                          || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
                          || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
@@ -1907,13 +1897,13 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                {
                  bfd_put_64 (output_bfd, relocation, sgot->contents + off);
 
-                 if (info->shared)
+                 if (bfd_link_pic (info))
                    {
                      asection *s;
                      Elf_Internal_Rela outrel;
                      bfd_byte *loc;
 
-                     s = bfd_get_section_by_name (dynobj, ".rela.got");
+                     s = elf_hash_table (info)->srelgot;
                      BFD_ASSERT (s != NULL);
 
                      outrel.r_offset = (sgot->output_section->vma
@@ -1935,7 +1925,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              relocation = sgot->output_offset + off;
            }
 
-         relocation -= GOT_BIAS;
+         relocation -= GOT_BIAS;
 
          goto final_link_relocate;
 
@@ -1946,11 +1936,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* Relocation is relative to the start of the global offset
             table.  */
 
-         if (sgot == NULL)
-           {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
-             BFD_ASSERT (sgot != NULL);
-           }
+         sgot = elf_hash_table (info)->sgot;
+         BFD_ASSERT (sgot != NULL);
 
          /* Note that sgot->output_offset is not involved in this
             calculation.  We always want the start of .got.  If we
@@ -1971,11 +1958,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
        case R_SH_GOTPC_HI16:
          /* Use global offset table as symbol value.  */
 
-         if (sgot == NULL)
-           {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
-             BFD_ASSERT (sgot != NULL);
-           }
+         sgot = elf_hash_table (info)->sgot;
+         BFD_ASSERT (sgot != NULL);
 
          relocation = sgot->output_section->vma;
 
@@ -2009,11 +1993,8 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              goto final_link_relocate;
            }
 
-         if (splt == NULL)
-           {
-             splt = bfd_get_section_by_name (dynobj, ".plt");
-             BFD_ASSERT (splt != NULL);
-           }
+         splt = elf_hash_table (info)->splt;
+         BFD_ASSERT (splt != NULL);
 
          relocation = (splt->output_section->vma
                        + splt->output_offset
@@ -2081,11 +2062,9 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                    if (*name == '\0')
                      name = bfd_section_name (input_bfd, sec);
                  }
-               if (! ((*info->callbacks->reloc_overflow)
-                      (info, (h ? &h->root : NULL), name, howto->name,
-                       (bfd_vma) 0, input_bfd, input_section,
-                       rel->r_offset)))
-                 return FALSE;
+               (*info->callbacks->reloc_overflow)
+                 (info, (h ? &h->root : NULL), name, howto->name,
+                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              }
              break;
            }
@@ -2167,17 +2146,12 @@ sh_elf64_get_relocated_section_contents (bfd *output_bfd,
 
          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;
        }
@@ -2264,30 +2238,12 @@ sh_elf64_set_private_flags (bfd *abfd, flagword flags)
 static bfd_boolean
 sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd)
 {
-  Elf_Internal_Shdr **o_shdrp;
-  asection *isec;
-  asection *osec;
-
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
 
-  o_shdrp = elf_elfsections (obfd);
-  for (osec = obfd->sections; osec; osec = osec->next)
-    {
-      int oIndex = ((struct bfd_elf_section_data *) elf_section_data (osec))->this_idx;
-      for (isec = ibfd->sections; isec; isec = isec->next)
-       {
-         if (strcmp (osec->name, isec->name) == 0)
-           {
-             /* Note that we're not disallowing mixing data and code.  */
-             if ((elf_section_data (isec)->this_hdr.sh_flags
-                  & SHF_SH5_ISA32) != 0)
-               o_shdrp[oIndex]->sh_flags |= SHF_SH5_ISA32;
-             break;
-           }
-       }
-    }
+  /* Copy object attributes.  */
+  _bfd_elf_copy_private_bfd_data (ibfd, obfd);
 
   return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
 }
@@ -2299,11 +2255,12 @@ sh_elf64_copy_private_data (bfd *ibfd, bfd *obfd)
 }
 
 static bfd_boolean
-sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
+sh_elf64_merge_private_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   flagword old_flags, new_flags;
 
-  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+  if (! _bfd_generic_verify_endian_match (ibfd, info))
     return FALSE;
 
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
@@ -2316,15 +2273,17 @@ sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
 
       if (bfd_get_arch_size (ibfd) == 32
          && bfd_get_arch_size (obfd) == 64)
-       msg = _("%s: compiled as 32-bit object and %s is 64-bit");
+       /* xgettext:c-format */
+       msg = _("%pB: compiled as 32-bit object and %pB is 64-bit");
       else if (bfd_get_arch_size (ibfd) == 64
               && bfd_get_arch_size (obfd) == 32)
-       msg = _("%s: compiled as 64-bit object and %s is 32-bit");
+       /* xgettext:c-format */
+       msg = _("%pB: compiled as 64-bit object and %pB is 32-bit");
       else
-       msg = _("%s: object size does not match that of target %s");
+       /* xgettext:c-format */
+       msg = _("%pB: object size does not match that of target %pB");
 
-      (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
-                            bfd_get_filename (obfd));
+      _bfd_error_handler (msg, ibfd, obfd);
       bfd_set_error (bfd_error_wrong_format);
       return FALSE;
     }
@@ -2342,9 +2301,8 @@ sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
      here as things change.  */
   else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
     {
-      (*_bfd_error_handler)
-       ("%s: does not use the SH64 64-bit ABI as previous modules do",
-        bfd_get_filename (ibfd));
+      _bfd_error_handler
+       ("%pB: does not use the SH64 64-bit ABI as previous modules do", ibfd);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -2363,53 +2321,20 @@ sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
 
 static asection *
 sh_elf64_gc_mark_hook (asection *sec,
-                      struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                      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);
+    switch (ELF64_R_TYPE (rel->r_info))
+      {
+      case R_SH_GNU_VTINHERIT:
+      case R_SH_GNU_VTENTRY:
+       return NULL;
+      }
 
-  return NULL;
-}
-
-/* Update the got entry reference counts for the section being removed.  */
-
-static bfd_boolean
-sh_elf64_gc_sweep_hook (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.
@@ -2421,7 +2346,7 @@ 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;
@@ -2430,18 +2355,13 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   asection *srelgot;
   asection *sreloc;
 
-  sgot = NULL;
-  srelgot = NULL;
   sreloc = NULL;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     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);
@@ -2454,7 +2374,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       r_symndx = ELF64_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
-        h = NULL;
+       h = NULL;
       else
        {
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
@@ -2499,20 +2419,22 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        }
 
       switch (ELF64_R_TYPE (rel->r_info))
-        {
+       {
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
-        case R_SH_GNU_VTINHERIT:
-          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-            return FALSE;
-          break;
+       case R_SH_GNU_VTINHERIT:
+         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_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
-            return FALSE;
-          break;
+       case R_SH_GNU_VTENTRY:
+         BFD_ASSERT (h != NULL);
+         if (h != NULL
+             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+           return FALSE;
+         break;
 
        force_got:
        case R_SH_GOT_LOW16:
@@ -2523,31 +2445,9 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_SH_GOT10BY8:
          /* This symbol requires a global offset table entry.  */
 
-         if (sgot == NULL)
-           {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
-             BFD_ASSERT (sgot != NULL);
-           }
-
-         if (srelgot == NULL
-             && (h != NULL || info->shared))
-           {
-             srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
-             if (srelgot == NULL)
-               {
-                 srelgot = bfd_make_section_with_flags (dynobj,
-                                                        ".rela.got",
-                                                        (SEC_ALLOC
-                                                         | SEC_LOAD
-                                                         | SEC_HAS_CONTENTS
-                                                         | SEC_IN_MEMORY
-                                                         | SEC_LINKER_CREATED
-                                                         | SEC_READONLY));
-                 if (srelgot == NULL
-                     || ! bfd_set_section_alignment (dynobj, srelgot, 2))
-                   return FALSE;
-               }
-           }
+         sgot = elf_hash_table (info)->sgot;
+         srelgot = elf_hash_table (info)->srelgot;
+         BFD_ASSERT (sgot != NULL && srelgot != NULL);
 
          if (h != NULL)
            {
@@ -2583,7 +2483,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            }
          else
            {
-             /* This is a global offset table entry for a local
+             /* This is a global offset table entry for a local
                 symbol.  */
              if (local_got_offsets == NULL)
                {
@@ -2624,7 +2524,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  local_got_offsets[r_symndx] = sgot->size;
                }
 
-             if (info->shared)
+             if (bfd_link_pic (info))
                {
                  /* If we are generating a shared object, we need to
                     output a R_SH_RELATIVE reloc so that the dynamic
@@ -2649,7 +2549,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
          if (h == NULL
              || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
              || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
-             || ! info->shared
+             || ! bfd_link_pic (info)
              || info->symbolic
              || h->dynindx == -1
              || h->got.offset != (bfd_vma) -1)
@@ -2707,7 +2607,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
             later (it is never cleared).  We account for that
             possibility below by storing information in the
             pcrel_relocs_copied field of the hash table entry.  */
-         if (info->shared
+         if (bfd_link_pic (info)
              && (sec->flags & SEC_ALLOC) != 0
              && (ELF32_R_TYPE (rel->r_info) != R_SH_64_PCREL
                  || (h != NULL
@@ -2719,35 +2619,11 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                 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;
-
-                     flags = (SEC_HAS_CONTENTS | SEC_READONLY
-                              | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-                     if ((sec->flags & SEC_ALLOC) != 0)
-                       flags |= SEC_ALLOC | SEC_LOAD;
-                     sreloc = bfd_make_section_with_flags (dynobj,
-                                                           name,
-                                                           flags);
-                     if (sreloc == NULL
-                         || ! bfd_set_section_alignment (dynobj, sreloc, 2))
-                       return FALSE;
-                   }
+                   return FALSE;
                }
 
              sreloc->size += sizeof (Elf64_External_Rela);
@@ -2789,7 +2665,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            }
 
          break;
-        }
+       }
     }
 
   return TRUE;
@@ -2842,7 +2718,7 @@ sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
         right, and tweak the name when it's output.  Otherwise, we make
         an indirect symbol of it.  */
       flagword flags
-       = info->relocatable || info->emitrelocations
+       = bfd_link_relocatable (info) || info->emitrelocations
        ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
 
       char *dl_name
@@ -2886,15 +2762,14 @@ sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
        free (dl_name);
 
       if (h->type != STT_DATALABEL
-         || ((info->relocatable || info->emitrelocations)
+         || ((bfd_link_relocatable (info) || info->emitrelocations)
              && h->root.type != bfd_link_hash_undefined)
-         || (! info->relocatable && !info->emitrelocations
+         || (! bfd_link_relocatable (info) && !info->emitrelocations
              && h->root.type != bfd_link_hash_indirect))
        {
          /* Make sure we don't get confused on invalid input.  */
-         (*_bfd_error_handler)
-           (_("%s: encountered datalabel symbol in input"),
-            bfd_get_filename (abfd));
+         _bfd_error_handler
+           (_("%pB: encountered datalabel symbol in input"), abfd);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
@@ -2923,7 +2798,7 @@ sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
    we don't need to look up and make sure to emit the main symbol for each
    DataLabel symbol.  */
 
-static bfd_boolean
+static int
 sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info,
                                    const char *cname,
                                    Elf_Internal_Sym *sym,
@@ -2932,13 +2807,13 @@ sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info,
 {
   char *name = (char *) cname;
 
-  if (info->relocatable || info->emitrelocations)
+  if (bfd_link_relocatable (info) || 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
@@ -3128,21 +3003,22 @@ sh64_elf64_link_hash_newfunc (struct bfd_hash_entry *entry,
 static struct bfd_link_hash_table *
 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
@@ -3217,7 +3093,7 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   if (bed->plt_readonly)
     pltflags |= SEC_READONLY;
 
-  s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
+  s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
   if (s == NULL
       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
     return FALSE;
@@ -3237,15 +3113,17 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
       h = (struct elf_link_hash_entry *) bh;
       h->def_regular = 1;
       h->type = STT_OBJECT;
+      elf_hash_table (info)->hplt = h;
 
-      if (info->shared
+      if (bfd_link_pic (info)
          && ! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
     }
 
-  s = bfd_make_section_with_flags (abfd,
-                                  bed->default_use_rela_p ? ".rela.plt" : ".rel.plt",
-                                  flags | SEC_READONLY);
+  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_alignment (abfd, s, ptralign))
     return FALSE;
@@ -3253,30 +3131,6 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   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_with_flags (abfd, relname,
-                                        flags | SEC_READONLY);
-       if (s == NULL
-           || ! 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
@@ -3285,8 +3139,8 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *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_with_flags (abfd, ".dynbss",
-                                      SEC_ALLOC | SEC_LINKER_CREATED);
+      s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
+                                             SEC_ALLOC | SEC_LINKER_CREATED);
       if (s == NULL)
        return FALSE;
 
@@ -3301,12 +3155,12 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
         be needed, we can discard it later.  We will never need this
         section when generating a shared object, since they do not use
         copy relocs.  */
-      if (! info->shared)
+      if (! bfd_link_pic (info))
        {
-         s = bfd_make_section_with_flags (abfd,
-                                          (bed->default_use_rela_p
-                                           ? ".rela.bss" : ".rel.bss"),
-                                          flags | SEC_READONLY);
+         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_alignment (abfd, s, ptralign))
            return FALSE;
@@ -3328,14 +3182,13 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   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->needs_plt
-                 || h->u.weakdef != NULL
+                 || h->is_weakalias
                  || (h->def_dynamic
                      && h->ref_regular
                      && !h->def_regular)));
@@ -3346,7 +3199,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (h->type == STT_FUNC
       || h->needs_plt)
     {
-      if (! info->shared
+      if (! bfd_link_pic (info)
          && !h->def_dynamic
          && !h->ref_dynamic)
        {
@@ -3366,7 +3219,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
            return FALSE;
        }
 
-      s = bfd_get_section_by_name (dynobj, ".plt");
+      s = elf_hash_table (info)->splt;
       BFD_ASSERT (s != NULL);
 
       /* If this is the first .plt entry, make room for the special
@@ -3379,7 +3232,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
         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
+      if (! bfd_link_pic (info)
          && !h->def_regular)
        {
          h->root.u.def.section = s;
@@ -3394,13 +3247,13 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *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 = elf_hash_table (info)->sgotplt;
       BFD_ASSERT (s != NULL);
       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 = elf_hash_table (info)->srelplt;
       BFD_ASSERT (s != NULL);
       s->size += sizeof (Elf64_External_Rela);
 
@@ -3410,12 +3263,12 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->u.weakdef != NULL)
+  if (h->is_weakalias)
     {
-      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;
+      struct elf_link_hash_entry *def = weakdef (h);
+      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+      h->root.u.def.section = def->root.u.def.section;
+      h->root.u.def.value = def->root.u.def.value;
       return TRUE;
     }
 
@@ -3426,7 +3279,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
      only references to the symbol are via the global offset table.
      For such cases we need not do anything here; the relocations will
      be handled correctly by relocate_section.  */
-  if (info->shared)
+  if (bfd_link_pic (info))
     return TRUE;
 
   /* If there are no references to this symbol that do not use the
@@ -3444,45 +3297,24 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
      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->size += sizeof (Elf64_External_Rela);
       h->needs_copy = 1;
     }
 
-  /* 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->size = BFD_ALIGN (s->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;
-    }
-
-  /* Define the symbol as being at this point in the section.  */
-  h->root.u.def.section = s;
-  h->root.u.def.value = s->size;
-
-  /* Increment the section size to make room for the symbol.  */
-  s->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
@@ -3498,9 +3330,6 @@ sh64_elf64_discard_copies (struct elf_sh64_link_hash_entry *h,
 {
   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.def_regular)
     return TRUE;
@@ -3529,9 +3358,9 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
+      if (bfd_link_executable (info) && !info->nointerp)
        {
-         s = bfd_get_section_by_name (dynobj, ".interp");
+         s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
@@ -3544,7 +3373,7 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
         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 = elf_hash_table (info)->srelgot;
       if (s != NULL)
        s->size = 0;
     }
@@ -3553,8 +3382,8 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
      PC relative relocs against symbols defined in a regular object.
      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),
+  if (bfd_link_pic (info) && info->symbolic)
+    sh64_elf64_link_hash_traverse (elf_hash_table (info),
                                   sh64_elf64_discard_copies, NULL);
 
   /* The check_relocs and adjust_dynamic_symbol entry points have
@@ -3566,7 +3395,6 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char *name;
-      bfd_boolean strip;
 
       if ((s->flags & SEC_LINKER_CREATED) == 0)
        continue;
@@ -3575,38 +3403,14 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
         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->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->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;
 
@@ -3637,21 +3441,34 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
              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)
        {
+         /* 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->size);
-      if (s->contents == NULL && s->size != 0)
+      if (s->contents == NULL)
        return FALSE;
     }
 
@@ -3662,7 +3479,7 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
         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
         dynamic linker and used by the debugger.  */
-      if (info->executable)
+      if (bfd_link_executable (info))
        {
          if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
            return FALSE;
@@ -3725,9 +3542,9 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
 
       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 = elf_hash_table (info)->splt;
+      sgot = elf_hash_table (info)->sgotplt;
+      srel = elf_hash_table (info)->srelplt;
       BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
 
       /* Get the index in the procedure linkage table which
@@ -3741,11 +3558,11 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
         The first three are reserved.  */
       got_offset = (plt_index + 3) * 8;
 
-      if (info->shared)
+      if (bfd_link_pic (info))
        got_offset -= GOT_BIAS;
 
       /* Fill in the entry in the procedure linkage table.  */
-      if (! info->shared)
+      if (! bfd_link_pic (info))
        {
          if (elf_sh64_plt_entry == NULL)
            {
@@ -3784,7 +3601,7 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
                              + elf_sh64_plt_symbol_offset (info)));
        }
 
-      if (info->shared)
+      if (bfd_link_pic (info))
        got_offset += GOT_BIAS;
 
       movi_shori_putval (output_bfd,
@@ -3828,8 +3645,8 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
       /* 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 = elf_hash_table (info)->sgot;
+      srel = elf_hash_table (info)->srelgot;
       BFD_ASSERT (sgot != NULL && srel != NULL);
 
       rel.r_offset = (sgot->output_section->vma
@@ -3841,7 +3658,7 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
         the symbol was forced to be local because of a version file.
         The entry in the global offset table will already have been
         initialized in the relocate_section function.  */
-      if (info->shared
+      if (bfd_link_pic (info)
          && (info->symbolic || h->dynindx == -1)
          && h->def_regular)
        {
@@ -3874,8 +3691,7 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
                  && (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
@@ -3889,8 +3705,8 @@ sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   /* 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;
@@ -3908,9 +3724,9 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
 
   dynobj = elf_hash_table (info)->dynobj;
 
-  sgot = bfd_get_section_by_name (dynobj, ".got.plt");
+  sgot = elf_hash_table (info)->sgotplt;
   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)
     {
@@ -3955,48 +3771,29 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_PLTGOT:
-             name = ".got";
+             s = elf_hash_table (info)->sgotplt;
              goto get_vma;
 
            case DT_JMPREL:
-             name = ".rela.plt";
+             s = elf_hash_table (info)->srelplt;
            get_vma:
-             s = bfd_get_section_by_name (output_bfd, name);
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->vma;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_PLTRELSZ:
-             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
-             BFD_ASSERT (s != NULL);
+             s = elf_hash_table (info)->srelplt;
              dyn.d_un.d_val = s->size;
              bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
-
-           case DT_RELASZ:
-             /* My reading of the SVR4 ABI indicates that the
-                procedure linkage table relocs (DT_JMPREL) should be
-                included in the overall relocs (DT_RELA).  This is
-                what Solaris does.  However, UnixWare can not handle
-                that case.  Therefore, we override the DT_RELASZ entry
-                here to make it not include the JMPREL relocs.  Since
-                the linker script arranges for .rela.plt to follow all
-                other relocation sections, we don't have to worry
-                about changing the DT_RELA entry.  */
-             s = bfd_get_section_by_name (output_bfd, ".rela.plt");
-             if (s != NULL)
-               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");
+      splt = elf_hash_table (info)->splt;
       if (splt && splt->size > 0)
        {
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              if (elf_sh64_pic_plt_entry == NULL)
                {
@@ -4053,9 +3850,9 @@ static void
 sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
                                   const Elf_Internal_Sym *isym,
                                   bfd_boolean definition,
-                                  bfd_boolean dynamic)
+                                  bfd_boolean dynamic ATTRIBUTE_UNUSED)
 {
-  if (isym->st_other != 0 && dynamic)
+  if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
     {
       unsigned char other;
 
@@ -4068,33 +3865,15 @@ sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
   return;
 }
 
-static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
+static const struct bfd_elf_special_section sh64_elf64_special_sections[]=
 {
-  { ".cranges", 8, 0, SHT_PROGBITS, 0 },
-  { NULL,       0, 0, 0,            0 }
+  { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
+  { NULL,                      0, 0, 0,            0 }
 };
 
-static const struct bfd_elf_special_section *
-sh64_elf64_get_sec_type_attr (bfd *abfd, asection *sec)
-{
-  const struct bfd_elf_special_section const *ssect;
-
-  /* See if this is one of the special sections.  */
-  if (sec->name == NULL)
-    return NULL;
-
-  ssect = _bfd_elf_get_special_section (sec->name,
-                                       sh64_elf64_special_sections,
-                                       sec->use_rela_p);
-  if (ssect != NULL)
-    return ssect;
-
-  return _bfd_elf_get_sec_type_attr (abfd, sec);
-}
-
-#define TARGET_BIG_SYM         bfd_elf64_sh64_vec
+#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
@@ -4103,6 +3882,8 @@ sh64_elf64_get_sec_type_attr (bfd *abfd, asection *sec)
 #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.  */
@@ -4119,9 +3900,8 @@ sh64_elf64_get_sec_type_attr (bfd *abfd, asection *sec)
                                        sh_elf64_merge_private_data
 #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_gc_mark_hook       sh_elf64_gc_mark_hook
+#define elf_backend_check_relocs       sh_elf64_check_relocs
 
 #define elf_backend_can_gc_sections    1
 
@@ -4136,7 +3916,7 @@ sh64_elf64_get_sec_type_attr (bfd *abfd, asection *sec)
        sh64_elf64_merge_symbol_attribute
 
 #define elf_backend_final_write_processing \
-       sh64_elf64_final_write_processing
+       sh64_elf64_final_write_processing
 
 #define elf_backend_create_dynamic_sections \
                                        sh64_elf64_create_dynamic_sections
@@ -4146,26 +3926,30 @@ sh64_elf64_get_sec_type_attr (bfd *abfd, asection *sec)
                                        sh64_elf64_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
                                        sh64_elf64_size_dynamic_sections
+#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
 #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_get_sec_type_attr  sh64_elf64_get_sec_type_attr
+#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_dtrel_excludes_plt 1
+
+#define elf_backend_linux_prpsinfo64_ugid16    TRUE
 
 #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
@@ -4179,13 +3963,14 @@ sh64_elf64_get_sec_type_attr (bfd *abfd, asection *sec)
 
 /* 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.053725 seconds and 4 git commands to generate.