[lld] [lld][ELF] Introduce an option to keep data section prefix. (PR #148985)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 14:25:23 PDT 2025
================
@@ -103,13 +103,48 @@ 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)) {
+ StringRef secName = s->name;
+ if (!secName.consume_front(v))
+ continue;
+ if (!secName.empty() && secName[0] != '.') {
+ continue;
+ }
+
+ // The section name starts with 'v', and the remaining string is either
+ // empty or starts with a '.' character. If keep-data-section-prefix is
+ // false, map s to output section with name 'v'.
+ if (!ctx.arg.zKeepDataSectionPrefix)
+ return v;
+ // Preserve .hot or .unlikely suffixes in data sections with
+ // keep-data-section-prefix=true.
+ if (isSectionPrefix(".hot", secName))
+ return s->name.substr(0, v.size() + 4);
+ if (isSectionPrefix(".unlikely", secName))
+ return s->name.substr(0, v.size() + 9);
+ if (index == 2) {
----------------
mingmingl-llvm wrote:
> I think it's ok for linker to map input .bss.hot. to .bss.hot even if compilers don't generate .bss.hot. .
yes, it's ok to map `.bss.hot.` to `.bss.hot`, in which case `if (isSectionPrefix(".hot", secName))` at L127 will return `.bss.hot`, and code at L131 `(if index==2)` won't run.
As discussed in https://github.com/llvm/llvm-project/pull/148985#discussion_r2221133248 and https://github.com/llvm/llvm-project/pull/148985#discussion_r2233382641, patterns like `.rodata.str1.1.unlikely.` or `.rodata.cst4.hot.` are not mapped before `if (index==2)` because of the strings between section name and hot/unlikely prefix, and `if(index==2)` is added to map them. Meanwhile, we can use `s->name.substr` to return a StringRef by referencing `s->name`.
To get rid of `if (index==2)` specialization, one implementation would be something like [1]. If this version is more readable, I can update the patch to it.
[1]
```
// records the hot prefixes in data array.
// Note `bss.rel.ro` doesn't have hot prefix.
static constexpr StringRef dataSectionHotPrefixes[] = {
".data.rel.ro.hot", ".data.hot", ".rodata.hot", ".bss.rel.ro", ".bss.hot",
};
// records the unlikely suffixes in data array
// Note `bss.rel.ro` doesn't have unlikely prefix.
static constexpr StringRef dataSectionUnlikelyPrefixes[] = {
".data.rel.ro.unlikely", ".data.unlikely", ".rodata.unlikely", ".bss.rel.ro", ".bss.unlikely",
};
for (auto [index, v] : llvm::enumerate(dataSectionPrefixes)) {
... // code before `ctx.arg.zKeepDataSectionPrefix`
if (!ctx.arg.zKeepDataSectionPrefix)
return v;
// We require the trailing dot after hot or unlikely to exist to map them
// to hot or unlikely variant.
if (s->name.ends_with(".hot.")
return dataSectionHotPrefixes[index];
if (s->name.ends_with(".unlikely.")
return dataSectionUnlikelyPrefixes[index];
}
```
https://github.com/llvm/llvm-project/pull/148985
More information about the llvm-commits
mailing list