aarch64: Enable Cortex-X4 CPU
[binutils-gdb.git] / bfd / elf32-d10v.c
index 293b1419de7c6baf12c95153f8b30ec3d74515f9..0677d73f21cda4eb1a1500a27fe22b570b66a301 100644 (file)
@@ -1,13 +1,12 @@
 /* D10V-specific support for 32-bit ELF
 /* D10V-specific support for 32-bit ELF
-   Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1996-2023 Free Software Foundation, Inc.
    Contributed by Martin Hunt (hunt@cygnus.com).
 
    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
    Contributed by Martin Hunt (hunt@cygnus.com).
 
    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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -20,8 +19,8 @@
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/d10v.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/d10v.h"
@@ -34,137 +33,137 @@ static reloc_howto_type elf_d10v_howto_table[] =
   /* This reloc does nothing.  */
   HOWTO (R_D10V_NONE,          /* Type.  */
         0,                     /* Rightshift.  */
   /* This reloc does nothing.  */
   HOWTO (R_D10V_NONE,          /* Type.  */
         0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        32,                    /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
+        0,                     /* Size.  */
+        0,                     /* Bitsize.  */
+        false,                 /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_NONE",         /* Name.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_NONE",         /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0,                     /* Src_mask.  */
         0,                     /* Dst_mask.  */
         0,                     /* Src_mask.  */
         0,                     /* Dst_mask.  */
-        FALSE),                /* PCrel_offset.  */
+        false),                /* PCrel_offset.  */
 
   /* An PC Relative 10-bit relocation, shifted by 2, right container.  */
   HOWTO (R_D10V_10_PCREL_R,    /* Type.  */
 
   /* An PC Relative 10-bit relocation, shifted by 2, right container.  */
   HOWTO (R_D10V_10_PCREL_R,    /* Type.  */
-        2,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        8,                     /* Bitsize.  */
-        TRUE,                  /* PC_relative.  */
-        0,                     /* Bitpos.  */
+        2,                     /* Rightshift.  */
+        4,                     /* Size.  */
+        8,                     /* Bitsize.  */
+        true,                  /* PC_relative.  */
+        0,                     /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_10_PCREL_R",   /* Name.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_10_PCREL_R",   /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0xff,                  /* Src_mask.  */
         0xff,                  /* Src_mask.  */
-        0xff,                  /* Dst_mask.  */
-        TRUE),                 /* PCrel_offset.  */
+        0xff,                  /* Dst_mask.  */
+        true),                 /* PCrel_offset.  */
 
   /* An PC Relative 10-bit relocation, shifted by 2, left container.  */
   HOWTO (R_D10V_10_PCREL_L,    /* Type.  */
 
   /* An PC Relative 10-bit relocation, shifted by 2, left container.  */
   HOWTO (R_D10V_10_PCREL_L,    /* Type.  */
-        2,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        8,                     /* Bitsize.  */
-        TRUE,                  /* PC_relative.  */
-        15,                    /* Bitpos.  */
+        2,                     /* Rightshift.  */
+        4,                     /* Size.  */
+        8,                     /* Bitsize.  */
+        true,                  /* PC_relative.  */
+        15,                    /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_10_PCREL_L",   /* Name.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_10_PCREL_L",   /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0x07f8000,             /* Src_mask.  */
         0x07f8000,             /* Src_mask.  */
-        0x07f8000,             /* Dst_mask.  */
-        TRUE),                 /* PCrel_offset.  */
+        0x07f8000,             /* Dst_mask.  */
+        true),                 /* PCrel_offset.  */
 
   /* A 16 bit absolute relocation.  */
   HOWTO (R_D10V_16,            /* Type.  */
         0,                     /* Rightshift.  */
 
   /* A 16 bit absolute relocation.  */
   HOWTO (R_D10V_16,            /* Type.  */
         0,                     /* Rightshift.  */
-        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        2,                     /* Size.  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
+        false,                 /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_16",           /* Name.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_16",           /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0xffff,                /* Src_mask.  */
         0xffff,                /* Dst_mask.  */
         0xffff,                /* Src_mask.  */
         0xffff,                /* Dst_mask.  */
-        FALSE),                /* PCrel_offset.  */
+        false),                /* PCrel_offset.  */
 
   /* An 18 bit absolute relocation, right shifted 2.  */
   HOWTO (R_D10V_18,            /* Type.  */
         2,                     /* Rightshift.  */
 
   /* An 18 bit absolute relocation, right shifted 2.  */
   HOWTO (R_D10V_18,            /* Type.  */
         2,                     /* Rightshift.  */
-        1,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        2,                     /* Size.  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
+        false,                 /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_18",           /* Name.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_18",           /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0xffff,                /* Src_mask.  */
         0xffff,                /* Dst_mask.  */
         0xffff,                /* Src_mask.  */
         0xffff,                /* Dst_mask.  */
-        FALSE),                /* PCrel_offset.  */
+        false),                /* PCrel_offset.  */
 
   /* A relative 18 bit relocation, right shifted by 2.  */
   HOWTO (R_D10V_18_PCREL,      /* Type.  */
         2,                     /* Rightshift.  */
 
   /* A relative 18 bit relocation, right shifted by 2.  */
   HOWTO (R_D10V_18_PCREL,      /* Type.  */
         2,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        4,                     /* Size.  */
         16,                    /* Bitsize.  */
         16,                    /* Bitsize.  */
-        TRUE,                  /* PC_relative.  */
+        true,                  /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_18_PCREL",     /* Name.  */
         0,                     /* Bitpos.  */
         complain_overflow_signed, /* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_18_PCREL",     /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0xffff,                /* Src_mask.  */
         0xffff,                /* Dst_mask.  */
         0xffff,                /* Src_mask.  */
         0xffff,                /* Dst_mask.  */
-        TRUE),                 /* PCrel_offset.  */
+        true),                 /* PCrel_offset.  */
 
   /* A 32 bit absolute relocation.  */
   HOWTO (R_D10V_32,            /* Type.  */
         0,                     /* Rightshift.  */
 
   /* A 32 bit absolute relocation.  */
   HOWTO (R_D10V_32,            /* Type.  */
         0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        4,                     /* Size.  */
         32,                    /* Bitsize.  */
         32,                    /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
+        false,                 /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_32",           /* Name.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         bfd_elf_generic_reloc, /* Special_function.  */
         "R_D10V_32",           /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
+        false,                 /* Partial_inplace.  */
         0xffffffff,            /* Src_mask.  */
         0xffffffff,            /* Dst_mask.  */
         0xffffffff,            /* Src_mask.  */
         0xffffffff,            /* Dst_mask.  */
-        FALSE),                /* PCrel_offset.  */
+        false),                /* PCrel_offset.  */
 
   /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_D10V_GNU_VTINHERIT, /* Type.  */
 
   /* GNU extension to record C++ vtable hierarchy.  */
   HOWTO (R_D10V_GNU_VTINHERIT, /* Type.  */
-        0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
-        0,                     /* Bitpos.  */
+        0,                     /* Rightshift.  */
+        4,                     /* Size.  */
+        0,                     /* Bitsize.  */
+        false,                 /* PC_relative.  */
+        0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
-        NULL,                  /* Special_function.  */
+        NULL,                  /* Special_function.  */
         "R_D10V_GNU_VTINHERIT",/* Name.  */
         "R_D10V_GNU_VTINHERIT",/* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Src_mask.  */
-        0,                     /* Dst_mask.  */
-        FALSE),                /* PCrel_offset.  */
+        false,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        false),                /* PCrel_offset.  */
 
   /* GNU extension to record C++ vtable member usage.  */
 
   /* GNU extension to record C++ vtable member usage.  */
