summaryrefslogtreecommitdiff
path: root/src/binary-reader-objdump.cc
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2017-03-30 14:17:29 -0700
committerGitHub <noreply@github.com>2017-03-30 14:17:29 -0700
commitca9ccccd10d1975eb117dd9ce05a189270f2fb01 (patch)
tree91bd0c8d5fb961fb5287eb77b0a34c199ac07357 /src/binary-reader-objdump.cc
parent2e9e6ce3f5f4ccf2983338fb5353013d2a5bb94d (diff)
downloadwabt-ca9ccccd10d1975eb117dd9ce05a189270f2fb01.tar.gz
wabt-ca9ccccd10d1975eb117dd9ce05a189270f2fb01.tar.bz2
wabt-ca9ccccd10d1975eb117dd9ce05a189270f2fb01.zip
Use classes + virtual functions for BinaryReader (#376)
This adds a few new classes: * BinaryReader: the abstract base class * BinaryReaderNop: implements all of BinaryReader, but does nothing * BinaryReaderLogging: logs calls through BinaryReader, and forwards to another BinaryReader Typically this means we can remove the Context structs from these implementations, since that data can just move into the BinaryReader subclasses. I also took the opportunity to rename the new member functions to MixedCase instead of snake_case, since that's more common in C++.
Diffstat (limited to 'src/binary-reader-objdump.cc')
-rw-r--r--src/binary-reader-objdump.cc936
1 files changed, 499 insertions, 437 deletions
diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc
index bb251fa2..c6698289 100644
--- a/src/binary-reader-objdump.cc
+++ b/src/binary-reader-objdump.cc
@@ -23,7 +23,7 @@
#include <vector>
-#include "binary-reader.h"
+#include "binary-reader-nop.h"
#include "literal.h"
namespace wabt {
@@ -32,36 +32,48 @@ namespace {
typedef std::vector<uint32_t> Uint32Vector;
-struct Context {
- ObjdumpOptions* options;
- Stream* out_stream;
- const uint8_t* data;
- size_t size;
- Opcode current_opcode;
- size_t current_opcode_offset;
- size_t last_opcode_end;
- int indent_level;
- bool print_details;
- bool header_printed;
- int section_found;
-
+class BinaryReaderObjdumpBase : public BinaryReaderNop {
+ public:
+ BinaryReaderObjdumpBase(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options);
+
+ virtual Result OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name);
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend);
+
+ protected:
+ bool ShouldPrintDetails();
+ void PrintDetails(const char* fmt, ...);
+
+ ObjdumpOptions* options = nullptr;
+ const uint8_t* data = nullptr;
+ size_t size = 0;
+ bool print_details = false;
+ BinarySection reloc_section = BinarySection::Invalid;
uint32_t section_starts[kBinarySectionCount];
- BinarySection reloc_section;
-
- uint32_t next_reloc;
};
-} // namespace
+BinaryReaderObjdumpBase::BinaryReaderObjdumpBase(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options)
+ : options(options), data(data), size(size) {
+ WABT_ZERO_MEMORY(section_starts);
+}
-static bool should_print_details(Context* ctx) {
- if (ctx->options->mode != ObjdumpMode::Details)
+bool BinaryReaderObjdumpBase::ShouldPrintDetails() {
+ if (options->mode != ObjdumpMode::Details)
return false;
- return ctx->print_details;
+ return print_details;
}
-static void WABT_PRINTF_FORMAT(2, 3)
- print_details(Context* ctx, const char* fmt, ...) {
- if (!should_print_details(ctx))
+void WABT_PRINTF_FORMAT(2, 3)
+ BinaryReaderObjdumpBase::PrintDetails(const char* fmt, ...) {
+ if (!ShouldPrintDetails())
return;
va_list args;
va_start(args, fmt);
@@ -69,40 +81,224 @@ static void WABT_PRINTF_FORMAT(2, 3)
va_end(args);
}
-static Result begin_section(BinaryReaderContext* ctx,
- BinarySection section_code,
- uint32_t size) {
- Context* context = static_cast<Context*>(ctx->user_data);
- context->section_starts[static_cast<size_t>(section_code)] = ctx->offset;
+Result BinaryReaderObjdumpBase::OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name) {
+ reloc_section = section_code;
+ PrintDetails(" - section: %s\n", get_section_name(section_code));
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdumpBase::OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ uint32_t total_offset =
+ section_starts[static_cast<size_t>(reloc_section)] + offset;
+ PrintDetails(" - %-18s idx=%#-4x addend=%#-4x offset=%#x(file=%#x)\n",
+ get_reloc_type_name(type), index, addend, offset, total_offset);
+ return Result::Ok;
+}
+
+class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase {
+ public:
+ BinaryReaderObjdumpPrepass(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options);
+
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend);
+};
+
+BinaryReaderObjdumpPrepass::BinaryReaderObjdumpPrepass(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options)
+ : BinaryReaderObjdumpBase(data, size, options) {}
+
+Result BinaryReaderObjdumpPrepass::OnFunctionName(uint32_t index,
+ StringSlice name) {
+ if (options->mode == ObjdumpMode::Prepass) {
+ options->function_names.resize(index + 1);
+ options->function_names[index] = string_slice_to_string(name);
+ } else {
+ PrintDetails(" - func[%d] " PRIstringslice "\n", index,
+ WABT_PRINTF_STRING_SLICE_ARG(name));
+ }
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdumpPrepass::OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ BinaryReaderObjdumpBase::OnReloc(type, offset, index, addend);
+ if (reloc_section == BinarySection::Code) {
+ options->code_relocations.emplace_back(type, offset, index, addend);
+ }
+ return Result::Ok;
+}
+
+class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
+ public:
+ BinaryReaderObjdump(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options);
+
+ virtual Result BeginModule(uint32_t version);
+ virtual Result EndModule();
+
+ virtual Result BeginSection(BinarySection section_type, uint32_t size);
+
+ virtual Result BeginCustomSection(uint32_t size, StringSlice section_name);
+
+ virtual Result OnTypeCount(uint32_t count);
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types);
+
+ virtual Result OnImportCount(uint32_t count);
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index);
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits);
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits);
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_);
+
+ virtual Result OnFunctionCount(uint32_t count);
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index);
+
+ virtual Result OnTableCount(uint32_t count);
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits);
+
+ virtual Result OnMemoryCount(uint32_t count);
+ virtual Result OnMemory(uint32_t index, const Limits* limits);
+
+ virtual Result OnGlobalCount(uint32_t count);
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_);
+
+ virtual Result OnExportCount(uint32_t count);
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+
+ virtual Result OnFunctionBodyCount(uint32_t count);
+ virtual Result BeginFunctionBody(uint32_t index);
+
+ virtual Result OnOpcode(Opcode Opcode);
+ virtual Result OnOpcodeBare();
+ virtual Result OnOpcodeUint32(uint32_t value);
+ virtual Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2);
+ virtual Result OnOpcodeUint64(uint64_t value);
+ virtual Result OnOpcodeF32(uint32_t value);
+ virtual Result OnOpcodeF64(uint64_t value);
+ virtual Result OnOpcodeBlockSig(uint32_t num_types, Type* sig_types);
+
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth);
+ virtual Result OnEndExpr();
+ virtual Result OnEndFunc();
+
+ virtual Result OnElemSegmentCount(uint32_t count);
+ virtual Result BeginElemSegment(uint32_t index, uint32_t table_index);
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index);
+
+ virtual Result OnDataSegmentCount(uint32_t count);
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index);
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size);
+
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+ virtual Result OnLocalName(uint32_t function_index,
+ uint32_t local_index,
+ StringSlice local_name);
+
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value);
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index, uint32_t global_index);
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value);
+
+ private:
+ Result OnCount(uint32_t count);
+ void LogOpcode(const uint8_t* data, size_t data_size, const char* fmt, ...);
+
+ Stream* out_stream = nullptr;
+ Opcode current_opcode = Opcode::Unreachable;
+ size_t current_opcode_offset = 0;
+ size_t last_opcode_end = 0;
+ int indent_level = 0;
+ bool header_printed = false;
+ int section_found = false;
+ uint32_t next_reloc = 0;
+};
+
+BinaryReaderObjdump::BinaryReaderObjdump(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options)
+ : BinaryReaderObjdumpBase(data, size, options),
+ out_stream(init_stdout_stream()) {}
+
+Result BinaryReaderObjdump::BeginSection(BinarySection section_code,
+ uint32_t size) {
+ section_starts[static_cast<size_t>(section_code)] = state->offset;
const char* name = get_section_name(section_code);
- bool section_match = !context->options->section_name ||
- !strcasecmp(context->options->section_name, name);
+ bool section_match =
+ !options->section_name || !strcasecmp(options->section_name, name);
if (section_match)
- context->section_found = true;
+ section_found = true;
- switch (context->options->mode) {
+ switch (options->mode) {
case ObjdumpMode::Prepass:
break;
case ObjdumpMode::Headers:
printf("%9s start=%#010" PRIzx " end=%#010" PRIzx " (size=%#010x) ", name,
- ctx->offset, ctx->offset + size, size);
+ state->offset, state->offset + size, size);
break;
case ObjdumpMode::Details:
if (section_match) {
if (section_code != BinarySection::Code)
printf("%s:\n", name);
- context->print_details = true;
+ print_details = true;
} else {
- context->print_details = false;
+ print_details = false;
}
break;
case ObjdumpMode::RawData:
if (section_match) {
printf("\nContents of section %s:\n", name);
- write_memory_dump(context->out_stream, context->data + ctx->offset,
- size, ctx->offset, PrintChars::Yes, nullptr, nullptr);
+ write_memory_dump(out_stream, data + state->offset, size, state->offset,
+ PrintChars::Yes, nullptr, nullptr);
}
break;
case ObjdumpMode::Disassemble:
@@ -111,40 +307,36 @@ static Result begin_section(BinaryReaderContext* ctx,
return Result::Ok;
}
-static Result begin_custom_section(BinaryReaderContext* ctx,
- uint32_t size,
- StringSlice section_name) {
- Context* context = static_cast<Context*>(ctx->user_data);
- print_details(context, " - name: \"" PRIstringslice "\"\n",
- WABT_PRINTF_STRING_SLICE_ARG(section_name));
- if (context->options->mode == ObjdumpMode::Headers) {
+Result BinaryReaderObjdump::BeginCustomSection(uint32_t size,
+ StringSlice section_name) {
+ PrintDetails(" - name: \"" PRIstringslice "\"\n",
+ WABT_PRINTF_STRING_SLICE_ARG(section_name));
+ if (options->mode == ObjdumpMode::Headers) {
printf("\"" PRIstringslice "\"\n",
WABT_PRINTF_STRING_SLICE_ARG(section_name));
}
return Result::Ok;
}
-static Result on_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->mode == ObjdumpMode::Headers) {
+Result BinaryReaderObjdump::OnCount(uint32_t count) {
+ if (options->mode == ObjdumpMode::Headers) {
printf("count: %d\n", count);
}
return Result::Ok;
}
-static Result begin_module(uint32_t version, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->print_header) {
- const char* basename = strrchr(ctx->options->infile, '/');
+Result BinaryReaderObjdump::BeginModule(uint32_t version) {
+ if (options->print_header) {
+ const char* basename = strrchr(options->infile, '/');
if (basename)
basename++;
else
- basename = ctx->options->infile;
+ basename = options->infile;
printf("%s:\tfile format wasm %#08x\n", basename, version);
- ctx->header_printed = true;
+ header_printed = true;
}
- switch (ctx->options->mode) {
+ switch (options->mode) {
case ObjdumpMode::Headers:
printf("\n");
printf("Sections:\n\n");
@@ -165,11 +357,10 @@ static Result begin_module(uint32_t version, void* user_data) {
return Result::Ok;
}
-static Result end_module(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->section_name) {
- if (!ctx->section_found) {
- printf("Section not found: %s\n", ctx->options->section_name);
+Result BinaryReaderObjdump::EndModule() {
+ if (options->section_name) {
+ if (!section_found) {
+ printf("Section not found: %s\n", options->section_name);
return Result::Error;
}
}
@@ -177,44 +368,44 @@ static Result end_module(void* user_data) {
return Result::Ok;
}
-static Result on_opcode(BinaryReaderContext* ctx, Opcode opcode) {
- Context* context = static_cast<Context*>(ctx->user_data);
+Result BinaryReaderObjdump::OnOpcode(Opcode opcode) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
- if (context->options->debug) {
+ if (options->debug) {
const char* opcode_name = get_opcode_name(opcode);
- printf("on_opcode: %#" PRIzx ": %s\n", ctx->offset, opcode_name);
+ printf("on_opcode: %#" PRIzx ": %s\n", state->offset, opcode_name);
}
- if (context->last_opcode_end) {
- if (ctx->offset != context->last_opcode_end + 1) {
- uint8_t missing_opcode = ctx->data[context->last_opcode_end];
+ if (last_opcode_end) {
+ if (state->offset != last_opcode_end + 1) {
+ uint8_t missing_opcode = data[last_opcode_end];
const char* opcode_name =
get_opcode_name(static_cast<Opcode>(missing_opcode));
fprintf(stderr, "warning: %#" PRIzx " missing opcode callback at %#" PRIzx
" (%#02x=%s)\n",
- ctx->offset, context->last_opcode_end + 1,
- ctx->data[context->last_opcode_end], opcode_name);
+ state->offset, last_opcode_end + 1, data[last_opcode_end],
+ opcode_name);
return Result::Error;
}
}
- context->current_opcode_offset = ctx->offset;
- context->current_opcode = opcode;
+ current_opcode_offset = state->offset;
+ current_opcode = opcode;
return Result::Ok;
}
#define IMMEDIATE_OCTET_COUNT 9
-static void log_opcode(Context* ctx,
- const uint8_t* data,
- size_t data_size,
- const char* fmt,
- ...) {
- size_t offset = ctx->current_opcode_offset;
+void BinaryReaderObjdump::LogOpcode(const uint8_t* data,
+ size_t data_size,
+ const char* fmt,
+ ...) {
+ size_t offset = current_opcode_offset;
// Print binary data
printf(" %06" PRIzx ": %02x", offset - 1,
- static_cast<unsigned>(ctx->current_opcode));
+ static_cast<unsigned>(current_opcode));
for (size_t i = 0; i < data_size && i < IMMEDIATE_OCTET_COUNT;
i++, offset++) {
printf(" %02x", data[offset]);
@@ -225,14 +416,14 @@ static void log_opcode(Context* ctx,
printf(" | ");
// Print disassemble
- int indent_level = ctx->indent_level;
- if (ctx->current_opcode == Opcode::Else)
+ int indent_level = this->indent_level;
+ if (current_opcode == Opcode::Else)
indent_level--;
for (int j = 0; j < indent_level; j++) {
printf(" ");
}
- const char* opcode_name = get_opcode_name(ctx->current_opcode);
+ const char* opcode_name = get_opcode_name(current_opcode);
printf("%s", opcode_name);
if (fmt) {
printf(" ");
@@ -244,15 +435,15 @@ static void log_opcode(Context* ctx,
printf("\n");
- ctx->last_opcode_end = ctx->current_opcode_offset + data_size;
+ last_opcode_end = current_opcode_offset + data_size;
- if (ctx->options->relocs) {
- if (ctx->next_reloc < ctx->options->code_relocations.size()) {
- Reloc* reloc = &ctx->options->code_relocations[ctx->next_reloc];
+ if (options->relocs) {
+ if (next_reloc < options->code_relocations.size()) {
+ Reloc* reloc = &options->code_relocations[next_reloc];
size_t code_start =
- ctx->section_starts[static_cast<size_t>(BinarySection::Code)];
+ section_starts[static_cast<size_t>(BinarySection::Code)];
size_t abs_offset = code_start + reloc->offset;
- if (ctx->last_opcode_end > abs_offset) {
+ if (last_opcode_end > abs_offset) {
printf(" %06" PRIzx ": %-18s %d", abs_offset,
get_reloc_type_name(reloc->type), reloc->index);
switch (reloc->type) {
@@ -265,85 +456,92 @@ static void log_opcode(Context* ctx,
break;
}
printf("\n");
- ctx->next_reloc++;
+ next_reloc++;
}
}
}
}
-static Result on_opcode_bare(BinaryReaderContext* ctx) {
- Context* context = static_cast<Context*>(ctx->user_data);
- log_opcode(context, ctx->data, 0, nullptr);
+Result BinaryReaderObjdump::OnOpcodeBare() {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ LogOpcode(data, 0, nullptr);
return Result::Ok;
}
-static Result on_opcode_uint32(BinaryReaderContext* ctx, uint32_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
- log_opcode(context, ctx->data, immediate_len, "%#x", value);
+Result BinaryReaderObjdump::OnOpcodeUint32(uint32_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
+ LogOpcode(data, immediate_len, "%#x", value);
return Result::Ok;
}
-static Result on_opcode_uint32_uint32(BinaryReaderContext* ctx,
- uint32_t value,
- uint32_t value2) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
- log_opcode(context, ctx->data, immediate_len, "%lu %lu", value, value2);
+Result BinaryReaderObjdump::OnOpcodeUint32Uint32(uint32_t value,
+ uint32_t value2) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
+ LogOpcode(data, immediate_len, "%lu %lu", value, value2);
return Result::Ok;
}
-static Result on_opcode_uint64(BinaryReaderContext* ctx, uint64_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
- log_opcode(context, ctx->data, immediate_len, "%d", value);
+Result BinaryReaderObjdump::OnOpcodeUint64(uint64_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
+ LogOpcode(data, immediate_len, "%d", value);
return Result::Ok;
}
-static Result on_opcode_f32(BinaryReaderContext* ctx, uint32_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
+Result BinaryReaderObjdump::OnOpcodeF32(uint32_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
char buffer[WABT_MAX_FLOAT_HEX];
write_float_hex(buffer, sizeof(buffer), value);
- log_opcode(context, ctx->data, immediate_len, buffer);
+ LogOpcode(data, immediate_len, buffer);
return Result::Ok;
}
-static Result on_opcode_f64(BinaryReaderContext* ctx, uint64_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
+Result BinaryReaderObjdump::OnOpcodeF64(uint64_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
char buffer[WABT_MAX_DOUBLE_HEX];
write_double_hex(buffer, sizeof(buffer), value);
- log_opcode(context, ctx->data, immediate_len, buffer);
+ LogOpcode(data, immediate_len, buffer);
return Result::Ok;
}
-Result on_br_table_expr(BinaryReaderContext* ctx,
- uint32_t num_targets,
- uint32_t* target_depths,
- uint32_t default_target_depth) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
+Result BinaryReaderObjdump::OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
/* TODO(sbc): Print targets */
- log_opcode(context, ctx->data, immediate_len, nullptr);
+ LogOpcode(data, immediate_len, nullptr);
return Result::Ok;
}
-static Result on_end_func(void* user_data) {
- Context* context = static_cast<Context*>(user_data);
- log_opcode(context, nullptr, 0, nullptr);
+Result BinaryReaderObjdump::OnEndFunc() {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ LogOpcode(nullptr, 0, nullptr);
return Result::Ok;
}
-static Result on_end_expr(void* user_data) {
- Context* context = static_cast<Context*>(user_data);
- context->indent_level--;
- assert(context->indent_level >= 0);
- log_opcode(context, nullptr, 0, nullptr);
+Result BinaryReaderObjdump::OnEndExpr() {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ indent_level--;
+ assert(indent_level >= 0);
+ LogOpcode(nullptr, 0, nullptr);
return Result::Ok;
}
-static const char* type_name(Type type) {
+const char* type_name(Type type) {
switch (type) {
case Type::I32:
return "i32";
@@ -363,27 +561,26 @@ static const char* type_name(Type type) {
}
}
-static Result on_opcode_block_sig(BinaryReaderContext* ctx,
- uint32_t num_types,
- Type* sig_types) {
- Context* context = static_cast<Context*>(ctx->user_data);
+Result BinaryReaderObjdump::OnOpcodeBlockSig(uint32_t num_types,
+ Type* sig_types) {
if (num_types)
- log_opcode(context, ctx->data, 1, "%s", type_name(*sig_types));
+ LogOpcode(data, 1, "%s", type_name(*sig_types));
else
- log_opcode(context, ctx->data, 1, nullptr);
- context->indent_level++;
+ LogOpcode(data, 1, nullptr);
+ indent_level++;
return Result::Ok;
}
-static Result on_signature(uint32_t index,
- uint32_t param_count,
- Type* param_types,
- uint32_t result_count,
- Type* result_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnTypeCount(uint32_t count) {
+ return OnCount(count);
+}
- if (!should_print_details(ctx))
+Result BinaryReaderObjdump::OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) {
+ if (!ShouldPrintDetails())
return Result::Ok;
printf(" - [%d] (", index);
for (uint32_t i = 0; i < param_count; i++) {
@@ -401,380 +598,245 @@ static Result on_signature(uint32_t index,
return Result::Ok;
}
-static Result on_function_signature(uint32_t index,
- uint32_t sig_index,
- void* user_data) {
- print_details(static_cast<Context*>(user_data), " - func[%d] sig=%d\n", index,
- sig_index);
+Result BinaryReaderObjdump::OnFunctionCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnFunction(uint32_t index, uint32_t sig_index) {
+ PrintDetails(" - func[%d] sig=%d\n", index, sig_index);
return Result::Ok;
}
-static Result begin_function_body(BinaryReaderContext* context,
- uint32_t index) {
- Context* ctx = static_cast<Context*>(context->user_data);
+Result BinaryReaderObjdump::OnFunctionBodyCount(uint32_t count) {
+ return OnCount(count);
+}
- if (ctx->options->mode == ObjdumpMode::Disassemble) {
- if (index < ctx->options->function_names.size() &&
- !ctx->options->function_names[index].empty())
- printf("%06" PRIzx " <%s>:\n", context->offset,
- ctx->options->function_names[index].c_str());
+Result BinaryReaderObjdump::BeginFunctionBody(uint32_t index) {
+ if (options->mode == ObjdumpMode::Disassemble) {
+ if (index < options->function_names.size() &&
+ !options->function_names[index].empty())
+ printf("%06" PRIzx " <%s>:\n", state->offset,
+ options->function_names[index].c_str());
else
- printf("%06" PRIzx " func[%d]:\n", context->offset, index);
+ printf("%06" PRIzx " func[%d]:\n", state->offset, index);
}
- ctx->last_opcode_end = 0;
+ last_opcode_end = 0;
return Result::Ok;
}
-static Result on_import_func(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t func_index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx,
- " - func[%d] sig=%d <- " PRIstringslice "." PRIstringslice "\n",
- func_index, sig_index,
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
+Result BinaryReaderObjdump::OnImportCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) {
+ PrintDetails(" - func[%d] sig=%d <- " PRIstringslice "." PRIstringslice "\n",
+ func_index, sig_index, WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
return Result::Ok;
}
-static Result on_import_table(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t table_index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(
- ctx, " - " PRIstringslice "." PRIstringslice
- " -> table elem_type=%s init=%" PRId64 " max=%" PRId64 "\n",
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name),
- get_type_name(elem_type), elem_limits->initial, elem_limits->max);
+Result BinaryReaderObjdump::OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ PrintDetails(" - " PRIstringslice "." PRIstringslice
+ " -> table elem_type=%s init=%" PRId64 " max=%" PRId64 "\n",
+ WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name),
+ get_type_name(elem_type), elem_limits->initial,
+ elem_limits->max);
return Result::Ok;
}
-static Result on_import_memory(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t memory_index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - " PRIstringslice "." PRIstringslice " -> memory\n",
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
+Result BinaryReaderObjdump::OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) {
+ PrintDetails(" - " PRIstringslice "." PRIstringslice " -> memory\n",
+ WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
return Result::Ok;
}
-static Result on_import_global(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - global[%d] %s mutable=%d <- " PRIstringslice
- "." PRIstringslice "\n",
- global_index, get_type_name(type), mutable_,
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
- return Result::Ok;
-}
-
-static Result on_memory(uint32_t index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - memory[%d] pages: initial=%" PRId64, index,
- page_limits->initial);
+Result BinaryReaderObjdump::OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ PrintDetails(" - global[%d] %s mutable=%d <- " PRIstringslice
+ "." PRIstringslice "\n",
+ global_index, get_type_name(type), mutable_,
+ WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdump::OnMemoryCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnMemory(uint32_t index,
+ const Limits* page_limits) {
+ PrintDetails(" - memory[%d] pages: initial=%" PRId64, index,
+ page_limits->initial);
if (page_limits->has_max)
- print_details(ctx, " max=%" PRId64, page_limits->max);
- print_details(ctx, "\n");
+ PrintDetails(" max=%" PRId64, page_limits->max);
+ PrintDetails("\n");
return Result::Ok;
}
-static Result on_table(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - table[%d] type=%s initial=%" PRId64, index,
- get_type_name(elem_type), elem_limits->initial);
+Result BinaryReaderObjdump::OnTableCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ PrintDetails(" - table[%d] type=%s initial=%" PRId64, index,
+ get_type_name(elem_type), elem_limits->initial);
if (elem_limits->has_max)
- print_details(ctx, " max=%" PRId64, elem_limits->max);
- print_details(ctx, "\n");
+ PrintDetails(" max=%" PRId64, elem_limits->max);
+ PrintDetails("\n");
return Result::Ok;
}
-static Result on_export(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - %s[%d] ", get_kind_name(kind), item_index);
- print_details(ctx, PRIstringslice, WABT_PRINTF_STRING_SLICE_ARG(name));
- print_details(ctx, "\n");
+Result BinaryReaderObjdump::OnExportCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
+ PrintDetails(" - %s[%d] ", get_kind_name(kind), item_index);
+ PrintDetails(PRIstringslice, WABT_PRINTF_STRING_SLICE_ARG(name));
+ PrintDetails("\n");
return Result::Ok;
}
-static Result on_elem_segment_function_index(uint32_t index,
- uint32_t func_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - func[%d]\n", func_index);
+Result BinaryReaderObjdump::OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index) {
+ PrintDetails(" - func[%d]\n", func_index);
return Result::Ok;
}
-static Result begin_elem_segment(uint32_t index,
- uint32_t table_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - segment[%d] table=%d\n", index, table_index);
+Result BinaryReaderObjdump::OnElemSegmentCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::BeginElemSegment(uint32_t index,
+ uint32_t table_index) {
+ PrintDetails(" - segment[%d] table=%d\n", index, table_index);
return Result::Ok;
}
-static Result begin_global(uint32_t index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - global[%d] %s mutable=%d", index, get_type_name(type),
- mutable_);
+Result BinaryReaderObjdump::OnGlobalCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::BeginGlobal(uint32_t index,
+ Type type,
+ bool mutable_) {
+ PrintDetails(" - global[%d] %s mutable=%d", index, get_type_name(type),
+ mutable_);
return Result::Ok;
}
-static Result on_init_expr_f32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnInitExprF32ConstExpr(uint32_t index,
+ uint32_t value) {
char buffer[WABT_MAX_FLOAT_HEX];
write_float_hex(buffer, sizeof(buffer), value);
- print_details(ctx, " - init f32=%s\n", buffer);
+ PrintDetails(" - init f32=%s\n", buffer);
return Result::Ok;
}
-static Result on_init_expr_f64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnInitExprF64ConstExpr(uint32_t index,
+ uint64_t value) {
char buffer[WABT_MAX_DOUBLE_HEX];
write_float_hex(buffer, sizeof(buffer), value);
- print_details(ctx, " - init f64=%s\n", buffer);
+ PrintDetails(" - init f64=%s\n", buffer);
return Result::Ok;
}
-static Result on_init_expr_get_global_expr(uint32_t index,
- uint32_t global_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - init global=%d\n", global_index);
+Result BinaryReaderObjdump::OnInitExprGetGlobalExpr(uint32_t index,
+ uint32_t global_index) {
+ PrintDetails(" - init global=%d\n", global_index);
return Result::Ok;
}
-static Result on_init_expr_i32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - init i32=%d\n", value);
+Result BinaryReaderObjdump::OnInitExprI32ConstExpr(uint32_t index,
+ uint32_t value) {
+ PrintDetails(" - init i32=%d\n", value);
return Result::Ok;
}
-static Result on_init_expr_i64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - init i64=%" PRId64 "\n", value);
+Result BinaryReaderObjdump::OnInitExprI64ConstExpr(uint32_t index,
+ uint64_t value) {
+ PrintDetails(" - init i64=%" PRId64 "\n", value);
return Result::Ok;
}
-static Result on_function_name(uint32_t index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->mode == ObjdumpMode::Prepass) {
- ctx->options->function_names.resize(index+1);
- ctx->options->function_names[index] = string_slice_to_string(name);
- } else {
- print_details(ctx, " - func[%d] " PRIstringslice "\n", index,
- WABT_PRINTF_STRING_SLICE_ARG(name));
- }
+Result BinaryReaderObjdump::OnFunctionName(uint32_t index, StringSlice name) {
+ PrintDetails(" - func[%d] " PRIstringslice "\n", index,
+ WABT_PRINTF_STRING_SLICE_ARG(name));
return Result::Ok;
}
-static Result on_local_name(uint32_t func_index,
- uint32_t local_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnLocalName(uint32_t func_index,
+ uint32_t local_index,
+ StringSlice name) {
if (name.length) {
- print_details(ctx, " - func[%d] local[%d] " PRIstringslice "\n", func_index,
- local_index, WABT_PRINTF_STRING_SLICE_ARG(name));
+ PrintDetails(" - func[%d] local[%d] " PRIstringslice "\n", func_index,
+ local_index, WABT_PRINTF_STRING_SLICE_ARG(name));
}
return Result::Ok;
}
-Result on_reloc_count(uint32_t count,
- BinarySection section_code,
- StringSlice section_name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->reloc_section = section_code;
- print_details(ctx, " - section: %s\n", get_section_name(section_code));
- return Result::Ok;
-}
-
-Result on_reloc(RelocType type,
- uint32_t offset,
- uint32_t index,
- int32_t addend,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- uint32_t total_offset =
- ctx->section_starts[static_cast<size_t>(ctx->reloc_section)] + offset;
- print_details(ctx, " - %-18s idx=%#-4x addend=%#-4x offset=%#x(file=%#x)\n",
- get_reloc_type_name(type), index, addend, offset, total_offset);
- if (ctx->options->mode == ObjdumpMode::Prepass &&
- ctx->reloc_section == BinarySection::Code) {
- ctx->options->code_relocations.emplace_back(type, offset, index, addend);
- }
- return Result::Ok;
+Result BinaryReaderObjdump::OnDataSegmentCount(uint32_t count) {
+ return OnCount(count);
}
-static Result begin_data_segment(uint32_t index,
- uint32_t memory_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - memory[%d]", memory_index);
+Result BinaryReaderObjdump::BeginDataSegment(uint32_t index,
+ uint32_t memory_index) {
+ PrintDetails(" - memory[%d]", memory_index);
return Result::Ok;
}
-static Result on_data_segment_data(uint32_t index,
- const void* src_data,
- uint32_t size,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (should_print_details(ctx)) {
- write_memory_dump(ctx->out_stream, src_data, size, 0, PrintChars::Yes,
- " - ", nullptr);
+Result BinaryReaderObjdump::OnDataSegmentData(uint32_t index,
+ const void* src_data,
+ uint32_t size) {
+ if (ShouldPrintDetails()) {
+ write_memory_dump(out_stream, src_data, size, 0, PrintChars::Yes, " - ",
+ nullptr);
}
return Result::Ok;
}
+} // namespace
+
Result read_binary_objdump(const uint8_t* data,
size_t size,
ObjdumpOptions* options) {
- Context context;
- WABT_ZERO_MEMORY(context);
- context.header_printed = false;
- context.print_details = false;
- context.section_found = false;
- context.data = data;
- context.size = size;
- context.options = options;
- context.out_stream = init_stdout_stream();
-
- BinaryReader reader;
- WABT_ZERO_MEMORY(reader);
- if (options->mode == ObjdumpMode::Prepass) {
- reader.on_function_name = on_function_name;
- reader.on_reloc_count = on_reloc_count;
- reader.on_reloc = on_reloc;
- } else {
- reader.begin_module = begin_module;
- reader.end_module = end_module;
-
- reader.begin_section = begin_section;
-
- // User section
- reader.begin_custom_section = begin_custom_section;
-
- // Signature section
- reader.on_signature_count = on_count;
- reader.on_signature = on_signature;
-
- // Import section
- reader.on_import_count = on_count;
- reader.on_import_func = on_import_func;
- reader.on_import_table = on_import_table;
- reader.on_import_memory = on_import_memory;
- reader.on_import_global = on_import_global;
-
- // Function sigs section
- reader.on_function_signatures_count = on_count;
- reader.on_function_signature = on_function_signature;
-
- // Table section
- reader.on_table_count = on_count;
- reader.on_table = on_table;
-
- // Memory section
- reader.on_memory_count = on_count;
- reader.on_memory = on_memory;
-
- // Globl seciont
- reader.begin_global = begin_global;
- reader.on_global_count = on_count;
-
- // Export section
- reader.on_export_count = on_count;
- reader.on_export = on_export;
-
- // Body section
- reader.on_function_bodies_count = on_count;
- reader.begin_function_body = begin_function_body;
-
- // Elems section
- reader.begin_elem_segment = begin_elem_segment;
- reader.on_elem_segment_count = on_count;
- reader.on_elem_segment_function_index = on_elem_segment_function_index;
-
- // Data section
- reader.begin_data_segment = begin_data_segment;
- reader.on_data_segment_data = on_data_segment_data;
- reader.on_data_segment_count = on_count;
-
- // Known "User" sections:
- // - Names section
- reader.on_function_name = on_function_name;
- reader.on_local_name = on_local_name;
-
- reader.on_reloc_count = on_reloc_count;
- reader.on_reloc = on_reloc;
-
- reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr;
- reader.on_init_expr_i64_const_expr = on_init_expr_i64_const_expr;
- reader.on_init_expr_f32_const_expr = on_init_expr_f32_const_expr;
- reader.on_init_expr_f64_const_expr = on_init_expr_f64_const_expr;
- reader.on_init_expr_get_global_expr = on_init_expr_get_global_expr;
- }
-
- if (options->mode == ObjdumpMode::Disassemble) {
- reader.on_opcode = on_opcode;
- reader.on_opcode_bare = on_opcode_bare;
- reader.on_opcode_uint32 = on_opcode_uint32;
- reader.on_opcode_uint32_uint32 = on_opcode_uint32_uint32;
- reader.on_opcode_uint64 = on_opcode_uint64;
- reader.on_opcode_f32 = on_opcode_f32;
- reader.on_opcode_f64 = on_opcode_f64;
- reader.on_opcode_block_sig = on_opcode_block_sig;
- reader.on_end_expr = on_end_expr;
- reader.on_end_func = on_end_func;
- reader.on_br_table_expr = on_br_table_expr;
- }
-
- reader.user_data = &context;
-
ReadBinaryOptions read_options = WABT_READ_BINARY_OPTIONS_DEFAULT;
read_options.read_debug_names = true;
read_options.log_stream = options->log_stream;
- return read_binary(data, size, &reader, 1, &read_options);
+
+ if (options->mode == ObjdumpMode::Prepass) {
+ BinaryReaderObjdumpPrepass reader(data, size, options);
+ return read_binary(data, size, &reader, &read_options);
+ } else {
+ BinaryReaderObjdump reader(data, size, options);
+ return read_binary(data, size, &reader, &read_options);
+ }
}
} // namespace wabt