summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/test/generate_lld_tests.py68
-rwxr-xr-xscripts/test/lld.py15
-rw-r--r--src/shared-constants.h1
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp25
-rw-r--r--src/wasm-emscripten.h2
-rw-r--r--src/wasm/wasm-emscripten.cpp149
-rw-r--r--src/wasm/wasm.cpp1
-rw-r--r--test/lld/duplicate_imports.wast.out8
-rw-r--r--test/lld/em_asm.wast.mem.out8
-rw-r--r--test/lld/em_asm.wast.out8
-rw-r--r--test/lld/em_asm_O0.wast.out8
-rw-r--r--test/lld/hello_world.wast.mem.out8
-rw-r--r--test/lld/hello_world.wast.out8
-rw-r--r--test/lld/init.wast.out8
-rw-r--r--test/lld/recursive.wast.out8
-rw-r--r--test/lld/reserved_func_ptr.wast.out8
-rw-r--r--test/lld/shared.c7
-rw-r--r--test/lld/shared.wast34
-rw-r--r--test/lld/shared.wast.out75
19 files changed, 346 insertions, 103 deletions
diff --git a/scripts/test/generate_lld_tests.py b/scripts/test/generate_lld_tests.py
index f3905b077..31634e7b0 100755
--- a/scripts/test/generate_lld_tests.py
+++ b/scripts/test/generate_lld_tests.py
@@ -22,7 +22,7 @@ import shared
def files_with_extensions(path, extensions):
for file in sorted(os.listdir(path)):
- _, ext = os.path.splitext(file)
+ ext = os.path.splitext(file)[1]
if ext in extensions:
yield file, ext
@@ -33,37 +33,47 @@ def generate_wast_files(llvm_bin, emscripten_root):
lld_path = os.path.join(shared.options.binaryen_test, 'lld')
for src_file, ext in files_with_extensions(lld_path, ['.c', '.cpp']):
print '..', src_file
- try:
- obj_file = src_file.replace(ext, '.o')
+ obj_file = src_file.replace(ext, '.o')
+
+ src_path = os.path.join(lld_path, src_file)
+ obj_path = os.path.join(lld_path, obj_file)
+
+ wasm_file = src_file.replace(ext, '.wasm')
+ wast_file = src_file.replace(ext, '.wast')
- src_path = os.path.join(lld_path, src_file)
- obj_path = os.path.join(lld_path, obj_file)
- run_command([
- os.path.join(llvm_bin, 'clang'), src_path, '-o', obj_path,
- '--target=wasm32-unknown-unknown-wasm',
- '-c',
- '-nostdinc',
- '-Xclang', '-nobuiltininc',
- '-Xclang', '-nostdsysteminc',
- '-Xclang', '-I%s/system/include' % emscripten_root,
- '-O1',
- ])
+ obj_path = os.path.join(lld_path, obj_file)
+ wasm_path = os.path.join(lld_path, wasm_file)
+ wast_path = os.path.join(lld_path, wast_file)
+ is_shared = 'shared' in src_file
- wasm_file = src_file.replace(ext, '.wasm')
- wast_file = src_file.replace(ext, '.wast')
+ compile_cmd = [
+ os.path.join(llvm_bin, 'clang'), src_path, '-o', obj_path,
+ '--target=wasm32-unknown-unknown-wasm',
+ '-c',
+ '-nostdinc',
+ '-Xclang', '-nobuiltininc',
+ '-Xclang', '-nostdsysteminc',
+ '-Xclang', '-I%s/system/include' % emscripten_root,
+ '-O1',
+ ]
- obj_path = os.path.join(lld_path, obj_file)
- wasm_path = os.path.join(lld_path, wasm_file)
- wast_path = os.path.join(lld_path, wast_file)
- run_command([
- os.path.join(llvm_bin, 'wasm-ld'),
- '-z', '-stack-size=1048576',
- obj_path, '-o', wasm_path,
- '--entry=main',
- '--allow-undefined',
- '--export', '__wasm_call_ctors',
- '--global-base=568',
- ])
+ link_cmd = [
+ os.path.join(llvm_bin, 'wasm-ld'), '-flavor', 'wasm',
+ '-z', '-stack-size=1048576',
+ obj_path, '-o', wasm_path,
+ '--entry=main',
+ '--allow-undefined',
+ '--export', '__wasm_call_ctors',
+ '--global-base=568',
+ ]
+ if is_shared:
+ compile_cmd.append('-fPIC')
+ compile_cmd.append('-fvisibility=default')
+ link_cmd.append('-shared')
+
+ try:
+ run_command(compile_cmd)
+ run_command(link_cmd)
run_command(shared.WASM_DIS + [wasm_path, '-o', wast_path])
finally:
# Don't need the .o or .wasm files, don't leave them around
diff --git a/scripts/test/lld.py b/scripts/test/lld.py
index a96062331..fae551f0d 100755
--- a/scripts/test/lld.py
+++ b/scripts/test/lld.py
@@ -21,6 +21,13 @@ from shared import (
)
+def args_for_finalize(filename):
+ if 'shared' in filename:
+ return ['--side-module']
+ else:
+ return ['--global-base=568', '--initial-stack-pointer=16384']
+
+
def test_wasm_emscripten_finalize():
print '\n[ checking wasm-emscripten-finalize testcases... ]\n'
@@ -36,8 +43,8 @@ def test_wasm_emscripten_finalize():
if ext != '.out' and not os.path.exists(expected_file):
continue
- cmd = (WASM_EMSCRIPTEN_FINALIZE +
- [wast_path, '-S', '--global-base=568', '--initial-stack-pointer=16384'] + ext_args)
+ cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
+ cmd += args_for_finalize(os.path.basename(wast_path))
actual = run_command(cmd)
if not os.path.exists(expected_file):
@@ -65,8 +72,8 @@ def update_lld_tests():
out_path = wast_path + ext
if ext != '.out' and not os.path.exists(out_path):
continue
- cmd = (WASM_EMSCRIPTEN_FINALIZE +
- [wast_path, '-S', '--global-base=568', '--initial-stack-pointer=16384'] + ext_args)
+ cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
+ cmd += args_for_finalize(os.path.basename(wast_path))
actual = run_command(cmd)
with open(out_path, 'w') as o:
o.write(actual)
diff --git a/src/shared-constants.h b/src/shared-constants.h
index ae7d915ef..52124d891 100644
--- a/src/shared-constants.h
+++ b/src/shared-constants.h
@@ -22,6 +22,7 @@
namespace wasm {
extern Name GROW_WASM_MEMORY,
+ WASM_CALL_CTORS,
MEMORY_BASE,
TABLE_BASE,
GET_TEMP_RET0,
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index 2aa5de46f..180383a90 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -46,6 +46,7 @@ int main(int argc, const char *argv[]) {
std::string dataSegmentFile;
bool emitBinary = true;
bool debugInfo = false;
+ bool isSideModule = false;
bool legalizeJavaScriptFFI = true;
uint64_t globalBase = INVALID_BASE;
uint64_t initialStackPointer = INVALID_BASE;
@@ -79,7 +80,11 @@ int main(int argc, const char *argv[]) {
[&initialStackPointer](Options*, const std::string&argument ) {
initialStackPointer = std::stoull(argument);
})
-
+ .add("--side-module", "", "Input is an emscripten side module",
+ Options::Arguments::Zero,
+ [&isSideModule](Options *o, const std::string& argument) {
+ isSideModule = true;
+ })
.add("--input-source-map", "-ism", "Consume source map from the specified file",
Options::Arguments::One,
[&inputSourceMapFilename](Options *o, const std::string& argument) { inputSourceMapFilename = argument; })
@@ -130,7 +135,6 @@ int main(int argc, const char *argv[]) {
WasmPrinter::printModule(&wasm, std::cerr);
}
- bool isSideModule = false;
for (const UserSection& section : wasm.userSections) {
if (section.name == BinaryConsts::UserSections::Dylink) {
isSideModule = true;
@@ -166,12 +170,6 @@ int main(int argc, const char *argv[]) {
std::vector<Name> initializerFunctions;
- // The names of standard imports/exports used by lld doesn't quite match that
- // expected by emscripten.
- // TODO(sbc): Unify these
- if (Export* ex = wasm.getExportOrNull("__wasm_call_ctors")) {
- ex->name = "__post_instantiate";
- }
if (wasm.table.imported()) {
if (wasm.table.base != "table") wasm.table.base = Name("table");
}
@@ -182,14 +180,17 @@ int main(int argc, const char *argv[]) {
if (isSideModule) {
generator.replaceStackPointerGlobal();
+ generator.generatePostInstantiateFunction();
} else {
generator.generateRuntimeFunctions();
generator.generateMemoryGrowthFunction();
generator.generateStackInitialization(initialStackPointer);
- // emscripten calls this by default for side libraries so we only need
- // to include in as a static ctor for main module case.
- if (wasm.getExportOrNull("__post_instantiate")) {
- initializerFunctions.push_back("__post_instantiate");
+ // For side modules these gets called via __post_instantiate
+ if (Function* F = generator.generateAssignGOTEntriesFunction()) {
+ initializerFunctions.push_back(F->name);
+ }
+ if (auto* e = wasm.getExportOrNull(WASM_CALL_CTORS)) {
+ initializerFunctions.push_back(e->value);
}
}
diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h
index acb2994ad..67ba408f5 100644
--- a/src/wasm-emscripten.h
+++ b/src/wasm-emscripten.h
@@ -36,7 +36,9 @@ public:
void generateRuntimeFunctions();
Function* generateMemoryGrowthFunction();
+ Function* generateAssignGOTEntriesFunction();
void generateStackInitialization(Address addr);
+ void generatePostInstantiateFunction();
// Create thunks for use with emscripten Runtime.dynCall. Creates one for each
// signature in the indirect function table.
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index ea24b945d..404d93ca3 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -36,7 +36,9 @@ cashew::IString EM_JS_PREFIX("__em_js__");
static Name STACK_SAVE("stackSave"),
STACK_RESTORE("stackRestore"),
STACK_ALLOC("stackAlloc"),
- STACK_INIT("stack$init");
+ STACK_INIT("stack$init"),
+ POST_INSTANTIATE("__post_instantiate"),
+ ASSIGN_GOT_ENTIRES("__assign_got_enties");
void addExportedFunction(Module& wasm, Function* function) {
wasm.addFunction(function);
@@ -47,15 +49,20 @@ void addExportedFunction(Module& wasm, Function* function) {
}
Global* EmscriptenGlueGenerator::getStackPointerGlobal() {
- // Assumption: The first non-imported global is global is __stack_pointer
+ // Assumption: The stack pointer is either imported as __stack_pointer or
+ // its the first non-imported global.
// TODO(sbc): Find a better way to discover the stack pointer. Perhaps the
// linker could export it by name?
for (auto& g : wasm.globals) {
- if (!g->imported()) {
+ if (g->imported()) {
+ if (g->base == "__stack_pointer") {
+ return g.get();
+ }
+ } else {
return g.get();
}
}
- Fatal() << "stack pointer global not found";
+ return nullptr;
}
Expression* EmscriptenGlueGenerator::generateLoadStackPointer() {
@@ -70,6 +77,8 @@ Expression* EmscriptenGlueGenerator::generateLoadStackPointer() {
);
}
Global* stackPointer = getStackPointerGlobal();
+ if (!stackPointer)
+ Fatal() << "stack pointer global not found";
return builder.makeGetGlobal(stackPointer->name, i32);
}
@@ -85,6 +94,8 @@ Expression* EmscriptenGlueGenerator::generateStoreStackPointer(Expression* value
);
}
Global* stackPointer = getStackPointerGlobal();
+ if (!stackPointer)
+ Fatal() << "stack pointer global not found";
return builder.makeSetGlobal(stackPointer->name, value);
}
@@ -143,6 +154,116 @@ void EmscriptenGlueGenerator::generateRuntimeFunctions() {
generateStackRestoreFunction();
}
+static Function* ensureFunctionImport(Module* module, Name name, std::string sig) {
+ // Then see if its already imported
+ ImportInfo info(*module);
+ if (Function* f = info.getImportedFunction(ENV, name)) {
+ return f;
+ }
+ // Failing that create a new function import.
+ auto import = new Function;
+ import->name = name;
+ import->module = ENV;
+ import->base = name;
+ auto* functionType = ensureFunctionType(sig, module);
+ import->type = functionType->name;
+ FunctionTypeUtils::fillFunction(import, functionType);
+ module->addFunction(import);
+ return import;
+}
+
+Function* EmscriptenGlueGenerator::generateAssignGOTEntriesFunction() {
+ std::vector<Global*> got_entries_func;
+ std::vector<Global*> got_entries_mem;
+ for (auto& g : wasm.globals) {
+ if (!g->imported()) {
+ continue;
+ }
+ if (g->module == "GOT.func") {
+ got_entries_func.push_back(g.get());
+ } else if (g->module == "GOT.mem") {
+ got_entries_mem.push_back(g.get());
+ } else {
+ continue;
+ }
+ // Make this an internal, non-imported, global.
+ g->module.clear();
+ g->init = Builder(wasm).makeConst(Literal(0));
+ }
+
+ if (!got_entries_func.size() && !got_entries_mem.size()) {
+ return nullptr;
+ }
+
+ Function* assign_func =
+ builder.makeFunction(ASSIGN_GOT_ENTIRES, std::vector<NameType>{}, none, {});
+ Block* block = builder.makeBlock();
+ assign_func->body = block;
+
+ for (Global* g : got_entries_mem) {
+ Name getter(std::string("g$") + g->base.c_str());
+ ensureFunctionImport(&wasm, getter, "i");
+ Expression* call = builder.makeCall(getter, {}, i32);
+ SetGlobal* set_global = builder.makeSetGlobal(g->name, call);
+ block->list.push_back(set_global);
+ }
+
+ for (Global* g : got_entries_func) {
+ Name getter(std::string("f$") + g->base.c_str());
+ if (auto* f = wasm.getFunctionOrNull(g->base)) {
+ getter.set((getter.c_str() + std::string("$") + getSig(f)).c_str(), false);
+ }
+ ensureFunctionImport(&wasm, getter, "i");
+ Expression* call = builder.makeCall(getter, {}, i32);
+ SetGlobal* set_global = builder.makeSetGlobal(g->name, call);
+ block->list.push_back(set_global);
+ }
+
+ wasm.addFunction(assign_func);
+ return assign_func;
+}
+
+// For emscripten SIDE_MODULE we generate a single exported function called
+// __post_instantiate which calls two functions:
+//
+// - __assign_got_enties
+// - __wasm_call_ctors
+//
+// The former is function we generate here which calls imported g$XXX functions
+// order to assign values to any globals imported from GOT.func or GOT.mem.
+// These globals hold address of functions and globals respectively.
+//
+// The later is the constructor function generaed by lld which performs any
+// fixups on the memory section and calls static constructors.
+void EmscriptenGlueGenerator::generatePostInstantiateFunction() {
+ Builder builder(wasm);
+ Function* post_instantiate =
+ builder.makeFunction(POST_INSTANTIATE, std::vector<NameType>{}, none, {});
+ wasm.addFunction(post_instantiate);
+
+ if (Function* F = generateAssignGOTEntriesFunction()) {
+ // call __assign_got_enties from post_instantiate
+ Expression* call = builder.makeCall(F->name, {}, none);
+ post_instantiate->body = builder.blockify(call);
+ }
+
+ // The names of standard imports/exports used by lld doesn't quite match that
+ // expected by emscripten.
+ // TODO(sbc): Unify these
+ if (auto* e = wasm.getExportOrNull(WASM_CALL_CTORS)) {
+ Expression* call = builder.makeCall(e->value, {}, none);
+ post_instantiate->body = builder.blockify(post_instantiate->body, call);
+ wasm.removeExport(WASM_CALL_CTORS);
+ }
+
+ auto* ex = new Export();
+ ex->value = post_instantiate->name;
+ ex->name = POST_INSTANTIATE;
+ ex->kind = ExternalKind::Function;
+ wasm.addExport(ex);
+ wasm.updateMaps();
+}
+
Function* EmscriptenGlueGenerator::generateMemoryGrowthFunction() {
Name name(GROW_WASM_MEMORY);
std::vector<NameType> params { { NEW_SIZE, i32 } };
@@ -215,24 +336,6 @@ void EmscriptenGlueGenerator::generateDynCallThunks() {
}
}
-static Function* ensureFunctionImport(Module* module, Name name, std::string sig) {
- // Then see if its already imported
- ImportInfo info(*module);
- if (Function* f = info.getImportedFunction(ENV, name)) {
- return f;
- }
- // Failing that create a new function import.
- auto import = new Function;
- import->name = name;
- import->module = ENV;
- import->base = name;
- auto* functionType = ensureFunctionType(sig, module);
- import->type = functionType->name;
- FunctionTypeUtils::fillFunction(import, functionType);
- module->addFunction(import);
- return import;
-}
-
struct RemoveStackPointer : public PostWalker<RemoveStackPointer> {
RemoveStackPointer(Global* stackPointer) : stackPointer(stackPointer) {}
@@ -262,6 +365,8 @@ private:
void EmscriptenGlueGenerator::replaceStackPointerGlobal() {
Global* stackPointer = getStackPointerGlobal();
+ if (!stackPointer)
+ return;
// Replace all uses of stack pointer global
RemoveStackPointer walker(stackPointer);
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index e135ba750..f7081e49c 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -37,6 +37,7 @@ const char* TargetFeatures = "target_features";
}
Name GROW_WASM_MEMORY("__growWasmMemory"),
+ WASM_CALL_CTORS("__wasm_call_ctors"),
MEMORY_BASE("__memory_base"),
TABLE_BASE("__table_base"),
GET_TEMP_RET0("getTempRet0"),
diff --git a/test/lld/duplicate_imports.wast.out b/test/lld/duplicate_imports.wast.out
index 3a9fa2474..f01f8bb96 100644
--- a/test/lld/duplicate_imports.wast.out
+++ b/test/lld/duplicate_imports.wast.out
@@ -20,7 +20,7 @@
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 581))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "main" (func $main))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
@@ -107,7 +107,7 @@
"staticBump": 13,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
"puts"
@@ -115,7 +115,7 @@
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -124,7 +124,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"main",
"__heap_base",
"__data_end",
diff --git a/test/lld/em_asm.wast.mem.out b/test/lld/em_asm.wast.mem.out
index c1cd18ae5..08bca193e 100644
--- a/test/lld/em_asm.wast.mem.out
+++ b/test/lld/em_asm.wast.mem.out
@@ -14,7 +14,7 @@
(global $global$1 i32 (i32.const 66192))
(global $global$2 i32 (i32.const 652))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -233,14 +233,14 @@
"staticBump": 84,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
],
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -249,7 +249,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/em_asm.wast.out b/test/lld/em_asm.wast.out
index b9e95d3ec..50d4628c9 100644
--- a/test/lld/em_asm.wast.out
+++ b/test/lld/em_asm.wast.out
@@ -15,7 +15,7 @@
(global $global$1 i32 (i32.const 66192))
(global $global$2 i32 (i32.const 652))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -234,14 +234,14 @@
"staticBump": 84,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
],
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -250,7 +250,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/em_asm_O0.wast.out b/test/lld/em_asm_O0.wast.out
index cbc93c5cb..c45799980 100644
--- a/test/lld/em_asm_O0.wast.out
+++ b/test/lld/em_asm_O0.wast.out
@@ -17,7 +17,7 @@
(global $global$1 i32 (i32.const 66192))
(global $global$2 i32 (i32.const 652))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "main" (func $main))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
@@ -94,14 +94,14 @@
"staticBump": 84,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
],
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -110,7 +110,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"main",
"__heap_base",
"__data_end",
diff --git a/test/lld/hello_world.wast.mem.out b/test/lld/hello_world.wast.mem.out
index dce3de59c..32f8ddc14 100644
--- a/test/lld/hello_world.wast.mem.out
+++ b/test/lld/hello_world.wast.mem.out
@@ -11,7 +11,7 @@
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 581))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -68,7 +68,7 @@
"staticBump": 13,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
"puts"
@@ -76,7 +76,7 @@
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -85,7 +85,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/hello_world.wast.out b/test/lld/hello_world.wast.out
index a06e7b287..20ffaf2cd 100644
--- a/test/lld/hello_world.wast.out
+++ b/test/lld/hello_world.wast.out
@@ -12,7 +12,7 @@
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 581))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -69,7 +69,7 @@
"staticBump": 13,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
"puts"
@@ -77,7 +77,7 @@
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -86,7 +86,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/init.wast.out b/test/lld/init.wast.out
index 35fda658b..90c95263b 100644
--- a/test/lld/init.wast.out
+++ b/test/lld/init.wast.out
@@ -9,7 +9,7 @@
(global $global$1 i32 (i32.const 66112))
(global $global$2 i32 (i32.const 576))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -81,14 +81,14 @@
"staticBump": 8,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
],
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -97,7 +97,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/recursive.wast.out b/test/lld/recursive.wast.out
index fcb6c1333..95f82f767 100644
--- a/test/lld/recursive.wast.out
+++ b/test/lld/recursive.wast.out
@@ -11,7 +11,7 @@
(global $global$1 i32 (i32.const 66128))
(global $global$2 i32 (i32.const 587))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -126,7 +126,7 @@
"staticBump": 19,
"tableSize": 1,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
"printf"
@@ -134,7 +134,7 @@
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -143,7 +143,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/reserved_func_ptr.wast.out b/test/lld/reserved_func_ptr.wast.out
index 5c8333d09..6afc10291 100644
--- a/test/lld/reserved_func_ptr.wast.out
+++ b/test/lld/reserved_func_ptr.wast.out
@@ -16,7 +16,7 @@
(global $global$1 i32 (i32.const 66112))
(global $global$2 i32 (i32.const 568))
(export "memory" (memory $0))
- (export "__post_instantiate" (func $__wasm_call_ctors))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global $global$1))
(export "__data_end" (global $global$2))
(export "main" (func $main))
@@ -161,7 +161,7 @@
"staticBump": 0,
"tableSize": 3,
"initializers": [
- "__post_instantiate"
+ "__wasm_call_ctors"
],
"declares": [
"_Z4atoiPKc"
@@ -169,7 +169,7 @@
"externs": [
],
"implementedFunctions": [
- "___post_instantiate",
+ "___wasm_call_ctors",
"_main",
"_stackSave",
"_stackAlloc",
@@ -179,7 +179,7 @@
],
"exports": [
"memory",
- "__post_instantiate",
+ "__wasm_call_ctors",
"__heap_base",
"__data_end",
"main",
diff --git a/test/lld/shared.c b/test/lld/shared.c
new file mode 100644
index 000000000..1d98b068b
--- /dev/null
+++ b/test/lld/shared.c
@@ -0,0 +1,7 @@
+int puts(const char* str);
+extern int external_var;
+
+int print_message() {
+ puts("Hello, world");
+ return external_var;
+}
diff --git a/test/lld/shared.wast b/test/lld/shared.wast
new file mode 100644
index 000000000..f8b0a746c
--- /dev/null
+++ b/test/lld/shared.wast
@@ -0,0 +1,34 @@
+(module
+ (type $0 (func (param i32) (result i32)))
+ (type $1 (func))
+ (type $2 (func (result i32)))
+ (import "env" "memory" (memory $0 0))
+ (data (global.get $gimport$2) "Hello, world\00")
+ (import "env" "__indirect_function_table" (table $timport$1 0 funcref))
+ (import "env" "__memory_base" (global $gimport$2 i32))
+ (import "env" "__table_base" (global $gimport$3 i32))
+ (import "GOT.func" "puts" (global $gimport$5 (mut i32)))
+ (import "GOT.mem" "external_var" (global $gimport$6 (mut i32)))
+ (import "env" "puts" (func $puts (param i32) (result i32)))
+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))
+ (export "print_message" (func $print_message))
+ (func $__wasm_call_ctors (; 1 ;) (type $1)
+ )
+ (func $print_message (; 2 ;) (type $2) (result i32)
+ (drop
+ (i32.add
+ (global.get $gimport$2)
+ (i32.const 0)
+ )
+ )
+ (drop
+ (call $print_message)
+ )
+ (i32.load
+ (global.get $gimport$6)
+ )
+ )
+ ;; custom section "dylink", size 5
+ ;; custom section "producers", size 125
+)
+
diff --git a/test/lld/shared.wast.out b/test/lld/shared.wast.out
new file mode 100644
index 000000000..c4f110972
--- /dev/null
+++ b/test/lld/shared.wast.out
@@ -0,0 +1,75 @@
+(module
+ (type $0 (func (param i32) (result i32)))
+ (type $1 (func))
+ (type $2 (func (result i32)))
+ (type $FUNCSIG$ii (func (param i32) (result i32)))
+ (type $FUNCSIG$i (func (result i32)))
+ (import "env" "memory" (memory $0 0))
+ (data (global.get $gimport$2) "Hello, world\00")
+ (import "env" "table" (table $0 0 funcref))
+ (import "env" "__memory_base" (global $gimport$2 i32))
+ (import "env" "__table_base" (global $gimport$3 i32))
+ (import "env" "puts" (func $puts (param i32) (result i32)))
+ (import "env" "g$external_var" (func $g$external_var (result i32)))
+ (import "env" "f$puts$ii" (func $f$puts$ii (result i32)))
+ (global $gimport$5 (mut i32) (i32.const 0))
+ (global $gimport$6 (mut i32) (i32.const 0))
+ (export "print_message" (func $print_message))
+ (export "__post_instantiate" (func $__post_instantiate))
+ (func $__wasm_call_ctors (; 3 ;) (type $1)
+ (nop)
+ )
+ (func $print_message (; 4 ;) (type $2) (result i32)
+ (drop
+ (i32.add
+ (global.get $gimport$2)
+ (i32.const 0)
+ )
+ )
+ (drop
+ (call $print_message)
+ )
+ (i32.load
+ (global.get $gimport$6)
+ )
+ )
+ (func $__post_instantiate (; 5 ;)
+ (call $__assign_got_enties)
+ (call $__wasm_call_ctors)
+ )
+ (func $__assign_got_enties (; 6 ;)
+ (global.set $gimport$6
+ (call $g$external_var)
+ )
+ (global.set $gimport$5
+ (call $f$puts$ii)
+ )
+ )
+)
+(;
+--BEGIN METADATA --
+{
+ "staticBump": 0,
+ "tableSize": 0,
+ "declares": [
+ "puts",
+ "g$external_var",
+ "f$puts$ii"
+ ],
+ "externs": [
+ "___memory_base",
+ "___table_base"
+ ],
+ "implementedFunctions": [
+ "_print_message",
+ "___post_instantiate"
+ ],
+ "exports": [
+ "print_message",
+ "__post_instantiate"
+ ],
+ "invokeFuncs": [
+ ]
+}
+-- END METADATA --
+;)