diff options
author | Sam Clegg <sbc@chromium.org> | 2020-10-29 11:44:20 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-29 11:44:20 -0700 |
commit | 76f5b362bfc2665196048f8d811f259614db0072 (patch) | |
tree | 79f25c01419f8dc613f8c9ca6ebcc75b1838238a /src/passes/EmscriptenPIC.cpp | |
parent | 8cd3ad23543b1e6d0c8e5f8a1563ca5f87960645 (diff) | |
download | binaryen-76f5b362bfc2665196048f8d811f259614db0072.tar.gz binaryen-76f5b362bfc2665196048f8d811f259614db0072.tar.bz2 binaryen-76f5b362bfc2665196048f8d811f259614db0072.zip |
Remove support for emscripten legacy PIC ABI (#3299)
Diffstat (limited to 'src/passes/EmscriptenPIC.cpp')
-rw-r--r-- | src/passes/EmscriptenPIC.cpp | 142 |
1 files changed, 0 insertions, 142 deletions
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 |