The code below is a sketch of how Clang>=13 PGO intends to make metadata sections subject to --gc-sections. It uses a SHF_LINK_ORDER self-link trick. However, that currently causes an infinite loop in GNU ld. cat > a.s <<e .hidden __start___llvm_prf_cnts .hidden __stop___llvm_prf_cnts .globl _start _start: leaq __start___llvm_prf_cnts(%rip), %rdi leaq __stop___llvm_prf_cnts(%rip), %rsi .section .text.foo,"ax",@progbits .globl foo foo: incq .L__profc_foo(%rip) .section __llvm_prf_cnts,"aw",@progbits .section __llvm_prf_data,"aw",@progbits .section __llvm_prf_cnts,"awo",@progbits,.L__profc_foo,unique,1 ### #.section __llvm_prf_cnts,"aw",@progbits .L__profc_foo: .zero 8 .section __llvm_prf_data,"awo",@progbits,.L__profc_foo,unique,2 .L__profd_foo: .quad 6699318081062747564 # 0x5cf8c24cdb18bdac .quad 0 # 0x0 .quad .L__profc_foo .quad foo .quad 0 .long 1 # 0x1 .zero 4 e as a.s -o a.o ld-new -shared a.o --print-gc-sections --gc-sections # infinite loop If the alternative (indicated as ###) .section directive is used, there is no infinite loop. However, __llvm_prf_cnts & __llvm_prf_data cannot be garbage collected. The reason is that the C identifier sections are considered as GC roots. Adding SHF_LINK_ORDER is a trick to defeat the GC root semantics.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=def97fb945a98544938087eff3111e16ce58da6d commit def97fb945a98544938087eff3111e16ce58da6d Author: Alan Modra <amodra@gmail.com> Date: Thu Jan 28 10:30:36 2021 +1030 PR27259, SHF_LINK_ORDER self-link This stops ld from endless looping on SHF_LINK_ORDER sh_link loops. bfd/ PR 27259 * elflink.c (_bfd_elf_gc_mark_extra_sections): Use linker_mark to prevent endless looping of linked-to sections. ld/ PR 27259 * ldelf.c (ldelf_before_place_orphans): Use linker_mark to prevent endless looping of linked-to sections.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=53e556e5b45e3d8fda25be3623883a0952c0c716 commit 53e556e5b45e3d8fda25be3623883a0952c0c716 Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Jan 28 05:36:51 2021 -0800 ld: Add a test for PR ld/27259 PR ld/27259 * testsuite/ld-elf/pr27259.d: New file. * testsuite/ld-elf/pr27259.s: Likewise.
Thanks for the patch. The infinite loop has been fixed. The remaining issue is that: .text.foo & its associated __llvm_prf_cnts & __llvm_prf_data cannot be GC'ed. % ld-new a.o --print-gc-sections --gc-sections # no output Clang has now -fbinutils-version= . If this is back ported to 2.36, I'd suggest that patch to use -fbinutils-version=2.37 . If this is back ported, I'll suggest =2.36.
The binutils-2_36-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fe0e833171513c1d89668bc5f454192d2db39bce commit fe0e833171513c1d89668bc5f454192d2db39bce Author: Alan Modra <amodra@gmail.com> Date: Thu Jan 28 10:30:36 2021 +1030 PR27259, SHF_LINK_ORDER self-link This stops ld from endless looping on SHF_LINK_ORDER sh_link loops. bfd/ PR 27259 * elflink.c (_bfd_elf_gc_mark_extra_sections): Use linker_mark to prevent endless looping of linked-to sections. ld/ PR 27259 * ldelf.c (ldelf_before_place_orphans): Use linker_mark to prevent endless looping of linked-to sections. (cherry picked from commit def97fb945a98544938087eff3111e16ce58da6d)
The binutils-2_35-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7ed5ed075b9a166f74cf13be216b3e5cf04cd622 commit 7ed5ed075b9a166f74cf13be216b3e5cf04cd622 Author: Alan Modra <amodra@gmail.com> Date: Thu Jan 28 10:30:36 2021 +1030 PR27259, SHF_LINK_ORDER self-link This stops ld from endless looping on SHF_LINK_ORDER sh_link loops. bfd/ PR 27259 * elflink.c (_bfd_elf_gc_mark_extra_sections): Use linker_mark to prevent endless looping of linked-to sections. ld/ PR 27259 * ldelf.c (ldelf_before_place_orphans): Use linker_mark to prevent endless looping of linked-to sections. (cherry picked from commit def97fb945a98544938087eff3111e16ce58da6d)
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=49daa38f31404d4f4d94d7654248b62183ec9c15 commit 49daa38f31404d4f4d94d7654248b62183ec9c15 Author: Alan Modra <amodra@gmail.com> Date: Mon Feb 1 09:56:48 2021 +1030 Re: ld: Add a test for PR ld/27259 * testsuite/ld-elf/pr27259.d: Correct sh_link match.
How exactly is the proposed SHF_LINK_ORDER trick supposed to work? A reference to start_foo/stop_foo symbols from a kept section currently marks all input sections named foo as kept. Are you suggesting that any section named foo that is SHF_LINK_ORDER with a self-link should not be marked? But those foo that do not have a self-link should be marked? Has there been any comment about this idea from the gABI group?
Created attachment 13198 [details] implement If comment 7 is correct then this fairly trivial patch should implement it.
(In reply to Alan Modra from comment #7) > How exactly is the proposed SHF_LINK_ORDER trick supposed to work? A > reference to start_foo/stop_foo symbols from a kept section currently marks > all input sections named foo as kept. Are you suggesting that any section > named foo that is SHF_LINK_ORDER with a self-link should not be marked? But > those foo that do not have a self-link should be marked? > > Has there been any comment about this idea from the gABI group? Started https://groups.google.com/g/generic-abi/c/LxmRJRBBbHk "__start_<section>/__stop_<section> symbols and GC". No response yet.
On LLD side, I've sent https://lists.llvm.org/pipermail/llvm-dev/2021-February/148682.html to seek for feedback whether we can drop the "__start_/__stop_ retain C identifier name sections" rule. On the Linux kernel side, I've created https://github.com/ClangBuiltLinux/linux/issues/1307 to ask for tests.