[lld] [ELF] Move merge section offset validation to getSymVA (PR #188677)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 25 22:03:12 PDT 2026
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/188677
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.
>From dde8fc093e157c0429cafab802badd66b86317b1 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 25 Mar 2026 22:00:15 -0700
Subject: [PATCH] [ELF] Move merge section offset validation to getSymVA
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.
---
lld/ELF/InputSection.cpp | 5 +----
lld/ELF/Symbols.cpp | 8 +++++++-
lld/test/ELF/relocation-before-merge-start.s | 2 ++
3 files changed, 10 insertions(+), 5 deletions(-)
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
More information about the llvm-commits
mailing list