Skip to content

Commit 4b1e2ea

Browse files
authored
Fix undefined EM_JS symbol with dynamic linking (emscripten-core#18502)
There are two issues that need fixing to actually fix emscripten-core#18494. This only fixes one of them.
1 parent e1ac185 commit 4b1e2ea

4 files changed

Lines changed: 41 additions & 8 deletions

File tree

emscripten.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,12 +673,13 @@ def create_sending(invoke_funcs, metadata):
673673
# Map of wasm imports to mangled/external/JS names
674674
send_items_map = {}
675675

676-
for name in metadata.emJsFuncs:
677-
send_items_map[name] = name
678676
for name in invoke_funcs:
679677
send_items_map[name] = name
680678
for name in metadata.imports:
681-
send_items_map[name] = asmjs_mangle(name)
679+
if name in metadata.emJsFuncs:
680+
send_items_map[name] = name
681+
else:
682+
send_items_map[name] = asmjs_mangle(name)
682683

683684
add_standard_wasm_imports(send_items_map)
684685

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <emscripten.h>
2+
#include <stdio.h>
3+
4+
EM_JS(void, foo, (void), {
5+
err("hello");
6+
});
7+
8+
// Take the address of foo and store it in a global.
9+
void (*f)(void) = &foo;
10+
11+
int main() {
12+
printf("main\n");
13+
// Calling en EM_JS function by its address, without also importing
14+
// as a normal function, doesn't yet work with dynamic linking and this
15+
// call will fail with `Missing signature argument to addFunction`.
16+
f();
17+
printf("done\n");
18+
return 0;
19+
}

test/test_other.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11666,6 +11666,20 @@ def test_em_js_side_module(self):
1166611666
err = self.expect_fail([EMXX, '-sSIDE_MODULE', test_file('core/test_em_js.cpp')])
1166711667
self.assertContained('EM_JS is not supported in side modules', err)
1166811668

11669+
def test_em_js_main_module(self):
11670+
self.set_setting('MAIN_MODULE', 2)
11671+
self.set_setting('EXPORTED_FUNCTIONS', '_main,_malloc')
11672+
self.do_runf(test_file('core/test_em_js.cpp'))
11673+
11674+
def test_em_js_main_module_address(self):
11675+
# This works under static linking but is known to fail with dynamic linking
11676+
# See https://github.com/emscripten-core/emscripten/issues/18494
11677+
self.do_runf(test_file('other/test_em_js_main_module_address.c'))
11678+
11679+
self.set_setting('MAIN_MODULE', 2)
11680+
expected = 'Aborted(Assertion failed: Missing signature argument to addFunction: function foo() { err("hello"); })'
11681+
self.do_runf(test_file('other/test_em_js_main_module_address.c'), expected, assert_returncode=NON_ZERO)
11682+
1166911683
# On Windows maximum command line length is 32767 characters. Create such a long build line by linking together
1167011684
# several .o files to test that emcc internally uses response files properly when calling llvmn-nm and wasm-ld.
1167111685
@is_slow_test

tools/extract_metadata.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,12 @@ def get_export_names(module):
254254
def update_metadata(filename, metadata):
255255
imports = []
256256
invoke_funcs = []
257-
em_js_funcs = set(metadata.emJsFuncs)
258257
with webassembly.Module(filename) as module:
259258
for i in module.get_imports():
260259
if i.kind == webassembly.ExternType.FUNC:
261260
if i.field.startswith('invoke_'):
262261
invoke_funcs.append(i.field)
263-
elif i.field not in em_js_funcs:
262+
else:
264263
imports.append(i.field)
265264
elif i.kind in (webassembly.ExternType.GLOBAL, webassembly.ExternType.TAG):
266265
imports.append(i.field)
@@ -316,10 +315,10 @@ def extract_metadata(filename):
316315
if i.kind == webassembly.ExternType.FUNC:
317316
if i.field.startswith('invoke_'):
318317
invoke_funcs.append(i.field)
319-
elif i.field in em_js_funcs:
320-
types = module.get_types()
321-
em_js_func_types[i.field] = types[i.type]
322318
else:
319+
if i.field in em_js_funcs:
320+
types = module.get_types()
321+
em_js_func_types[i.field] = types[i.type]
323322
import_names.append(i.field)
324323
elif i.kind in (webassembly.ExternType.GLOBAL, webassembly.ExternType.TAG):
325324
import_names.append(i.field)

0 commit comments

Comments
 (0)