Bug 28124 - ld: Make special sections in a section group GCable
Summary: ld: Make special sections in a section group GCable
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-07-23 03:29 UTC by Fangrui Song
Modified: 2024-02-16 01:01 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed: 2024-02-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fangrui Song 2021-07-23 03:29:04 UTC
% cat a.s
.globl _start, bbb
_start:

.section .mytext.bbb,"axG",@progbits,bbb,comdat
bbb:
.byte 0

.section .init_array.bbb,"awG",@init_array,bbb,comdat
.byte 0
% cc -c a.s && ld.bfd --gc-sections --print-gc-sections a.o
(no output)

If I rename .init_array.bbb to .myinit_array.bbb, the group can be GCed

% cc -c a.s && ld.bfd --gc-sections --print-gc-sections a.o
ld.bfd: removing unused section '.group' in file 'a.o'
ld.bfd: removing unused section '.mytext.bbb[bbb]' in file 'a.o'
ld.bfd: removing unused section '.myinit_array.bbb[bbb]' in file 'a.o'

It seems favorable to make all special sections GCable if in a section group.
This makes the rule more consistent.

An SHF_ALLOC SHT_NOTE appears to be a GC root outside of a group.

---

Before 13.0,
clang -fsanitize-coverage=... abuses .init_array.2 (SHT_INIT_ARRAY) in a section group to make the group a GC root, e.g.

% clang -fsanitize-coverage=trace-pc-guard -c -xc++ =(printf 'int main(){}') -ffunction-sections -fdata-sections -c -o a.o
% readelf -Wg a.o

group section [    3] `.group' [main] contains 3 sections:
   [Index]    Name
   [    4]   .text.main
   [    5]   .rela.text.main
   [    9]   __sancov_guards

COMDAT group section [    6] `.group' [sancov.module_ctor_trace_pc_guard] contains 4 sections:
   [Index]    Name
   [    7]   .text.sancov.module_ctor_trace_pc_guard
   [    8]   .rela.text.sancov.module_ctor_trace_pc_guard
   [   10]   .init_array.2
   [   11]   .rela.init_array.2

The intention is that .text.sancov.module_ctor_trace_pc_guard will be retained.

I changed 13.0.0 to use SHF_GNU_RETAIN to express the GC root intention explicitly.
You may consider work around it, but I think not working around it is also fine.
Comment 1 Fangrui Song 2021-07-23 23:46:17 UTC
For SHF_LINK_ORDER:

% cat a.s
.globl _start; _start: nop
.section .text.a,"ax",@progbits; ret
.section .init_array.a,"awo",@init_array,.text.a; ret
% gcc -fuse-ld=bfd a.s -nostdlib -Wl,--gc-sections
/usr/bin/ld.bfd: a.out: sh_link of section `.init_array' points to discarded section `.text.a' of `/tmp/cceqfqVM.o'
/usr/bin/ld.bfd: final link failed: bad value
collect2: error: ld returned 1 exit status

(Trunk GNU ld is the same.)

If we allow GCable .init_array, we should discard .init_array.a and this should link without an error.
Comment 2 Alan Modra 2024-02-16 01:01:45 UTC
It isn't that SHT_INIT_ARRAY sections are treated specially (although they are for ld -r).  The reason why .init_array.bbb and .init_array.a is kept is the KEEP in the default linker script:

  .init_array    :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }

The pattern .init_array.* is there to match .init_array.65530 or similar with a numeric suffix.  (In fact, it's probably wrong to match other named .init_array sections there, but that's a side issue.)

KEEP operates on the named sections regardless of whether they are part of a group or not.  We'd need to change the behaviour of KEEP (or invent a new keyword) if .init_array inside a group was to be gc'ed.