[llvm-branch-commits] [lld] release/21.x: [ELF] -r/--emit-relocs: Fix crash when processing .rela.text before .text (#156354) (PR #159948)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Sep 20 14:18:19 PDT 2025


https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/159948

Backport 507f394d03d8cb24c90ae4b2d28e8afae3b4088d

Requested by: @MaskRay

>From f0eb5b7e6094f73b497106ff9cb5a1aee9724acd Mon Sep 17 00:00:00 2001
From: mykouHW <koumeiyuan at huawei.com>
Date: Sun, 21 Sep 2025 00:41:54 +0800
Subject: [PATCH] [ELF] -r/--emit-relocs: Fix crash when processing .rela.text
 before .text (#156354)

fixes #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 at maskray.me>
(cherry picked from commit 507f394d03d8cb24c90ae4b2d28e8afae3b4088d)
---
 lld/ELF/LinkerScript.cpp                      | 20 +++++++-----
 lld/test/ELF/linkerscript/orphan-relocation.s | 31 +++++++++++++++++++
 2 files changed, 43 insertions(+), 8 deletions(-)
 create mode 100644 lld/test/ELF/linkerscript/orphan-relocation.s

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) }
+}



More information about the llvm-branch-commits mailing list