Skip to content

Conversation

@llvmbot
Copy link
Member

@llvmbot llvmbot commented Sep 20, 2025

Backport 507f394

Requested by: @MaskRay

@llvmbot
Copy link
Member Author

llvmbot commented Sep 20, 2025

@MaskRay What do you think about merging this PR to the release branch?

@llvmbot
Copy link
Member Author

llvmbot commented Sep 20, 2025

@llvm/pr-subscribers-lld-elf

@llvm/pr-subscribers-lld

Author: None (llvmbot)

Changes

Backport 507f394

Requested by: @MaskRay


Full diff: https://github.com/llvm/llvm-project/pull/159948.diff

2 Files Affected:

  • (modified) lld/ELF/LinkerScript.cpp (+12-8)
  • (added) lld/test/ELF/linkerscript/orphan-relocation.s (+31)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index a5d08f4979dab..b55c19933a13b 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1021,10 +1021,6 @@ void LinkerScript::addOrphanSections() {
     }
   };
 
-  // For further --emit-reloc handling code we need target output section
-  // to be created before we create relocation output section, so we want
-  // to create target sections first. We do not want priority handling
-  // for synthetic sections because them are special.
   size_t n = 0;
   for (InputSectionBase *isec : ctx.inputSections) {
     // Process InputSection and MergeInputSection.
@@ -1037,10 +1033,18 @@ void LinkerScript::addOrphanSections() {
     if (ctx.arg.relocatable && (isec->flags & SHF_LINK_ORDER))
       continue;
 
-    if (auto *sec = dyn_cast<InputSection>(isec))
-      if (InputSectionBase *rel = sec->getRelocatedSection())
-        if (auto *relIS = dyn_cast_or_null<InputSectionBase>(rel->parent))
-          add(relIS);
+    if (auto *sec = dyn_cast<InputSection>(isec)) {
+      if (InputSectionBase *relocated = sec->getRelocatedSection()) {
+        // For --emit-relocs and -r, ensure the output section for .text.foo
+        // is created before the output section for .rela.text.foo.
+        add(relocated);
+        // EhInputSection sections are not added to ctx.inputSections. If we see
+        // .rela.eh_frame, ensure the output section for the synthetic
+        // EhFrameSection is created first.
+        if (auto *p = dyn_cast_or_null<InputSectionBase>(relocated->parent))
+          add(p);
+      }
+    }
     add(isec);
     if (ctx.arg.relocatable)
       for (InputSectionBase *depSec : isec->dependentSections)
diff --git a/lld/test/ELF/linkerscript/orphan-relocation.s b/lld/test/ELF/linkerscript/orphan-relocation.s
new file mode 100644
index 0000000000000..adf5cac6c3e82
--- /dev/null
+++ b/lld/test/ELF/linkerscript/orphan-relocation.s
@@ -0,0 +1,31 @@
+# REQUIRES: x86
+## Test that orphan section placement can handle a relocatable link where
+## the relocation section is seen before the relocated section.
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 a.s -o a.o
+## In a.ro, .rela.text precedes its relocated section.
+# RUN: ld.lld -r a.o -T 1.lds -o a.ro
+# RUN: llvm-readelf -S a.ro | FileCheck %s
+# CHECK:       .rela.text    RELA
+# CHECK-NEXT:  .text         PROGBITS
+
+# RUN: llvm-objcopy --rename-section .text=.com.text --rename-section .rela.text=.rela.com.text a.ro a1.o
+
+## Regression test for #156354 , where we added an orphan RELA section before its relocated section.
+# RUN: ld.lld -r a1.o -o a1.ro
+# RUN: llvm-readelf -S a1.ro | FileCheck %s --check-prefix=CHECK1
+# CHECK1:       .com.text         PROGBITS
+# CHECK1-NEXT:  .rela.com.text    RELA
+
+#--- a.s
+.globl foo
+foo:
+  call foo
+
+#--- 1.lds
+SECTIONS {
+  .rela.text 0 : { *(.rela.text) }
+  .text      0 : { *(.text) }
+}

@github-project-automation github-project-automation bot moved this from Needs Triage to Needs Merge in LLVM Release Status Sep 20, 2025
…text (llvm#156354)

fixes llvm#156417

When the relocation section is placed before the relocated section and
the relocated section is not defined in the linker script, an error will
occur during the linking process.

**Issue Cause:**
In a.ro, `.rela.text` precedes its relocated `InputSection` `.text`.
`addOrphanSections` doesn't handle this scenario.
When it processes `.rela.text`, in the called `getOutputSectionName`,
`rel->getOutputSection()` is nullptr (input `.text` doesn't yet have a
parent output section), leading to an assertion failure.

**Solution:**
For --emit-relocs and -r, ensure the output section for `.text.foo` is
created before the output section for `.rela.text.foo`.

---------

Co-authored-by: Fangrui Song <i@maskray.me>
(cherry picked from commit 507f394)
@tstellar tstellar merged commit 9c8736f into llvm:release/21.x Sep 23, 2025
4 of 8 checks passed
@github-project-automation github-project-automation bot moved this from Needs Merge to Done in LLVM Release Status Sep 23, 2025
@github-actions
Copy link

@MaskRay (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

4 participants