-  HOWTO (R_D10V_GNU_VTENTRY,    /* Type.  */
-        0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        0,                     /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
-        0,                     /* Bitpos.  */
+  HOWTO (R_D10V_GNU_VTENTRY,   /* Type.  */
+        0,                     /* Rightshift.  */
+        4,                     /* Size.  */
+        0,                     /* Bitsize.  */
+        false,                 /* PC_relative.  */
+        0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         _bfd_elf_rel_vtable_reloc_fn,  /* Special_function.  */
-        "R_D10V_GNU_VTENTRY",  /* Name.  */
-        FALSE,                 /* Partial_inplace.  */
-        0,                     /* Src_mask.  */
-        0,                     /* Dst_mask.  */
-        FALSE),                /* PCrel_offset.  */
+        "R_D10V_GNU_VTENTRY",  /* Name.  */
+        false,                 /* Partial_inplace.  */
+        0,                     /* Src_mask.  */
+        0,                     /* Dst_mask.  */
+        false),                /* PCrel_offset.  */
 };
 
 /* Map BFD reloc types to D10V ELF reloc types.  */
 };
 
 /* Map BFD reloc types to D10V ELF reloc types.  */
@@ -203,89 +202,82 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return NULL;
 }
 
   return NULL;
 }
 
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (elf_d10v_howto_table) / sizeof (elf_d10v_howto_table[0]);
+       i++)
+    if (elf_d10v_howto_table[i].name != NULL
+       && strcasecmp (elf_d10v_howto_table[i].name, r_name) == 0)
+      return &elf_d10v_howto_table[i];
+
+  return NULL;
+}
+
 /* Set the howto pointer for an D10V ELF reloc.  */
 
 /* Set the howto pointer for an D10V ELF reloc.  */
 
