summaryrefslogtreecommitdiff
path: root/src/binary-reader-objdump.cc
diff options
context:
space:
mode:
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