[MIPS] When calculating a relocation using an undefined weak symbol don't check for...
authorAndrew Bennett <andrew.bennett@imgtec.com>
Thu, 20 Nov 2014 15:40:16 +0000 (15:40 +0000)
committerMatthew Fortune <matthew.fortune@imgtec.com>
Fri, 19 Dec 2014 14:43:21 +0000 (14:43 +0000)
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
bfd/elfxx-mips.c
ld/testsuite/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/undefweak-overflow.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/undefweak-overflow.s [new file with mode: 0644]

index a4af0be..369cb6a 100644 (file)
@@ -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
index 2717610..a0cc26e 100644 (file)
@@ -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;
index e2dfdbc..81339e8 100644 (file)
@@ -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
index 91036de..21c809f 100644 (file)
@@ -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 (file)
index 0000000..4d965b8
--- /dev/null
@@ -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 (file)
index 0000000..e0d9fda
--- /dev/null
@@ -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 (file)
index 0000000..18b3a90
--- /dev/null
@@ -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 (file)
index 0000000..525f11b
--- /dev/null
@@ -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