[hjl@gnu-6 saved]$ cat x.S .text .globl foo .type foo, @gnu_indirect_function foo: ret .text .type bar, @gnu_indirect_function bar: ret .globl _start .type _start, @function _start: #ifdef __x86_64__ call *foo@GOTPCREL(%rip) jmp *bar@GOTPCREL(%rip) movq $0, bar@GOTPCREL(%rip) cmpq $0, foo@GOTPCREL(%rip) cmpq foo@GOTPCREL(%rip), %rcx cmpq bar@GOTPCREL(%rip), %rcx #else call *foo@GOT jmp *bar@GOT movl $0, bar@GOT cmpl $0, foo@GOT cmpl foo@GOT, %ecx cmpl bar@GOT, %ecx #endif [hjl@gnu-6 saved]$ make x32 gcc -B./ -c -mx32 -o x32.o x.S ld -z nocombreloc -m elf32_x86_64 -o x32 x32.o objdump -dw x32 x32: file format elf32-x86-64 Disassembly of section .plt: 00400090 <.plt>: 400090: ff 25 62 00 20 00 jmpq *0x200062(%rip) # 6000f8 <_GLOBAL_OFFSET_TABLE_+0x18> 400096: 68 00 00 00 00 pushq $0x0 40009b: e9 00 00 00 00 jmpq 4000a0 <foo-0x10> 4000a0: ff 25 5a 00 20 00 jmpq *0x20005a(%rip) # 600100 <_GLOBAL_OFFSET_TABLE_+0x20> 4000a6: 68 00 00 00 00 pushq $0x0 4000ab: e9 00 00 00 00 jmpq 4000b0 <foo> Disassembly of section .text: 004000b0 <foo>: 4000b0: c3 retq 004000b1 <bar>: 4000b1: c3 retq 004000b2 <_start>: 4000b2: ff 15 40 00 20 00 callq *0x200040(%rip) # 6000f8 <_GLOBAL_OFFSET_TABLE_+0x18> 4000b8: ff 25 42 00 20 00 jmpq *0x200042(%rip) # 600100 <_GLOBAL_OFFSET_TABLE_+0x20> 4000be: 48 c7 05 37 00 20 00 00 00 00 00 movq $0x0,0x200037(%rip) # 600100 <_GLOBAL_OFFSET_TABLE_+0x20> 4000c9: 48 83 3d 27 00 20 00 00 cmpq $0x0,0x200027(%rip) # 6000f8 <_GLOBAL_OFFSET_TABLE_+0x18> 4000d1: 48 3b 0d 20 00 20 00 cmp 0x200020(%rip),%rcx # 6000f8 <_GLOBAL_OFFSET_TABLE_+0x18> 4000d8: 48 3b 0d 21 00 20 00 cmp 0x200021(%rip),%rcx # 600100 <_GLOBAL_OFFSET_TABLE_+0x20> [hjl@gnu-6 saved]$ make i386 gcc -B./ -c -m32 -o i386.o x.S ld -z nocombreloc -m elf_i386 -o i386 i386.o objdump -dw i386 i386: file format elf32-i386 Disassembly of section .plt: 08048090 <.plt>: 8048090: ff 25 e8 90 04 08 jmp *0x80490e8 8048096: 68 00 00 00 00 push $0x0 804809b: e9 00 00 00 00 jmp 80480a0 <foo-0x10> 80480a0: ff 25 ec 90 04 08 jmp *0x80490ec 80480a6: 68 00 00 00 00 push $0x0 80480ab: e9 00 00 00 00 jmp 80480b0 <foo> Disassembly of section .text: 080480b0 <foo>: 80480b0: c3 ret 080480b1 <bar>: 80480b1: c3 ret 080480b2 <_start>: 80480b2: ff 15 e8 90 04 08 call *0x80490e8 80480b8: ff 25 ec 90 04 08 jmp *0x80490ec 80480be: c7 05 ec 90 04 08 00 00 00 00 movl $0x0,0x80490ec 80480c8: 83 3d e8 90 04 08 00 cmpl $0x0,0x80490e8 80480cf: 3b 0d e8 90 04 08 cmp 0x80490e8,%ecx 80480d5: 3b 0d ec 90 04 08 cmp 0x80490ec,%ecx [hjl@gnu-6 saved]$ make x86_64 gcc -B./ -c -m64 -o x86_64.o x.S ld -z nocombreloc -m elf_x86_64 -o x86_64 x86_64.o objdump -dw x86_64 x86_64: file format elf64-x86-64 Disassembly of section .plt: 00000000004000e0 <.plt>: 4000e0: ff 25 62 00 20 00 jmpq *0x200062(%rip) # 600148 <_GLOBAL_OFFSET_TABLE_+0x18> 4000e6: 68 00 00 00 00 pushq $0x0 4000eb: e9 00 00 00 00 jmpq 4000f0 <foo-0x10> 4000f0: ff 25 5a 00 20 00 jmpq *0x20005a(%rip) # 600150 <_GLOBAL_OFFSET_TABLE_+0x20> 4000f6: 68 00 00 00 00 pushq $0x0 4000fb: e9 00 00 00 00 jmpq 400100 <foo> Disassembly of section .text: 0000000000400100 <foo>: 400100: c3 retq 0000000000400101 <bar>: 400101: c3 retq 0000000000400102 <_start>: 400102: ff 15 40 00 20 00 callq *0x200040(%rip) # 600148 <_GLOBAL_OFFSET_TABLE_+0x18> 400108: ff 25 42 00 20 00 jmpq *0x200042(%rip) # 600150 <_GLOBAL_OFFSET_TABLE_+0x20> 40010e: 48 c7 05 37 00 20 00 00 00 00 00 movq $0x0,0x200037(%rip) # 600150 <_GLOBAL_OFFSET_TABLE_+0x20> 400119: 48 83 3d 27 00 20 00 00 cmpq $0x0,0x200027(%rip) # 600148 <_GLOBAL_OFFSET_TABLE_+0x18> 400121: 48 3b 0d 20 00 20 00 cmp 0x200020(%rip),%rcx # 600148 <_GLOBAL_OFFSET_TABLE_+0x18> 400128: 48 3b 0d 21 00 20 00 cmp 0x200021(%rip),%rcx # 600150 <_GLOBAL_OFFSET_TABLE_+0x20> [hjl@gnu-6 saved]$ All of PLT entries should be removed.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=233cc9c13af8e8182d0ce5b306526b59f5b11f37 commit 233cc9c13af8e8182d0ce5b306526b59f5b11f37 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Jun 18 09:16:52 2016 -0700 Don't generate PLT for IFUNC GOT/pointer reference If a backend supports it, PLT entry isn't needed when all references to a STT_GNU_IFUNC symbols are done via GOT or static function pointers. For GOT entries, We generate dynamic R_*_GLOB_DAT relocations for preemptable symbols and R_*_IRELATIVE relocations for non-preemptable symbols to update them with real function address. For static pointer pointers, we generate dynamic pointer relocations and store them in: 1. .rel[a].ifunc section in PIC object. 2. .rel[a].got section in dynamic executable. 3. .rel[a].iplt section in static executable. We don't allocate GOT entry if it isn't used. bfd/ PR ld/20253 * elf-bfd.h (_bfd_elf_allocate_ifunc_dyn_relocs): Add an bfd_boolean argument. * elf-ifunc.c (_bfd_elf_create_ifunc_sections): Replace "shared object" with "PIC object" in comments. (_bfd_elf_allocate_ifunc_dyn_relocs): Updated. Replace "shared object" with "PIC object" in comments. Avoid PLT if requested. Generate dynamic relocations for non-GOT references. Make room for the special first entry in PLT and allocate PLT entry only for PLT and PC-relative references. Store dynamic GOT relocations in .rel[a].iplt section for static executables. If PLT isn't used, always use GOT for symbol value. Don't allocate GOT entry if it isn't used. * elf32-i386.c (elf_i386_check_relocs): Increment PLT reference count only in the code section. Allocate dynamic pointer relocation against STT_GNU_IFUNC symbol in the non-code section. (elf_i386_adjust_dynamic_symbol): Increment PLT reference count only for PC-relative references. (elf_i386_allocate_dynrelocs): Pass TRUE to _bfd_elf_allocate_ifunc_dyn_relocs. (elf_i386_relocate_section): Allow R_386_GOT32/R_386_GOT32X relocations against STT_GNU_IFUNC symbols without PLT. Generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the non-code section and store it in the proper REL section. Don't allow non-pointer relocation against STT_GNU_IFUNC symbol without PLT. (elf_i386_finish_dynamic_symbol): Generate dynamic R_386_IRELATIVE and R_386_GLOB_DAT GOT relocations against STT_GNU_IFUNC symbols without PLT. (elf_i386_finish_dynamic_sections): Don't handle local STT_GNU_IFUNC symbols here. (elf_i386_output_arch_local_syms): Handle local STT_GNU_IFUNC symbols here. (elf_backend_output_arch_local_syms): New. * elf32-x86-64.c (elf_i386_check_relocs): Increment PLT reference count only in the code section. Allocate dynamic pointer relocation against STT_GNU_IFUNC symbol in the non-code section. (elf_x86_64_adjust_dynamic_symbol): Increment PLT reference count only for PC-relative references. (elf_x86_64_allocate_dynrelocs): Pass TRUE to _bfd_elf_allocate_ifunc_dyn_relocs. (elf_x86_64_relocate_section): Allow R_X86_64_GOTPCREL, R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX and R_X86_64_GOTPCREL64 relocations against STT_GNU_IFUNC symbols without PLT. Generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the non-code section and store it in the proper RELA section. Don't allow non-pointer relocation against STT_GNU_IFUNC symbol without PLT. (elf_x86_64_finish_dynamic_symbol): Generate dynamic R_X86_64_IRELATIVE and R_X86_64_GLOB_DAT GOT relocations against STT_GNU_IFUNC symbols without PLT. (elf_x86_64_finish_dynamic_sections): Don't handle local STT_GNU_IFUNC symbols here. (elf_x86_64_output_arch_local_syms): Handle local STT_GNU_IFUNC symbols here. (elf_backend_output_arch_local_syms): New. * elfnn-aarch64.c (elfNN_aarch64_allocate_ifunc_dynrelocs): Pass FALSE to _bfd_elf_allocate_ifunc_dyn_relocs. ld/ PR ld/20253 * testsuite/ld-i386/i386.exp: Run PR ld/20253 tests. * testsuite/ld-i386/no-plt.exp: Likewise. * testsuite/ld-x86-64/no-plt.exp: Likewise. * testsuite/ld-i386/pr13302.d: Remove .rel.plt section. * testsuite/ld-ifunc/ifunc-13-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-13-x86-64.d: Likewise. * testsuite/ld-ifunc/ifunc-15-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-15-x86-64.d: Likewise. * testsuite/ld-x86-64/pr13082-5a.d: Likewise. * testsuite/ld-x86-64/pr13082-5b.d: Likewise. * testsuite/ld-x86-64/pr13082-6a.d: Likewise. * testsuite/ld-x86-64/pr13082-6b.d: Likewise. * testsuite/ld-i386/pr20244-2a.d: Remove .plt section. * testsuite/ld-ifunc/ifunc-21-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-21-x86-64.d: Likewise. * testsuite/ld-ifunc/ifunc-22-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-22-x86-64.d: Likewise. * testsuite/ld-i386/pr20244-2b.d: Updated. * testsuite/ld-i386/pr20244-2c.d: Likewise. * testsuite/ld-ifunc/ifunc-18a-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise. * testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise. * testsuite/ld-i386/pr20253-1a.c: New file. * testsuite/ld-i386/pr20253-1b.S: Likewise. * testsuite/ld-i386/pr20253-1c.S: Likewise. * testsuite/ld-i386/pr20253-1d.S: Likewise. * testsuite/ld-i386/pr20253-2a.c: Likewise. * testsuite/ld-i386/pr20253-2b.S: Likewise. * testsuite/ld-i386/pr20253-2c.S: Likewise. * testsuite/ld-i386/pr20253-2d.S: Likewise. * testsuite/ld-i386/pr20253-3.d: Likewise. * testsuite/ld-i386/pr20253-3.s: Likewise. * testsuite/ld-i386/pr20253-4.s: Likewise. * testsuite/ld-i386/pr20253-4a.d: Likewise. * testsuite/ld-i386/pr20253-4b.d: Likewise. * testsuite/ld-i386/pr20253-4c.d: Likewise. * testsuite/ld-i386/pr20253-5.d: Likewise. * testsuite/ld-i386/pr20253-5.s: Likewise. * testsuite/ld-ifunc/ifunc-23-x86.s: Likewise. * testsuite/ld-ifunc/ifunc-23a-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-23b-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-23c-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-24-x86.s: Likewise. * testsuite/ld-ifunc/ifunc-24a-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-24b-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-24c-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-25-x86.s: Likewise. * testsuite/ld-ifunc/ifunc-25a-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-25b-x86.d: Likewise. * testsuite/ld-ifunc/ifunc-25c-x86.d: Likewise. * testsuite/ld-x86-64/pr20253-1.s: Likewise. * testsuite/ld-x86-64/pr20253-1a.d: Likewise. * testsuite/ld-x86-64/pr20253-1b.d: Likewise. * testsuite/ld-x86-64/pr20253-1c.d: Likewise. * testsuite/ld-x86-64/pr20253-1d.d: Likewise. * testsuite/ld-x86-64/pr20253-1e.d: Likewise. * testsuite/ld-x86-64/pr20253-1f.d: Likewise. * testsuite/ld-x86-64/pr20253-1g.d: Likewise. * testsuite/ld-x86-64/pr20253-1h.d: Likewise. * testsuite/ld-x86-64/pr20253-1i.d: Likewise. * testsuite/ld-x86-64/pr20253-1j.d: Likewise. * testsuite/ld-x86-64/pr20253-1k.d: Likewise. * testsuite/ld-x86-64/pr20253-1l.d: Likewise. * testsuite/ld-x86-64/pr20253-2a.c: Likewise. * testsuite/ld-x86-64/pr20253-2b.S: Likewise. * testsuite/ld-x86-64/pr20253-2c.S: Likewise. * testsuite/ld-x86-64/pr20253-2d.S: Likewise. * testsuite/ld-x86-64/pr20253-3.d: Likewise. * testsuite/ld-x86-64/pr20253-3.s: Likewise. * testsuite/ld-x86-64/pr20253-4.s: Likewise. * testsuite/ld-x86-64/pr20253-4a.d: Likewise. * testsuite/ld-x86-64/pr20253-4b.d: Likewise. * testsuite/ld-x86-64/pr20253-4c.d: Likewise. * testsuite/ld-x86-64/pr20253-4d.d: Likewise. * testsuite/ld-x86-64/pr20253-4e.d: Likewise. * testsuite/ld-x86-64/pr20253-4f.d: Likewise. * testsuite/ld-x86-64/pr20253-5.s: Likewise. * testsuite/ld-x86-64/pr20253-5a.d: Likewise. * testsuite/ld-x86-64/pr20253-5b.d: Likewise. * testsuite/ld-ifunc/ifunc-18a-i386.d: Remove extra IRELATIVE relocation. * testsuite/ld-ifunc/ifunc-18a-x86-64.d: Likewise. * testsuite/ld-ifunc/ifunc-18b-i386.d: Likewise. * testsuite/ld-ifunc/ifunc-18b-x86-64.d: Likewise. * testsuite/ld-ifunc/ifunc-18a.s: Fix a typo. * testsuite/ld-x86-64/x86-64.exp: Run pr20253-1 tests.
Fixed for 2.27.