diff options
author | Jacob Gravelle <jgravelle@google.com> | 2018-01-22 12:50:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-22 12:50:36 -0800 |
commit | 02729a12e1735f629d3066b51c96a056f712b080 (patch) | |
tree | 353a495836776695d0f86f08b6292635c4dba101 /src/tools | |
parent | b01f2bb237e086fe4ae852c6004297fa8f8b39c2 (diff) | |
download | binaryen-02729a12e1735f629d3066b51c96a056f712b080.tar.gz binaryen-02729a12e1735f629d3066b51c96a056f712b080.tar.bz2 binaryen-02729a12e1735f629d3066b51c96a056f712b080.zip |
First pass at LLD support for Emscripten (#1346)
* Skeleton of a beginning of o2wasm, WIP and probably not going to be used
* Get building post-cherry-pick
* ast->ir, remove commented out code, include a debug module print because linking
* Read linking section, print emscripten metadata json
* WasmBinaryWriter emits user sections on Module
* Remove debugging prints, everything that isn't needed to build metadata
* Rename o2wasm to lld-metadata
* lld-metadata support for outputting to file
* Use tables index instead of function index for initializer functions
* Add lld-emscripten tool to add emscripten-runtime functions to wasm modules (built with lld)
* Handle EM_ASM in lld-emscripten
* Add a list of functions to forcibly export (for initializer functions)
* Disable incorrect initializer function reading
* Add error printing when parsing .o files in lld-metadata
* Remove ';; METADATA: ' prefix from lld-metadata, output is now standalone json
* Support em_asm consts that aren't at the start of a segment
* Initial test framework for lld-metadata tool
* Add em_asm test
* Add support for WASM_INIT_FUNCS in the linking section
* Remove reloc section parsing because it's unused
* lld-emscripten can read and write text
* Add test harness for lld-emscripten
* Export all functions for now
* Add missing lld test output
* Add support for reading object files differently
Only difference so far is in importing mutable globals being an object
file representation for symbols, but invalid wasm.
* Update help strings
* Update linking tests for stackAlloc fix
* Rename lld-emscripten,lld-metadata to wasm-emscripten-finalize,wasm-link-metadata
* Add help text to header comments
* auto& instead of auto &
* Extract LinkType to abi/wasm-object.h
* Remove special handling for wasm object file reading, allow mutable globals
* Add braces around default switch case
* Fix flake8 errors
* Handle generating dyncall thunks for imports as well
* Use explicit bool for stackPointerGlobal
* Use glob patterns for lld file iteration
* Use __wasm_call_ctors for all initializer functions
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/s2wasm.cpp | 2 | ||||
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 103 | ||||
-rw-r--r-- | src/tools/wasm-link-metadata.cpp | 118 |
3 files changed, 222 insertions, 1 deletions
diff --git a/src/tools/s2wasm.cpp b/src/tools/s2wasm.cpp index 6e7b2c05e..32af57dba 100644 --- a/src/tools/s2wasm.cpp +++ b/src/tools/s2wasm.cpp @@ -184,7 +184,7 @@ int main(int argc, const char *argv[]) { std::cerr << "Emscripten gluing..." << std::endl; WasmPrinter::printModule(&wasm, std::cerr); } - metadata = emscriptenGlue( + metadata = ";; METADATA: " + emscriptenGlue( wasm, allowMemoryGrowth, linker.getStackPointerAddress(), diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp new file mode 100644 index 000000000..87505748c --- /dev/null +++ b/src/tools/wasm-emscripten-finalize.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2017 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. + */ + +// +// wasm-emscripten-finalize console tool +// Performs Emscripten-specific transforms on .wasm files +// + +#include <exception> + +#include "ir/trapping.h" +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" +#include "wasm-binary.h" +#include "wasm-emscripten.h" +#include "wasm-io.h" +#include "wasm-linker.h" +#include "wasm-printing.h" +#include "wasm-validator.h" + +using namespace cashew; +using namespace wasm; + +int main(int argc, const char *argv[]) { + std::string infile; + std::string outfile; + bool emitBinary = true; + std::vector<Name> forcedExports; + Options options("wasm-emscripten-finalize", + "Performs Emscripten-specific transforms on .wasm files"); + options + .add("--output", "-o", "Output file", + Options::Arguments::One, + [&outfile](Options*, const std::string &argument) { + outfile = argument; + Colors::disable(); + }) + .add("--emit-text", "-S", "Emit text instead of binary for the output file", + Options::Arguments::Zero, + [&emitBinary](Options*, const std::string &) { + emitBinary = false; + }) + .add_positional("INFILE", Options::Arguments::One, + [&infile](Options *o, const std::string &argument) { + infile = argument; + }); + options.parse(argc, argv); + + if (infile == "") { + Fatal() << "Need to specify an infile\n"; + } + if (outfile == "" && emitBinary) { + Fatal() << "Need to specify an outfile, or use text output\n"; + } + + Module wasm; + ModuleReader reader; + reader.read(infile, wasm); + + if (options.debug) { + std::cerr << "Module before:\n"; + WasmPrinter::printModule(&wasm, std::cerr); + } + + EmscriptenGlueGenerator generator(wasm); + generator.generateRuntimeFunctions(); + generator.generateMemoryGrowthFunction(); + generator.generateDynCallThunks(); + generator.fixEmAsmConsts(); + + if (options.debug) { + std::cerr << "Module after:\n"; + WasmPrinter::printModule(&wasm, std::cerr); + } + + ModuleWriter writer; + // writer.setDebug(options.debug); + writer.setDebugInfo(true); + // writer.setDebugInfo(options.passOptions.debugInfo); + // writer.setSymbolMap(symbolMap); + writer.setBinary(emitBinary); + // if (emitBinary) { + // writer.setSourceMapFilename(sourceMapFilename); + // writer.setSourceMapUrl(sourceMapUrl); + // } + writer.write(wasm, outfile); + + return 0; +} diff --git a/src/tools/wasm-link-metadata.cpp b/src/tools/wasm-link-metadata.cpp new file mode 100644 index 000000000..1ca64880f --- /dev/null +++ b/src/tools/wasm-link-metadata.cpp @@ -0,0 +1,118 @@ +/* + * Copyright 2017 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. + */ + +// +// wasm-link-metadata console tool +// Reads wasm .o file and emits .json metadata +// + +#include <exception> + +#include "abi/wasm-object.h" +#include "ir/trapping.h" +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" +#include "wasm-binary.h" +#include "wasm-emscripten.h" +#include "wasm-io.h" +#include "wasm-linker.h" +#include "wasm-printing.h" +#include "wasm-validator.h" + +using namespace cashew; +using namespace wasm; + +void parseLinkingSection(std::vector<char> const& data, uint32_t &dataSize) { + unsigned idx = 0; + auto get = [&idx, &data](){ return data[idx++]; }; + auto readNext = [get](){ + U32LEB leb; + leb.read(get); + return leb.value; + }; + + while (idx < data.size()) { + ABI::LinkType type = static_cast<ABI::LinkType>(readNext()); + uint32_t size = readNext(); + uint32_t startIdx = idx; + + switch(type) { + case ABI::WASM_DATA_SIZE: { + dataSize = readNext(); + break; + } + default: { + break; + } + } + // Always go to the end of the subsection based on size, not contents. + idx = startIdx + size; + } +} + +int main(int argc, const char *argv[]) { + std::string infile; + std::string outfile; + Options options("wasm-link-metadata", + "Reads wasm .o file and emits .json metadata"); + options + .add("--output", "-o", "Output file", + Options::Arguments::One, + [&outfile](Options *o, const std::string &argument) { + outfile = argument; + Colors::disable(); + }) + .add_positional("INFILE", Options::Arguments::One, + [&infile](Options *o, const std::string &argument) { + infile = argument; + }); + options.parse(argc, argv); + + if (infile == "") { + Fatal() << "Need to specify an infile\n"; + } + + Module wasm; + try { + ModuleReader reader; + reader.readBinary(infile, wasm); + } catch (ParseException& p) { + p.dump(std::cerr); + Fatal() << "error in parsing wasm binary"; + } + + if (options.debug) { + WasmPrinter::printModule(&wasm, std::cerr); + } + + uint32_t dataSize = 0; + for (auto §ion : wasm.userSections) { + if (section.name == "linking") { + parseLinkingSection(section.data, dataSize); + } + } + + std::vector<Name> initializerFunctions; + initializerFunctions.push_back("__wasm_call_ctors"); + + EmscriptenGlueGenerator generator(wasm); + std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions); + Output output(outfile, Flags::Text, Flags::Release); + output << metadata; + + return 0; +} |