MIPS: Don't sign extend the addend for RELA relocations
authorMatthew Fortune <matthew.fortune@imgtec.com>
Mon, 22 Sep 2014 08:43:52 +0000 (09:43 +0100)
committerMatthew Fortune <matthew.fortune@imgtec.com>
Mon, 22 Sep 2014 08:43:52 +0000 (09:43 +0100)
bfd/

* elfxx-mips.c (mips_elf_calculate_relocation): Don't sign extend
the addend if relocations are RELA.

bfd/ChangeLog
bfd/elfxx-mips.c

index 1f06e7e..b817554 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-22  Andrew Bennett  <andrew.bennett@imgtec.com>
+
+       * elfxx-mips.c (mips_elf_calculate_relocation): Don't sign extend
+       the addend if relocations are RELA.
+
 2014-09-22  Kuan-Lin Chen  <kuanlinchentw@gmail.com>
 
        * elf32-nds32.c (nds32_elf_ex9_build_hash_table,
index 2c7b35f..7343835 100644 (file)
@@ -5714,7 +5714,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       return bfd_reloc_continue;
 
     case R_MIPS_16:
-      value = symbol + _bfd_mips_elf_sign_extend (addend, 16);
+      if (howto->partial_inplace)
+       addend = _bfd_mips_elf_sign_extend (addend, 16);
+      value = symbol + addend;
       overflowed_p = mips_elf_overflow_p (value, 16);
       break;
 
@@ -5786,8 +5788,10 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 
        if (was_local_p)
          value = addend | ((p + 4) & (0xfc000000 << shift));
-       else
+       else if (howto->partial_inplace)
          value = _bfd_mips_elf_sign_extend (addend, 26 + shift);
+       else
+         value = addend;
        value = (value + symbol) >> shift;
        if (!was_local_p && h->root.root.type != bfd_link_hash_undefweak)
          overflowed_p = (value >> 26) != ((p + 4) >> (26 + shift));
@@ -5972,7 +5976,13 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 
     case R_MIPS_PC16:
     case R_MIPS_GNU_REL16_S2:
-      value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
+      if (howto->partial_inplace)
+       addend = _bfd_mips_elf_sign_extend (addend, 18);
+
+      if ((symbol + addend) & 3)
+       return bfd_reloc_outofrange;
+
+      value = symbol + addend - p;
       overflowed_p = mips_elf_overflow_p (value, 18);
       value >>= howto->rightshift;
       value &= howto->dst_mask;
@@ -6044,28 +6054,36 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       break;
 
     case R_MICROMIPS_PC7_S1:
-      value = symbol + _bfd_mips_elf_sign_extend (addend, 8) - p;
+      if (howto->partial_inplace)
+       addend = _bfd_mips_elf_sign_extend (addend, 8);
+      value = symbol + addend - p;
       overflowed_p = mips_elf_overflow_p (value, 8);
       value >>= howto->rightshift;
       value &= howto->dst_mask;
       break;
 
     case R_MICROMIPS_PC10_S1:
-      value = symbol + _bfd_mips_elf_sign_extend (addend, 11) - p;
+      if (howto->partial_inplace)
+       addend = _bfd_mips_elf_sign_extend (addend, 11);
+      value = symbol + addend - p;
       overflowed_p = mips_elf_overflow_p (value, 11);
       value >>= howto->rightshift;
       value &= howto->dst_mask;
       break;
 
     case R_MICROMIPS_PC16_S1:
-      value = symbol + _bfd_mips_elf_sign_extend (addend, 17) - p;
+      if (howto->partial_inplace)
+       addend = _bfd_mips_elf_sign_extend (addend, 17);
+      value = symbol + addend - p;
       overflowed_p = mips_elf_overflow_p (value, 17);
       value >>= howto->rightshift;
       value &= howto->dst_mask;
       break;
 
     case R_MICROMIPS_PC23_S2:
-      value = symbol + _bfd_mips_elf_sign_extend (addend, 25) - ((p | 3) ^ 3);
+      if (howto->partial_inplace)
+       addend = _bfd_mips_elf_sign_extend (addend, 25);
+      value = symbol + addend - ((p | 3) ^ 3);
       overflowed_p = mips_elf_overflow_p (value, 25);
       value >>= howto->rightshift;
       value &= howto->dst_mask;