% cat a.c void foo(){} void bar(){} % clang -fpatchable-function-entry=2 -ffunction-sections -S a.c # clang HEAD https://reviews.llvm.org/D72222 https://reviews.llvm.org/D72222 % grep __patchable a.s .section __patchable_function_entries,"awo",@progbits,foo,unique,0 .section __patchable_function_entries,"awo",@progbits,bar,unique,1 % clang -fpatchable-function-entry=2 -ffunction-sections -c a.c % readelf -S a.o ... [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .strtab STRTAB 0000000000000000 000210 000087 00 0 0 1 [ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 4 [ 3] .text.foo PROGBITS 0000000000000000 000040 000008 00 AX 0 0 16 [ 4] __patchable_function_entries PROGBITS 0000000000000000 000048 000008 00 WAL 3 0 8 [ 5] .rela__patchable_function_entries RELA 0000000000000000 0001b0 000018 18 14 4 8 [ 6] .text.bar PROGBITS 0000000000000000 000050 000008 00 AX 0 0 16 [ 7] __patchable_function_entries PROGBITS 0000000000000000 000058 000008 00 WAL 6 0 8 [ 8] .rela__patchable_function_entries RELA 0000000000000000 0001c8 000018 18 14 7 8 ... The section flag 'o' takes an argument (`,foo` and `,bar` above), adds SHF_LINK_ORDER to sh_flags, and sets sh_link to sh_shndx of the target symbol. You may try `clang -fstack-size-section -ffunction-sections` with older clang (clang >= 8). https://sourceware.org/bugzilla/show_bug.cgi?id=25380 tracks the section linkage feature (`,unique`) This can be seen as a lightweight COMDAT. See https://gcc.gnu.org/ml/gcc/2020-01/msg00067.html (__patchable_function_entries is flawed) https://sourceware.org/ml/binutils/2019-11/msg00266.html (SHF_LINK_ORDER and --gc-sections)
gABI says This flag adds special ordering requirements for link editors. The requirements apply if the sh_link field of this section's header references another section (the linked-to section). If this section is combined with other sections in the output file, it must appear in the same relative order with respect to those sections, as the linked-to section appears with respect to sections the linked-to section is combined with.  A typical use of this flag is to build a table that references text or data sections in address order. But __patchable_function_entries section doesn't have requirement on section order. All it requires that __patchable_function_entries section must be treated as a group together with the section it references.
Created attachment 12246 [details] A patch
(In reply to Fangrui Song from comment #0) > % cat a.c > void foo(){} > void bar(){} > % clang -fpatchable-function-entry=2 -ffunction-sections -S a.c # clang HEAD > https://reviews.llvm.org/D72222 https://reviews.llvm.org/D72222 > % grep __patchable a.s > .section > __patchable_function_entries,"awo",@progbits,foo,unique,0 > .section > __patchable_function_entries,"awo",@progbits,bar,unique,1 unique,N is not required here since .section __patchable_function_entries,"awo",@progbits,foo .section __patchable_function_entries,"awo",@progbits,bar are unique.
> .section __patchable_function_entries,"awo",@progbits,foo > .section __patchable_function_entries,"awo",@progbits,bar clang's integrated assembler uses either section_name or the pair (section_name,unique id) to differentiate sections. If two sections just have different flags (SHF_LINK_ORDER in this example), they are not considered different. Thus, for the example, `,unique,0` and `,unique,1` are still needed.
(In reply to Fangrui Song from comment #4) > > .section __patchable_function_entries,"awo",@progbits,foo > > .section __patchable_function_entries,"awo",@progbits,bar > > clang's integrated assembler uses either section_name or the pair > (section_name,unique id) to differentiate sections. > > If two sections just have different flags (SHF_LINK_ORDER in this example), > they are not considered different. How can a section have 2 different SHF_LINK_ORDER links?
When both o and G present, like .section .text,"axG",@progbits,foo,comdat foo: .section __patchable_function_entries,"awoG",@progbits,foo,foo,comdat .p2align 3 .dc.a .LPFE1 .LPFE1: nop .section .text,"axG",@progbits,foo,comdat ret It is "@progbits,linked-to-symbol-name,group-name,comdat".
A patch is posted at https://sourceware.org/ml/binutils/2020-02/msg00028.html
(In reply to H.J. Lu from comment #5) > (In reply to Fangrui Song from comment #4) > > > .section __patchable_function_entries,"awo",@progbits,foo > > > .section __patchable_function_entries,"awo",@progbits,bar > > > > clang's integrated assembler uses either section_name or the pair > > (section_name,unique id) to differentiate sections. > > > > If two sections just have different flags (SHF_LINK_ORDER in this example), > > they are not considered different. > > How can a section have 2 different SHF_LINK_ORDER links? I opened: https://bugs.llvm.org/show_bug.cgi?id=44775
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b7d072167715829eed0622616f6ae0182900de3e commit b7d072167715829eed0622616f6ae0182900de3e Author: H.J. Lu <hjl.tools@gmail.com> Date: Thu Feb 6 18:04:58 2020 -0800 ELF: Support the section flag 'o' in .section directive As shown in https://sourceware.org/bugzilla/show_bug.cgi?id=25490 --gc-sections will silently remove __patchable_function_entries section and generate corrupt result. This patch adds the section flag 'o' to .section directive: .section __patchable_function_entries,"awo",@progbits,foo .section __patchable_function_entries,"awoG",@progbits,foo,foo,comdat .section __patchable_function_entries,"awo",@progbits,bar,unique,4 .section __patchable_function_entries,"awoG",@progbits,foo,foo,comdat,unique,1 which specifies the symbol name which the section references. Assmebler will set its elf_linked_to_section to a local section where the symbol is defined. Linker is updated to call mark_hook if gc_mark of any of its linked-to sections is set after all sections, except for backend specific ones, have been garbage collected. bfd/ PR gas/25381 * bfd-in2.h: Regenerated. * elflink.c (_bfd_elf_gc_mark_extra_sections): Call mark_hook on section if gc_mark of any of its linked-to sections is set and don't set gc_mark again. * section.c (asection): Add linked_to_symbol_name to map_head union. gas/ PR gas/25381 * config/obj-elf.c (get_section): Also check linked_to_symbol_name. (obj_elf_change_section): Also set map_head.linked_to_symbol_name. (obj_elf_parse_section_letters): Handle the 'o' flag. (build_group_lists): Renamed to ... (build_additional_section_info): This. Set elf_linked_to_section from map_head.linked_to_symbol_name. (elf_adjust_symtab): Updated. * config/obj-elf.h (elf_section_match): Add linked_to_symbol_name. * doc/as.texi: Document the 'o' flag. * testsuite/gas/elf/elf.exp: Run PR gas/25381 tests. * testsuite/gas/elf/section18.d: New file. * testsuite/gas/elf/section18.s: Likewise. * testsuite/gas/elf/section19.d: Likewise. * testsuite/gas/elf/section19.s: Likewise. * testsuite/gas/elf/section20.d: Likewise. * testsuite/gas/elf/section20.s: Likewise. * testsuite/gas/elf/section21.d: Likewise. * testsuite/gas/elf/section21.l: Likewise. * testsuite/gas/elf/section21.s: Likewise. ld/ PR ld/24526 PR ld/25021 PR ld/25490 * testsuite/ld-elf/elf.exp: Run PR ld/25490 tests. * testsuite/ld-elf/pr24526.d: New file. * testsuite/ld-elf/pr24526.s: Likewise. * testsuite/ld-elf/pr25021.d: Likewise. * testsuite/ld-elf/pr25021.s: Likewise. * testsuite/ld-elf/pr25490-2-16.rd: Likewise. * testsuite/ld-elf/pr25490-2-32.rd: Likewise. * testsuite/ld-elf/pr25490-2-64.rd: Likewise. * testsuite/ld-elf/pr25490-2.s: Likewise. * testsuite/ld-elf/pr25490-3-16.rd: Likewise. * testsuite/ld-elf/pr25490-3-32.rd: Likewise. * testsuite/ld-elf/pr25490-3-64.rd: Likewise. * testsuite/ld-elf/pr25490-3.s: Likewise. * testsuite/ld-elf/pr25490-4-16.rd: Likewise. * testsuite/ld-elf/pr25490-4-32.rd: Likewise. * testsuite/ld-elf/pr25490-4-64.rd: Likewise. * testsuite/ld-elf/pr25490-4.s: Likewise. * testsuite/ld-elf/pr25490-5-16.rd: Likewise. * testsuite/ld-elf/pr25490-5-32.rd: Likewise. * testsuite/ld-elf/pr25490-5-64.rd: Likewise. * testsuite/ld-elf/pr25490-5.s: Likewise. * testsuite/ld-elf/pr25490-6-16.rd: Likewise. * testsuite/ld-elf/pr25490-6-32.rd: Likewise. * testsuite/ld-elf/pr25490-6-64.rd: Likewise. * testsuite/ld-elf/pr25490-6.s: Likewise.
Fixed for 2.35.