summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--src/tools/wasm-strip.cc111
-rw-r--r--test/find_exe.py6
-rwxr-xr-xtest/run-tests.py6
-rw-r--r--test/strip/basic.txt31
-rw-r--r--test/strip/names.txt41
-rw-r--r--test/strip/no-custom-sections.txt22
7 files changed, 219 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff739823..0640e989 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -323,6 +323,9 @@ if (NOT EMSCRIPTEN)
# wasm-validate
wabt_executable(wasm-validate src/tools/wasm-validate.cc)
+
+ # wasm-strip
+ wabt_executable(wasm-strip src/tools/wasm-strip.cc)
endif ()
find_package(Threads)
diff --git a/src/tools/wasm-strip.cc b/src/tools/wasm-strip.cc
new file mode 100644
index 00000000..c12d105a
--- /dev/null
+++ b/src/tools/wasm-strip.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#include "src/binary.h"
+#include "src/binary-reader.h"
+#include "src/binary-reader-nop.h"
+#include "src/error-handler.h"
+#include "src/leb128.h"
+#include "src/option-parser.h"
+#include "src/stream.h"
+
+using namespace wabt;
+
+static std::string s_filename;
+
+static const char s_description[] =
+R"( Remove sections of a WebAssembly binary file.
+
+examples:
+ # Remove all custom sections from test.wasm
+ $ wasm-strip test.wasm
+)";
+
+static void ParseOptions(int argc, char** argv) {
+ OptionParser parser("wasm-strip", s_description);
+
+ parser.AddHelpOption();
+ parser.AddArgument("filename", OptionParser::ArgumentCount::One,
+ [](const char* argument) {
+ s_filename = argument;
+ ConvertBackslashToSlash(&s_filename);
+ });
+ parser.Parse(argc, argv);
+}
+
+class BinaryReaderStrip : public BinaryReaderNop {
+ public:
+ explicit BinaryReaderStrip(ErrorHandler* error_handler)
+ : error_handler_(error_handler) {
+ stream_.WriteU32(WABT_BINARY_MAGIC, "WASM_BINARY_MAGIC");
+ stream_.WriteU32(WABT_BINARY_VERSION, "WASM_BINARY_VERSION");
+ }
+
+ bool OnError(ErrorLevel error_level, const char* message) override {
+ return error_handler_->OnError(error_level, state->offset, message);
+ }
+
+ Result BeginSection(BinarySection section_type, Offset size) override {
+ if (section_type == BinarySection::Custom) {
+ return Result::Ok;
+ }
+ stream_.WriteU8Enum(section_type, "section code");
+ WriteU32Leb128(&stream_, size, "section size");
+ stream_.WriteData(state->data + state->offset, size, "section data");
+ return Result::Ok;
+ }
+
+ Result WriteToFile(string_view filename) {
+ return stream_.WriteToFile(filename);
+ }
+
+ private:
+ MemoryStream stream_;
+ ErrorHandler* error_handler_;
+};
+
+int ProgramMain(int argc, char** argv) {
+ Result result;
+
+ InitStdio();
+ ParseOptions(argc, argv);
+
+ std::vector<uint8_t> file_data;
+ result = ReadFile(s_filename.c_str(), &file_data);
+ if (Succeeded(result)) {
+ Features features;
+ ErrorHandlerFile error_handler(Location::Type::Binary);
+ const bool kReadDebugNames = false;
+ const bool kStopOnFirstError = true;
+ const bool kFailOnCustomSectionError = false;
+ ReadBinaryOptions options(features, nullptr, kReadDebugNames,
+ kStopOnFirstError, kFailOnCustomSectionError);
+
+ BinaryReaderStrip reader(&error_handler);
+ result = ReadBinary(file_data.data(), file_data.size(), &reader, options);
+
+ if (Succeeded(result)) {
+ result = reader.WriteToFile(s_filename);
+ }
+ }
+ return result != Result::Ok;
+}
+
+int main(int argc, char** argv) {
+ WABT_TRY
+ return ProgramMain(argc, argv);
+ WABT_CATCH_BAD_ALLOC_AND_EXIT
+}
diff --git a/test/find_exe.py b/test/find_exe.py
index 00a844e2..44a82bf4 100644
--- a/test/find_exe.py
+++ b/test/find_exe.py
@@ -26,7 +26,7 @@ REPO_ROOT_DIR = os.path.dirname(SCRIPT_DIR)
EXECUTABLES = [
'wat2wasm', 'wast2json', 'wasm2wat', 'wasm-objdump', 'wasm-interp',
'wasm-opcodecnt', 'wat-desugar', 'spectest-interp', 'wasm-validate',
- 'wasm2c',
+ 'wasm2c', 'wasm-strip'
]
GEN_WASM_PY = os.path.join(SCRIPT_DIR, 'gen-wasm.py')
@@ -106,3 +106,7 @@ def GetWasmValidateExecutable(override=None):
def GetWasm2CExecutable(override=None):
return FindExecutable('wasm2c', override)
+
+
+def GetWasmStripExecutable(override=None):
+ return FindExecutable('wasm-strip', override)
diff --git a/test/run-tests.py b/test/run-tests.py
index 221608aa..f6e10d86 100755
--- a/test/run-tests.py
+++ b/test/run-tests.py
@@ -112,6 +112,12 @@ TOOLS = {
('RUN', '%(wasm-interp)s --run-all-exports %(temp_file)s.wasm'),
('VERBOSE-ARGS', ['--print-cmd', '-v']),
],
+ 'run-gen-wasm-strip': [
+ ('RUN', '%(gen_wasm_py)s %(in_file)s -o %(temp_file)s.wasm'),
+ ('RUN', '%(wasm-strip)s %(temp_file)s.wasm'),
+ ('RUN', '%(wasm-objdump)s -h %(temp_file)s.wasm'),
+ ('VERBOSE-ARGS', ['--print-cmd', '-v']),
+ ],
'run-opcodecnt': [
('RUN', '%(wat2wasm)s %(in_file)s -o %(temp_file)s.wasm'),
('RUN', '%(wasm-opcodecnt)s %(temp_file)s.wasm'),
diff --git a/test/strip/basic.txt b/test/strip/basic.txt
new file mode 100644
index 00000000..30368991
--- /dev/null
+++ b/test/strip/basic.txt
@@ -0,0 +1,31 @@
+;;; TOOL: run-gen-wasm-strip
+magic
+version
+section("one") { "Lorem ipsum dolor sit amet," }
+section(TYPE) { count[1] function params[0] results[1] i32 }
+section("two") { "consectetur adipiscing elit," }
+section(FUNCTION) { count[1] type[0] }
+section("three") { "sed do eiusmod tempor incididunt" }
+section(EXPORT) { count[1] str("main") func_kind func[0] }
+section("four") { "ut labore et dolore magna aliqua." }
+section(CODE) {
+ count[1]
+ func {
+ locals[0]
+ i32.const
+ leb_i32(-420)
+ return
+ }
+}
+section("five") { "Ut enim ad minim veniam," }
+(;; STDOUT ;;;
+
+basic.wasm: file format wasm 0x1
+
+Sections:
+
+ Type start=0x0000000a end=0x0000000f (size=0x00000005) count: 1
+ Function start=0x00000011 end=0x00000013 (size=0x00000002) count: 1
+ Export start=0x00000015 end=0x0000001d (size=0x00000008) count: 1
+ Code start=0x0000001f end=0x00000027 (size=0x00000008) count: 1
+;;; STDOUT ;;)
diff --git a/test/strip/names.txt b/test/strip/names.txt
new file mode 100644
index 00000000..dbd375bb
--- /dev/null
+++ b/test/strip/names.txt
@@ -0,0 +1,41 @@
+;;; TOOL: run-gen-wasm-strip
+magic
+version
+section(TYPE) { count[1] function params[0] results[1] i32 }
+section(FUNCTION) { count[1] type[0] }
+section(CODE) {
+ count[1]
+ func {
+ locals[decl_count[1] i32_count[1] i32]
+ get_local 0
+ }
+}
+section("name") {
+ section(NAME_MODULE) {
+ str("M0")
+ }
+
+ section(NAME_FUNCTION) {
+ func_count[1]
+ index[0]
+ str("F0")
+ }
+
+ section(NAME_LOCALS) {
+ func_count[1]
+ index[0]
+ local_count[1]
+ index[0]
+ str("L0")
+ }
+}
+(;; STDOUT ;;;
+
+names.wasm: file format wasm 0x1
+
+Sections:
+
+ Type start=0x0000000a end=0x0000000f (size=0x00000005) count: 1
+ Function start=0x00000011 end=0x00000013 (size=0x00000002) count: 1
+ Code start=0x00000015 end=0x0000001d (size=0x00000008) count: 1
+;;; STDOUT ;;)
diff --git a/test/strip/no-custom-sections.txt b/test/strip/no-custom-sections.txt
new file mode 100644
index 00000000..c2e3703f
--- /dev/null
+++ b/test/strip/no-custom-sections.txt
@@ -0,0 +1,22 @@
+;;; TOOL: run-gen-wasm-strip
+magic
+version
+section(TYPE) { count[1] function params[0] results[1] i32 }
+section(FUNCTION) { count[1] type[0] }
+section(CODE) {
+ count[1]
+ func {
+ locals[decl_count[1] i32_count[1] i32]
+ get_local 0
+ }
+}
+(;; STDOUT ;;;
+
+no-custom-sections.wasm: file format wasm 0x1
+
+Sections:
+
+ Type start=0x0000000a end=0x0000000f (size=0x00000005) count: 1
+ Function start=0x00000011 end=0x00000013 (size=0x00000002) count: 1
+ Code start=0x00000015 end=0x0000001d (size=0x00000008) count: 1
+;;; STDOUT ;;)