gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-d10v.c
index 8d7cd944f7b76638135e04c67034eef02ccc5422..9f921c907ac993d7f3a2800a9b27dc7bcd03d430 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, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 1996-2020 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,8 +33,8 @@ 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.  */
+        3,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        0,                     /* Bitsize.  */
         FALSE,                 /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
         FALSE,                 /* PC_relative.  */
         0,                     /* Bitpos.  */
         complain_overflow_dont,/* Complain_on_overflow.  */
@@ -48,32 +47,32 @@ static reloc_howto_type elf_d10v_howto_table[] =
 
   /* 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.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        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.  */
+        0xff,                  /* Dst_mask.  */
         TRUE),                 /* PCrel_offset.  */
 
   /* An PC Relative 10-bit relocation, shifted by 2, left container.  */
   HOWTO (R_D10V_10_PCREL_L,    /* Type.  */
         TRUE),                 /* PCrel_offset.  */
 
   /* 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.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        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.  */
+        0x07f8000,             /* Dst_mask.  */
         TRUE),                 /* PCrel_offset.  */
 
   /* A 16 bit absolute relocation.  */
         TRUE),                 /* PCrel_offset.  */
 
   /* A 16 bit absolute relocation.  */
@@ -138,33 +137,33 @@ static reloc_howto_type elf_d10v_howto_table[] =
 
   /* 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.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        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.  */
+        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.  */
         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,18 +202,42 @@ 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 bfd_boolean
+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 *
 }
 
 static asection *
@@ -246,18 +269,15 @@ elf32_d10v_check_relocs (bfd *abfd,
                         const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
                         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)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
     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 (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++)
@@ -267,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];
@@ -277,21 +297,21 @@ 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;
@@ -401,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;
@@ -444,40 +435,45 @@ 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;
+         bfd_boolean 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 (r_symndx == 0)
-       {
-         /* r_symndx will be zero only for relocs against symbols from
-            removed linkonce sections, or sections discarded by a linker
-            script.  For these relocs, we just want the section contents
-            zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         continue;
-       }
+      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;
 
       if (h != NULL)
        name = h->root.root.string;
@@ -486,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)
        {
@@ -500,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:
@@ -531,10 +523,8 @@ 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;
            }
        }
@@ -547,16 +537,15 @@ elf32_d10v_relocate_section (bfd *output_bfd,
 #define ELF_MACHINE_ALT1       EM_CYGNUS_D10V
 #define ELF_MAXPAGESIZE                0x1000
 
 #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_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"
This page took 0.035467 seconds and 4 git commands to generate.