From 8f29211c3f0a6335c17e0a90396c146facf6dba4 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 21 Jul 2022 10:35:58 -0700 Subject: [PATCH] i386: Don't allow GOTOFF relocation against IFUNC symbol for PIC 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 for 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.30.2