From 538baf8b7e6d17a490f126f8565638469da70204 Mon Sep 17 00:00:00 2001 From: Andrew Bennett Date: Thu, 20 Nov 2014 15:40:16 +0000 Subject: [MIPS] When calculating a relocation using an undefined weak symbol don't check for overflow. In MIPS the relocation calculation only ignores the overflow checks for undefined weak symbols on relocations associated with j/jal. This patch extends this to the relocations used by the: b* instructions; pc/gp relative symbol offsets; and the lwpc/ldpc MIPS r6 instructions. bfd/ * elfxx-mips.c (mips_elf_calculate_relocation): Only check for overflow on non-weak undefined symbols. ld/testsuite/ * ld-mips-elf/mips-elf.exp: Add in undefined weak overflow tests for o32, n32 and n64. * ld-mips-elf/undefweak-overflow.s: New test. * ld-mips-elf/undefweak-overflow.d: New test. * ld-mips-elf/undefweak-overflow-n32.d: New test. * ld-mips-elf/undefweak-overflow-n64.d: New test. --- bfd/elfxx-mips.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'bfd/elfxx-mips.c') diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 8664c18..4cf4ac0 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -5928,7 +5928,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, to them before. */ if (was_local_p) value += gp0; - overflowed_p = mips_elf_overflow_p (value, 16); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 16); break; case R_MIPS16_GOT16: @@ -5983,7 +5984,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, return bfd_reloc_outofrange; value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 18); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 18); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -5996,7 +5998,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, return bfd_reloc_outofrange; value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 23); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 23); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -6009,7 +6012,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, return bfd_reloc_outofrange; value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 28); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 28); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -6022,7 +6026,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, return bfd_reloc_outofrange; value = symbol + addend - ((p | 7) ^ 7); - overflowed_p = mips_elf_overflow_p (value, 21); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 21); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -6035,14 +6040,16 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, return bfd_reloc_outofrange; value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 21); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 21); value >>= howto->rightshift; value &= howto->dst_mask; break; case R_MIPS_PCHI16: value = mips_elf_high (symbol + addend - p); - overflowed_p = mips_elf_overflow_p (value, 16); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 16); value &= howto->dst_mask; break; @@ -6057,7 +6064,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, if (howto->partial_inplace) addend = _bfd_mips_elf_sign_extend (addend, 8); value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 8); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 8); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -6066,7 +6074,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, if (howto->partial_inplace) addend = _bfd_mips_elf_sign_extend (addend, 11); value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 11); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 11); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -6075,7 +6084,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, if (howto->partial_inplace) addend = _bfd_mips_elf_sign_extend (addend, 17); value = symbol + addend - p; - overflowed_p = mips_elf_overflow_p (value, 17); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 17); value >>= howto->rightshift; value &= howto->dst_mask; break; @@ -6084,7 +6094,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, 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); + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) + overflowed_p = mips_elf_overflow_p (value, 25); value >>= howto->rightshift; value &= howto->dst_mask; break; -- cgit v1.1