This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: [PATCH, MIPS] When calculating a relocation using an undefined weak symbol don't check for overflow.
- From: Andrew Bennett <Andrew dot Bennett at imgtec dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: "rdsandiford at googlemail dot com" <rdsandiford at googlemail dot com>
- Date: Mon, 1 Dec 2014 10:41:46 +0000
- Subject: RE: [PATCH, MIPS] When calculating a relocation using an undefined weak symbol don't check for overflow.
- Authentication-results: sourceware.org; auth=none
- References: <0DA23CC379F5F945ACB41CF394B9827720F35D28 at LEMAIL01 dot le dot imgtec dot org>
Ping.
I was wondering if anyone has had a chance to look at this yet?
Many thanks,
Andrew
> -----Original Message-----
> From: binutils-owner@sourceware.org [mailto:binutils-owner@sourceware.org] On
> Behalf Of Andrew Bennett
> Sent: 21 November 2014 13:14
> To: binutils@sourceware.org
> Cc: rdsandiford@googlemail.com
> Subject: [PATCH, MIPS] When calculating a relocation using an undefined weak
> symbol don't check for overflow.
>
> Hi,
>
> 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.
>
> I have added a new test into the linker testsuite, and both the gas and ld
> testsuites successfully pass with my patch.
>
> On a side note I noticed that for the R_MIPS_26 relocation the overflow check
> is
> only performed for global non undefined weak symbols. I was wondering why it
> is not
> done for local symbols?
>
> The ChangeLog and patch are below.
>
> Ok to commit?
>
> Many thanks,
>
>
>
> Andrew
>
>
>
> 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-n64.d: New test.
> * ld-mips-elf/undefweak-overflow-n64.d: New test.
>
>
>
> diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
> index 8664c18..4cf4ac0 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/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-
> elf/mips-elf.exp
> index 91036de..21c809f 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 0000000..4d965b8
> --- /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 0000000..e0d9fda
> --- /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 0000000..18b3a90
> --- /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 0000000..525f11b
> --- /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
>