[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.
This commit is contained in:
Andrew Bennett 2014-11-20 15:40:16 +00:00
parent 51aecdc532
commit 538baf8b7e
8 changed files with 137 additions and 11 deletions

View file

@ -1,3 +1,8 @@
2014-12-02 Andrew Bennett <andrew.bennett@imgtec.com>
* elfxx-mips.c (mips_elf_calculate_relocation): Only check for
overflow on non-weak undefined symbols.
2014-12-02 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (OPD_NDX): Define. Use throughout for sizing/indexing

View 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;

View file

@ -1,3 +1,12 @@
2014-12-02 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-01 H.J. Lu <hongjiu.lu@intel.com>
PR ld/16452

View 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)]]
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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