Skip to content

Commit 25c6149

Browse files
update code comment, and add a regression test
1 parent 6328b71 commit 25c6149

File tree

4 files changed

+154
-4
lines changed

4 files changed

+154
-4
lines changed

lld/ELF/Driver.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,6 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
15681568
args, "keep-data-section-prefix", "nokeep-data-section-prefix", false);
15691569
ctx.arg.zKeepTextSectionPrefix = getZFlag(
15701570
args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
1571-
15721571
ctx.arg.zLrodataAfterBss =
15731572
getZFlag(args, "lrodata-after-bss", "nolrodata-after-bss", false);
15741573
ctx.arg.zNoBtCfi = hasZOption(args, "nobtcfi");

lld/ELF/LinkerScript.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,15 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
118118

119119
for (auto [index, v] : llvm::enumerate(dataSectionPrefixes)) {
120120
if (isSectionPrefix(v, s->name)) {
121-
if (ctx.arg.zKeepDataSectionPrefix) {
121+
// The .bss.rel.ro section is considered rarely accessed. So this section
122+
// is not partitioned and zKeepDataSectionPrefix is not applied to
123+
// make the executable simpler with fewer elf sections.
124+
if (ctx.arg.zKeepDataSectionPrefix && index != 3) {
122125
if (isSectionPrefix(".hot", s->name.substr(v.size())))
123126
return s->name.substr(0, v.size() + 4);
124127
if (isSectionPrefix(".unlikely", s->name.substr(v.size())))
125128
return s->name.substr(0, v.size() + 9);
126-
// for .rodata, a section could be`.rodata.cst<N>.hot.` for constant
129+
// For .rodata, a section could be`.rodata.cst<N>.hot.` for constant
127130
// pool or `rodata.str<N>.hot.` for string literals.
128131
if (index == 2) {
129132
if (isSectionSuffix(".hot", s->name)) {

lld/ELF/Writer.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,27 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
555555
}
556556
}
557557

558+
// Returns true if the section is a data section that's read only and
559+
// relocatable per its section name.
560+
static bool isRelRoDataSection(Ctx &ctx, StringRef secName) {
561+
// The section name should start with ".data.rel.ro".
562+
if (!secName.consume_front(".data.rel.ro"))
563+
return false;
564+
565+
// If the section name is .data.rel.ro, it is a relocatable read-only data
566+
// section.
567+
if (secName.empty())
568+
return true;
569+
// If -z keep-data-section-prefix is given, '.data.rel.ro.hot' and
570+
// '.data.rel.ro.unlikely' are considered a split of '.data.rel.ro' based on
571+
// hotness.
572+
if (ctx.arg.zKeepDataSectionPrefix) {
573+
return secName == ".hot" || secName == ".unlikely";
574+
}
575+
576+
return false;
577+
}
578+
558579
// Today's loaders have a feature to make segments read-only after
559580
// processing dynamic relocations to enhance security. PT_GNU_RELRO
560581
// is defined for that.
@@ -631,7 +652,7 @@ static bool isRelroSection(Ctx &ctx, const OutputSection *sec) {
631652
// magic section names.
632653
StringRef s = sec->name;
633654

634-
bool abiAgnostic = s == ".data.rel.ro" || s == ".bss.rel.ro" ||
655+
bool abiAgnostic = isRelRoDataSection(ctx, s) || s == ".bss.rel.ro" ||
635656
s == ".ctors" || s == ".dtors" || s == ".jcr" ||
636657
s == ".eh_frame" || s == ".fini_array" ||
637658
s == ".init_array" || s == ".preinit_array";

lld/test/ELF/data-section-prefix.s

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# REQUIRES: x86
2+
## -z keep-data-section-prefix separates static data sections with prefix
3+
## .<section>.hot, .<section>.unlikely in the absence of a SECTIONS command.
4+
5+
# RUN: rm -rf %t && split-file %s %t && cd %t
6+
7+
# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
8+
9+
# RUN: ld.lld a.o -o out1
10+
# RUN: llvm-readelf -S out1 | FileCheck --check-prefix=BASIC %s
11+
# RUN: ld.lld -z nokeep-text-section-prefix a.o -o out2
12+
# RUN: cmp out1 out2
13+
14+
# RUN: ld.lld -z keep-data-section-prefix a.o -o out3
15+
# RUN: llvm-readelf -S out3 | FileCheck --check-prefix=KEEP %s
16+
17+
## With a SECTIONS command, orphan sections are created verbatim.
18+
## No grouping is performed for them.
19+
# RUN: ld.lld -T x.lds -z keep-data-section-prefix a.o -o out4
20+
# RUN: llvm-readelf -S out4 | FileCheck --check-prefix=SCRIPT %s
21+
22+
# BASIC: [Nr] Name Type Address Off Size
23+
# BASIC: [ 1] .text
24+
# BASIC-NEXT: [ 2] .data.rel.ro PROGBITS 00000000002021c9 0001c9 00000f
25+
# BASIC-NEXT: [ 3] .bss.rel.ro NOBITS 00000000002021d8 0001d8 000008
26+
# BASIC-NEXT: [ 4] .relro_padding NOBITS 00000000002021e0 0001d8 000e20
27+
# BASIC-NEXT: [ 5] .rodata PROGBITS 00000000002031e0 0001e0 000006
28+
# BASIC-NEXT: [ 6] .data PROGBITS 00000000002031e6 0001e6 000004
29+
# BASIC-NEXT: [ 7] .bss NOBITS 00000000002031ea 0001ea 000004
30+
31+
# KEEP: [Nr] Name Type Address Off Size
32+
# KEEP: [ 1] .text
33+
# KEEP-NEXT: [ 2] .data.rel.ro PROGBITS 00000000002021c9 0001c9 000009
34+
# KEEP-NEXT: [ 3] .data.rel.ro.hot PROGBITS 00000000002021d2 0001d2 000004
35+
# KEEP-NEXT: [ 4] .data.rel.ro.unlikely PROGBITS 00000000002021d6 0001d6 000002
36+
# KEEP-NEXT: [ 5] .bss.rel.ro NOBITS 00000000002021d8 0001d8 000008
37+
# KEEP-NEXT: [ 6] .relro_padding NOBITS 00000000002021e0 0001d8 000e20
38+
# KEEP-NEXT: [ 7] .rodata PROGBITS 00000000002031e0 0001e0 000002
39+
# KEEP-NEXT: [ 8] .rodata.hot PROGBITS 00000000002031e2 0001e2 000002
40+
# KEEP-NEXT: [ 9] .rodata.unlikely PROGBITS 00000000002031e4 0001e4 000002
41+
# KEEP-NEXT: [10] .data PROGBITS 00000000002031e6 0001e6 000002
42+
# KEEP-NEXT: [11] .data.hot PROGBITS 00000000002031e8 0001e8 000001
43+
# KEEP-NEXT: [12] .data.unlikely PROGBITS 00000000002031e9 0001e9 000001
44+
# KEEP-NEXT: [13] .bss NOBITS 00000000002031ea 0001ea 000002
45+
# KEEP-NEXT: [14] .bss.hot NOBITS 00000000002031ec 0001ea 000001
46+
# KEEP-NEXT: [15] .bss.unlikely NOBITS 00000000002031ed 0001ea 000001
47+
48+
# SCRIPT: .text
49+
# SCRIPT-NEXT: .rodata.i
50+
# SCRIPT-NEXT: .rodata.hot.j
51+
# SCRIPT-NEXT: .rodata.unlikely.k
52+
# SCRIPT-NEXT: .rodata.split.l
53+
# SCRIPT-NEXT: .rodata.cst32.hot.
54+
# SCRIPT-NEXT: .rodata.str1.1.unlikely.
55+
# SCRIPT-NEXT: .data.m
56+
# SCRIPT-NEXT: .data.hot.n
57+
# SCRIPT-NEXT: .data.unlikely.o
58+
# SCRIPT-NEXT: .data.split.p
59+
# SCRIPT-NEXT: .data.rel.ro.q
60+
# SCRIPT-NEXT: .data.rel.ro.hot.r
61+
# SCRIPT-NEXT: .data.rel.ro.unlikely.s
62+
# SCRIPT-NEXT: .data.rel.ro.split.t
63+
# SCRIPT-NEXT: .bss.a
64+
# SCRIPT-NEXT: .bss.hot.b
65+
# SCRIPT-NEXT: .bss.unlikely.c
66+
# SCRIPT-NEXT: .bss.split.d
67+
# SCRIPT-NEXT: .bss.rel.ro.e
68+
# SCRIPT-NEXT: .bss.rel.ro.hot.f
69+
# SCRIPT-NEXT: .bss.rel.ro.unlikely.g
70+
# SCRIPT-NEXT: .bss.rel.ro.split.h
71+
72+
#--- a.s
73+
.globl _start
74+
_start:
75+
ret
76+
77+
.section .bss.a,"aw"
78+
.byte 0
79+
.section .bss.hot.b,"aw"
80+
.byte 0
81+
.section .bss.unlikely.c,"aw"
82+
.byte 0
83+
.section .bss.split.d,"aw"
84+
.byte 0
85+
86+
.section .bss.rel.ro.e, "aw"
87+
.space 2
88+
.section .bss.rel.ro.hot.f, "aw"
89+
.space 2
90+
.section .bss.rel.ro.unlikely.g, "aw"
91+
.space 2
92+
.section .bss.rel.ro.split.h, "aw"
93+
.space 2
94+
95+
.section .rodata.i,"aw"
96+
.byte 1
97+
.section .rodata.hot.j,"aw"
98+
.byte 2
99+
.section .rodata.unlikely.k,"aw"
100+
.byte 3
101+
.section .rodata.split.l,"aw"
102+
.byte 4
103+
.section .rodata.cst32.hot.,"aw"
104+
.byte 5
105+
.section .rodata.str1.1.unlikely.,"aw"
106+
.byte 6
107+
108+
.section .data.m,"aw"
109+
.byte 5
110+
.section .data.hot.n,"aw"
111+
.byte 6
112+
.section .data.unlikely.o,"aw"
113+
.byte 7
114+
.section .data.split.p,"aw"
115+
.byte 8
116+
117+
.section .data.rel.ro.q,"aw"
118+
.quad 0
119+
.section .data.rel.ro.hot.r,"aw"
120+
.long 255
121+
.section .data.rel.ro.unlikely.s,"aw"
122+
.word 1
123+
.section .data.rel.ro.split.t,"aw"
124+
.byte 0
125+
126+
#--- x.lds
127+
SECTIONS {}

0 commit comments

Comments
 (0)