* elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the
authorAndreas Jaeger <aj@suse.de>
Sun, 26 Aug 2001 18:03:19 +0000 (18:03 +0000)
committerAndreas Jaeger <aj@suse.de>
Sun, 26 Aug 2001 18:03:19 +0000 (18:03 +0000)
reloc is against read-only section.
(elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of
looking up section names for DT_TEXTREL.
(elf_cris_reloc_type_class): New.
(elf_backend_reloc_type_class): Define.

* elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is
against read-only section.
(elf_backend_reloc_type_class): Define.
(sh_elf_reloc_type_class): New.
(sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
looking up section names for DT_TEXTREL.

* elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the
reloc is against read-only section.
(elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of
looking up section names for DT_TEXTREL.
(elf32_arm_reloc_type_class): New.

bfd/ChangeLog
bfd/elf32-arm.h
bfd/elf32-cris.c
bfd/elf32-sh.c

index cdab09608c3094516211dc8004210476132dd128..2d21d8ad8e5a38d9c445e18c390f50ab45210b5b 100644 (file)
@@ -1,3 +1,26 @@
+2001-08-26  Andreas Jaeger  <aj@suse.de>
+
+       * elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the
+       reloc is against read-only section.
+       (elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of
+       looking up section names for DT_TEXTREL.
+       (elf_cris_reloc_type_class): New.
+       (elf_backend_reloc_type_class): Define.
+
+       * elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is
+       against read-only section.
+       (elf_backend_reloc_type_class): Define.
+       (sh_elf_reloc_type_class): New.
+       (sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
+       looking up section names for DT_TEXTREL.
+
+       * elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the
+       reloc is against read-only section.
+       (elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of
+       looking up section names for DT_TEXTREL.
+       (elf32_arm_reloc_type_class): New.
+       (elf_backend_reloc_type_class): Define.
+
 2001-08-25  Andreas Jaeger  <aj@suse.de>
 
        * oasys.c: Add missing prototypes.
index af27354f40046b8630e4bb2b91f5fe078ff85ef0..fcde30ec84c57221337af88c68bf4e091482028b 100644 (file)
@@ -91,6 +91,9 @@ boolean bfd_elf32_arm_get_bfd_for_interworking
   PARAMS ((bfd *, struct bfd_link_info *));
 boolean bfd_elf32_arm_process_before_allocation
   PARAMS ((bfd *, struct bfd_link_info *, int));
+static enum elf_reloc_type_class elf32_arm_reloc_type_class
+  PARAMS ((int));
+
 #define INTERWORK_FLAG(abfd)   (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK)
 
 /* The linker script knows the section names for placement.
@@ -125,7 +128,7 @@ static const unsigned long elf32_arm_plt0_entry [PLT_ENTRY_SIZE / 4] =
 /* Subsequent entries in a procedure linkage table look like
    this.  */
 static const unsigned long elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] =
- { 
+ {
    0xe59fc004, /* ldr   ip, [pc, #4]       */
    0xe08fc00c, /* add   ip, pc, ip         */
    0xe59cf000, /* ldr   pc, [ip]           */
@@ -1058,7 +1061,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
   /* If the start address has been set, then set the EF_ARM_HASENTRY
      flag.  Setting this more than once is redundant, but the cost is
      not too high, and it keeps the code simple.
-     
+
      The test is done  here, rather than somewhere else, because the
      start address is only set just before the final link commences.
 
@@ -1066,7 +1069,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
      flag will not be set.  */
   if (bfd_get_start_address (output_bfd) != 0)
     elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
-      
+
   globals = elf32_arm_hash_table (info);
 
   dynobj = elf_hash_table (info)->dynobj;
@@ -1110,7 +1113,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
         into the output file to be resolved at run time.  */
       if (info->shared
          && (r_type != R_ARM_PC24
-             || (h != NULL
+             || (h != NULL
                  && h->dynindx != -1
                  && (! info->symbolic
                      || (h->elf_link_hash_flags
@@ -1493,7 +1496,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
             corresponding bit one in the target address will be set from bit
             one of the source address.  */
          lower_insn &= ~1;
-#endif 
+#endif
        /* Put the relocated value back in the object file:  */
        bfd_put_16 (input_bfd, upper_insn, hit_data);
        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
@@ -1533,8 +1536,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
          calculation.  */
       value -= sgot->output_section->vma;
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                      contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                                      contents, rel->r_offset, value,
+                                      (bfd_vma) 0);
 
     case R_ARM_GOTPC:
       /* Use global offset table as symbol value.  */
@@ -1545,8 +1548,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
 
       value = sgot->output_section->vma;
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                      contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                                      contents, rel->r_offset, value,
+                                      (bfd_vma) 0);
 
     case R_ARM_GOT32:
       /* Relocation is to the entry for this symbol in the
@@ -1629,8 +1632,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        }
 
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                      contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                                      contents, rel->r_offset, value,
+                                      (bfd_vma) 0);
 
     case R_ARM_PLT32:
       /* Relocation is to the entry for this symbol in the
@@ -1640,8 +1643,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
          without using the procedure linkage table.  */
       if (h == NULL)
         return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                        contents, rel->r_offset, value,
-                                        (bfd_vma) 0);
+                                contents, rel->r_offset, value,
+                                (bfd_vma) 0);
 
       if (h->plt.offset == (bfd_vma) -1)
         /* We didn't make a PLT entry for this symbol.  This
@@ -1659,8 +1662,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
               + splt->output_offset
               + h->plt.offset);
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                      contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                              contents, rel->r_offset, value,
+                              (bfd_vma) 0);
 
     case R_ARM_SBREL32:
       return bfd_reloc_notsupported;
@@ -1872,7 +1875,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                case R_ARM_ABS32:
                  if (info->shared
                      && (
-                         (!info->symbolic && h->dynindx != -1)
+                 (!info->symbolic && h->dynindx != -1)
                          || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
                          )
                      && ((input_section->flags & SEC_ALLOC) != 0
@@ -2310,7 +2313,7 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
       if (flags & EF_ARM_MAPSYMSFIRST)
        fprintf (file, _(" [mapping symbols precede others]"));
 
-      flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX 
+      flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
                 | EF_ARM_MAPSYMSFIRST);
       break;
 
@@ -2506,7 +2509,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                    srelgot = bfd_make_section (dynobj, ".rel.got");
                    if (srelgot == NULL
                        || ! bfd_set_section_flags (dynobj, srelgot,
-                                                   (SEC_ALLOC
+                                                   (SEC_ALLOC
                                                     | SEC_LOAD
                                                     | SEC_HAS_CONTENTS
                                                     | SEC_IN_MEMORY
@@ -2534,7 +2537,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
              }
            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)
                  {
@@ -2566,7 +2569,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
            sgot->_raw_size += 4;
            break;
 
-         case R_ARM_PLT32:
+         case R_ARM_PLT32:
            /* This symbol requires a procedure linkage table entry.  We
                actually build the entry in adjust_dynamic_symbol,
                because this might be a case of linking PIC code which is
@@ -2619,7 +2622,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                      return false;
 
                    BFD_ASSERT (strncmp (name, ".rel", 4) == 0
-                               && strcmp (bfd_get_section_name (abfd, sec),
+                               && strcmp (bfd_get_section_name (abfd, sec),
                                           name + 4) == 0);
 
                    sreloc = bfd_get_section_by_name (dynobj, name);
@@ -2637,6 +2640,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                            || ! bfd_set_section_alignment (dynobj, sreloc, 2))
                          return false;
                      }
+                 if (sec->flags & SEC_READONLY)
+                   info->flags |= DF_TEXTREL;
                  }
 
                sreloc->_raw_size += sizeof (Elf32_External_Rel);
@@ -2951,14 +2956,13 @@ elf32_arm_adjust_dynamic_symbol (info, h)
 
 static boolean
 elf32_arm_size_dynamic_sections (output_bfd, info)
-     bfd * output_bfd;
+     bfd * output_bfd ATTRIBUTE_UNUSED;
      struct bfd_link_info * info;
 {
   bfd * dynobj;
   asection * s;
   boolean plt;
   boolean relocs;
-  boolean reltext;
 
   dynobj = elf_hash_table (info)->dynobj;
   BFD_ASSERT (dynobj != NULL);
@@ -3000,7 +3004,6 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
      memory for them.  */
   plt = false;
   relocs = false;
-  reltext = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char * name;
@@ -3046,30 +3049,10 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
            }
          else
            {
-             asection * target;
-
              /* Remember whether there are any reloc sections other
                  than .rel.plt.  */
              if (strcmp (name, ".rel.plt") != 0)
-               {
-                 const char *outname;
-
-                 relocs = true;
-
-                 /* If this relocation section applies to a read only
-                    section, then we probably need a DT_TEXTREL
-                    entry.  The entries in the .rel.plt section
-                    really apply to the .got section, which we
-                    created ourselves and so know is not readonly.  */
-                 outname = bfd_get_section_name (output_bfd,
-                                                 s->output_section);
-                 target = bfd_get_section_by_name (output_bfd, outname + 4);
-
-                 if (target != NULL
-                     && (target->flags & SEC_READONLY) != 0
-                     && (target->flags & SEC_ALLOC) != 0)
-                   reltext = true;
-               }
+               relocs = true;
 
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
@@ -3133,7 +3116,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
            return false;
        }
 
-      if (reltext)
+      if ((info->flags & DF_TEXTREL) != 0)
        {
          if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
            return false;
@@ -3457,29 +3440,48 @@ elf32_arm_post_process_headers (abfd, link_info)
   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
 }
 
+static enum elf_reloc_type_class
+elf32_arm_reloc_type_class (type)
+     int type;
+{
+  switch (type)
+    {
+    case R_ARM_RELATIVE:
+      return reloc_class_relative;
+    case R_ARM_JUMP_SLOT:
+      return reloc_class_plt;
+    case R_ARM_COPY:
+      return reloc_class_copy;
+    default:
+      return reloc_class_normal;
+    }
+}
+
+
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_MACHINE_CODE               EM_ARM
 #define ELF_MAXPAGESIZE                        0x8000
 
-#define bfd_elf32_bfd_copy_private_bfd_data    elf32_arm_copy_private_bfd_data
-#define bfd_elf32_bfd_merge_private_bfd_data   elf32_arm_merge_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data    elf32_arm_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data   elf32_arm_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags                elf32_arm_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data   elf32_arm_print_private_bfd_data
 #define bfd_elf32_bfd_link_hash_table_create    elf32_arm_link_hash_table_create
-#define bfd_elf32_bfd_reloc_type_lookup        elf32_arm_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_type_lookup        elf32_arm_reloc_type_lookup
 #define bfd_elf32_find_nearest_line            elf32_arm_find_nearest_line
 
 #define elf_backend_get_symbol_type             elf32_arm_get_symbol_type
 #define elf_backend_gc_mark_hook                elf32_arm_gc_mark_hook
 #define elf_backend_gc_sweep_hook               elf32_arm_gc_sweep_hook
 #define elf_backend_check_relocs                elf32_arm_check_relocs
-#define elf_backend_relocate_section           elf32_arm_relocate_section
+#define elf_backend_relocate_section   elf32_arm_relocate_section
 #define elf_backend_adjust_dynamic_symbol      elf32_arm_adjust_dynamic_symbol
 #define elf_backend_create_dynamic_sections    _bfd_elf_create_dynamic_sections
 #define elf_backend_finish_dynamic_symbol      elf32_arm_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections    elf32_arm_finish_dynamic_sections
 #define elf_backend_size_dynamic_sections      elf32_arm_size_dynamic_sections
 #define elf_backend_post_process_headers       elf32_arm_post_process_headers
+#define elf_backend_reloc_type_class           elf32_arm_reloc_type_class
 
 #define elf_backend_can_gc_sections 1
 #define elf_backend_plt_readonly    1
index e57202b37dcc0d4fc21dd4f7b01277f1b41da8cd..a4b5e09dc10b1c5dab7d358ac030e30c35f9efd2 100644 (file)
@@ -85,6 +85,8 @@ static boolean elf_cris_finish_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static void elf_cris_hide_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static enum elf_reloc_type_class elf_cris_reloc_type_class
+  PARAMS ((int));
 
 static reloc_howto_type cris_elf_howto_table [] =
 {
@@ -2575,6 +2577,8 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
                      || !bfd_set_section_alignment (dynobj, sreloc, 2))
                    return false;
                }
+             if (sec->flags & SEC_READONLY)
+               info->flags |= DF_TEXTREL;
            }
 
          sreloc->_raw_size += sizeof (Elf32_External_Rela);
@@ -2642,14 +2646,13 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
 
 static boolean
 elf_cris_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
+     bfd *output_bfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
   bfd *dynobj;
   asection *s;
   boolean plt;
   boolean relocs;
-  boolean reltext;
 
   dynobj = elf_hash_table (info)->dynobj;
   BFD_ASSERT (dynobj != NULL);
@@ -2703,7 +2706,6 @@ elf_cris_size_dynamic_sections (output_bfd, info)
      memory for them.  */
   plt = false;
   relocs = false;
-  reltext = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char *name;
@@ -2749,41 +2751,11 @@ elf_cris_size_dynamic_sections (output_bfd, info)
            }
          else
            {
-             asection *target;
-
              /* Remember whether there are any reloc sections other
                  than .rela.plt.  */
              if (strcmp (name, ".rela.plt") != 0)
-               {
-                 const char *outname;
-
                  relocs = true;
 
-                 /* If this relocation section applies to a read only
-                    section, then we probably need a DT_TEXTREL entry.
-                    The entries in the .rela.plt section are actually
-                    associated with .got.plt, which we created ourselves
-                    and so know is not readonly.  */
-                 outname = bfd_get_section_name (output_bfd,
-                                                 s->output_section);
-                 target
-                   = bfd_get_section_by_name (output_bfd,
-                                              outname + strlen (".rela"));
-
-                 /* We have to test the .text section by name, becase for
-                    some reason it does not have SEC_READONLY set at this
-                    time.  That flag is actually set in ldmain.c:main
-                    specifically for ".text" at a time long after this
-                    function is called.  FIXME: This might be due to a
-                    general bug.  FIXME: Have testcase for this.  */
-                 if (target != NULL
-                     && (target->flags & SEC_ALLOC) != 0
-                     && ((target->flags & SEC_READONLY) != 0
-                         || strcmp (outname + strlen (".rela"),
-                                    ".text") == 0))
-                   reltext = true;
-               }
-
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
@@ -2842,7 +2814,7 @@ elf_cris_size_dynamic_sections (output_bfd, info)
            return false;
        }
 
-      if (reltext)
+      if ((info->flags & DF_TEXTREL) != 0)
        {
          if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
            return false;
@@ -3020,6 +2992,24 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
 
   return true;
 }
+
+
+static enum elf_reloc_type_class
+elf_cris_reloc_type_class (type)
+     int type;
+{
+  switch (type)
+    {
+    case R_CRIS_RELATIVE:
+      return reloc_class_relative;
+    case R_CRIS_JUMP_SLOT:
+      return reloc_class_plt;
+    case R_CRIS_COPY:
+      return reloc_class_copy;
+    default:
+      return reloc_class_normal;
+    }
+}
 \f
 #define ELF_ARCH               bfd_arch_cris
 #define ELF_MACHINE_CODE       EM_CRIS
@@ -3063,6 +3053,7 @@ cris_elf_merge_private_bfd_data (ibfd, obfd)
 #define bfd_elf32_bfd_final_link \
        _bfd_elf32_gc_common_final_link
 #define elf_backend_hide_symbol                        elf_cris_hide_symbol
+#define elf_backend_reloc_type_class           elf_cris_reloc_type_class
 
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1
index 11ea3a5d4f42a9dbbf08c7096bbf5272692ebc85..6cf497491825994caa3bc7a20f25edd8b2826dbc 100644 (file)
@@ -83,6 +83,8 @@ static asection * sh_elf_gc_mark_hook
 static boolean sh_elf_gc_sweep_hook
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
+static enum elf_reloc_type_class sh_elf_reloc_type_class
+  PARAMS ((int));
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
@@ -1111,11 +1113,11 @@ sh_elf_relax_section (abfd, sec, link_info, again)
        }
 
       /* Get the address from which the register is being loaded.  The
-        displacement in the mov.l instruction is quadrupled.  It is a
-        displacement from four bytes after the movl instruction, but,
-        before adding in the PC address, two least significant bits
-        of the PC are cleared.  We assume that the section is aligned
-        on a four byte boundary.  */
+        displacement in the mov.l instruction is quadrupled.  It is a
+        displacement from four bytes after the movl instruction, but,
+        before adding in the PC address, two least significant bits
+        of the PC are cleared.  We assume that the section is aligned
+        on a four byte boundary.  */
       paddr = insn & 0xff;
       paddr *= 4;
       paddr += (laddr + 4) & ~3;
@@ -2761,14 +2763,13 @@ sh_elf_adjust_dynamic_symbol (info, h)
 
 static boolean
 sh_elf_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
+     bfd *output_bfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
   bfd *dynobj;
   asection *s;
   boolean plt;
   boolean relocs;
-  boolean reltext;
 
   dynobj = elf_hash_table (info)->dynobj;
   BFD_ASSERT (dynobj != NULL);
@@ -2810,7 +2811,6 @@ sh_elf_size_dynamic_sections (output_bfd, info)
      memory for them.  */
   plt = false;
   relocs = false;
-  reltext = false;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
       const char *name;
@@ -2856,29 +2856,10 @@ sh_elf_size_dynamic_sections (output_bfd, info)
            }
          else
            {
-             asection *target;
-
              /* Remember whether there are any reloc sections other
                 than .rela.plt.  */
              if (strcmp (name, ".rela.plt") != 0)
-               {
-                 const char *outname;
-
-                 relocs = true;
-
-                 /* If this relocation section applies to a read only
-                    section, then we probably need a DT_TEXTREL
-                    entry.  The entries in the .rela.plt section
-                    really apply to the .got section, which we
-                    created ourselves and so know is not readonly.  */
-                 outname = bfd_get_section_name (output_bfd,
-                                                 s->output_section);
-                 target = bfd_get_section_by_name (output_bfd, outname + 5);
-                 if (target != NULL
-                     && (target->flags & SEC_READONLY) != 0
-                     && (target->flags & SEC_ALLOC) != 0)
-                   reltext = true;
-               }
+               relocs = true;
 
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
@@ -2934,7 +2915,7 @@ sh_elf_size_dynamic_sections (output_bfd, info)
            return false;
        }
 
-      if (reltext)
+      if ((info->flags & DF_TEXTREL) != 0)
        {
          if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
            return false;
@@ -3957,6 +3938,8 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
                          || ! bfd_set_section_alignment (dynobj, sreloc, 2))
                        return false;
                    }
+                 if (sec->flags & SEC_READONLY)
+                   info->flags |= DF_TEXTREL;
                }
 
              sreloc->_raw_size += sizeof (Elf32_External_Rela);
@@ -4441,6 +4424,23 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
   return true;
 }
 
+static enum elf_reloc_type_class
+sh_elf_reloc_type_class (type)
+     int type;
+{
+  switch (type)
+    {
+    case R_SH_RELATIVE:
+      return reloc_class_relative;
+    case R_SH_JMP_SLOT:
+      return reloc_class_plt;
+    case R_SH_COPY:
+      return reloc_class_copy;
+    default:
+      return reloc_class_normal;
+    }
+}
+
 #ifndef ELF_ARCH
 #define TARGET_BIG_SYM         bfd_elf32_sh_vec
 #define TARGET_BIG_NAME                "elf32-sh"
@@ -4484,6 +4484,7 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
                                        sh_elf_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections \
                                        sh_elf_finish_dynamic_sections
+#define elf_backend_reloc_type_class   sh_elf_reloc_type_class
 
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1