[PATCH, MIPS] When calculating a relocation using an undefined weak symbol don't check for overflow.

Andrew Bennett Andrew.Bennett@imgtec.com
Mon Dec 1 10:41:00 GMT 2014


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
> 



More information about the Binutils mailing list