* elf32-sh.c (sh_elf_relocate_section) [R_SH_IND12W,
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 22 Aug 2000 04:58:25 +0000 (04:58 +0000)
committerAlexandre Oliva <aoliva@redhat.com>
Tue, 22 Aug 2000 04:58:25 +0000 (04:58 +0000)
R_SH_DIR8WPN, R_SH_DIR8WPZ, R_SH_DIR8WPL]: Handle them
explicitly.  Improve validation of r_type.

bfd/ChangeLog
bfd/elf32-sh.c

index 15e54dff23d734d7581a5540a8911ffce28a99fa..4bbb6c0846e936ebb8300d07501a5d966ef9a2f8 100644 (file)
@@ -1,3 +1,9 @@
+2000-08-22  Alexandre Oliva  <aoliva@redhat.com>
+
+       * elf32-sh.c (sh_elf_relocate_section) [R_SH_IND12W,
+       R_SH_DIR8WPN, R_SH_DIR8WPZ, R_SH_DIR8WPL]: Handle them
+       explicitly.  Improve validation of r_type.
+
 2000-08-21  H.J. Lu  <hjl@gnu.org>
 
        * elf32-i386.c (elf_i386_size_dynamic_sections): Zero out the
index f1e0027761ad689e7278ffd7e4ee959a2eedc7f8..9e2d8237ca4ec042d6f16d1c38603c0ab75e150b 100644 (file)
@@ -1884,6 +1884,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        continue;
 
       if (r_type < 0
+         || r_type >= R_SH_max
          || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
              && r_type <= (int) R_SH_LAST_INVALID_RELOC))
        {
@@ -1891,14 +1892,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          return false;
        }
 
-      /* FIXME: This is certainly incorrect.  However, it is how the
-         COFF linker works.  */
-      if (r_type != (int) R_SH_DIR32
-         && r_type != (int) R_SH_IND12W
-         && r_type != (int) R_SH_LOOP_START
-         && r_type != (int) R_SH_LOOP_END)
-       continue;
-
       howto = sh_elf_howto_table + r_type;
 
       /* This is a final link.  */
@@ -1907,11 +1900,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       sec = NULL;
       if (r_symndx < symtab_hdr->sh_info)
        {
-         /* There is nothing to be done for an internal IND12W
-             relocation.  FIXME: This is probably wrong, but it's how
-             the COFF relocations work.  */
-         if (r_type == (int) R_SH_IND12W)
-           continue;
          sym = local_syms + r_symndx;
          sec = local_sections[r_symndx];
          relocation = (sec->output_section->vma
@@ -1944,22 +1932,34 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            }
        }
 
-      /* FIXME: This is how the COFF relocations work.  */
-      if (r_type == (int) R_SH_IND12W)
-       relocation -= 4;
-
       switch ((int)r_type)
        {
-       case (int)R_SH_DIR32:
-         addend = rel->r_addend;
-         /* Fall through.  */
-       default:
+       final_link_relocate:
          /* COFF relocs don't use the addend. The addend is used for
             R_SH_DIR32 to be compatible with other compilers. */
          r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                        contents, rel->r_offset,
                                        relocation, addend);
          break;
+
+       case R_SH_IND12W:
+       case R_SH_DIR8WPN:
+       case R_SH_DIR8WPZ:
+       case R_SH_DIR8WPL:
+         /* These should normally be handled by the assembler, but at
+            least IND12W is generated by ourselves, so we must deal
+            with it.  */
+         relocation -= 4;
+         goto final_link_relocate;
+
+       default:
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+
+       case R_SH_DIR32:
+         addend = rel->r_addend;
+         goto final_link_relocate;
+
        case R_SH_LOOP_START:
          {
            static bfd_vma start, end;
@@ -1969,6 +1969,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            r = sh_elf_reloc_loop (r_type, input_bfd, input_section, contents,
                                   rel->r_offset, sec, start, end);
            break;
+
        case R_SH_LOOP_END:
            end = (relocation + rel->r_addend
                   - (sec->output_section->vma + sec->output_offset));