[lld] [lld][ELF] Add /PASSTHRU/. #65087 (PR #84287)
Bevin Hansson via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 7 00:33:48 PST 2024
https://github.com/bevin-hansson created https://github.com/llvm/llvm-project/pull/84287
This adds a special output section name to linker
scripts similar to /DISCARD/, but where any input
section mentioned in the description will not be
considered for any further matching, and will not
result in any orphan handling diagnostics if they
are enabled.
>From 7fa5029e82893308723ce5cbd31abb781f145b5a Mon Sep 17 00:00:00 2001
From: Bevin Hansson <bevin.hansson at ericsson.com>
Date: Wed, 6 Mar 2024 17:00:26 +0100
Subject: [PATCH] [lld][ELF] Add /PASSTHRU/. #65087
This adds a special output section name to linker
scripts similar to /DISCARD/, but where any input
section mentioned in the description will not be
considered for any further matching, and will not
result in any orphan handling diagnostics if they
are enabled.
---
lld/ELF/InputSection.cpp | 1 +
lld/ELF/InputSection.h | 1 +
lld/ELF/LinkerScript.cpp | 17 ++++++++++--
lld/test/ELF/linkerscript/Inputs/passthru2.s | 6 +++++
lld/test/ELF/linkerscript/passthru.s | 27 ++++++++++++++++++++
5 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 lld/test/ELF/linkerscript/Inputs/passthru2.s
create mode 100644 lld/test/ELF/linkerscript/passthru.s
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index e033a715b59214..5184f78449160c 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -310,6 +310,7 @@ std::string InputSectionBase::getObjMsg(uint64_t off) const {
}
InputSection InputSection::discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
+InputSection InputSection::passthru(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
InputSection::InputSection(InputFile *f, uint64_t flags, uint32_t type,
uint32_t addralign, ArrayRef<uint8_t> data,
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index b8af962877b4e9..91efaae5103c9a 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -415,6 +415,7 @@ class InputSection : public InputSectionBase {
void replace(InputSection *other);
static InputSection discarded;
+ static InputSection passthru;
private:
template <class ELFT, class RelTy> void copyRelocations(uint8_t *buf);
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9e7647f63ca5ae..bbeb3d815895eb 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -620,6 +620,17 @@ void LinkerScript::processSectionCommands() {
return false;
}
+ // The output section name `/PASSTHRU/' is special.
+ // Any input section assigned to it is not considered for further
+ // assignment, and also does not result in orphan handling diagnostics.
+ if (osec->name == "/PASSTHRU/") {
+ for (InputSectionBase *s : v)
+ s->parent = &InputSection::passthru;
+ osec->commands.clear();
+ return false;
+ }
+
+
// This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
// ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
// sections satisfy a given constraint. If not, a directive is handled
@@ -832,8 +843,10 @@ void LinkerScript::addOrphanSections() {
SmallVector<OutputDesc *, 0> v;
auto add = [&](InputSectionBase *s) {
- if (s->isLive() && !s->parent) {
- orphanSections.push_back(s);
+ bool isPassthru = s->parent == &InputSection::passthru;
+ if (s->isLive() && (!s->parent || isPassthru)) {
+ if (!isPassthru)
+ orphanSections.push_back(s);
StringRef name = getOutputSectionName(s);
if (config->unique) {
diff --git a/lld/test/ELF/linkerscript/Inputs/passthru2.s b/lld/test/ELF/linkerscript/Inputs/passthru2.s
new file mode 100644
index 00000000000000..510452e417487a
--- /dev/null
+++ b/lld/test/ELF/linkerscript/Inputs/passthru2.s
@@ -0,0 +1,6 @@
+
+.section .x.b, "a"
+ .quad 0
+
+.section .y.b, "a"
+ .quad 0
diff --git a/lld/test/ELF/linkerscript/passthru.s b/lld/test/ELF/linkerscript/passthru.s
new file mode 100644
index 00000000000000..001f7412b3d90c
--- /dev/null
+++ b/lld/test/ELF/linkerscript/passthru.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/passthru2.s -o %t2
+# RUN: echo "SECTIONS { " \
+# RUN: " /PASSTHRU/ : { *(.x*); *(.y*) }" \
+# RUN: " .y.foo : { *(.x*); }" \
+# RUN: " .x.foo : { *(.y*); }" \
+# RUN: "}" > %t.script
+# RUN: ld.lld -o %t.out --script %t.script %t1 %t2
+# RUN: llvm-objdump --section-headers %t.out | FileCheck %s
+
+# The order should not be affected by the order of matches in the /PASSTHRU/
+# section, and we should not have any .x.foo or .y.foo sections.
+
+# CHECK: 1 .x.a
+# CHECK: 2 .y.a
+# CHECK: 3 .x.b
+# CHECK: 4 .y.b
+
+# CHECK-NOT: .x.foo
+# CHECK-NOT: .y.foo
+
+.section .x.a, "a"
+ .quad 0
+
+.section .y.a, "a"
+ .quad 0
More information about the llvm-commits
mailing list