diff options
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 16 | ||||
-rw-r--r-- | test/lit/wasm-emscripten-finalize/passive-pic.wat | 38 |
2 files changed, 50 insertions, 4 deletions
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 19498300f..f8dc16a32 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -85,9 +85,19 @@ std::vector<Address> getSegmentOffsets(Module& wasm) { OffsetSearcher(std::unordered_map<unsigned, Address>& offsets) : offsets(offsets) {} void visitMemoryInit(MemoryInit* curr) { + // The desitination of the memory.init is either a constant + // or the result of an addition with __memory_base in the + // case of PIC code. auto* dest = curr->dest->dynCast<Const>(); if (!dest) { - return; + auto* add = curr->dest->dynCast<Binary>(); + if (!add) { + return; + } + dest = add->left->dynCast<Const>(); + if (!dest) { + return; + } } auto it = offsets.find(curr->segment); if (it != offsets.end()) { @@ -170,9 +180,7 @@ std::string codeForConstAddr(Module& wasm, int32_t address) { const char* str = stringAtAddr(wasm, segmentOffsets, address); if (!str) { - // If we can't find the segment corresponding with the address, then we - // omitted the segment and the address points to an empty string. - return escape(""); + Fatal() << "unable to find data for ASM/EM_JS const at: " << address; } return escape(str); } diff --git a/test/lit/wasm-emscripten-finalize/passive-pic.wat b/test/lit/wasm-emscripten-finalize/passive-pic.wat new file mode 100644 index 000000000..e9af5b1d9 --- /dev/null +++ b/test/lit/wasm-emscripten-finalize/passive-pic.wat @@ -0,0 +1,38 @@ +;; Test that wasm-emscripten-finalize can locate data within passive segments +;; even when compiled with PIC, which means that segment addresses are non-constant. + +;; RUN: wasm-emscripten-finalize --enable-bulk-memory %s -o out.wasm | filecheck %s + +;; CHECK: "asmConsts": { +;; CHECK: "3": ["hello", ["iii"], [""]] +;; CHECK: }, + +(module + (import "env" "memory" (memory $memory 1 1)) + (import "env" "__memory_base" (global $__memory_base i32)) + (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i32 i32 i32) (result i32))) + (data passive "xxxhello\00yyy") + ;; memory init function similar to those generated by wasm-ld + (start $__wasm_init_memory) + (func $__wasm_init_memory + (memory.init 0 + (i32.add + (i32.const 0) + (global.get $__memory_base) + ) + (i32.const 0) + (i32.const 12) + ) + ) + ;; EM_ASM call passing string at address 3 in the passive segment + (func $foo (result i32) + (call $emscripten_asm_const_int + (i32.add + (global.get $__memory_base) + (i32.const 3) + ) + (i32.const 0) + (i32.const 0) + ) + ) +) |