[lld] [ELF] Fix location counter used for output section address with MEMOR… (PR #197293)

via llvm-commits llvm-commits at lists.llvm.org
Tue May 12 14:00:55 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld

Author: Deepak Shirke (deepakshirkem)

<details>
<summary>Changes</summary>

When a section uses '.' as its address expression inside a MEMORY region (e.g. 's02 . : { ... } > FLASH'), lld was incorrectly evaluating '.' against the memory region's current position instead of the global location counter. Save the global dot before the memRegion override and restore it when an explicit addrExpr is present.

Fixes #<!-- -->112919

@<!-- -->maskray @<!-- -->smithp35 could you please review this patch?

---
Full diff: https://github.com/llvm/llvm-project/pull/197293.diff


2 Files Affected:

- (modified) lld/ELF/LinkerScript.cpp (+4-1) 
- (added) lld/test/ELF/linkerscript/memory-loc-counter-dot-addr.test (+23) 


``````````diff
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index b9ed964b8c720..f5e3563b93c84 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -1197,10 +1197,13 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
     else
       dot = state->tbssAddr;
   } else {
+    const uint64_t savedDot = dot;
     if (state->memRegion)
       dot = state->memRegion->curPos;
-    if (sec->addrExpr)
+    if (sec->addrExpr) {
+      dot = savedDot;
       setDot(sec->addrExpr, sec->location, false);
+    }
 
     // If the address of the section has been moved forward by an explicit
     // expression so that it now starts past the current curPos of the enclosing
diff --git a/lld/test/ELF/linkerscript/memory-loc-counter-dot-addr.test b/lld/test/ELF/linkerscript/memory-loc-counter-dot-addr.test
new file mode 100644
index 0000000000000..67066f63f14db
--- /dev/null
+++ b/lld/test/ELF/linkerscript/memory-loc-counter-dot-addr.test
@@ -0,0 +1,23 @@
+# REQUIRES: aarch64
+# RUN: echo '.section s01,"a"; .byte 1; .section s02,"a"; .balign 4; .short 1' \
+# RUN:   | llvm-mc -filetype=obj -triple=aarch64 - -o %t.o
+# RUN: ld.lld %t.o --script %s -o %t
+# RUN: llvm-readelf -S %t | FileCheck %s
+
+## Test that when a section uses '.' as its address expression inside a MEMORY
+## region, the global location counter is used, not the memory region position.
+
+# CHECK: s01 PROGBITS 0000000000001000 {{.*}} 000001
+# CHECK: s02 PROGBITS 0000000000001004 {{.*}} 000002
+
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100
+}
+
+SECTIONS
+{
+  s01 : { *(s01) } > FLASH
+  . = ALIGN(4);
+  s02 . : { *(s02) } > FLASH
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/197293


More information about the llvm-commits mailing list