* elf-m10300.c (mn10300_elf_final_link_relocate): Correct overflow
authorDJ Delorie <dj@redhat.com>
Tue, 15 Jul 2008 18:48:07 +0000 (18:48 +0000)
committerDJ Delorie <dj@redhat.com>
Tue, 15 Jul 2008 18:48:07 +0000 (18:48 +0000)
checks for PCREL8, PCREL16, GOTPC16, GOTOFF16, PLT16, and GOT16
relocs.
(mn10300_elf_relax_section): Correct jump offset check when target
is in a different section.

bfd/ChangeLog
bfd/elf-m10300.c

index 769dd8bf11977688884f9cf59067e7c818ef896d..443786bc313016ce577cbd0e86cc6433a3c7c77e 100644 (file)
@@ -1,3 +1,11 @@
+2008-07-14  DJ Delorie  <dj@redhat.com>
+
+       * elf-m10300.c (mn10300_elf_final_link_relocate): Correct overflow
+       checks for PCREL8, PCREL16, GOTPC16, GOTOFF16, PLT16, and GOT16
+       relocs.
+       (mn10300_elf_relax_section): Correct jump offset check when target
+       is in a different section.
+
 2008-07-15  Jie Zhang  <jie.zhang@analog.com>
 
        * elf32-bfin.c (elf32_bfin_special_sections[]): New.
index 61ce3e167fe7eaaa851b103721e83e2b7e9e78ea..37c4f3b5756eb80d849f31fb7ea7bdb20343eb2a 100644 (file)
@@ -1212,7 +1212,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
       value -= offset;
       value += addend;
 
-      if ((long) value > 0xff || (long) value < -0x100)
+      if ((long) value > 0x7f || (long) value < -0x80)
        return bfd_reloc_overflow;
 
       bfd_put_8 (input_bfd, value, hit_data);
@@ -1224,7 +1224,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
       value -= offset;
       value += addend;
 
-      if ((long) value > 0xffff || (long) value < -0x10000)
+      if ((long) value > 0x7fff || (long) value < -0x8000)
        return bfd_reloc_overflow;
 
       bfd_put_16 (input_bfd, value, hit_data);
@@ -1264,7 +1264,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
       value -= offset;
       value += addend;
 
-      if ((long) value > 0xffff || (long) value < -0x10000)
+      if ((long) value > 0x7fff || (long) value < -0x8000)
        return bfd_reloc_overflow;
 
       bfd_put_16 (input_bfd, value, hit_data);
@@ -1296,7 +1296,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
                                        ".got")->output_section->vma;
       value += addend;
 
-      if ((long) value > 0xffff || (long) value < -0x10000)
+      if ((long) value > 0x7fff || (long) value < -0x8000)
        return bfd_reloc_overflow;
 
       bfd_put_16 (input_bfd, value, hit_data);
@@ -1345,7 +1345,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
       value -= offset;
       value += addend;
 
-      if ((long) value > 0xffff || (long) value < -0x10000)
+      if ((long) value > 0x7fff || (long) value < -0x8000)
        return bfd_reloc_overflow;
 
       bfd_put_16 (input_bfd, value, hit_data);
@@ -1433,7 +1433,7 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto,
        }
       else if (r_type == R_MN10300_GOT16)
        {
-         if ((long) value > 0xffff || (long) value < -0x10000)
+         if ((long) value > 0x7fff || (long) value < -0x8000)
            return bfd_reloc_overflow;
 
          bfd_put_16 (input_bfd, value, hit_data);
@@ -2751,6 +2751,8 @@ mn10300_elf_relax_section (bfd *abfd,
   for (irel = internal_relocs; irel < irelend; irel++)
     {
       bfd_vma symval;
+      bfd_signed_vma jump_offset;
+      asection *sym_sec = NULL;
       struct elf32_mn10300_link_hash_entry *h = NULL;
 
       /* If this isn't something that can be relaxed, then ignore
@@ -2790,7 +2792,6 @@ mn10300_elf_relax_section (bfd *abfd,
       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
        {
          Elf_Internal_Sym *isym;
-         asection *sym_sec = NULL;
          const char *sym_name;
          char *new_name;
 
@@ -2857,6 +2858,8 @@ mn10300_elf_relax_section (bfd *abfd,
          if (h->root.root.u.def.section->output_section == NULL)
            continue;
 
+         sym_sec = h->root.root.u.def.section->output_section;
+
          symval = (h->root.root.u.def.value
                    + h->root.root.u.def.section->output_section->vma
                    + h->root.root.u.def.section->output_offset);
@@ -2959,10 +2962,15 @@ mn10300_elf_relax_section (bfd *abfd,
 
          /* See if the value will fit in 16 bits, note the high value is
             0x7fff + 2 as the target will be two bytes closer if we are
-            able to relax.  */
+            able to relax, if it's in the same section.  */
+         if (sec->output_section == sym_sec->output_section)
+           jump_offset = 0x8001;
+         else
+           jump_offset = 0x7fff;
+
          /* Account for jumps across alignment boundaries using
             align_gap_adjustment.  */
-         if ((bfd_signed_vma) value < 0x8001 - (bfd_signed_vma) align_gap_adjustment
+         if ((bfd_signed_vma) value < jump_offset - (bfd_signed_vma) align_gap_adjustment
              && ((bfd_signed_vma) value > -0x8000 + (bfd_signed_vma) align_gap_adjustment))
            {
              unsigned char code;