[lld] [ELF] Move merge section offset validation to getSymVA (PR #188677)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 25 22:03:47 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
@llvm/pr-subscribers-lld-elf
Author: Fangrui Song (MaskRay)
<details>
<summary>Changes</summary>
Move the "offset is outside the section" error for merge sections from
getSectionPiece to getSymVA, where we know the offset comes from a
section symbol + addend. This makes getSectionPiece simpler (assert
instead of error) and ensures the validation happens before the offset
reaches getParentOffset.
---
Full diff: https://github.com/llvm/llvm-project/pull/188677.diff
3 Files Affected:
- (modified) lld/ELF/InputSection.cpp (+1-4)
- (modified) lld/ELF/Symbols.cpp (+7-1)
- (modified) lld/test/ELF/relocation-before-merge-start.s (+2)
``````````diff
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index c8c0a7cdbf109..855d520b6194e 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -1548,10 +1548,7 @@ void MergeInputSection::splitIntoPieces() {
}
SectionPiece &MergeInputSection::getSectionPiece(uint64_t offset) {
- if (content().size() <= offset) {
- Err(getCtx()) << this << ": offset is outside the section";
- return pieces[0];
- }
+ assert(offset < content().size());
return partition_point(
pieces, [=](SectionPiece p) { return p.inputOff <= offset; })[-1];
}
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index d9c46c9d28d3a..23caceb45f25b 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -88,8 +88,14 @@ static uint64_t getSymVA(Ctx &ctx, const Symbol &sym, int64_t addend) {
// To make this work, we incorporate the addend into the section
// offset (and zero out the addend for later processing) so that
// we find the right object in the section.
- if (d.isSection())
+ if (d.isSection()) {
offset += addend;
+ if (auto *ms = dyn_cast<MergeInputSection>(isec);
+ ms && offset >= ms->content().size()) {
+ Err(ctx) << ms << ": offset is outside the section";
+ return 0;
+ }
+ }
// In the typical case, this is actually very simple and boils
// down to adding together 3 numbers:
diff --git a/lld/test/ELF/relocation-before-merge-start.s b/lld/test/ELF/relocation-before-merge-start.s
index b5f7406f3a685..be07b9984538c 100644
--- a/lld/test/ELF/relocation-before-merge-start.s
+++ b/lld/test/ELF/relocation-before-merge-start.s
@@ -2,8 +2,10 @@
// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
// RUN: not ld.lld %t.o -o /dev/null -shared 2>&1 | FileCheck %s --implicit-check-not=error:
// CHECK: error: {{.*}}:(.foo): offset is outside the section
+// CHECK: error: {{.*}}:(.foo): offset is outside the section
.data
.quad .foo - 1
+.quad .foo + 0x100000000
.section .foo,"aM", at progbits,4
.quad 0
``````````
</details>
https://github.com/llvm/llvm-project/pull/188677
More information about the llvm-commits
mailing list