[PATCH] D77007: [ELF] Allow SHF_LINK_ORDER and non-SHF_LINK_ORDER to be mixed
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 28 23:58:01 PDT 2020
MaskRay created this revision.
MaskRay added reviewers: grimar, psmith, ruiu.
Herald added subscribers: llvm-commits, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
Currently, `error: incompatible section flags for .rodata` is reported
when we mix SHF_LINK_ORDER and non-SHF_LINK_ORDER sections in an output section.
This is over-constrained. This patch allows mixed flags with the
requirement that SHF_LINK_ORDER sections must be contiguous.
This requirement is caused by an interaction of Linux kernel
.init.data : { ... KEEP(*(__patchable_function_entries)) ... }
and clang's -fpatchable-function-entry=N[,M] implementation which sets
the SHF_LINK_ORDER flag (D72215 <https://reviews.llvm.org/D72215>) to fix a number of garbage collection
issues.
This patch also imposes one restriction: SHF_LINK_ORDER sections cannot
be separated by a symbol assignment or a BYTE command.
Link: https://github.com/ClangBuiltLinux/linux/issues/953
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D77007
Files:
lld/ELF/OutputSections.cpp
lld/ELF/Writer.cpp
lld/test/ELF/linkerscript/linkorder.s
Index: lld/test/ELF/linkerscript/linkorder.s
===================================================================
--- lld/test/ELF/linkerscript/linkorder.s
+++ lld/test/ELF/linkerscript/linkorder.s
@@ -35,7 +35,7 @@
## Non-contiguous SHF_LINK_ORDER sections, separated by a BYTE.
# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) BYTE(0) *(.rodata.bar)} }' > %terr1.lds
-# RUN: ld.lld -T %terr1.lds %t.o -o /dev/null
+# RUN: not ld.lld -T %terr1.lds %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
## Non-contiguous SHF_LINK_ORDER sections, separated by a non-SHF_LINK_ORDER section.
# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) *(.text) *(.rodata.bar)} }' > %terr2.lds
@@ -43,9 +43,9 @@
## Non-contiguous SHF_LINK_ORDER sections, separated by a symbol assignment.
# RUN: echo 'SECTIONS { .rodata : {*(.rodata.foo) a = .; *(.rodata.bar)} }' > %terr3.lds
-# RUN: ld.lld -T %terr3.lds %t.o -o /dev/null
+# RUN: not ld.lld -T %terr3.lds %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
-# ERR: error: incompatible section flags for .rodata
+# ERR: error: {{.*}}.o:(.rodata.bar): SHF_LINK_ORDER sections in .rodata are not contiguous
.global _start
_start:
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -1562,17 +1562,30 @@
// but sort must consider them all at once.
std::vector<InputSection **> scriptSections;
std::vector<InputSection *> sections;
+ bool started = false, stopped = false;
for (BaseCommand *base : sec->sectionCommands) {
if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
for (InputSection *&isec : isd->sections) {
- scriptSections.push_back(&isec);
- sections.push_back(isec);
+ if (!(isec->flags & SHF_LINK_ORDER)) {
+ if (started)
+ stopped = true;
+ } else if (stopped) {
+ error(toString(isec) + ": SHF_LINK_ORDER sections in " + sec->name +
+ " are not contiguous");
+ } else {
+ started = true;
- InputSection *link = isec->getLinkOrderDep();
- if (!link->getParent())
- error(toString(isec) + ": sh_link points to discarded section " +
- toString(link));
+ scriptSections.push_back(&isec);
+ sections.push_back(isec);
+
+ InputSection *link = isec->getLinkOrderDep();
+ if (!link->getParent())
+ error(toString(isec) + ": sh_link points to discarded section " +
+ toString(link));
+ }
}
+ } else if (started) {
+ stopped = true;
}
}
Index: lld/ELF/OutputSections.cpp
===================================================================
--- lld/ELF/OutputSections.cpp
+++ lld/ELF/OutputSections.cpp
@@ -114,8 +114,7 @@
flags = isec->flags;
} else {
// Otherwise, check if new type or flags are compatible with existing ones.
- unsigned mask = SHF_TLS | SHF_LINK_ORDER;
- if ((flags & mask) != (isec->flags & mask))
+ if ((flags ^ isec->flags) & SHF_TLS)
error("incompatible section flags for " + name + "\n>>> " + toString(isec) +
": 0x" + utohexstr(isec->flags) + "\n>>> output section " + name +
": 0x" + utohexstr(flags));
@@ -366,8 +365,9 @@
// all InputSections in the OutputSection have the same dependency.
if (auto *ex = dyn_cast<ARMExidxSyntheticSection>(first))
link = ex->getLinkOrderDep()->getParent()->sectionIndex;
- else if (auto *d = first->getLinkOrderDep())
- link = d->getParent()->sectionIndex;
+ else if (first->flags & SHF_LINK_ORDER)
+ if (auto *d = first->getLinkOrderDep())
+ link = d->getParent()->sectionIndex;
}
if (type == SHT_GROUP) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77007.253403.patch
Type: text/x-patch
Size: 3850 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200329/6491bdc1/attachment-0001.bin>
More information about the llvm-commits
mailing list