From 538baf8b7e6d17a490f126f8565638469da70204 Mon Sep 17 00:00:00 2001 From: Andrew Bennett Date: Thu, 20 Nov 2014 15:40:16 +0000 Subject: [PATCH] [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/ChangeLog | 5 +++ bfd/elfxx-mips.c | 33 ++++++++++++------- ld/testsuite/ChangeLog | 9 +++++ ld/testsuite/ld-mips-elf/mips-elf.exp | 7 ++++ .../ld-mips-elf/undefweak-overflow-n32.d | 23 +++++++++++++ .../ld-mips-elf/undefweak-overflow-n64.d | 23 +++++++++++++ ld/testsuite/ld-mips-elf/undefweak-overflow.d | 23 +++++++++++++ ld/testsuite/ld-mips-elf/undefweak-overflow.s | 25 ++++++++++++++ 8 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d create mode 100644 ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d create mode 100644 ld/testsuite/ld-mips-elf/undefweak-overflow.d create mode 100644 ld/testsuite/ld-mips-elf/undefweak-overflow.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 67b00707ad..010cf55521 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2014-12-02 Andrew Bennett + + * elfxx-mips.c (mips_elf_calculate_relocation): Only check for + overflow on non-weak undefined symbols. + 2014-12-02 Alan Modra * elf64-ppc.c (OPD_NDX): Define. Use throughout for sizing/indexing diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 8664c18913..4cf4ac094c 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; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index ef59947221..de784f798e 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2014-12-02 Andrew Bennett + + * ld-mips-elf/mips-elf.exp: Add 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. + 2014-12-01 H.J. Lu PR ld/16452 diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index 91036de714..21c809fafc 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -434,6 +434,13 @@ if {$linux_gnu} { run_dump_test "jaloverflow" run_dump_test "jaloverflow-2" +run_dump_test "undefweak-overflow" + +if {$has_newabi} { + run_dump_test "undefweak-overflow-n32" + run_dump_test "undefweak-overflow-n64" +} + if {$has_newabi} { run_dump_test "jalbal" [list [list ld $abi_ldflags(n32)]] } diff --git a/ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d b/ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d new file mode 100644 index 0000000000..4d965b8dcf --- /dev/null +++ b/ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d @@ -0,0 +1,23 @@ +#name: undefined weak symbol overflow (n32) +#source: undefweak-overflow.s +#as: -n32 -EB +#ld: -melf32btsmipn32 -Ttext=0x20000000 -e start +#objdump: -dr +#... +0*20000000: d85fffff.* +0*20000004: 00000000.* +0*20000008: f85ffffd.* +0*2000000c: ec4ffffd.* +0*20000010: ec5bfffe.* +0*20000014: cbfffffa.* +0*20000018: 3c04e000.* +0*2000001c: 1000fff8.* +0*20000020: 2484ffe0.* +0*20000024: 0411fff6.* +0*20000028: 00000000.* +0*2000002c: 3c047fd0.* +0*20000030: 8e670c00.* +0*20000034: cfe50c00.* +0*20000038: 9400ffe2.* +0*2000003c: 0c000c00.* +#pass diff --git a/ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d b/ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d new file mode 100644 index 0000000000..e0d9fdade7 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d @@ -0,0 +1,23 @@ +#name: undefined weak symbol overflow (n64) +#source: undefweak-overflow.s +#as: -64 -EB +#ld: -melf64btsmip -Ttext=0x20000000 -e start +#objdump: -dr +#... + 0*20000000: d85fffff.* + 0*20000004: 00000000.* + 0*20000008: f85ffffd.* + 0*2000000c: ec4ffffd.* + 0*20000010: ec5bfffe.* + 0*20000014: cbfffffa.* + 0*20000018: 3c04e000.* + 0*2000001c: 1000fff8.* + 0*20000020: 2484ffe0.* + 0*20000024: 0411fff6.* + 0*20000028: 00000000.* + 0*2000002c: 3c047fd0.* + 0*20000030: 8e670c00.* + 0*20000034: cfe50c00.* + 0*20000038: 9400ffe2.* + 0*2000003c: 0c000c00.* +#pass diff --git a/ld/testsuite/ld-mips-elf/undefweak-overflow.d b/ld/testsuite/ld-mips-elf/undefweak-overflow.d new file mode 100644 index 0000000000..18b3a90009 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/undefweak-overflow.d @@ -0,0 +1,23 @@ +#name: undefined weak symbol overflow +#source: undefweak-overflow.s +#as: -32 -EB +#ld: -melf32btsmip -Ttext=0x20000000 -e start +#objdump: -dr +#... +0*20000000: d85fffff.* +0*20000004: 00000000.* +0*20000008: f85ffffd.* +0*2000000c: ec4ffffd.* +0*20000010: ec5bfffe.* +0*20000014: cbfffffa.* +0*20000018: 3c04e000.* +0*2000001c: 1000fff8.* +0*20000020: 2484ffe0.* +0*20000024: 0411fff6.* +0*20000028: 00000000.* +0*2000002c: 3c047fd0.* +0*20000030: 8e670c00.* +0*20000034: cfe50c00.* +0*20000038: 9400ffe2.* +0*2000003c: 0c000c00.* +#pass diff --git a/ld/testsuite/ld-mips-elf/undefweak-overflow.s b/ld/testsuite/ld-mips-elf/undefweak-overflow.s new file mode 100644 index 0000000000..525f11b14e --- /dev/null +++ b/ld/testsuite/ld-mips-elf/undefweak-overflow.s @@ -0,0 +1,25 @@ +# relocs against undefined weak symbols should not be treated as +# overflowing + + + .globl start + .weak foo +start: + .set mips64r6 + beqzc $2, foo + bnezc $2, foo + lwpc $2, foo + ldpc $2, foo + bc foo + lui $4, %pcrel_hi(foo) + addiu $4, $4, %pcrel_lo(foo) + + .set mips32r2 + b foo + bal foo + lui $4, %gp_rel(foo) + + .set micromips + beqz16 $4, foo + b16 foo + b foo -- 2.34.1