[PATCH, ARM] Fix handling of GOT and PLT access to IFUNC symbols

Richard Earnshaw rearnsha@arm.com
Mon Apr 15 15:18:00 GMT 2013


On 12/04/13 17:42, Will Newton wrote:
>
> Hi all,
>
> The current ARM IFUNC code appears to have a bug when an access is made via
> the PLT and GOT in the same object. This results in two relocs being swapped
> out into the same slot so one R_ARM_IRELATIVE reloc goes missing.
>
> This patch changes the behaviour to use an incremented reloc count rather
> than the calculated PLT index to match the behaviour of elf32_arm_add_dynreloc
> and as a result requires the order of relocs in the ifunc tests to be adjusted.
>
> bfd/ChangeLog:
>
> 2013-04-12  Will Newton  <will.newton@linaro.org>
>
> 	* elf32-arm.c (elf32_arm_populate_plt_entry): Increment reloc_count
> 	when emitting R_ARM_IRELATIVE relocs.
>

Hmm, it looks somewhat suspicious to me to be changing the reloc count 
this late on.

Richard, do you know if this is safe?  If not, can you recommend a 
better approach?

R.

> ld/testsuite/ChangeLog:
>
> 2013-04-12  Will Newton  <will.newton@linaro.org>
>
> 	* ld-arm/arm-elf.exp: Add IFUNC test 17.
> 	* ld-arm/ifunc-17.dd: New file.
> 	* ld-arm/ifunc-17.gd: Likewise.
> 	* ld-arm/ifunc-17.rd: Likewise.
> 	* ld-arm/ifunc-17.s: Likweise.
> 	* ld-arm/ifunc-1.rd: Reorder relocs to match linker output.
> 	* ld-arm/ifunc-2.rd: Likewise.
> 	* ld-arm/ifunc-5.rd: Likewise.
> 	* ld-arm/ifunc-6.rd: Likewise.
> ---
>   bfd/elf32-arm.c                 |  5 ++++-
>   ld/testsuite/ld-arm/arm-elf.exp |  5 +++++
>   ld/testsuite/ld-arm/ifunc-1.rd  |  2 +-
>   ld/testsuite/ld-arm/ifunc-17.dd | 25 +++++++++++++++++++++++++
>   ld/testsuite/ld-arm/ifunc-17.gd | 10 ++++++++++
>   ld/testsuite/ld-arm/ifunc-17.rd |  5 +++++
>   ld/testsuite/ld-arm/ifunc-17.s  | 24 ++++++++++++++++++++++++
>   ld/testsuite/ld-arm/ifunc-2.rd  |  4 ++--
>   ld/testsuite/ld-arm/ifunc-5.rd  |  2 +-
>   ld/testsuite/ld-arm/ifunc-6.rd  |  4 ++--
>   10 files changed, 79 insertions(+), 7 deletions(-)
>   create mode 100644 ld/testsuite/ld-arm/ifunc-17.dd
>   create mode 100644 ld/testsuite/ld-arm/ifunc-17.gd
>   create mode 100644 ld/testsuite/ld-arm/ifunc-17.rd
>   create mode 100644 ld/testsuite/ld-arm/ifunc-17.s
>
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index 78c2d1d..37690e9 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -7695,7 +7695,10 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
>   		  sgot->contents + got_offset);
>       }
>
> -  loc = srel->contents + plt_index * RELOC_SIZE (htab);
> +  if (dynindx == -1)
> +    loc = srel->contents + srel->reloc_count++ * RELOC_SIZE (htab);
> +  else
> +    loc = srel->contents + plt_index * RELOC_SIZE (htab);
>     SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
>   }
>
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
> index f13fae5..c488e3c 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -451,6 +451,11 @@ set armelftests_nonacl {
>         {objdump {-s -j.data -j.got} ifunc-16.gd}
>         {readelf -r ifunc-16.rd}}
>        "ifunc-16"}
> +    {"IFUNC test 17" "" "" "" {ifunc-17.s}
> +     {{objdump -d ifunc-17.dd}
> +      {objdump {-s -j.data -j.got} ifunc-17.gd}
> +      {readelf -r ifunc-17.rd}}
> +     "ifunc-17"}
>   }
>
>   run_ld_link_tests $armelftests_common
> diff --git a/ld/testsuite/ld-arm/ifunc-1.rd b/ld/testsuite/ld-arm/ifunc-1.rd
> index 75e6d70..2644123 100644
> --- a/ld/testsuite/ld-arm/ifunc-1.rd
> +++ b/ld/testsuite/ld-arm/ifunc-1.rd
> @@ -4,5 +4,5 @@ There is no dynamic section in this file\.
>   Relocation section '\.rel\.dyn' at offset 0x8000 contains 3 entries:
>    Offset     Info    Type            Sym\.Value  Sym\. Name
>   0001100c  ......a0 R_ARM_IRELATIVE
> -00011010  ......a0 R_ARM_IRELATIVE
>   00011014  ......a0 R_ARM_IRELATIVE
> +00011010  ......a0 R_ARM_IRELATIVE
> diff --git a/ld/testsuite/ld-arm/ifunc-17.dd b/ld/testsuite/ld-arm/ifunc-17.dd
> new file mode 100644
> index 0000000..9d0e222
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/ifunc-17.dd
> @@ -0,0 +1,25 @@
> +
> +.*
> +
> +
> +Disassembly of section \.iplt:
> +
> +00008084 <.iplt>:
> +#------------------------------------------------------------------------------
> +#------ libfunc1's .iplt entry
> +#------------------------------------------------------------------------------
> +    8084:	e28fc600 	add	ip, pc, #0, 12
> +    8088:	e28cca08 	add	ip, ip, #8, 20	; 0x8000
> +    808c:	e5bcf01c 	ldr	pc, \[ip, #28\]!
> +
> +Disassembly of section \.text:
> +
> +00008090 <appfunc1>:
> +    8090:	46f7      	mov	pc, lr
> +
> +00008092 <appfunc2>:
> +    8092:	46f7      	mov	pc, lr
> +
> +00008094 <_start>:
> +    8094:	f7ff eff6 	blx	8084 <appfunc1-0xc>
> +    8098:	00000010 	\.word	0x00000010
> diff --git a/ld/testsuite/ld-arm/ifunc-17.gd b/ld/testsuite/ld-arm/ifunc-17.gd
> new file mode 100644
> index 0000000..4a12eb8
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/ifunc-17.gd
> @@ -0,0 +1,10 @@
> +
> +.*
> +
> +Contents of section \.got:
> +#------------------------------------------------------------------------------
> +#------ 000100a8: 0x8091 (appfunc1)
> +#------ 000100ac: 0x8093 (appfunc2)
> +#------------------------------------------------------------------------------
> + 1009c 00000000 00000000 00000000 91800000  .*
> + 100ac 93800000                             .*
> diff --git a/ld/testsuite/ld-arm/ifunc-17.rd b/ld/testsuite/ld-arm/ifunc-17.rd
> new file mode 100644
> index 0000000..a93fd64
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/ifunc-17.rd
> @@ -0,0 +1,5 @@
> +
> +Relocation section '\.rel\.dyn' at offset 0x74 contains 2 entries:
> + Offset     Info    Type            Sym\.Value  Sym\. Name
> +000100a8  ......a0 R_ARM_IRELATIVE
> +000100ac  ......a0 R_ARM_IRELATIVE
> diff --git a/ld/testsuite/ld-arm/ifunc-17.s b/ld/testsuite/ld-arm/ifunc-17.s
> new file mode 100644
> index 0000000..75c4c56
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/ifunc-17.s
> @@ -0,0 +1,24 @@
> +	.syntax unified
> +	.arch armv6t2
> +
> +	.global appfunc1
> +	.type	appfunc1,%gnu_indirect_function
> +	.thumb
> +appfunc1:
> +	mov	pc,lr
> +	.size	appfunc1,.-appfunc1
> +
> +	.global appfunc2
> +	.type	appfunc2,%gnu_indirect_function
> +	.thumb
> +appfunc2:
> +	mov	pc,lr
> +	.size	appfunc2,.-appfunc2
> +
> +	.global _start
> +	.type _start,%function
> +	.thumb
> +_start:
> +	bl	appfunc1(PLT)
> +	.word	appfunc2(GOT)
> +	.size	_start,.-_start
> diff --git a/ld/testsuite/ld-arm/ifunc-2.rd b/ld/testsuite/ld-arm/ifunc-2.rd
> index 92b000a..7bbabf4 100644
> --- a/ld/testsuite/ld-arm/ifunc-2.rd
> +++ b/ld/testsuite/ld-arm/ifunc-2.rd
> @@ -5,9 +5,9 @@ Relocation section '\.rel\.dyn' at offset 0x8000 contains 8 entries:
>    Offset     Info    Type            Sym\.Value  Sym\. Name
>   0001100c  ......a0 R_ARM_IRELATIVE
>   00011010  ......a0 R_ARM_IRELATIVE
> +00011020  ......a0 R_ARM_IRELATIVE
> +00011028  ......a0 R_ARM_IRELATIVE
>   00011014  ......a0 R_ARM_IRELATIVE
>   00011018  ......a0 R_ARM_IRELATIVE
>   0001101c  ......a0 R_ARM_IRELATIVE
> -00011020  ......a0 R_ARM_IRELATIVE
>   00011024  ......a0 R_ARM_IRELATIVE
> -00011028  ......a0 R_ARM_IRELATIVE
> diff --git a/ld/testsuite/ld-arm/ifunc-5.rd b/ld/testsuite/ld-arm/ifunc-5.rd
> index 75e6d70..2644123 100644
> --- a/ld/testsuite/ld-arm/ifunc-5.rd
> +++ b/ld/testsuite/ld-arm/ifunc-5.rd
> @@ -4,5 +4,5 @@ There is no dynamic section in this file\.
>   Relocation section '\.rel\.dyn' at offset 0x8000 contains 3 entries:
>    Offset     Info    Type            Sym\.Value  Sym\. Name
>   0001100c  ......a0 R_ARM_IRELATIVE
> -00011010  ......a0 R_ARM_IRELATIVE
>   00011014  ......a0 R_ARM_IRELATIVE
> +00011010  ......a0 R_ARM_IRELATIVE
> diff --git a/ld/testsuite/ld-arm/ifunc-6.rd b/ld/testsuite/ld-arm/ifunc-6.rd
> index 0fbfec5..04c18a9 100644
> --- a/ld/testsuite/ld-arm/ifunc-6.rd
> +++ b/ld/testsuite/ld-arm/ifunc-6.rd
> @@ -3,7 +3,7 @@ There is no dynamic section in this file\.
>
>   Relocation section '\.rel\.dyn' at offset 0x8000 contains 4 entries:
>    Offset     Info    Type            Sym\.Value  Sym\. Name
> -0001100c  ......a0 R_ARM_IRELATIVE
> +00011018  ......a0 R_ARM_IRELATIVE
>   00011010  ......a0 R_ARM_IRELATIVE
> +0001100c  ......a0 R_ARM_IRELATIVE
>   00011014  ......a0 R_ARM_IRELATIVE
> -00011018  ......a0 R_ARM_IRELATIVE
>




More information about the Binutils mailing list