Skip to content

Commit 9e7a17c

Browse files
authored
Apply relocations before static constructor (#17628)
This bug applied to libraries loaded after the runtime initialized. Fixes: #17601
1 parent c8b81d9 commit 9e7a17c

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed

src/library_dylink.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,14 @@ var LibraryDylink = {
648648
registerTLSInit(moduleExports['_emscripten_tls_init'], instance.exports, metadata)
649649
if (!ENVIRONMENT_IS_PTHREAD) {
650650
#endif
651+
var applyRelocs = moduleExports['__wasm_apply_data_relocs'];
652+
if (applyRelocs) {
653+
if (runtimeInitialized) {
654+
applyRelocs();
655+
} else {
656+
__RELOC_FUNCS__.push(applyRelocs);
657+
}
658+
}
651659
var init = moduleExports['__wasm_call_ctors'];
652660
if (init) {
653661
if (runtimeInitialized) {
@@ -657,14 +665,6 @@ var LibraryDylink = {
657665
__ATINIT__.push(init);
658666
}
659667
}
660-
var applyRelocs = moduleExports['__wasm_apply_data_relocs'];
661-
if (applyRelocs) {
662-
if (runtimeInitialized) {
663-
applyRelocs();
664-
} else {
665-
__RELOC_FUNCS__.push(applyRelocs);
666-
}
667-
}
668668
#if USE_PTHREADS
669669
}
670670
#endif

test/test_other.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6107,6 +6107,48 @@ def test_dlopen_bad_flags(self):
61076107
out = self.run_js('a.out.js')
61086108
self.assertContained('invalid mode for dlopen(): Either RTLD_LAZY or RTLD_NOW is required', out)
61096109

6110+
def test_dlopen_contructors(self):
6111+
create_file('side.c', r'''
6112+
#include <stdio.h>
6113+
#include <assert.h>
6114+
6115+
static int foo;
6116+
static int* ptr = &foo;
6117+
6118+
void check_relocations(void) {
6119+
assert(ptr == &foo);
6120+
}
6121+
6122+
__attribute__((constructor)) void ctor(void) {
6123+
printf("foo address: %p\n", ptr);
6124+
// Check that relocations have already been applied by the time
6125+
// contructor functions run.
6126+
check_relocations();
6127+
printf("done ctor\n");
6128+
}
6129+
''')
6130+
create_file('main.c', r'''
6131+
#include <assert.h>
6132+
#include <stdio.h>
6133+
#include <dlfcn.h>
6134+
6135+
int main() {
6136+
void (*check) (void);
6137+
void* h = dlopen("libside.wasm", RTLD_NOW|RTLD_GLOBAL);
6138+
assert(h);
6139+
check = dlsym(h, "check_relocations");
6140+
assert(check);
6141+
check();
6142+
printf("done\n");
6143+
return 0;
6144+
}''')
6145+
self.run_process([EMCC, '-g', '-o', 'libside.wasm', 'side.c', '-sSIDE_MODULE'])
6146+
self.run_process([EMCC, '-g', '-sMAIN_MODULE=2', 'main.c', 'libside.wasm', '-sNO_AUTOLOAD_DYLIBS'])
6147+
self.assertContained('done', self.run_js('a.out.js'))
6148+
# Repeat the test without NO_AUTOLOAD_DYLIBS
6149+
self.run_process([EMCC, '-g', '-sMAIN_MODULE=2', 'main.c', 'libside.wasm'])
6150+
self.assertContained('done', self.run_js('a.out.js'))
6151+
61106152
def test_dlopen_rtld_global(self):
61116153
# This test checks RTLD_GLOBAL where a module is loaded
61126154
# before the module providing a global it needs is. in asm.js we use JS

0 commit comments

Comments
 (0)