Skip to content

Commit d0f2c6f

Browse files
committed
[lld][WebAssembly] Honor requiredInBinary when combining data segments
In most circumstances BSS segments are not required in the output binary but combineOutputSegments was erroneously including them. This meant that PIC binaries were including the BSS data as zero in the binary. Fixes: emscripten-core/emscripten#23683
1 parent b100c50 commit d0f2c6f

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

lld/test/wasm/data-segments.ll

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry %t.bulk-mem64.o -o %t.bulk-mem64.wasm
1818
; RUN: obj2yaml %t.bulk-mem64.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE64
1919

20+
;; In -pie mode segments are combined into one active segment.
21+
; RUN: wasm-ld --experimental-pic --import-memory -pie -no-gc-sections --no-entry %t.atomics.bulk-mem.pic.o -o %t.pic.wasm
22+
; RUN: obj2yaml %t.pic.wasm | FileCheck %s --check-prefixes ACTIVE-PIC
23+
; 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
24+
2025
;; atomics, bulk memory, shared memory => passive segments
2126
; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.wasm
2227
; RUN: obj2yaml %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefix PASSIVE
@@ -28,9 +33,9 @@
2833
; 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
2934

3035
;; Also test in combination with PIC/pie
31-
; 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
32-
; RUN: obj2yaml %t.pic.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE32-PIC
33-
; 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
36+
; 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
37+
; RUN: obj2yaml %t.shared.pic.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE32-PIC
38+
; 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
3439

3540
;; Also test in combination with PIC/pie + wasm64
3641
; 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
@@ -47,7 +52,7 @@
4752

4853
@g = thread_local global i32 99, align 4
4954

50-
; ERROR: 'bulk-memory' feature must be used in order to use shared memory
55+
;; ERROR: 'bulk-memory' feature must be used in order to use shared memory
5156

5257
; ACTIVE-LABEL: - Type: CODE
5358
; ACTIVE-NEXT: Functions:
@@ -76,6 +81,20 @@
7681
; ACTIVE-NEXT: - Index: 0
7782
; ACTIVE-NEXT: Name: __wasm_call_ctors
7883

84+
;; In ACTIVE-PIC mode the memory is imported which means all data segments
85+
;; (except BSS) are combined in the single one.
86+
;; BSS is not included here, and instead initialized using `memory.init` in
87+
;; `__wasm_init_memory`
88+
89+
; ACTIVE-PIC: - Type: DATA
90+
; ACTIVE-PIC-NEXT: Segments:
91+
; ACTIVE-PIC-NEXT: - SectionOffset: 6
92+
; ACTIVE-PIC-NEXT: InitFlags: 0
93+
; ACTIVE-PIC-NEXT: Offset:
94+
; ACTIVE-PIC-NEXT: Opcode: GLOBAL_GET
95+
; ACTIVE-PIC-NEXT: Index: 1
96+
; ACTIVE-PIC-NEXT: Content: 63000000636F6E7374616E74000000002B00000068656C6C6F00676F6F646279650000002A000000
97+
7998
; PASSIVE-LABEL: - Type: START
8099
; PASSIVE-NEXT: StartFunction: 2
81100
; PASSIVE-LABEL: - Type: DATACOUNT
@@ -151,6 +170,18 @@
151170
; PASSIVE-PIC-NEXT: - Index: 2
152171
; PASSIVE-PIC-NEXT: Name: __wasm_init_memory
153172

173+
;; For the non-shared PIC case the __wasm_init_memory only deals with BSS since
174+
;; all other segments are active
175+
; PIC-NON-SHARED-DIS: <__wasm_init_memory>:
176+
; PIC-NON-SHARED-DIS-EMPTY:
177+
; PIC-NON-SHARED-DIS-NEXT: i32.const 40
178+
; PIC-NON-SHARED-DIS-NEXT: global.get 1
179+
; PIC-NON-SHARED-DIS-NEXT: i32.add
180+
; PIC-NON-SHARED-DIS-NEXT: i32.const 0
181+
; PIC-NON-SHARED-DIS-NEXT: i32.const 10000
182+
; PIC-NON-SHARED-DIS-NEXT: memory.fill 0
183+
; PIC-NON-SHARED-DIS-NEXT: end
184+
154185
;; no data relocations.
155186
; DIS-LABEL: <__wasm_call_ctors>:
156187
; DIS-EMPTY:

lld/wasm/OutputSections.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ void DataSection::finalizeContents() {
101101
});
102102
#ifndef NDEBUG
103103
unsigned activeCount = llvm::count_if(segments, [](OutputSegment *segment) {
104-
return (segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0;
104+
return segment->requiredInBinary() &&
105+
(segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0;
105106
});
106107
#endif
107108

lld/wasm/Writer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,12 @@ void Writer::combineOutputSegments() {
10811081
return;
10821082
OutputSegment *combined = make<OutputSegment>(".data");
10831083
combined->startVA = segments[0]->startVA;
1084+
std::vector<OutputSegment *> newSegments = {combined};
10841085
for (OutputSegment *s : segments) {
1086+
if (!s->requiredInBinary()) {
1087+
newSegments.push_back(s);
1088+
continue;
1089+
}
10851090
bool first = true;
10861091
for (InputChunk *inSeg : s->inputSegments) {
10871092
if (first)
@@ -1100,7 +1105,7 @@ void Writer::combineOutputSegments() {
11001105
}
11011106
}
11021107

1103-
segments = {combined};
1108+
segments = newSegments;
11041109
}
11051110

11061111
static void createFunction(DefinedFunction *func, StringRef bodyContent) {

0 commit comments

Comments
 (0)