[lld] [lld][ELF] Introduce an option to keep data section prefix. (PR #148985)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 23 12:24:37 PDT 2025
================
@@ -105,13 +110,41 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
return ".text";
}
- for (StringRef v : {".data.rel.ro", ".data", ".rodata",
- ".bss.rel.ro", ".bss", ".ldata",
- ".lrodata", ".lbss", ".gcc_except_table",
- ".init_array", ".fini_array", ".tbss",
- ".tdata", ".ARM.exidx", ".ARM.extab",
- ".ctors", ".dtors", ".sbss",
- ".sdata", ".srodata"})
+ // When zKeepDataSectionPrefix is true, keep .hot and .unlikely suffixes
+ // in data sections.
+ static constexpr StringRef dataSectionPrefixes[] = {
+ ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
+ };
+
+ for (auto [index, v] : llvm::enumerate(dataSectionPrefixes)) {
+ if (isSectionPrefix(v, s->name)) {
+ // The .bss.rel.ro section is considered rarely accessed. So this section
+ // is not partitioned and zKeepDataSectionPrefix is not applied to
+ // make the executable simpler with fewer elf sections.
+ if (ctx.arg.zKeepDataSectionPrefix && index != 3) {
+ if (isSectionPrefix(".hot", s->name.substr(v.size())))
+ return s->name.substr(0, v.size() + 4);
+ if (isSectionPrefix(".unlikely", s->name.substr(v.size())))
+ return s->name.substr(0, v.size() + 9);
+ // For .rodata, a section could be`.rodata.cst<N>.hot.` for constant
+ // pool or `rodata.str<N>.hot.` for string literals.
+ if (index == 2) {
+ if (isSectionSuffix(".hot", s->name)) {
+ return ".rodata.hot";
----------------
mingmingl-llvm wrote:
> delete braces for single-line simple body.
done
> Is it necessary to make the feature specific to `.rodata`? While I understand that it probably has not been extended to `.data`, we are adding an option with a quite generic name, can we include these other sections as well?
This is a good question. The reason for `if (index == 2) {` (the whole if-block in [1]) is to have simpler code by spelling out `.rodata.hot` string literal when we cannot return a substring as a StringRef. I added a code comment for this.
To elaborate
1) For majority cases, the section name has one of the three prefixes (`.<section>.hot`, `.<section>.unlikely` or `.<section>`). In those cases, the returned StringRef is a substring of `s->name`. This works well, without the need to separate if-else branches for different data sections.
2) The `isSectionPrefix` pattern above cannot be easily extended to return StringRef as a substring of `.str<N>` or `.cst<N>` come in between, and specifically we cannot get `StringRef` from .rodata.str<N>.hot.` .
[1]
```
if (index == 2) {
if (s->name.ends_with(".hot."))
return ".rodata.hot";
if (s->name.ends_with(".unlikely."))
return ".rodata.unlikely";
}
}
```
https://github.com/llvm/llvm-project/pull/148985
More information about the llvm-commits
mailing list