Bug 25381 - Support section flag 'o' (SHF_LINK_ORDER)
Summary: Support section flag 'o' (SHF_LINK_ORDER)
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.35
: P2 normal
Target Milestone: 2.35
Assignee: Not yet assigned to anyone
URL: https://sourceware.org/ml/binutils/20...
Keywords:
Depends on: 25380 25490
Blocks:
  Show dependency treegraph
 
Reported: 2020-01-14 01:34 UTC by Fangrui Song
Modified: 2020-02-07 02:26 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2020-02-02 00:00:00


Attachments
A patch (2.27 KB, patch)
2020-02-01 21:43 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2020-01-14 01:34:02 UTC
% 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)
Comment 1 H.J. Lu 2020-02-01 14:47:11 UTC
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.
Comment 2 H.J. Lu 2020-02-01 21:43:15 UTC
Created attachment 12246 [details]
A patch
Comment 3 H.J. Lu 2020-02-02 02:49:25 UTC
(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.
Comment 4 Fangrui Song 2020-02-02 03:29:05 UTC
> .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.
Comment 5 H.J. Lu 2020-02-02 13:46:34 UTC
(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?
Comment 6 H.J. Lu 2020-02-02 19:15:01 UTC
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".
Comment 7 H.J. Lu 2020-02-03 02:21:55 UTC
A patch is posted at

https://sourceware.org/ml/binutils/2020-02/msg00028.html
Comment 8 H.J. Lu 2020-02-04 19:09:27 UTC
(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
Comment 9 Sourceware Commits 2020-02-07 02:09:16 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=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.
Comment 10 H.J. Lu 2020-02-07 02:26:34 UTC
Fixed for 2.35.