Skip to content

Commit ca72013

Browse files
authored
Fix dynamic library alignment, and add test for emscripten-core#6355 (emscripten-core#6423)
1 parent af2254e commit ca72013

3 files changed

Lines changed: 85 additions & 2 deletions

File tree

src/jsifier.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ function JSify(data, functionsOnly) {
432432
print('STATIC_BASE = GLOBAL_BASE;\n');
433433
print('STATICTOP = STATIC_BASE + ' + Runtime.alignMemory(Variables.nextIndexedOffset) + ';\n');
434434
} else {
435-
print('gb = alignMemory(getMemory({{{ STATIC_BUMP }}}), ' + MAX_GLOBAL_ALIGN + ' || 1);\n');
435+
print('gb = alignMemory(getMemory({{{ STATIC_BUMP }}} + ' + MAX_GLOBAL_ALIGN + '), ' + MAX_GLOBAL_ALIGN + ' || 1);\n');
436436
// The static area consists of explicitly initialized data, followed by zero-initialized data.
437437
// The latter may need zeroing out if the MAIN_MODULE has already used this memory area before
438438
// dlopen'ing the SIDE_MODULE. Since we don't know the size of the explicitly initialized data

src/shell_sharedlib.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
assert(STACKTOP % 8 == 0);
1515
var STACK_MAX = STACKTOP + TOTAL_STACK;
1616
Module.cleanups.push(function() {
17-
parentModule['_free'](STACKTOP); // XXX ensure exported
17+
parentModule['_free'](STACKTOP); // XXX ensure exported, and that it was actually malloc'ed and not static memory FIXME
1818
parentModule['_free'](gb);
1919
});
2020

tests/test_core.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,6 +2774,89 @@ def test_dlfcn_varargs(self):
27742774
self.do_run(src, '100\n200\n13\n42\n',
27752775
post_build=self.dlfcn_post_build)
27762776

2777+
@no_wasm # wasm shared libraries are just .wasm files, and there is no way to describe alignment there yet
2778+
# see https://github.com/WebAssembly/tool-conventions/pull/51
2779+
def test_dlfcn_alignment_and_zeroing(self):
2780+
if not self.can_dlfcn(): return
2781+
2782+
self.prep_dlfcn_lib()
2783+
Settings.TOTAL_MEMORY = 16 * 1024 * 1024
2784+
lib_src = r'''
2785+
extern "C" {
2786+
int prezero = 0;
2787+
__attribute__((aligned(1024))) int superAligned = 12345;
2788+
int postzero = 0;
2789+
}
2790+
'''
2791+
dirname = self.get_dir()
2792+
filename = os.path.join(dirname, 'liblib.cpp')
2793+
self.build_dlfcn_lib(lib_src, dirname, filename)
2794+
for i in range(10):
2795+
curr = '%d.so' % i
2796+
shutil.copyfile('liblib.so', curr)
2797+
self.emcc_args += ['--embed-file', curr]
2798+
2799+
self.prep_dlfcn_main()
2800+
Settings.TOTAL_MEMORY = 128 * 1024 * 1024
2801+
src = r'''
2802+
#include <stdio.h>
2803+
#include <stdlib.h>
2804+
#include <string.h>
2805+
#include <dlfcn.h>
2806+
#include <assert.h>
2807+
#include <emscripten.h>
2808+
2809+
int main() {
2810+
printf("'prepare' memory with non-zero inited stuff\n");
2811+
int num = 120 * 1024 * 1024; // total is 128; we'll use 5*5 = 25 at least, so allocate pretty much all of it
2812+
void* mem = malloc(num);
2813+
assert(mem);
2814+
printf("setting this range to non-zero: %d - %d\n", int(mem), int(mem) + num);
2815+
memset(mem, 1, num);
2816+
EM_ASM({
2817+
var value = HEAP8[64*1024*1024];
2818+
Module.print('verify middle of memory is non-zero: ' + value);
2819+
assert(value === 1);
2820+
});
2821+
free(mem);
2822+
for (int i = 0; i < 10; i++) {
2823+
printf("loading %d\n", i);
2824+
char* curr = "?.so";
2825+
curr[0] = '0' + i;
2826+
void* lib_handle = dlopen(curr, RTLD_NOW);
2827+
if (!lib_handle) {
2828+
puts(dlerror());
2829+
assert(0);
2830+
}
2831+
printf("getting superAligned\n");
2832+
int* superAligned = (int*)dlsym(lib_handle, "superAligned");
2833+
assert(superAligned);
2834+
assert(int(superAligned) % 1024 == 0); // alignment
2835+
printf("checking value of superAligned, at %d\n", superAligned);
2836+
assert(*superAligned == 12345); // value
2837+
printf("getting prezero\n");
2838+
int* prezero = (int*)dlsym(lib_handle, "prezero");
2839+
assert(prezero);
2840+
printf("checking value of prezero, at %d\n", prezero);
2841+
assert(*prezero == 0);
2842+
*prezero = 1;
2843+
assert(*prezero != 0);
2844+
printf("getting postzero\n");
2845+
int* postzero = (int*)dlsym(lib_handle, "postzero");
2846+
printf("checking value of postzero, at %d\n", postzero);
2847+
assert(postzero);
2848+
printf("checking value of postzero\n");
2849+
assert(*postzero == 0);
2850+
*postzero = 1;
2851+
assert(*postzero != 0);
2852+
}
2853+
printf("success.\n");
2854+
return 0;
2855+
}
2856+
'''
2857+
self.do_run(src, 'success.\n',
2858+
post_build=self.dlfcn_post_build)
2859+
27772860
@no_wasm # TODO: this needs to add JS functions to a wasm Table, need to figure that out
27782861
def test_dlfcn_self(self):
27792862
if not self.can_dlfcn(): return

0 commit comments

Comments
 (0)