/* * Copyright 2016 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 #include #include #include "src/common.h" #include "src/option-parser.h" #include "src/stream.h" #include "src/binary-reader.h" #include "src/binary-reader-objdump.h" using namespace wabt; static const char s_description[] = R"( Print information about the contents of wasm binaries. examples: $ wasm-objdump test.wasm )"; static ObjdumpOptions s_objdump_options; static std::vector s_infiles; static std::unique_ptr s_log_stream; static void ParseOptions(int argc, char** argv) { OptionParser parser("wasm-objdump", s_description); parser.AddOption('h', "headers", "Print headers", []() { s_objdump_options.headers = true; }); parser.AddOption( 'j', "section", "SECTION", "Select just one section", [](const char* argument) { s_objdump_options.section_name = argument; }); parser.AddOption('s', "full-contents", "Print raw section contents", []() { s_objdump_options.raw = true; }); parser.AddOption('d', "disassemble", "Disassemble function bodies", []() { s_objdump_options.disassemble = true; }); parser.AddOption("debug", "Print extra debug information", []() { s_objdump_options.debug = true; s_log_stream = FileStream::CreateStderr(); s_objdump_options.log_stream = s_log_stream.get(); }); parser.AddOption('x', "details", "Show section details", []() { s_objdump_options.details = true; }); parser.AddOption('r', "reloc", "Show relocations inline with disassembly", []() { s_objdump_options.relocs = true; }); parser.AddOption(0, "section-offsets", "Print section offsets instead of file offsets " "in code disassembly", []() { s_objdump_options.section_offsets = true; }); parser.AddArgument( "filename", OptionParser::ArgumentCount::OneOrMore, [](const char* argument) { s_infiles.push_back(argument); }); parser.Parse(argc, argv); } Result dump_file(const char* filename) { std::vector file_data; CHECK_RESULT(ReadFile(filename, &file_data)); uint8_t* data = file_data.data(); size_t size = file_data.size(); // Perform serveral passed over the binary in order to print out different // types of information. s_objdump_options.filename = filename; printf("\n"); ObjdumpState state; Result result = Result::Ok; // Pass 0: Prepass s_objdump_options.mode = ObjdumpMode::Prepass; result |= ReadBinaryObjdump(data, size, &s_objdump_options, &state); s_objdump_options.log_stream = nullptr; // Pass 1: Print the section headers if (s_objdump_options.headers) { s_objdump_options.mode = ObjdumpMode::Headers; result |= ReadBinaryObjdump(data, size, &s_objdump_options, &state); } // Pass 2: Print extra information based on section type if (s_objdump_options.details) { s_objdump_options.mode = ObjdumpMode::Details; result |= ReadBinaryObjdump(data, size, &s_objdump_options, &state); } // Pass 3: Disassemble code section if (s_objdump_options.disassemble) { s_objdump_options.mode = ObjdumpMode::Disassemble; result |= ReadBinaryObjdump(data, size, &s_objdump_options, &state); } // Pass 4: Dump to raw contents of the sections if (s_objdump_options.raw) { s_objdump_options.mode = ObjdumpMode::RawData; result |= ReadBinaryObjdump(data, size, &s_objdump_options, &state); } return result; } int ProgramMain(int argc, char** argv) { InitStdio(); ParseOptions(argc, argv); if (!s_objdump_options.headers && !s_objdump_options.details && !s_objdump_options.disassemble && !s_objdump_options.raw) { fprintf(stderr, "At least one of the following switches must be given:\n"); fprintf(stderr, " -d/--disassemble\n"); fprintf(stderr, " -h/--headers\n"); fprintf(stderr, " -x/--details\n"); fprintf(stderr, " -s/--full-contents\n"); return 1; } for (const char* filename: s_infiles) { if (Failed(dump_file(filename))) { return 1; } } return 0; } int main(int argc, char** argv) { WABT_TRY return ProgramMain(argc, argv); WABT_CATCH_BAD_ALLOC_AND_EXIT }