[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