summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bennett <andrew.bennett@imgtec.com>2014-11-20 15:40:16 +0000
committerMatthew Fortune <matthew.fortune@imgtec.com>2014-12-19 14:43:21 +0000
commitcfd4e875aeacf565f945c2818dbfff47807b6199 (patch)
tree7f6e92f87598a11245c3170eb9e2351a0cf88cef
parent80bfea8ac449dbce1636ff07dd8095bf00780ad4 (diff)
downloadbinutils-cfd4e875aeacf565f945c2818dbfff47807b6199.tar.gz
binutils-cfd4e875aeacf565f945c2818dbfff47807b6199.tar.bz2
binutils-cfd4e875aeacf565f945c2818dbfff47807b6199.zip
[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.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfxx-mips.c33
-rw-r--r--ld/testsuite/ChangeLog9
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp7
-rw-r--r--ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d23
-rw-r--r--ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d23
-rw-r--r--ld/testsuite/ld-mips-elf/undefweak-overflow.d23
-rw-r--r--ld/testsuite/ld-mips-elf/undefweak-overflow.s25
8 files changed, 137 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a4af0beb214..369cb6aa0ae 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-19 Andrew Bennett <andrew.bennett@imgtec.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Only check for
+ overflow on non-weak undefined symbols.
+
2014-12-15 H.J. Lu <hongjiu.lu@intel.com>
PR ld/17713
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 27176100a17..a0cc26e1858 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 e2dfdbc9d93..81339e8f4b3 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2014-12-19 Andrew Bennett <andrew.bennett@imgtec.com>
+
+ * 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-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/17689
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 91036de7148..21c809fafce 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 00000000000..4d965b8dcfe
--- /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 00000000000..e0d9fdade7f
--- /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 00000000000..18b3a900094
--- /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 00000000000..525f11b14e6
--- /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