Bug 27259 - ld: Support SHF_LINK_ORDER self-link
Summary: ld: Support SHF_LINK_ORDER self-link
Status: ASSIGNED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-01-27 22:26 UTC by Fangrui Song
Modified: 2023-08-07 10:08 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2021-01-27 00:00:00


Attachments
implement (475 bytes, patch)
2021-02-03 12:53 UTC, Alan Modra
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2021-01-27 22:26:07 UTC
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.
Comment 1 Sourceware Commits 2021-01-28 08:23:58 UTC
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.
Comment 2 Sourceware Commits 2021-01-28 13:42:21 UTC
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.
Comment 3 Fangrui Song 2021-01-29 01:28:16 UTC
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.
Comment 4 Sourceware Commits 2021-01-29 22:37:54 UTC
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)
Comment 5 Sourceware Commits 2021-01-29 22:50:00 UTC
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)
Comment 6 Sourceware Commits 2021-02-01 08:19:32 UTC
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.
Comment 7 Alan Modra 2021-02-03 08:45:24 UTC
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?
Comment 8 Alan Modra 2021-02-03 12:53:02 UTC
Created attachment 13198 [details]
implement

If comment 7 is correct then this fairly trivial patch should implement it.
Comment 9 Fangrui Song 2021-02-05 08:06:02 UTC
(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.
Comment 10 Fangrui Song 2021-02-20 01:54:43 UTC
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.