mirror of
https://github.com/fluencelabs/musl
synced 2025-06-13 23:11:51 +00:00
[WebAssembly] Fix shared library loading (#17)
Loading of shared libraries was broken back in:
39fde60
This change restores the ability for shared libraries to
be loaded such that they can share memory and provide
function exports to the main executable.
However the executable that libraries still need to built
in a specific way (i.e. all importing the same sized memory)
and their static globals need to be in the different address
range. This has the complication that the executables won't
run the wasm spec interpreter (since it doesn't pass in a
memory to the executables it runs). So although I'm fixing this
here in the musl repo I'm also proposiing that we remove the
continuous testing of this configurations on the wasm waterfall
in favor of concentrating on the statically linking lld case:
WebAssembly/waterfall#271
This commit is contained in:
@ -21,15 +21,17 @@
|
||||
* both as a hobbling libc and a linker/loader, including dynamic linking.
|
||||
*/
|
||||
|
||||
var heap_size_bytes;
|
||||
var heap;
|
||||
var heap_uint8;
|
||||
var heap_size_bytes = 16 * 1024 * 1024;
|
||||
var heap_size_pages = heap_size_bytes / (64 * 1024);
|
||||
var memory = new WebAssembly.Memory({initial: heap_size_pages, maximum: heap_size_pages})
|
||||
var heap = memory.buffer;
|
||||
var heap_uint8 = new Uint8Array(heap);
|
||||
|
||||
// Heap access helpers.
|
||||
function charFromHeap(ptr) { return String.fromCharCode(heap_uint8[ptr]); }
|
||||
function stringFromHeap(ptr) {
|
||||
var str = '';
|
||||
for (var i = ptr; heap_uint8[i] != 0; ++i)
|
||||
for (var i = ptr; i < heap_size_bytes && heap_uint8[i] != 0; ++i)
|
||||
str += charFromHeap(i);
|
||||
return str;
|
||||
}
|
||||
@ -522,9 +524,12 @@ var string = (function() {
|
||||
strchr: function(str, character) {
|
||||
character &= 0xff;
|
||||
var i = 0;
|
||||
for (; heap_uint8[str + i] != 0; ++i)
|
||||
for (; heap_uint8[str + i] != 0; ++i) {
|
||||
if (str + i >= heap_size_bytes)
|
||||
return 0;
|
||||
if (heap_uint8[str + i] == character)
|
||||
return str + i;
|
||||
}
|
||||
return character == 0 ? str + i : 0;
|
||||
},
|
||||
strcspn: NYI('strcspn'),
|
||||
@ -930,7 +935,7 @@ var syscall = (function() {
|
||||
|
||||
// Start with the stub implementations. Further module loads may shadow them.
|
||||
var ffi = (function() {
|
||||
var functions = {env:{}};
|
||||
var functions = {env:{memory: memory}};
|
||||
var libraries = [
|
||||
musl_hack, // Keep first, overriden later.
|
||||
builtins, ctype, math, runtime, stdio, stdlib, string, unix,
|
||||
@ -959,9 +964,14 @@ if (arguments[0] == '--dump-ffi-symbols') {
|
||||
? new Uint8Array(readbuffer(file_path))
|
||||
: read(file_path, 'binary');
|
||||
instance = new WebAssembly.Instance(new WebAssembly.Module(buf), ffi)
|
||||
// For the application exports its memory, we use that rather than
|
||||
// the one we created. In this way this code works with modules that
|
||||
// import or export their memory.
|
||||
if (instance.exports.memory) {
|
||||
heap = instance.exports.memory.buffer;
|
||||
heap_uint8 = new Uint8Array(heap);
|
||||
heap_size_bytes = heap.byteLength;
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -973,12 +983,13 @@ if (arguments[0] == '--dump-ffi-symbols') {
|
||||
for (var i = arguments.length - 1; i > 0; --i) {
|
||||
var path = arguments[i];
|
||||
modules[i] = load_wasm(path);
|
||||
for (var f in modules[i]) {
|
||||
for (var f in modules[i].exports) {
|
||||
// TODO wasm modules don't have hasOwnProperty. They probably should.
|
||||
// The code should look like:
|
||||
// if (modules[i].hasOwnProperty(f) &&
|
||||
// modules[i][f] instanceof Function)
|
||||
ffi[f] = modules[i][f];
|
||||
if (modules[i].exports[f] instanceof Function)
|
||||
ffi['env'][f] = modules[i].exports[f];
|
||||
}
|
||||
}
|
||||
|
||||
|
4
libc.py
4
libc.py
@ -171,6 +171,7 @@ class AsmCompiler(Compiler):
|
||||
return os.path.basename(src)[:-1] + 'll' # .c -> .ll
|
||||
|
||||
def binary(self):
|
||||
max_memory = str(16 * 1024 * 1024)
|
||||
bytecode = change_extension(self.out, '.bc')
|
||||
assembly = os.path.join(self.tmpdir, self.outbase + '.s')
|
||||
check_output([os.path.join(self.clang_dir, 'llvm-link'),
|
||||
@ -180,7 +181,8 @@ class AsmCompiler(Compiler):
|
||||
bytecode, '-o', assembly],
|
||||
cwd=self.tmpdir)
|
||||
check_output([os.path.join(self.binaryen_dir, 's2wasm'),
|
||||
assembly, '--ignore-unknown', '-o', self.out],
|
||||
assembly, '--ignore-unknown', '-o', self.out,
|
||||
'--import-memory', '-m', max_memory],
|
||||
cwd=self.tmpdir)
|
||||
|
||||
if self.sexpr_wasm:
|
||||
|
Reference in New Issue
Block a user