[lld] [ELF] Reject SHF_LINK_ORDER on a non-regular section (PR #219816)
Matt Turner via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 6 18:54:37 PDT 2026
https://github.com/mattst88 updated https://github.com/llvm/llvm-project/pull/219816
>From cbd5f813a6edef27b243132505d9de274306ded8 Mon Sep 17 00:00:00 2001
From: Matt Turner <mattst88 at gmail.com>
Date: Sun, 30 Aug 2026 11:15:10 -0400
Subject: [PATCH] [ELF] Reject SHF_LINK_ORDER on a non-regular section
initializeSections() unconditionally casts a linked-to section to
InputSection, but SHT_STRTAB, mergeable, and .eh_frame sections are not
InputSections, so the cast is invalid for them. Diagnose these cases
instead of asserting.
A follow-up PR will handle discarding an SHF_LINK_ORDER section whose
linked-to section is already discarded.
Assisted-by: Claude Code
---
lld/ELF/InputFiles.cpp | 10 +++++-
lld/test/ELF/linkorder-nonregular.test | 46 ++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)
create mode 100644 lld/test/ELF/linkorder-nonregular.test
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 23649d6200719..4c4b211ab64fc 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -951,9 +951,17 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
continue;
}
+ // dependentSections can only hold InputSections.
+ StringRef name = check(obj.getSectionName(sec, shstrtab));
+ auto *isec = dyn_cast_or_null<InputSection>(this->sections[i]);
+ if (!isec || (sec.sh_flags & SHF_MERGE) || name == ".eh_frame") {
+ ErrAlways(ctx) << this << ":(" << name
+ << "): unsupported section for SHF_LINK_ORDER";
+ continue;
+ }
+
// A SHF_LINK_ORDER section is discarded if its linked-to section is
// discarded.
- InputSection *isec = cast<InputSection>(this->sections[i]);
linkSec->dependentSections.push_back(isec);
if (!isa<InputSection>(linkSec))
ErrAlways(ctx)
diff --git a/lld/test/ELF/linkorder-nonregular.test b/lld/test/ELF/linkorder-nonregular.test
new file mode 100644
index 0000000000000..c2736626c89d3
--- /dev/null
+++ b/lld/test/ELF/linkorder-nonregular.test
@@ -0,0 +1,46 @@
+# REQUIRES: x86
+## dependentSections holds plain InputSections. An SHT_STRTAB section has no
+## InputSectionBase at all, a mergeable one has a MergeInputSection and
+## .eh_frame has an EhInputSection, so none of the three can record the
+## SHF_LINK_ORDER dependency. All three used to assert in cast<InputSection>.
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o /dev/null -e 0 2>&1 | FileCheck %s -DFILE=%t.o
+
+# CHECK-DAG: error: [[FILE]]:(lo_strtab): unsupported section for SHF_LINK_ORDER
+# CHECK-DAG: error: [[FILE]]:(lo_merge): unsupported section for SHF_LINK_ORDER
+# CHECK-DAG: error: [[FILE]]:(.eh_frame): unsupported section for SHF_LINK_ORDER
+
+## The diagnostic must not depend on whether this link happens to build a
+## MergeInputSection or an EhInputSection: -O0 does not merge, and -r keeps
+## .eh_frame a plain InputSection.
+# RUN: not ld.lld %t.o -o /dev/null -e 0 -O0 2>&1 | FileCheck %s -DFILE=%t.o
+# RUN: not ld.lld -r %t.o -o /dev/null 2>&1 | FileCheck %s -DFILE=%t.o
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Size: 1
+ - Name: lo_strtab
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC, SHF_LINK_ORDER ]
+ Link: .text
+ Size: 8
+ - Name: lo_merge
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_MERGE, SHF_LINK_ORDER ]
+ Link: .text
+ EntSize: 4
+ Size: 8
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_LINK_ORDER ]
+ Link: .text
+ Size: 0
More information about the llvm-commits
mailing list