Skip to content

Commit 1a3f3a3

Browse files
committed
[lld][ELF] __start_/__stop_ refs don't retain C-ident named group sections
The special root semantics for identifier-named sections is meant specifically for the metadata sections. In the context of group semantics, where group members are always retained or discarded as a unit, it's natural not to have this semantics apply to a section in a group, otherwise we would never discard the group defeating the purpose of using the group in the first place. This change modifies the GC behavior so that __start_/__stop_ references don't retain C identifier named sections in section groups which allows for these groups to be collected. This matches the behavior of BFD ld. The only kind of existing case that might break is interdependent metadata sections that are all in a group together, but that group doesn't contain any other sections referenced by anything except implicit inclusion in a `__start_` and/or `__stop_`-referenced identifier-named section, but such cases should be unlikely. Differential Revision: https://reviews.llvm.org/D96753
1 parent 0b417ba commit 1a3f3a3

File tree

3 files changed

+48
-45
lines changed

3 files changed

+48
-45
lines changed

lld/ELF/MarkLive.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
270270

271271
if (isReserved(sec) || script->shouldKeep(sec)) {
272272
enqueue(sec, 0);
273-
} else if (isValidCIdentifier(sec->name)) {
273+
} else if (isValidCIdentifier(sec->name) && !sec->nextInSectionGroup) {
274274
cNamedSections[saver.save("__start_" + sec->name)].push_back(sec);
275275
cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec);
276276
}

lld/test/ELF/gc-sections-startstop.s

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## Check that group members are retained or discarded as a unit, and
2+
## sections whose names are C identifiers aren't considered roots if
3+
## they're members of a group.
4+
5+
# REQUIRES: x86
6+
7+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
8+
# RUN: ld.lld %t.o --gc-sections -o %t
9+
# RUN: llvm-readelf -s %t | FileCheck %s
10+
11+
# RUN: echo ".global __start___data; __start___data:" > %t2.s
12+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o
13+
# RUN: ld.lld -shared %t2.o -o %t2.so
14+
# RUN: ld.lld %t.o --gc-sections -o %t2 %t2.so
15+
# RUN: llvm-readelf -s %t2 | FileCheck %s
16+
17+
# CHECK: [[#%x,ADDR:]] {{.*}} __start___data
18+
# CHECK: [[#ADDR + 8]] {{.*}} __stop___data
19+
# CHECK: _start
20+
# CHECK: f
21+
# CHECK-NOT: g
22+
23+
.weak __start___data
24+
.weak __stop___data
25+
26+
.section .text,"ax",@progbits
27+
.global _start
28+
_start:
29+
.quad __start___data - .
30+
.quad __stop___data - .
31+
call f
32+
33+
.section __data,"axG",@progbits,f
34+
.quad 0
35+
36+
.section .text.f,"axG",@progbits,f
37+
.global f
38+
f:
39+
nop
40+
41+
.section __data,"axG",@progbits,g
42+
.quad 0
43+
44+
.section .text.g,"axG",@progbits,g
45+
.global g
46+
g:
47+
nop

lld/test/ELF/startstop-gccollect.s

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)