Index: lld/trunk/test/wasm/shared-memory-no-atomics.yaml =================================================================== --- lld/trunk/test/wasm/shared-memory-no-atomics.yaml +++ lld/trunk/test/wasm/shared-memory-no-atomics.yaml @@ -0,0 +1,60 @@ +# RUN: yaml2obj %s -o %t1.o + +# RUN: wasm-ld --no-entry %t1.o -o - | obj2yaml | FileCheck %s --check-prefix NO-SHARED + +# RUN: not wasm-ld --no-entry --shared-memory --max-memory=131072 %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED + +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: IMPORT + Imports: + - Module: env + Field: __linear_memory + Kind: MEMORY + Memory: + Initial: 0x00000001 + - Module: env + Field: __indirect_function_table + Kind: TABLE + Table: + ElemType: FUNCREF + Limits: + Initial: 0x00000000 + - Type: DATA + Segments: + - SectionOffset: 6 + InitFlags: 0 + Offset: + Opcode: I32_CONST + Value: 0 + Content: 68656C6C6F0A00 + - Type: CUSTOM + Name: linking + Version: 2 + SymbolTable: + - Index: 0 + Kind: DATA + Name: hello_str + Flags: [ ] + Segment: 0 + Size: 7 + SegmentInfo: + - Index: 0 + Name: .rodata.hello_str + Alignment: 0 + Flags: [ ] + - Type: CUSTOM + Name: target_features + Features: + - Prefix: DISALLOWED + Name: "atomics" +... + +# NO-SHARED: - Type: MEMORY +# NO-SHARED-NEXT: Memories: +# NO-SHARED-NEXT: - Initial: 0x00000002 +# NO-SHARED-NOT: Maximum: + +# SHARED: 'atomics' feature is disallowed, so --shared-memory must not be used{{$}} Index: lld/trunk/test/wasm/shared-memory.yaml =================================================================== --- lld/trunk/test/wasm/shared-memory.yaml +++ lld/trunk/test/wasm/shared-memory.yaml @@ -0,0 +1,75 @@ +# RUN: yaml2obj %s -o %t1.o + +# RUN: not wasm-ld --no-entry --shared-memory %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED-NO-MAX + +# RUN: not wasm-ld --no-entry --shared-memory --max-memory=100000 %t1.o -o - 2>&1 | FileCheck %s --check-prefix SHARED-UNALIGNED + +# RUN: wasm-ld --no-entry --shared-memory --max-memory=131072 %t1.o -o - | obj2yaml | FileCheck %s --check-prefix SHARED + +# RUN: not wasm-ld --no-entry --features=atomics %t1.o -o - 2>&1 | FileCheck %s --check-prefix ATOMICS-NO-SHARED + +# RUN: not wasm-ld --no-entry --features=atomics --shared-memory %t1.o -o - 2>&1 | FileCheck %s --check-prefix ATOMICS-NO-MAX + +# RUN: not wasm-ld --no-entry --features=atomics --shared-memory --max-memory=100000 %t1.o -o - 2>&1 | FileCheck %s --check-prefix ATOMICS-UNALIGNED + +# RUN: wasm-ld --no-entry --features=atomics --shared-memory --max-memory=131072 %t1.o -o - | obj2yaml | FileCheck %s --check-prefix SHARED + + +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: IMPORT + Imports: + - Module: env + Field: __linear_memory + Kind: MEMORY + Memory: + Initial: 0x00000001 + - Module: env + Field: __indirect_function_table + Kind: TABLE + Table: + ElemType: FUNCREF + Limits: + Initial: 0x00000000 + - Type: DATA + Segments: + - SectionOffset: 6 + InitFlags: 0 + Offset: + Opcode: I32_CONST + Value: 0 + Content: 68656C6C6F0A00 + - Type: CUSTOM + Name: linking + Version: 2 + SymbolTable: + - Index: 0 + Kind: DATA + Name: hello_str + Flags: [ ] + Segment: 0 + Size: 7 + SegmentInfo: + - Index: 0 + Name: .rodata.hello_str + Alignment: 0 + Flags: [ ] +... + +# SHARED-NO-MAX: maximum memory too small, 66560 bytes needed{{$}} + +# SHARED-UNALIGNED: maximum memory must be 65536-byte aligned{{$}} + +# SHARED: - Type: MEMORY +# SHARED-NEXT: Memories: +# SHARED-NEXT: - Flags: [ HAS_MAX, IS_SHARED ] +# SHARED-NEXT: Initial: 0x00000002 +# SHARED-NEXT: Maximum: 0x00000002 + +# ATOMICS-NO-SHARED: 'atomics' feature is used, so --shared-memory must be used{{$}} + +# ATOMICS-NO-MAX: maximum memory too small, 66560 bytes needed{{$}} + +# ATOMICS-UNALIGNED: maximum memory must be 65536-byte aligned{{$}} Index: lld/trunk/wasm/Writer.cpp =================================================================== --- lld/trunk/wasm/Writer.cpp +++ lld/trunk/wasm/Writer.cpp @@ -169,7 +169,7 @@ Import.Kind = WASM_EXTERNAL_MEMORY; Import.Memory.Flags = 0; Import.Memory.Initial = NumMemoryPages; - if (MaxMemoryPages != 0) { + if (MaxMemoryPages != 0 || Config->SharedMemory) { Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; Import.Memory.Maximum = MaxMemoryPages; } @@ -257,7 +257,7 @@ SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY); raw_ostream &OS = Section->getStream(); - bool HasMax = MaxMemoryPages != 0; + bool HasMax = MaxMemoryPages != 0 || Config->SharedMemory; writeUleb128(OS, 1, "memory count"); unsigned Flags = 0; if (HasMax) @@ -831,7 +831,8 @@ NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; log("mem: total pages = " + Twine(NumMemoryPages)); - if (Config->MaxMemory != 0) { + // Check max if explicitly supplied or required by shared memory + if (Config->MaxMemory != 0 || Config->SharedMemory) { if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); if (MemoryPtr > Config->MaxMemory) @@ -927,9 +928,16 @@ if (InferFeatures) TargetFeatures.insert(Used.begin(), Used.end()); + if (TargetFeatures.count("atomics") && !Config->SharedMemory) + error("'atomics' feature is used, so --shared-memory must be used"); + if (!Config->CheckFeatures) return; + if (Disallowed.count("atomics") && Config->SharedMemory) + error( + "'atomics' feature is disallowed, so --shared-memory must not be used"); + // Validate that used features are allowed in output if (!InferFeatures) { for (auto &Feature : Used) {