Skip to content

Commit 441ec3c

Browse files
committed
Fix: When symbol is both imported and exported, don't drop import
This fixes wrapping syscalls with -sMAIN_MODULE and -sEXPORT_ALL. Resolves issue 26355.
1 parent d4c1c6e commit 441ec3c

3 files changed

Lines changed: 34 additions & 4 deletions

File tree

src/jsifier.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ function(${args}) {
559559

560560
// if the function was implemented in compiled code, there is no need to
561561
// include the js version
562-
if (WASM_EXPORTS.has(symbol)) {
562+
if (WASM_EXPORTS.has(symbol) && !DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.includes(symbol)) {
563563
return;
564564
}
565565

test/test_other.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,31 @@ def test_export_all(self):
16071607
# Without the `-sEXPORT_ALL` these symbols will not be visible from JS
16081608
self.do_runf('main.c', '_libf1 is not defined', assert_returncode=NON_ZERO, cflags=['-Oz', '-sMAIN_MODULE', '--pre-js', 'pre.js'])
16091609

1610+
def test_export_all_syscall_override(self):
1611+
create_file('main.c', r'''
1612+
#include "stdio.h"
1613+
#include <fcntl.h>
1614+
1615+
int syscall_openat_orig(int dirfd, intptr_t path, int flags, void* varags)
1616+
__attribute__((__import_module__("env"),
1617+
__import_name__("__syscall_openat"), __warn_unused_result__));
1618+
1619+
int __syscall_openat(int dirfd, intptr_t path, int flags, void* varargs) {
1620+
printf("__syscall_openat!\n");
1621+
return syscall_openat_orig(dirfd, path, flags, varargs);
1622+
}
1623+
1624+
int main() {
1625+
int fd = open("a.c", O_RDONLY);
1626+
printf("fd: %d\n", fd);
1627+
}
1628+
''')
1629+
1630+
self.do_runf('main.c', '__syscall_openat!', cflags=['-sEXPORT_ALL', '-sNODERAWFS'])
1631+
self.do_runf('main.c', '__syscall_openat!', cflags=['-sMAIN_MODULE', '-sNODERAWFS'])
1632+
self.do_runf('main.c', '__syscall_openat!', cflags=['-O2', '-sEXPORT_ALL', '-sMAIN_MODULE', '-sNODERAWFS'])
1633+
self.do_runf('main.c', '__syscall_openat!', cflags=['-sEXPORT_ALL', '-sMAIN_MODULE', '-sNODERAWFS'])
1634+
16101635
def test_export_keepalive(self):
16111636
create_file('main.c', r'''
16121637
#include <emscripten.h>

tools/emscripten.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ def should_export(sym):
969969
return settings.EXPORT_ALL or (settings.EXPORT_KEEPALIVE and sym in settings.EXPORTED_FUNCTIONS)
970970

971971

972-
def create_receiving(function_exports, other_exports, library_symbols, aliases):
972+
def create_receiving(function_exports, other_exports, library_symbols, aliases, wasm_imports):
973973
generate_dyncall_assignment = 'dynCalls' in library_symbols
974974
receiving = ['\n// Imports from the Wasm binary.']
975975

@@ -1019,6 +1019,7 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):
10191019
# In debug builds we generate trapping functions in case
10201020
# folks try to call/use a reference that was taken before the
10211021
# wasm module is available.
1022+
wasm_imports_mangled = {asmjs_mangle(s) for s in wasm_imports}
10221023
for sym in mangled:
10231024
module_export = (settings.MODULARIZE or not settings.MINIMAL_RUNTIME) and should_export(sym) and settings.MODULARIZE != 'instance'
10241025
if not js_manipulation.isidentifier(sym) and not module_export:
@@ -1029,7 +1030,11 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):
10291030
assignment += f" = Module['{sym}']"
10301031
else:
10311032
assignment = f"Module['{sym}']"
1032-
receiving.append(f"{assignment} = makeInvalidEarlyAccess('{sym}');")
1033+
# Don't generate early access traps for symbols that are also wasm imports.
1034+
if sym in wasm_imports_mangled:
1035+
receiving.append(f"{assignment};")
1036+
else:
1037+
receiving.append(f"{assignment} = makeInvalidEarlyAccess('{sym}');")
10331038
else:
10341039
# Declare all exports in a single var statement
10351040
sep = ',\n '
@@ -1100,7 +1105,7 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):
11001105

11011106
def create_module(metadata, function_exports, other_exports, library_symbols, aliases):
11021107
module = []
1103-
module.append(create_receiving(function_exports, other_exports, library_symbols, aliases))
1108+
module.append(create_receiving(function_exports, other_exports, library_symbols, aliases, metadata.imports))
11041109

11051110
sending = create_sending(metadata, library_symbols)
11061111
if settings.WASM_ESM_INTEGRATION:

0 commit comments

Comments
 (0)