[lld] wasm-ld: Preserve segment linking flags in --relocatable output (PR #210747)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 20 08:57:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
Author: Max Desiatov (MaxDesiatov)
<details>
<summary>Changes</summary>
`OutputSegment::addInputSegment` copied each input chunk's alignment but never its flags, so a relocatable link serialized `flags=0` for every data segment and dropped `RETAIN` and `STRINGS`. Losing `RETAIN` let the final default `--gc-sections` link discard runtime-registered sections such as Swift's `swift5_*` metadata, corrupting the program. This unions each input segment's flags into the output segment's `linkingFlags` and adds a `lld/test/wasm` test covering `RETAIN`, `STRINGS`, and flag accumulation across coalesced segments.
Resolves https://github.com/swiftlang/swift-package-manager/issues/10314.
---
Full diff: https://github.com/llvm/llvm-project/pull/210747.diff
2 Files Affected:
- (added) lld/test/wasm/relocatable-segment-flags.s (+39)
- (modified) lld/wasm/OutputSegment.cpp (+4)
``````````diff
diff --git a/lld/test/wasm/relocatable-segment-flags.s b/lld/test/wasm/relocatable-segment-flags.s
new file mode 100644
index 0000000000000..afed7b5ee18cb
--- /dev/null
+++ b/lld/test/wasm/relocatable-segment-flags.s
@@ -0,0 +1,39 @@
+# RUN: rm -rf %t && split-file %s %t
+# RUN: llvm-mc -filetype=obj --triple=wasm32-unknown-unknown -o %t/main.o %t/main.s
+# RUN: llvm-mc -filetype=obj --triple=wasm32-unknown-unknown -o %t/extra.o %t/extra.s
+# RUN: wasm-ld --relocatable -o %t/reloc.o %t/main.o %t/extra.o
+# RUN: obj2yaml %t/reloc.o | FileCheck %s
+
+# --relocatable must preserve per-segment linking flags (RETAIN, STRINGS). The plain
+# "retained" chunk in extra.s coalesces with the retained one in main.o, so RETAIN must
+# survive the flag union rather than be overwritten by the flag-less chunk.
+
+#--- main.s
+ .globl _start
+_start:
+ .functype _start () -> ()
+ end_function
+
+ .section retained,"R",@
+ .asciz "keep"
+
+ .section .rodata.str,"S",@
+ .asciz "merge"
+
+ .section plain,"",@
+ .asciz "drop"
+
+#--- extra.s
+ .section retained,"",@
+ .asciz "more"
+
+# CHECK: SegmentInfo:
+# CHECK: Name: .rodata.str
+# CHECK-NEXT: Alignment: 0
+# CHECK-NEXT: Flags: [ STRINGS ]
+# CHECK: Name: retained
+# CHECK-NEXT: Alignment: 0
+# CHECK-NEXT: Flags: [ RETAIN ]
+# CHECK: Name: plain
+# CHECK-NEXT: Alignment: 0
+# CHECK-NEXT: Flags: [ ]
diff --git a/lld/wasm/OutputSegment.cpp b/lld/wasm/OutputSegment.cpp
index ea052e89dbb55..10fef48c90690 100644
--- a/lld/wasm/OutputSegment.cpp
+++ b/lld/wasm/OutputSegment.cpp
@@ -19,6 +19,10 @@ namespace lld::wasm {
void OutputSegment::addInputSegment(InputChunk *inSeg) {
alignment = std::max(alignment, inSeg->alignment);
+ // Carry input flags (RETAIN, STRINGS) into the relocatable SegmentInfo output;
+ // otherwise a relocatable link drops them and the downstream link loses RETAIN
+ // (segment GC'd) and STRINGS (string merge disabled).
+ linkingFlags |= inSeg->flags;
inputSegments.push_back(inSeg);
size = llvm::alignTo(size, 1ULL << inSeg->alignment);
LLVM_DEBUG(dbgs() << "addInputSegment: " << inSeg->name << " oname=" << name
``````````
</details>
https://github.com/llvm/llvm-project/pull/210747
More information about the llvm-commits
mailing list