diff options
author | Matthew Fortune <matthew.fortune@imgtec.com> | 2014-09-22 09:43:52 +0100 |
---|---|---|
committer | Matthew Fortune <matthew.fortune@imgtec.com> | 2014-09-22 09:43:52 +0100 |
commit | c3eb94b43ee8cd748a3b03a5c3eed90f19e18a4b (patch) | |
tree | 1de1f2500fa21e3b8883ab07e36043476b3855c5 /bfd/elfxx-mips.c | |
parent | f4cb41f4af9e0441639c554472700fa4259dff02 (diff) | |
download | gdb-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.
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r-- | bfd/elfxx-mips.c | 32 |
1 files changed, 25 insertions, 7 deletions
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; |