Skip to content

Commit 2ef32d4

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 2ef32d4

3 files changed

Lines changed: 32 additions & 3 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: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ def update_settings_glue(wasm_file, metadata, base_metadata):
106106
# we don't need any JS library contents in side modules
107107
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = []
108108
else:
109-
syms = settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE + metadata.imports
110-
syms = set(syms).difference(metadata.all_exports)
109+
syms = set(settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE).difference(metadata.all_exports)
110+
syms.update(metadata.imports)
111111
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE = sorted(syms)
112112
if settings.MAIN_MODULE:
113113
settings.WEAK_IMPORTS += webassembly.get_weak_imports(wasm_file)
@@ -1020,6 +1020,10 @@ def create_receiving(function_exports, other_exports, library_symbols, aliases):
10201020
# folks try to call/use a reference that was taken before the
10211021
# wasm module is available.
10221022
for sym in mangled:
1023+
# Don't generate early access traps for symbols that are also JS
1024+
# library functions
1025+
if sym in library_symbols:
1026+
continue
10231027
module_export = (settings.MODULARIZE or not settings.MINIMAL_RUNTIME) and should_export(sym) and settings.MODULARIZE != 'instance'
10241028
if not js_manipulation.isidentifier(sym) and not module_export:
10251029
continue

0 commit comments

Comments
 (0)