[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:
parent
51aecdc532
commit
538baf8b7e
8 changed files with 137 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]]
|
||||
}
|
||||
|
|
23
ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d
Normal file
23
ld/testsuite/ld-mips-elf/undefweak-overflow-n32.d
Normal 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
|
23
ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d
Normal file
23
ld/testsuite/ld-mips-elf/undefweak-overflow-n64.d
Normal 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
|
23
ld/testsuite/ld-mips-elf/undefweak-overflow.d
Normal file
23
ld/testsuite/ld-mips-elf/undefweak-overflow.d
Normal 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
|
25
ld/testsuite/ld-mips-elf/undefweak-overflow.s
Normal file
25
ld/testsuite/ld-mips-elf/undefweak-overflow.s
Normal 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
|
Loading…
Reference in a new issue