[PATCH] i386: Don't allow GOTOFF relocation against IFUNC symbol for PIC
H.J. Lu
hjl.tools@gmail.com
Fri Jul 22 21:19:53 GMT 2022
On Thu, Jul 21, 2022 at 10:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> We can't use the PLT entry as the function address for PIC since the PIC
> register may not be set up properly for indirect call.
>
> bfd/
>
> PR ld/27998
> * elf32-i386.c (elf_i386_relocate_section): Don't allow GOTOFF
> relocation against IFUNC symbol in PIC.
>
> ld/
>
> PR ld/27998
> * testsuite/ld-i386/pr27998a.d: Replace -shared with -e bar.
> * testsuite/ld-i386/pr27998b.d: Expect a linker error.
> * testsuite/ld-ifunc/ifunc-2-i386-now.d: Updated.
> * testsuite/ld-ifunc/ifunc-2-local-i386-now.d: Likewise.
> * testsuite/ld-ifunc/ifunc-2-i386.s: Replace @GOTOFF with @GOT.
> * testsuite/ld-ifunc/ifunc-2-local-i386.s: Likewise.
> ---
> bfd/elf32-i386.c | 5 +++++
> ld/testsuite/ld-i386/pr27998a.d | 2 +-
> ld/testsuite/ld-i386/pr27998b.d | 6 +-----
> ld/testsuite/ld-ifunc/ifunc-2-i386-now.d | 2 +-
> ld/testsuite/ld-ifunc/ifunc-2-i386.s | 2 +-
> ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d | 2 +-
> ld/testsuite/ld-ifunc/ifunc-2-local-i386.s | 2 +-
> 7 files changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index cfb0085b245..52b1db44546 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -2460,6 +2460,11 @@ elf_i386_relocate_section (bfd *output_bfd,
> goto do_relocation;
>
> case R_386_GOTOFF:
> + /* NB: We can't use the PLT entry as the function address
> + for PIC since the PIC register may not be set up
> + properly for indirect call. */
> + if (bfd_link_pic (info))
> + goto bad_ifunc_reloc;
> relocation -= (gotplt->output_section->vma
> + gotplt->output_offset);
> goto do_relocation;
> diff --git a/ld/testsuite/ld-i386/pr27998a.d b/ld/testsuite/ld-i386/pr27998a.d
> index ca3c9205fa6..a8019730ec1 100644
> --- a/ld/testsuite/ld-i386/pr27998a.d
> +++ b/ld/testsuite/ld-i386/pr27998a.d
> @@ -1,5 +1,5 @@
> #as: --32
> -#ld: -shared -melf_i386
> +#ld: -e bar -melf_i386
> #readelf: -r --wide
>
> Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entry:
> diff --git a/ld/testsuite/ld-i386/pr27998b.d b/ld/testsuite/ld-i386/pr27998b.d
> index ca3c9205fa6..8f81edbe8df 100644
> --- a/ld/testsuite/ld-i386/pr27998b.d
> +++ b/ld/testsuite/ld-i386/pr27998b.d
> @@ -1,7 +1,3 @@
> #as: --32
> #ld: -shared -melf_i386
> -#readelf: -r --wide
> -
> -Relocation section '.rel.plt' at offset 0x[0-9a-f]+ contains 1 entry:
> - Offset Info Type Sym. Value Symbol's Name
> -[0-9a-f]+ +[0-9a-f]+ +R_386_IRELATIVE +
> +#error: relocation R_386_GOTOFF against STT_GNU_IFUNC symbol `foo' isn't supported
> diff --git a/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d b/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d
> index a5c56b5a8e3..8d9e8dc988f 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d
> +++ b/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d
> @@ -31,6 +31,6 @@ Disassembly of section .text:
> +[a-f0-9]+: 5b pop %ebx
> +[a-f0-9]+: 81 c3 9e 10 00 00 add \$0x109e,%ebx
> +[a-f0-9]+: e8 de ff ff ff call 100 <\*ABS\*@plt>
> - +[a-f0-9]+: 8d 83 4c ef ff ff lea -0x10b4\(%ebx\),%eax
> + +[a-f0-9]+: 8b 83 0c 00 00 00 mov 0xc\(%ebx\),%eax
> +[a-f0-9]+: c3 ret
> #pass
> diff --git a/ld/testsuite/ld-ifunc/ifunc-2-i386.s b/ld/testsuite/ld-ifunc/ifunc-2-i386.s
> index e84d6b7b5cc..1acf6847e0b 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-2-i386.s
> +++ b/ld/testsuite/ld-ifunc/ifunc-2-i386.s
> @@ -16,6 +16,6 @@ bar:
> popl %ebx
> addl $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
> call __GI_foo@PLT
> - leal __GI_foo@GOTOFF(%ebx), %eax
> + movl __GI_foo@GOT(%ebx), %eax
> ret
> .size bar, .-bar
> diff --git a/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d b/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d
> index ff494decbdd..9da37e51db7 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d
> +++ b/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d
> @@ -31,6 +31,6 @@ Disassembly of section .text:
> +[a-f0-9]+: 5b pop %ebx
> +[a-f0-9]+: 81 c3 9e 10 00 00 add \$0x109e,%ebx
> +[a-f0-9]+: e8 de ff ff ff call f0 <\*ABS\*@plt>
> - +[a-f0-9]+: 8d 83 4c ef ff ff lea -0x10b4\(%ebx\),%eax
> + +[a-f0-9]+: 8b 83 0c 00 00 00 mov 0xc\(%ebx\),%eax
> +[a-f0-9]+: c3 ret
> #pass
> diff --git a/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s b/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s
> index a69e060ddc0..54e0e179551 100644
> --- a/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s
> +++ b/ld/testsuite/ld-ifunc/ifunc-2-local-i386.s
> @@ -13,6 +13,6 @@ bar:
> popl %ebx
> addl $_GLOBAL_OFFSET_TABLE_+[.-.L6], %ebx
> call __GI_foo@PLT
> - leal __GI_foo@GOTOFF(%ebx), %eax
> + movl __GI_foo@GOT(%ebx), %eax
> ret
> .size bar, .-bar
> --
> 2.36.1
>
I am backporting this to 2.38 and 2.39 branches.
--
H.J.
More information about the Binutils
mailing list