Skip to content

[lld][WebAssembly] Skip BSS when combining data segments #127735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions lld/test/wasm/data-segments.ll
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry %t.bulk-mem64.o -o %t.bulk-mem64.wasm
; RUN: obj2yaml %t.bulk-mem64.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE64

;; In -pie mode segments are combined into one active segment.
; RUN: wasm-ld --experimental-pic --import-memory -pie -no-gc-sections --no-entry %t.atomics.bulk-mem.pic.o -o %t.pic.wasm
; RUN: obj2yaml %t.pic.wasm | FileCheck %s --check-prefixes ACTIVE-PIC
; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic.wasm | FileCheck %s --check-prefixes PIC-NON-SHARED-DIS

;; atomics, bulk memory, shared memory => passive segments
; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.wasm
; RUN: obj2yaml %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefix PASSIVE
Expand All @@ -28,9 +33,9 @@
; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.atomics.bulk-mem64.wasm | FileCheck %s --check-prefixes DIS,NOPIC-DIS -DPTR=i64

;; Also test in combination with PIC/pie
; RUN: wasm-ld --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic.o -o %t.pic.wasm
; RUN: obj2yaml %t.pic.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE32-PIC
; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i32
; RUN: wasm-ld --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic.o -o %t.shared.pic.wasm
; RUN: obj2yaml %t.shared.pic.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE32-PIC
; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.shared.pic.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i32

;; Also test in combination with PIC/pie + wasm64
; RUN: wasm-ld -mwasm64 --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic-mem64.o -o %t.pic-mem64.wasm
Expand Down Expand Up @@ -76,6 +81,20 @@
; ACTIVE-NEXT: - Index: 0
; ACTIVE-NEXT: Name: __wasm_call_ctors

;; In ACTIVE-PIC mode the memory is imported which means all data segments
;; (except BSS) are combined in the single one.
;; BSS is not included here, and instead initialized using `memory.init` in
;; `__wasm_init_memory`

; ACTIVE-PIC: - Type: DATA
; ACTIVE-PIC-NEXT: Segments:
; ACTIVE-PIC-NEXT: - SectionOffset: 6
; ACTIVE-PIC-NEXT: InitFlags: 0
; ACTIVE-PIC-NEXT: Offset:
; ACTIVE-PIC-NEXT: Opcode: GLOBAL_GET
; ACTIVE-PIC-NEXT: Index: 1
; ACTIVE-PIC-NEXT: Content: 63000000636F6E7374616E74000000002B00000068656C6C6F00676F6F646279650000002A000000

; PASSIVE-LABEL: - Type: START
; PASSIVE-NEXT: StartFunction: 2
; PASSIVE-LABEL: - Type: DATACOUNT
Expand Down Expand Up @@ -151,6 +170,18 @@
; PASSIVE-PIC-NEXT: - Index: 2
; PASSIVE-PIC-NEXT: Name: __wasm_init_memory

;; For the non-shared PIC case the __wasm_init_memory only deals with BSS since
;; all other segments are active
; PIC-NON-SHARED-DIS: <__wasm_init_memory>:
; PIC-NON-SHARED-DIS-EMPTY:
; PIC-NON-SHARED-DIS-NEXT: i32.const 40
; PIC-NON-SHARED-DIS-NEXT: global.get 1
; PIC-NON-SHARED-DIS-NEXT: i32.add
; PIC-NON-SHARED-DIS-NEXT: i32.const 0
; PIC-NON-SHARED-DIS-NEXT: i32.const 10000
; PIC-NON-SHARED-DIS-NEXT: memory.fill 0
; PIC-NON-SHARED-DIS-NEXT: end

;; no data relocations.
; DIS-LABEL: <__wasm_call_ctors>:
; DIS-EMPTY:
Expand Down
3 changes: 2 additions & 1 deletion lld/wasm/OutputSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ void DataSection::finalizeContents() {
});
#ifndef NDEBUG
unsigned activeCount = llvm::count_if(segments, [](OutputSegment *segment) {
return (segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0;
return segment->requiredInBinary() &&
(segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0;
});
#endif

Expand Down
7 changes: 6 additions & 1 deletion lld/wasm/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,12 @@ void Writer::combineOutputSegments() {
return;
OutputSegment *combined = make<OutputSegment>(".data");
combined->startVA = segments[0]->startVA;
std::vector<OutputSegment *> newSegments = {combined};
for (OutputSegment *s : segments) {
if (!s->requiredInBinary()) {
newSegments.push_back(s);
continue;
}
bool first = true;
for (InputChunk *inSeg : s->inputSegments) {
if (first)
Expand All @@ -1100,7 +1105,7 @@ void Writer::combineOutputSegments() {
}
}

segments = {combined};
segments = newSegments;
}

static void createFunction(DefinedFunction *func, StringRef bodyContent) {
Expand Down
Loading