[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