-static void
-d10v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+static bool
+d10v_info_to_howto_rel (bfd *abfd,
                        arelent *cache_ptr,
                        Elf_Internal_Rela *dst)
 {
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
                        arelent *cache_ptr,
                        Elf_Internal_Rela *dst)
 {
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  BFD_ASSERT (r_type < (unsigned int) R_D10V_max);
+  if (r_type >= (unsigned int) R_D10V_max)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
   cache_ptr->howto = &elf_d10v_howto_table[r_type];
   cache_ptr->howto = &elf_d10v_howto_table[r_type];
+  return true;
 }
 
 static asection *
 elf32_d10v_gc_mark_hook (asection *sec,
 }
 
 static asection *
 elf32_d10v_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)
                         Elf_Internal_Rela *rel,
                         struct elf_link_hash_entry *h,
                         Elf_Internal_Sym *sym)
 {
   if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
+    switch (ELF32_R_TYPE (rel->r_info))
       {
       case R_D10V_GNU_VTINHERIT:
       case R_D10V_GNU_VTENTRY:
       {
       case R_D10V_GNU_VTINHERIT:
       case R_D10V_GNU_VTENTRY:
-        break;
-
-      default:
-        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;
+      }
 
 
-  return NULL;
-}
-
-static bfd_boolean
-elf32_d10v_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)
-{
-  /* We don't use got and plt entries for d10v.  */
-  return TRUE;
+  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.  */
 
 }
 
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.  */
 
-static bfd_boolean
+static bool
 elf32_d10v_check_relocs (bfd *abfd,
                         struct bfd_link_info *info,
                         asection *sec,
                         const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
 elf32_d10v_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;
 
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
 
-  if (info->relocatable)
-    return TRUE;
+  if (bfd_link_relocatable (info))
+    return true;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -295,7 +287,7 @@ elf32_d10v_check_relocs (bfd *abfd,
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
 
       r_symndx = ELF32_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];
       else
        {
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
@@ -305,24 +297,24 @@ elf32_d10v_check_relocs (bfd *abfd,
        }
 
       switch (ELF32_R_TYPE (rel->r_info))
        }
 
       switch (ELF32_R_TYPE (rel->r_info))
-        {
-        /* This relocation describes the C++ object vtable hierarchy.
-           Reconstruct it for later use during GC.  */
-        case R_D10V_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_D10V_GNU_VTENTRY:
-          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
-            return FALSE;
-          break;
-        }
+       {
+       /* This relocation describes the C++ object vtable hierarchy.
+          Reconstruct it for later use during GC.  */
+       case R_D10V_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_D10V_GNU_VTENTRY:
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+           return false;
+         break;
+       }
     }
 
     }
 
-  return TRUE;
+  return true;
 }
 
 static bfd_vma
 }
 
 static bfd_vma
