[llvm-branch-commits] [lld] release/22.x: [lld][ELF] Fix crash when relaxation pass encounters synthetic sections (PR #186725)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Mar 15 19:21:29 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
Author: None (llvmbot)
<details>
<summary>Changes</summary>
Backport 655d5e7f690c37aad1da453ed5e3f354d5781d68
Requested by: @<!-- -->wangleiat
---
Full diff: https://github.com/llvm/llvm-project/pull/186725.diff
4 Files Affected:
- (modified) lld/ELF/Arch/LoongArch.cpp (+4-1)
- (modified) lld/ELF/Arch/RISCV.cpp (+8-1)
- (added) lld/test/ELF/loongarch-relax-synthetic-in-text.s (+31)
- (added) lld/test/ELF/riscv-relax-synthetic-in-text.s (+33)
``````````diff
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 9682b4722ac1e..7e6f14a7cc8f4 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -1579,7 +1579,8 @@ bool LoongArch::relaxOnce(int pass) const {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage))
- changed |= relax(ctx, *sec);
+ if (sec->relaxAux)
+ changed |= relax(ctx, *sec);
}
return changed;
}
@@ -1591,6 +1592,8 @@ void LoongArch::finalizeRelax(int passes) const {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage)) {
+ if (!sec->relaxAux)
+ continue;
RelaxAux &aux = *sec->relaxAux;
if (!aux.relocDeltas)
continue;
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index bdb728bc19e7b..4c2bca27e1047 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -706,6 +706,8 @@ void elf::initSymbolAnchors(Ctx &ctx) {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage)) {
+ if (isa<SyntheticSection>(sec))
+ continue;
sec->relaxAux = make<RelaxAux>();
if (sec->relocs().size()) {
sec->relaxAux->relocDeltas =
@@ -750,6 +752,8 @@ void elf::initSymbolAnchors(Ctx &ctx) {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage)) {
+ if (!sec->relaxAux)
+ continue;
llvm::sort(sec->relaxAux->anchors, [](auto &a, auto &b) {
return std::make_pair(a.offset, a.end) <
std::make_pair(b.offset, b.end);
@@ -980,7 +984,8 @@ bool RISCV::relaxOnce(int pass) const {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage))
- changed |= relax(ctx, pass, *sec);
+ if (sec->relaxAux)
+ changed |= relax(ctx, pass, *sec);
}
return changed;
}
@@ -1104,6 +1109,8 @@ void RISCV::finalizeRelax(int passes) const {
if (!(osec->flags & SHF_EXECINSTR))
continue;
for (InputSection *sec : getInputSections(*osec, storage)) {
+ if (!sec->relaxAux)
+ continue;
RelaxAux &aux = *sec->relaxAux;
if (!aux.relocDeltas)
continue;
diff --git a/lld/test/ELF/loongarch-relax-synthetic-in-text.s b/lld/test/ELF/loongarch-relax-synthetic-in-text.s
new file mode 100644
index 0000000000000..67c355e5a7595
--- /dev/null
+++ b/lld/test/ELF/loongarch-relax-synthetic-in-text.s
@@ -0,0 +1,31 @@
+# REQUIRES: loongarch
+# RUN: rm -rf %t && split-file %s %t
+# RUN: llvm-mc --filetype=obj -triple=loongarch64 -mattr=+relax %t/a.s -o %t/a.o
+
+## Do not crash when we encounter a synthetic section (like .got) that has
+## been placed inside an executable output section via a linker script.
+## Synthetic sections do not have relaxAux data structures initialized.
+
+# RUN: ld.lld -T %t/a.ld %t/a.o -o %t/a.out
+# RUN: llvm-objdump -s %t/a.out | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK-NEXT: 0400001a 8440c002 10000000 00000000
+
+#--- a.s
+.global _start
+_start:
+ pcalau12i $a0, %got_pc_hi20(sym)
+ ld.d $a0, $a0, %got_pc_lo12(sym)
+
+.data
+sym:
+ .word 0
+
+#--- a.ld
+SECTIONS {
+ .text : {
+ *(.text)
+ *(.got)
+ }
+}
diff --git a/lld/test/ELF/riscv-relax-synthetic-in-text.s b/lld/test/ELF/riscv-relax-synthetic-in-text.s
new file mode 100644
index 0000000000000..d892da3fdd3a4
--- /dev/null
+++ b/lld/test/ELF/riscv-relax-synthetic-in-text.s
@@ -0,0 +1,33 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t
+# RUN: llvm-mc --filetype=obj -triple=riscv64 -mattr=+relax %t/a.s -o %t/a.o
+
+## Do not crash when we encounter a synthetic section (like .got) that has
+## been placed inside an executable output section via a linker script.
+## Synthetic sections do not have relaxAux data structures initialized.
+
+# RUN: ld.lld -T %t/a.ld %t/a.o -o %t/a.out
+# RUN: llvm-objdump -s %t/a.out | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK-NEXT: 17050000 03350501 00000000 00000000
+# CHECK-NEXT: 18000000 00000000
+
+#--- a.s
+.global _start
+_start:
+1:
+ auipc a0, %got_pcrel_hi(sym)
+ ld a0, %pcrel_lo(1b)(a0)
+
+.data
+sym:
+ .word 0
+
+#--- a.ld
+SECTIONS {
+ .text : {
+ *(.text)
+ *(.got)
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/186725
More information about the llvm-branch-commits
mailing list