diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/EmscriptenPIC.cpp | 142 | ||||
-rw-r--r-- | src/passes/pass.cpp | 6 | ||||
-rw-r--r-- | src/passes/passes.h | 2 | ||||
-rw-r--r-- | src/shared-constants.h | 1 | ||||
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 30 | ||||
-rw-r--r-- | src/wasm-emscripten.h | 3 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 42 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 1 |
9 files changed, 6 insertions, 222 deletions
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 00cbaa526..a2cb9a50c 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -25,7 +25,6 @@ set(passes_SOURCES DuplicateImportElimination.cpp DuplicateFunctionElimination.cpp DWARF.cpp - EmscriptenPIC.cpp ExtractFunction.cpp Flatten.cpp FuncCastEmulation.cpp diff --git a/src/passes/EmscriptenPIC.cpp b/src/passes/EmscriptenPIC.cpp deleted file mode 100644 index 51f7ead6e..000000000 --- a/src/passes/EmscriptenPIC.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2020 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// Convert LLVM PIC ABI to emscripten ABI -// -// When generating -fPIC code llvm will generate imports call GOT.mem and -// GOT.func in order to access the addresses of external global data and -// functions. -// -// However emscripten uses a different ABI where function and data addresses -// are available at runtime via special `g$foo` and `fp$bar` function calls. -// -// Here we internalize all such wasm globals and generte code that sets their -// value based on the result of call `g$foo` and `fp$bar` functions at runtime. -// -// A function called `__assign_got_enties` is generated by this pass that -// performs all the assignments. -// - -#include "abi/js.h" -#include "asm_v_wasm.h" -#include "ir/import-utils.h" -#include "ir/table-utils.h" -#include "pass.h" -#include "shared-constants.h" -#include "support/debug.h" - -#define DEBUG_TYPE "emscripten-pic" - -namespace wasm { - -static Function* -ensureFunctionImport(Module* module, Name name, Signature sig) { - // See if its already imported. - // FIXME: O(N) - ImportInfo info(*module); - if (auto* f = info.getImportedFunction(ENV, name)) { - return f; - } - // Failing that create a new import. - auto import = new Function; - import->name = name; - import->module = ENV; - import->base = name; - import->sig = sig; - module->addFunction(import); - return import; -} - -struct EmscriptenPIC : public WalkerPass<PostWalker<EmscriptenPIC>> { - - EmscriptenPIC(bool sideModule) : sideModule(sideModule) {} - - void visitGlobal(Global* curr) { - if (!curr->imported()) { - return; - } - if (curr->module == "GOT.func") { - gotFuncEntries.push_back(curr); - } else if (curr->module == "GOT.mem") { - gotMemEntries.push_back(curr); - } else { - return; - } - // Make this an internal, non-imported, global. - curr->module.clear(); - curr->init = Builder(*getModule()).makeConst(int32_t(0)); - } - - void visitModule(Module* module) { - BYN_TRACE("generateAssignGOTEntriesFunction\n"); - if (!gotFuncEntries.size() && !gotMemEntries.size()) { - return; - } - - Builder builder(*getModule()); - Function* assignFunc = builder.makeFunction( - ASSIGN_GOT_ENTRIES, std::vector<NameType>{}, Type::none, {}); - Block* block = builder.makeBlock(); - assignFunc->body = block; - - for (Global* g : gotMemEntries) { - auto base = g->base; - Name getter(std::string("g$") + base.c_str()); - ensureFunctionImport(module, getter, Signature(Type::none, Type::i32)); - Expression* call = builder.makeCall(getter, {}, Type::i32); - GlobalSet* globalSet = builder.makeGlobalSet(g->name, call); - block->list.push_back(globalSet); - } - - ImportInfo importInfo(*module); - - for (Global* g : gotFuncEntries) { - // The function has to exist either as export or an import. - // Note that we don't search for the function by name since its internal - // name may be different. - auto* ex = module->getExportOrNull(g->base); - // This is imported create an fp$ import to get the function table index - // from the dynamic loader. - auto* f = importInfo.getImportedFunction(ENV, g->base); - if (!f) { - if (!module->getExportOrNull(g->base)) { - Fatal() << "GOT.func entry with no import/export: " << g->base; - } - f = module->getFunction(ex->value); - } - Name getter( - (std::string("fp$") + g->base.c_str() + std::string("$") + getSig(f)) - .c_str()); - ensureFunctionImport(module, getter, Signature(Type::none, Type::i32)); - auto* call = builder.makeCall(getter, {}, Type::i32); - auto* globalSet = builder.makeGlobalSet(g->name, call); - block->list.push_back(globalSet); - } - - module->addFunction(assignFunc); - } - - std::vector<Global*> gotFuncEntries; - std::vector<Global*> gotMemEntries; - bool sideModule; -}; - -Pass* createEmscriptenPICPass() { return new EmscriptenPIC(true); } - -Pass* createEmscriptenPICMainModulePass() { return new EmscriptenPIC(false); } - -} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 3e9429695..e6b537813 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -126,12 +126,6 @@ void PassRegistry::registerPasses() { registerPass("emit-target-features", "emit the target features section in the output", createEmitTargetFeaturesPass); - registerPass("emscripten-pic", - "Convert PIC ABI from llvm to emscripten", - createEmscriptenPICPass); - registerPass("emscripten-pic-main-module", - "Convert PIC ABI from llvm to emscripten", - createEmscriptenPICMainModulePass); registerPass("extract-function", "leaves just one function (useful for debugging)", createExtractFunctionPass); diff --git a/src/passes/passes.h b/src/passes/passes.h index e88dc835d..bc93cee05 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -41,8 +41,6 @@ Pass* createDWARFDumpPass(); Pass* createDuplicateImportEliminationPass(); Pass* createDuplicateFunctionEliminationPass(); Pass* createEmitTargetFeaturesPass(); -Pass* createEmscriptenPICPass(); -Pass* createEmscriptenPICMainModulePass(); Pass* createExtractFunctionPass(); Pass* createFlattenPass(); Pass* createFuncCastEmulationPass(); diff --git a/src/shared-constants.h b/src/shared-constants.h index b0fd7d625..797f60227 100644 --- a/src/shared-constants.h +++ b/src/shared-constants.h @@ -64,7 +64,6 @@ extern Name EXIT; extern Name SHARED; extern Name EVENT; extern Name ATTR; -extern Name ASSIGN_GOT_ENTRIES; } // namespace wasm diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp index ecf10119d..d76bd4fc9 100644 --- a/src/tools/wasm-emscripten-finalize.cpp +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -51,7 +51,6 @@ int main(int argc, const char* argv[]) { bool debugInfo = false; bool DWARF = false; bool sideModule = false; - bool legacyPIC = true; bool legalizeJavaScriptFFI = true; bool bigInt = false; bool checkStackOverflow = false; @@ -114,9 +113,7 @@ int main(int argc, const char* argv[]) { "", "Use new/llvm PIC abi", Options::Arguments::Zero, - [&legacyPIC](Options* o, const std::string& argument) { - legacyPIC = false; - }) + [&](Options* o, const std::string& argument) {}) .add("--input-source-map", "-ism", "Consume source map from the specified file", @@ -281,14 +278,6 @@ int main(int argc, const char* argv[]) { passRunner.add("stack-check"); } - if (legacyPIC) { - if (sideModule) { - passRunner.add("emscripten-pic"); - } else { - passRunner.add("emscripten-pic-main-module"); - } - } - if (!noDynCalls && !standaloneWasm) { // If not standalone wasm then JS is relevant and we need dynCalls. if (onlyI64DynCalls) { @@ -318,20 +307,13 @@ int main(int argc, const char* argv[]) { if (sideModule) { BYN_TRACE("finalizing as side module\n"); - generator.generatePostInstantiateFunction(); + // The emscripten PIC ABI still expects a function named + // __post_instantiate to be exported by side module. + if (auto* e = wasm.getExportOrNull(WASM_CALL_CTORS)) { + e->name = "__post_instantiate"; + } } else { BYN_TRACE("finalizing as regular module\n"); - if (legacyPIC) { - // For side modules these gets called via __post_instantiate - if (Function* F = wasm.getFunctionOrNull(ASSIGN_GOT_ENTRIES)) { - auto* ex = new Export(); - ex->value = F->name; - ex->name = F->name; - ex->kind = ExternalKind::Function; - wasm.addExport(ex); - initializerFunctions.push_back(F->name); - } - } // Costructors get called from crt1 in wasm standalone mode. // Unless there is no entry point. if (!standaloneWasm || !wasm.getExportOrNull("_start")) { diff --git a/src/wasm-emscripten.h b/src/wasm-emscripten.h index 8275f7bc8..d0e2d8cb3 100644 --- a/src/wasm-emscripten.h +++ b/src/wasm-emscripten.h @@ -33,9 +33,6 @@ public: : wasm(wasm), builder(wasm), stackPointerOffset(stackPointerOffset), useStackPointerGlobal(stackPointerOffset == 0) {} - Function* generateAssignGOTEntriesFunction(); - void generatePostInstantiateFunction(); - std::string generateEmscriptenMetadata(Address staticBump, std::vector<Name> const& initializerFunctions); diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 7f7b227cf..a1a53af7e 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -38,7 +38,6 @@ cashew::IString EM_ASM_PREFIX("emscripten_asm_const"); cashew::IString EM_JS_PREFIX("__em_js__"); static Name STACK_INIT("stack$init"); -static Name POST_INSTANTIATE("__post_instantiate"); void addExportedFunction(Module& wasm, Function* function) { wasm.addFunction(function); @@ -75,47 +74,6 @@ Global* getStackPointerGlobal(Module& wasm) { return nullptr; } -// 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() { - BYN_TRACE("generatePostInstantiateFunction\n"); - Builder builder(wasm); - Function* post_instantiate = builder.makeFunction( - POST_INSTANTIATE, std::vector<NameType>{}, Type::none, {}); - wasm.addFunction(post_instantiate); - - if (Function* F = wasm.getFunctionOrNull(ASSIGN_GOT_ENTRIES)) { - // call __assign_got_enties from post_instantiate - Expression* call = builder.makeCall(F->name, {}, Type::none); - post_instantiate->body = builder.blockify(post_instantiate->body, 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, {}, Type::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); -} - const Address UNKNOWN_OFFSET(uint32_t(-1)); std::vector<Address> getSegmentOffsets(Module& wasm) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 3db76d86e..215928793 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -92,7 +92,6 @@ Name EXIT("exit"); Name SHARED("shared"); Name EVENT("event"); Name ATTR("attr"); -Name ASSIGN_GOT_ENTRIES("__assign_got_enties"); // Expressions |