Skip to content

Commit 4a39566

Browse files
authored
Make RTLD_LOCAL work correctly for preloaded DSOs (emscripten-core#21985)
Follow-up to commit c9a5e63, for the FS.createPreloadedFile() case. Make sure loadWebAssemblyModule() and loadDynamicLibrary() are called with a valid 'localScope' object when invoked from the .so file type preload handler.
1 parent dd0c250 commit 4a39566

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/library_dylink.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var LibraryDylink = {
2626
// than just running the promises in parallel, this makes a chain of
2727
// promises to run in series.
2828
wasmPlugin['promiseChainEnd'] = wasmPlugin['promiseChainEnd'].then(
29-
() => loadWebAssemblyModule(byteArray, {loadAsync: true, nodelete: true}, name)).then(
29+
() => loadWebAssemblyModule(byteArray, {loadAsync: true, nodelete: true}, name, {})).then(
3030
(exports) => {
3131
#if DYLINK_DEBUG
3232
dbg(`registering preloadedWasm: ${name}`);
@@ -877,7 +877,7 @@ var LibraryDylink = {
877877
if (flags.loadAsync) {
878878
return metadata.neededDynlibs
879879
.reduce((chain, dynNeeded) => chain.then(() =>
880-
loadDynamicLibrary(dynNeeded, flags)
880+
loadDynamicLibrary(dynNeeded, flags, localScope)
881881
), Promise.resolve())
882882
.then(loadModule);
883883
}

test/test_core.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,6 +3958,52 @@ def test_dlfcn_rtld_local(self):
39583958

39593959
self.do_runf('main.c', 'main\nfunc_a\nfunc_sub\nfunc_b\nfunc_sub\ndone\n')
39603960

3961+
@needs_dylink
3962+
def test_dlfcn_preload(self):
3963+
# Create chain of dependencies and load the first libary with preload plugin.
3964+
# main -> libb.so -> liba.so
3965+
create_file('liba.c', r'''
3966+
#include <stdio.h>
3967+
int liba_fun() {
3968+
return 23;
3969+
}
3970+
''')
3971+
self.build_dlfcn_lib('liba.c', outfile='liba.so')
3972+
3973+
create_file('libb.c', r'''
3974+
#include <stdio.h>
3975+
int liba_fun();
3976+
3977+
int libb_fun() {
3978+
return liba_fun()*2;
3979+
}
3980+
''')
3981+
self.build_dlfcn_lib('libb.c', outfile='libb.so', emcc_args=['liba.so'])
3982+
3983+
self.prep_dlfcn_main(['--preload-file', 'libb.so', '--use-preload-plugins'])
3984+
create_file('main.c', r'''
3985+
#include <assert.h>
3986+
#include <dlfcn.h>
3987+
#include <stdio.h>
3988+
#include <sys/stat.h>
3989+
3990+
int main() {
3991+
// Check the file exists in the VFS
3992+
struct stat statbuf;
3993+
assert(stat("/libb.so", &statbuf) == 0);
3994+
void *lib_handle = dlopen("/libb.so", RTLD_LOCAL | RTLD_NOW);
3995+
assert(lib_handle);
3996+
typedef int (*intfunc)();
3997+
intfunc x = (intfunc)dlsym(lib_handle, "libb_fun");
3998+
assert(x);
3999+
assert(x() == 46);
4000+
printf("done\n");
4001+
return 0;
4002+
4003+
}
4004+
''')
4005+
self.do_runf('main.c', 'done\n')
4006+
39614007
def dylink_test(self, main, side, expected=None, header=None, force_c=False,
39624008
main_module=2, **kwargs):
39634009
# Same as dylink_testf but take source code in string form

0 commit comments

Comments
 (0)