@@ -332,15 +324,15 @@ extract_rel_addend (bfd *abfd,
 {
   bfd_vma insn, val;
 
 {
   bfd_vma insn, val;
 
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
     {
-    case 0:
+    case 1:
       insn = bfd_get_8 (abfd, where);
       break;
       insn = bfd_get_8 (abfd, where);
       break;
-    case 1:
+    case 2:
       insn = bfd_get_16 (abfd, where);
       break;
       insn = bfd_get_16 (abfd, where);
       break;
-    case 2:
+    case 4:
       insn = bfd_get_32 (abfd, where);
       break;
     default:
       insn = bfd_get_32 (abfd, where);
       break;
     default:
@@ -370,19 +362,19 @@ insert_rel_addend (bfd *abfd,
 
   addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
   insn = ~howto->dst_mask;
 
   addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
   insn = ~howto->dst_mask;
-  switch (howto->size)
+  switch (bfd_get_reloc_size (howto))
     {
     {
-    case 0:
+    case 1:
       insn &= bfd_get_8 (abfd, where);
       insn |= addend;
       bfd_put_8 (abfd, insn, where);
       break;
       insn &= bfd_get_8 (abfd, where);
       insn |= addend;
       bfd_put_8 (abfd, insn, where);
       break;
-    case 1:
+    case 2:
       insn &= bfd_get_16 (abfd, where);
       insn |= addend;
       bfd_put_16 (abfd, insn, where);
       break;
       insn &= bfd_get_16 (abfd, where);
       insn |= addend;
       bfd_put_16 (abfd, insn, where);
       break;
-    case 2:
+    case 4:
       insn &= bfd_get_32 (abfd, where);
       insn |= addend;
       bfd_put_32 (abfd, insn, where);
       insn &= bfd_get_32 (abfd, where);
       insn |= addend;
       bfd_put_32 (abfd, insn, where);
@@ -394,7 +386,7 @@ insert_rel_addend (bfd *abfd,
 
 /* Relocate a D10V ELF section.  */
 
 
 /* Relocate a D10V ELF section.  */
 
-static bfd_boolean
+static int
 elf32_d10v_relocate_section (bfd *output_bfd,
                             struct bfd_link_info *info,
                             bfd *input_bfd,
 elf32_d10v_relocate_section (bfd *output_bfd,
                             struct bfd_link_info *info,
                             bfd *input_bfd,
@@ -429,39 +421,10 @@ elf32_d10v_relocate_section (bfd *output_bfd,
       r_type = ELF32_R_TYPE (rel->r_info);
 
       if (r_type == R_D10V_GNU_VTENTRY
       r_type = ELF32_R_TYPE (rel->r_info);
 
       if (r_type == R_D10V_GNU_VTENTRY
-          || r_type == R_D10V_GNU_VTINHERIT)
-        continue;
+         || r_type == R_D10V_GNU_VTINHERIT)
+       continue;
 
       howto = elf_d10v_howto_table + r_type;
 
       howto = elf_d10v_howto_table + r_type;
-
-      if (info->relocatable)
-       {
-         bfd_vma val;
-         bfd_byte *where;
-
-         /* 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.  */
-         if (r_symndx >= symtab_hdr->sh_info)
-           continue;
-
-         sym = local_syms + r_symndx;
-         if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
-           continue;
-
-         sec = local_sections[r_symndx];
-         val = sec->output_offset;
-         if (val == 0)
-           continue;
-
-         where = contents + rel->r_offset;
-         val += extract_rel_addend (input_bfd, where, howto);
-         insert_rel_addend (input_bfd, where, howto, val);
-         continue;
-       }
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -472,31 +435,46 @@ elf32_d10v_relocate_section (bfd *output_bfd,
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
-         if ((sec->flags & SEC_MERGE)
-             && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+         if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
+             && ((sec->flags & SEC_MERGE) != 0
+                 || (bfd_link_relocatable (info)
+                     && sec->output_offset != 0)))
            {
            {
-             asection *msec;
              bfd_vma addend;
              bfd_byte *where = contents + rel->r_offset;
 
              addend = extract_rel_addend (input_bfd, where, howto);
              bfd_vma addend;
              bfd_byte *where = contents + rel->r_offset;
 
              addend = extract_rel_addend (input_bfd, where, howto);
-             msec = sec;
-             addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
-             addend -= relocation;
-             addend += msec->output_section->vma + msec->output_offset;
+
+             if (bfd_link_relocatable (info))
+               addend += sec->output_offset;
+             else
+               {
+                 asection *msec = sec;
+                 addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
+                                                  addend);
+                 addend -= relocation;
+                 addend += msec->output_section->vma + msec->output_offset;
+               }
              insert_rel_addend (input_bfd, where, howto, addend);
            }
        }
       else
        {
              insert_rel_addend (input_bfd, where, howto, addend);
            }
        }
       else
        {
-         bfd_boolean unresolved_reloc, warned;
+         bool unresolved_reloc, warned, ignored;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
        }
 
        }
 
+      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;
+
       if (h != NULL)
        name = h->root.root.string;
       else
       if (h != NULL)
        name = h->root.root.string;
       else
@@ -504,12 +482,12 @@ elf32_d10v_relocate_section (bfd *output_bfd,
          name = (bfd_elf_string_from_elf_section
                  (input_bfd, symtab_hdr->sh_link, sym->st_name));
          if (name == NULL || *name == '\0')
          name = (bfd_elf_string_from_elf_section
                  (input_bfd, symtab_hdr->sh_link, sym->st_name));
          if (name == NULL || *name == '\0')
-           name = bfd_section_name (input_bfd, sec);
+           name = bfd_section_name (sec);
        }
 
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
        }
 
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                    contents, rel->r_offset,
-                                    relocation, (bfd_vma) 0);
+                                   contents, rel->r_offset,
+                                   relocation, (bfd_vma) 0);
 
       if (r != bfd_reloc_ok)
        {
 
       if (r != bfd_reloc_ok)
        {
@@ -518,18 +496,14 @@ elf32_d10v_relocate_section (bfd *output_bfd,
          switch (r)
            {
            case bfd_reloc_overflow:
          switch (r)
            {
            case bfd_reloc_overflow:
-             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;
 
            case bfd_reloc_undefined:
              break;
 
            case bfd_reloc_undefined:
-             if (!((*info->callbacks->undefined_symbol)
-                   (info, name, input_bfd, input_section,
-                    rel->r_offset, TRUE)))
-               return FALSE;
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, rel->r_offset, true);
              break;
 
            case bfd_reloc_outofrange:
              break;
 
            case bfd_reloc_outofrange:
@@ -549,33 +523,29 @@ elf32_d10v_relocate_section (bfd *output_bfd,
              /* fall through */
 
            common_error:
              /* fall through */
 
            common_error:
-             if (!((*info->callbacks->warning)
-                   (info, msg, name, input_bfd, input_section,
-                    rel->r_offset)))
-               return FALSE;
+             (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                          input_section, rel->r_offset);
              break;
            }
        }
     }
 
              break;
            }
        }
     }
 
-  return TRUE;
+  return true;
 }
 #define ELF_ARCH               bfd_arch_d10v
 #define ELF_MACHINE_CODE       EM_D10V
 #define ELF_MACHINE_ALT1       EM_CYGNUS_D10V
 #define ELF_MAXPAGESIZE                0x1000
 
 }
 #define ELF_ARCH               bfd_arch_d10v
 #define ELF_MACHINE_CODE       EM_D10V
 #define ELF_MACHINE_ALT1       EM_CYGNUS_D10V
 #define ELF_MAXPAGESIZE                0x1000
 
-#define TARGET_BIG_SYM          bfd_elf32_d10v_vec
+#define TARGET_BIG_SYM         d10v_elf32_vec
 #define TARGET_BIG_NAME                "elf32-d10v"
 
 #define TARGET_BIG_NAME                "elf32-d10v"
 
-#define elf_info_to_howto                   0
-#define elf_info_to_howto_rel               d10v_info_to_howto_rel
-#define elf_backend_object_p                0
-#define elf_backend_final_write_processing   0
-#define elf_backend_gc_mark_hook             elf32_d10v_gc_mark_hook
-#define elf_backend_gc_sweep_hook            elf32_d10v_gc_sweep_hook
-#define elf_backend_check_relocs             elf32_d10v_check_relocs
-#define elf_backend_relocate_section         elf32_d10v_relocate_section
-#define elf_backend_can_gc_sections          1
+#define elf_info_to_howto                   NULL
+#define elf_info_to_howto_rel               d10v_info_to_howto_rel
+#define elf_backend_object_p                0
+#define elf_backend_gc_mark_hook            elf32_d10v_gc_mark_hook
+#define elf_backend_check_relocs            elf32_d10v_check_relocs
+#define elf_backend_relocate_section        elf32_d10v_relocate_section
+#define elf_backend_can_gc_sections         1
 
 #include "elf32-target.h"
 
 #include "elf32-target.h"