[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