Skip to content

Commit 346cb0c

Browse files
authored
Use alignment in wasm shared modules (emscripten-core#6440)
Implements WebAssembly/tool-conventions#51 Fixes wasm on test_dlfcn_alignment_and_zeroing, which tests alignment of memory of shared modules.
1 parent 28f4be5 commit 346cb0c

3 files changed

Lines changed: 26 additions & 5 deletions

File tree

src/support.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,29 @@ function loadWebAssemblyModule(binary) {
112112
assert(binary[next] === 'n'.charCodeAt(0)); next++;
113113
assert(binary[next] === 'k'.charCodeAt(0)); next++;
114114
var memorySize = getLEB();
115+
var memoryAlign = getLEB();
115116
var tableSize = getLEB();
117+
var tableAlign = getLEB();
118+
// alignments are powers of 2
119+
memoryAlign = Math.pow(2, memoryAlign);
120+
tableAlign = Math.pow(2, tableAlign);
121+
// finalize alignments and verify them
122+
memoryAlign = Math.max(memoryAlign, STACK_ALIGN); // we at least need stack alignment
123+
assert(tableAlign === 1);
124+
// prepare memory
125+
var memoryStart = alignMemory(getMemory(memorySize + memoryAlign), memoryAlign); // TODO: add to cleanups
126+
// The static area consists of explicitly initialized data, followed by zero-initialized data.
127+
// The latter may need zeroing out if the MAIN_MODULE has already used this memory area before
128+
// dlopen'ing the SIDE_MODULE. Since we don't know the size of the explicitly initialized data
129+
// here, we just zero the whole thing, which is suboptimal, but should at least resolve bugs
130+
// from uninitialized memory.
131+
for (var i = memoryStart; i < memoryStart + memorySize; ++i) HEAP8[i] = 0;
132+
// prepare env imports
116133
var env = Module['asmLibraryArg'];
117134
// TODO: use only memoryBase and tableBase, need to update asm.js backend
118135
var table = Module['wasmTable'];
119136
var oldTableSize = table.length;
120-
env['memoryBase'] = env['gb'] = alignMemory(getMemory(memorySize + STACK_ALIGN), STACK_ALIGN); // TODO: add to cleanups
137+
env['memoryBase'] = env['gb'] = memoryStart;
121138
env['tableBase'] = env['fb'] = oldTableSize;
122139
var originalTable = table;
123140
table.grow(tableSize);

tests/test_core.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,8 +2774,6 @@ def test_dlfcn_varargs(self):
27742774
self.do_run(src, '100\n200\n13\n42\n',
27752775
post_build=self.dlfcn_post_build)
27762776

2777-
@no_wasm # wasm shared libraries are just .wasm files, and there is no way to describe alignment there yet
2778-
# see https://github.com/WebAssembly/tool-conventions/pull/51
27792777
def test_dlfcn_alignment_and_zeroing(self):
27802778
if not self.can_dlfcn(): return
27812779

tools/shared.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2640,13 +2640,18 @@ def lebify(x):
26402640

26412641
@staticmethod
26422642
def make_shared_library(js_file, wasm_file):
2643+
import math
26432644
# a wasm shared library has a special "dylink" section, see tools-conventions repo
26442645
js = open(js_file).read()
26452646
m = re.search("var STATIC_BUMP = (\d+);", js)
26462647
mem_size = int(m.group(1))
26472648
m = re.search("Module\['wasmTableSize'\] = (\d+);", js)
26482649
table_size = int(m.group(1))
2649-
logging.debug('creating wasm dynamic library with mem size %d, table size %d' % (mem_size, table_size))
2650+
m = re.search('gb = alignMemory\(getMemory\(\d+ \+ (\d+)\), (\d+) \|\| 1\);', js)
2651+
assert m.group(1) == m.group(2), 'js must contain a clear alignment for the wasm shared library'
2652+
mem_align = int(m.group(1))
2653+
mem_align = int(math.log(mem_align, 2))
2654+
logging.debug('creating wasm dynamic library with mem size %d, table size %d, align %d' % (mem_size, table_size, mem_align))
26502655
wso = js_file + '.wso'
26512656
# write the binary
26522657
wasm = open(wasm_file, 'rb').read()
@@ -2656,7 +2661,8 @@ def make_shared_library(js_file, wasm_file):
26562661
f.write(b'\0') # user section is code 0
26572662
# need to find the size of this section
26582663
name = b"\06dylink" # section name, including prefixed size
2659-
contents = WebAssembly.lebify(mem_size) + WebAssembly.lebify(table_size)
2664+
contents = WebAssembly.lebify(mem_size) + WebAssembly.lebify(mem_align) + \
2665+
WebAssembly.lebify(table_size) + WebAssembly.lebify(0)
26602666
size = len(name) + len(contents)
26612667
f.write(WebAssembly.lebify(size))
26622668
f.write(name)

0 commit comments

Comments
 (0)