[lld] 507f394 - [ELF] -r/--emit-relocs: Fix crash when processing .rela.text before .text (#156354)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 20 09:41:58 PDT 2025


Author: mykouHW
Date: 2025-09-20T16:41:54Z
New Revision: 507f394d03d8cb24c90ae4b2d28e8afae3b4088d

URL: https://github.com/llvm/llvm-project/commit/507f394d03d8cb24c90ae4b2d28e8afae3b4088d
DIFF: https://github.com/llvm/llvm-project/commit/507f394d03d8cb24c90ae4b2d28e8afae3b4088d.diff

LOG: [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>

Added: 
    lld/test/ELF/linkerscript/orphan-relocation.s

Modified: 
    lld/ELF/LinkerScript.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 921128dae2bdb..218c9d3a86184 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-commits mailing list