Index: lld/test/wasm/data-segment-merging.ll =================================================================== --- lld/test/wasm/data-segment-merging.ll +++ lld/test/wasm/data-segment-merging.ll @@ -1,5 +1,3 @@ -target triple = "wasm32-unknown-unknown" - @a = hidden global [6 x i8] c"hello\00", align 1 @b = hidden global [8 x i8] c"goodbye\00", align 1 @c = hidden global [9 x i8] c"whatever\00", align 1 @@ -8,8 +6,9 @@ @e = private constant [9 x i8] c"constant\00", align 1 @f = private constant i8 43, align 4 -; RUN: llc -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.passive.o -; RUN: llc -filetype=obj %s -o %t.o +; RUN: llc --mtriple=wasm32-unknown-unknown -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.passive.o +; RUN: llc --mtriple=wasm64-unknown-unknown -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.passive64.o +; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.o ; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.o ; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE @@ -125,3 +124,61 @@ ; PASSIVE-SEPARATE-NEXT: Name: __wasm_init_memory ; PASSIVE-SEPARATE-NEXT: - Index: 2 ; PASSIVE-SEPARATE-NEXT: Name: __wasm_init_tls + +; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 -o %t.merged.passive64.wasm %t.passive64.o +; RUN: obj2yaml %t.merged.passive64.wasm | FileCheck %s --check-prefix=PASSIVE-MERGE64 + +; PASSIVE-MERGE64-LABEL: - Type: DATACOUNT +; PASSIVE-MERGE64-NEXT: Count: 2 +; PASSIVE-MERGE64-LABEL: - Type: DATA +; PASSIVE-MERGE64-NEXT: Segments: +; PASSIVE-MERGE64-NEXT: - SectionOffset: 3 +; PASSIVE-MERGE64-NEXT: InitFlags: 1 +; PASSIVE-MERGE64-NEXT: Content: 636F6E7374616E74000000002B +; PASSIVE-MERGE64-NEXT: - SectionOffset: 18 +; PASSIVE-MERGE64-NEXT: InitFlags: 1 +; PASSIVE-MERGE64-NEXT: Content: 68656C6C6F00676F6F6462796500776861746576657200002A000000 +; PASSIVE-MERGE64-NEXT: - Type: CUSTOM +; PASSIVE-MERGE64-NEXT: Name: name +; PASSIVE-MERGE64-NEXT: FunctionNames: +; PASSIVE-MERGE64-NEXT: - Index: 0 +; PASSIVE-MERGE64-NEXT: Name: __wasm_call_ctors +; PASSIVE-MERGE64-NEXT: - Index: 1 +; PASSIVE-MERGE64-NEXT: Name: __wasm_init_memory +; PASSIVE-MERGE64-NEXT: - Index: 2 +; PASSIVE-MERGE64-NEXT: Name: __wasm_init_tls + +; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 -no-merge-data-segments -o %t.separate.passive64.wasm %t.passive64.o +; RUN: obj2yaml %t.separate.passive64.wasm | FileCheck %s --check-prefix=PASSIVE-SEPARATE64 + +; PASSIVE-SEPARATE64-LABEL: - Type: DATACOUNT +; PASSIVE-SEPARATE64-NEXT: Count: 6 +; PASSIVE-SEPARATE64-LABEL: - Type: DATA +; PASSIVE-SEPARATE64-NEXT: Segments: +; PASSIVE-SEPARATE64-NEXT: - SectionOffset: 3 +; PASSIVE-SEPARATE64-NEXT: InitFlags: 1 +; PASSIVE-SEPARATE64-NEXT: Content: 636F6E7374616E7400 +; PASSIVE-SEPARATE64-NEXT: - SectionOffset: 14 +; PASSIVE-SEPARATE64-NEXT: InitFlags: 1 +; PASSIVE-SEPARATE64-NEXT: Content: 2B +; PASSIVE-SEPARATE64-NEXT: - SectionOffset: 17 +; PASSIVE-SEPARATE64-NEXT: InitFlags: 1 +; PASSIVE-SEPARATE64-NEXT: Content: 68656C6C6F00 +; PASSIVE-SEPARATE64-NEXT: - SectionOffset: 25 +; PASSIVE-SEPARATE64-NEXT: InitFlags: 1 +; PASSIVE-SEPARATE64-NEXT: Content: 676F6F6462796500 +; PASSIVE-SEPARATE64-NEXT: - SectionOffset: 35 +; PASSIVE-SEPARATE64-NEXT: InitFlags: 1 +; PASSIVE-SEPARATE64-NEXT: Content: '776861746576657200' +; PASSIVE-SEPARATE64-NEXT: - SectionOffset: 46 +; PASSIVE-SEPARATE64-NEXT: InitFlags: 1 +; PASSIVE-SEPARATE64-NEXT: Content: 2A000000 +; PASSIVE-SEPARATE64-NEXT: - Type: CUSTOM +; PASSIVE-SEPARATE64-NEXT: Name: name +; PASSIVE-SEPARATE64-NEXT: FunctionNames: +; PASSIVE-SEPARATE64-NEXT: - Index: 0 +; PASSIVE-SEPARATE64-NEXT: Name: __wasm_call_ctors +; PASSIVE-SEPARATE64-NEXT: - Index: 1 +; PASSIVE-SEPARATE64-NEXT: Name: __wasm_init_memory +; PASSIVE-SEPARATE64-NEXT: - Index: 2 +; PASSIVE-SEPARATE64-NEXT: Name: __wasm_init_tls Index: lld/test/wasm/data-segments.ll =================================================================== --- lld/test/wasm/data-segments.ll +++ lld/test/wasm/data-segments.ll @@ -1,6 +1,7 @@ -; RUN: llc -filetype=obj %s -o %t.atomics.o -mattr=+atomics -; RUN: llc -filetype=obj %s -o %t.bulk-mem.o -mattr=+bulk-memory -; RUN: llc -filetype=obj %s -o %t.atomics.bulk-mem.o -mattr=+atomics,+bulk-memory +; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.o -mattr=+atomics +; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.bulk-mem.o -mattr=+bulk-memory +; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem.o -mattr=+atomics,+bulk-memory +; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem64.o -mattr=+atomics,+bulk-memory ; atomics, shared memory => error ; RUN: not wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.o -o %t.atomics.wasm 2>&1 | FileCheck %s --check-prefix ERROR @@ -12,8 +13,8 @@ ; 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-prefixes PASSIVE - -target triple = "wasm32-unknown-unknown" +; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem64.o -o %t.atomics.bulk-mem64.wasm +; RUN: obj2yaml %t.atomics.bulk-mem64.wasm | FileCheck %s --check-prefixes PASSIVE64 @a = hidden global [6 x i8] c"hello\00", align 1 @b = hidden global [8 x i8] c"goodbye\00", align 1 @@ -83,3 +84,37 @@ ; PASSIVE-NEXT: Name: __wasm_init_memory ; PASSIVE-NEXT: - Index: 2 ; PASSIVE-NEXT: Name: __wasm_init_tls + +; PASSIVE64-LABEL: - Type: START +; PASSIVE64-NEXT: StartFunction: 1 +; PASSIVE64-LABEL: - Type: DATACOUNT +; PASSIVE64-NEXT: Count: 2 +; PASSIVE64-LABEL: - Type: CODE +; PASSIVE64-NEXT: Functions: +; PASSIVE64-NEXT: - Index: 0 +; PASSIVE64-NEXT: Locals: [] +; PASSIVE64-NEXT: Body: 0B +; PASSIVE64-NEXT: - Index: 1 +; PASSIVE64-NEXT: Locals: [] +; PASSIVE64-NEXT: Body: 42B4D60041004101FE480200044042B4D6004101427FFE0102001A054280084100410DFC08000042900841004114FC08010042B4D6004102FE17020042B4D600417FFE0002001A0BFC0900FC09010B + +; PASSIVE64-NEXT: - Index: 2 +; PASSIVE64-NEXT: Locals: [] +; PASSIVE64-NEXT: Body: 0B +; PASSIVE64-NEXT: - Type: DATA +; PASSIVE64-NEXT: Segments: +; PASSIVE64-NEXT: - SectionOffset: 3 +; PASSIVE64-NEXT: InitFlags: 1 +; PASSIVE64-NEXT: Content: 636F6E7374616E74000000002B +; PASSIVE64-NEXT: - SectionOffset: 18 +; PASSIVE64-NEXT: InitFlags: 1 +; PASSIVE64-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000 +; PASSIVE64-NEXT: - Type: CUSTOM +; PASSIVE64-NEXT: Name: name +; PASSIVE64-NEXT: FunctionNames: +; PASSIVE64-NEXT: - Index: 0 +; PASSIVE64-NEXT: Name: __wasm_call_ctors +; PASSIVE64-NEXT: - Index: 1 +; PASSIVE64-NEXT: Name: __wasm_init_memory +; PASSIVE64-NEXT: - Index: 2 +; PASSIVE64-NEXT: Name: __wasm_init_tls Index: lld/wasm/Writer.cpp =================================================================== --- lld/wasm/Writer.cpp +++ lld/wasm/Writer.cpp @@ -841,7 +841,7 @@ void Writer::createInitMemoryFunction() { LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); assert(WasmSym::initMemoryFlag); - uint32_t flagAddress = WasmSym::initMemoryFlag->getVirtualAddress(); + uint64_t flagAddress = WasmSym::initMemoryFlag->getVirtualAddress(); std::string bodyContent; { raw_string_ostream os(bodyContent); @@ -890,8 +890,10 @@ // ( ... drop data segments ... ) // ) + bool is64 = config->is64.getValueOr(false); + // Atomically check whether this is the main thread. - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, 0, "expected flag value"); writeI32Const(os, 1, "flag value"); writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); @@ -901,9 +903,10 @@ writeU8(os, WASM_TYPE_NORESULT, "blocktype"); // Did not increment 0, so wait for main thread to initialize memory - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, 1, "expected flag value"); writeI64Const(os, -1, "timeout"); + writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); writeUleb128(os, WASM_OPCODE_I32_ATOMIC_WAIT, "i32.atomic.wait"); writeMemArg(os, 2, 0); @@ -915,12 +918,7 @@ for (const OutputSegment *s : segments) { if (needsPassiveInitialization(s)) { // destination address - if (config->is64.getValueOr(false)) { - writeI64Const(os, s->startVA, "destination address"); - } else { - writeI32Const(os, static_cast(s->startVA), - "destination address"); - } + writePtrConst(os, s->startVA, is64, "destination address"); // source segment offset writeI32Const(os, 0, "segment offset"); // memory region size @@ -934,14 +932,14 @@ } // Set flag to 2 to mark end of initialization - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, 2, "flag value"); writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); writeUleb128(os, WASM_OPCODE_I32_ATOMIC_STORE, "i32.atomic.store"); writeMemArg(os, 2, 0); // Notify any waiters that memory initialization is complete - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, -1, "number of waiters"); writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); writeUleb128(os, WASM_OPCODE_ATOMIC_NOTIFY, "atomic.notify"); Index: lld/wasm/WriterUtils.h =================================================================== --- lld/wasm/WriterUtils.h +++ lld/wasm/WriterUtils.h @@ -40,6 +40,9 @@ void writeI64Const(raw_ostream &os, int64_t number, const Twine &msg); +void writePtrConst(raw_ostream &os, int64_t number, bool is64, + const Twine &msg); + void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset); void writeInitExpr(raw_ostream &os, const llvm::wasm::WasmInitExpr &initExpr); Index: lld/wasm/WriterUtils.cpp =================================================================== --- lld/wasm/WriterUtils.cpp +++ lld/wasm/WriterUtils.cpp @@ -136,6 +136,14 @@ writeSleb128(os, number, msg); } +void writePtrConst(raw_ostream &os, int64_t number, bool is64, + const Twine &msg) { + if (is64) + writeI64Const(os, number, msg); + else + writeI32Const(os, static_cast(number), msg); +} + void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset) { writeUleb128(os, alignment, "alignment"); writeUleb128(os, offset, "offset");