aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Fortune <matthew.fortune@imgtec.com>2014-09-22 09:43:52 +0100
committerMatthew Fortune <matthew.fortune@imgtec.com>2014-09-22 09:43:52 +0100
commitc3eb94b43ee8cd748a3b03a5c3eed90f19e18a4b (patch)
tree1de1f2500fa21e3b8883ab07e36043476b3855c5
parentf4cb41f4af9e0441639c554472700fa4259dff02 (diff)
downloadgdb-c3eb94b43ee8cd748a3b03a5c3eed90f19e18a4b.zip
gdb-c3eb94b43ee8cd748a3b03a5c3eed90f19e18a4b.tar.gz
gdb-c3eb94b43ee8cd748a3b03a5c3eed90f19e18a4b.tar.bz2
MIPS: Don't sign extend the addend for RELA relocations
bfd/ * elfxx-mips.c (mips_elf_calculate_relocation): Don't sign extend the addend if relocations are RELA.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfxx-mips.c32
2 files changed, 30 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1f06e7e..b817554 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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,
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 2c7b35f..7343835 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -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;