diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-ast.c | 5 | ||||
-rw-r--r-- | src/binary-reader-interpreter.c | 5 | ||||
-rw-r--r-- | src/binary-reader-objdump.c | 119 | ||||
-rw-r--r-- | src/binary-reader-objdump.h | 15 | ||||
-rw-r--r-- | src/binary-reader.c | 12 | ||||
-rw-r--r-- | src/binary-reader.h | 3 | ||||
-rw-r--r-- | src/tools/wasmdump.c | 12 |
7 files changed, 122 insertions, 49 deletions
diff --git a/src/binary-reader-ast.c b/src/binary-reader-ast.c index ddf1a7aa..3295d1be 100644 --- a/src/binary-reader-ast.c +++ b/src/binary-reader-ast.c @@ -479,8 +479,9 @@ static WasmResult on_function_bodies_count(uint32_t count, void* user_data) { return WASM_OK; } -static WasmResult begin_function_body(uint32_t index, void* user_data) { - Context* ctx = user_data; +static WasmResult begin_function_body(WasmBinaryReaderContext* context, + uint32_t index) { + Context* ctx = context->user_data; assert(index < ctx->module->funcs.size); ctx->current_func = ctx->module->funcs.data[index]; push_label(ctx, LABEL_TYPE_FUNC, &ctx->current_func->first_expr); diff --git a/src/binary-reader-interpreter.c b/src/binary-reader-interpreter.c index 87d260de..af0f46db 100644 --- a/src/binary-reader-interpreter.c +++ b/src/binary-reader-interpreter.c @@ -1131,8 +1131,9 @@ static WasmResult drop_types_for_return(Context* ctx, uint32_t arity) { return WASM_OK; } -static WasmResult begin_function_body(uint32_t index, void* user_data) { - Context* ctx = user_data; +static WasmResult begin_function_body(WasmBinaryReaderContext* context, + uint32_t index) { + Context* ctx = context->user_data; WasmInterpreterFunc* func = get_func_by_module_index(ctx, index); WasmInterpreterFuncSignature* sig = get_signature_by_env_index(ctx, func->sig_index); diff --git a/src/binary-reader-objdump.c b/src/binary-reader-objdump.c index cdc8f88d..dd8941e5 100644 --- a/src/binary-reader-objdump.c +++ b/src/binary-reader-objdump.c @@ -29,7 +29,7 @@ typedef uint32_t Uint32; WASM_DEFINE_VECTOR(uint32, Uint32); typedef struct Context { - const WasmObjdumpOptions* options; + WasmObjdumpOptions* options; WasmAllocator* allocator; WasmStream* out_stream; const uint8_t* data; @@ -47,6 +47,8 @@ typedef struct Context { WasmStringSlice import_module_name; WasmStringSlice import_field_name; + + uint32_t next_reloc; } Context; static WasmBool should_print_details(Context* ctx) { @@ -65,34 +67,40 @@ static void WASM_PRINTF_FORMAT(2, 3) va_end(args); } -static WasmResult do_begin_section(Context* ctx, - const char* name, - size_t offset, - size_t size) { - WasmBool section_match = !ctx->options->section_name || - !strcasecmp(ctx->options->section_name, name); +static WasmResult begin_section(WasmBinaryReaderContext* ctx, + WasmBinarySection section_code, + uint32_t size) { + Context* context = ctx->user_data; + context->section_starts[section_code] = ctx->offset; + + const char* name = wasm_get_section_name(section_code); + + WasmBool section_match = !context->options->section_name || + !strcasecmp(context->options->section_name, name); if (section_match) - ctx->section_found = WASM_TRUE; + context->section_found = WASM_TRUE; - switch (ctx->options->mode) { + switch (context->options->mode) { + case WASM_DUMP_PREPASS: + break; case WASM_DUMP_HEADERS: - printf("%9s start=%#010" PRIzx " end=%#010" PRIzx " (size=%#010" PRIzx - ") ", - name, offset, offset + size, size); + printf("%9s start=%#010" PRIzx " end=%#010" PRIzx " (size=%#010x) ", + name, ctx->offset, ctx->offset + size, size); break; case WASM_DUMP_DETAILS: if (section_match) { - printf("%s:\n", name); - ctx->print_details = WASM_TRUE; + if (section_code != WASM_BINARY_SECTION_CODE) + printf("%s:\n", name); + context->print_details = WASM_TRUE; } else { - ctx->print_details = WASM_FALSE; + context->print_details = WASM_FALSE; } break; case WASM_DUMP_RAW_DATA: if (section_match) { printf("\nContents of section %s:\n", name); - wasm_write_memory_dump(ctx->out_stream, ctx->data + offset, size, - offset, WASM_PRINT_CHARS, NULL, NULL); + wasm_write_memory_dump(context->out_stream, context->data + ctx->offset, + size, ctx->offset, WASM_PRINT_CHARS, NULL, NULL); } break; case WASM_DUMP_DISASSEMBLE: @@ -101,15 +109,6 @@ static WasmResult do_begin_section(Context* ctx, return WASM_OK; } -static WasmResult begin_section(WasmBinaryReaderContext* ctx, - WasmBinarySection type, - uint32_t size) { - Context* context = ctx->user_data; - context->section_starts[type] = ctx->offset; - return do_begin_section(context, wasm_get_section_name(type), ctx->offset, - size); -} - static WasmResult begin_custom_section(WasmBinaryReaderContext* ctx, uint32_t size, WasmStringSlice section_name) { @@ -146,17 +145,18 @@ static WasmResult begin_module(uint32_t version, void* user_data) { switch (ctx->options->mode) { case WASM_DUMP_HEADERS: printf("\n"); - printf("Sections:\n"); + printf("Sections:\n\n"); break; case WASM_DUMP_DETAILS: printf("\n"); - printf("Section Details:\n"); + printf("Section Details:\n\n"); break; case WASM_DUMP_DISASSEMBLE: printf("\n"); - printf("Code Disassembly:\n"); + printf("Code Disassembly:\n\n"); break; case WASM_DUMP_RAW_DATA: + case WASM_DUMP_PREPASS: break; } @@ -242,6 +242,19 @@ static void log_opcode(Context* ctx, printf("\n"); ctx->last_opcode_end = ctx->current_opcode_offset + data_size; + + if (ctx->options->relocs) { + if (ctx->next_reloc < ctx->options->code_relocations.size) { + WasmReloc* reloc = &ctx->options->code_relocations.data[ctx->next_reloc]; + size_t code_start = ctx->section_starts[WASM_BINARY_SECTION_CODE]; + size_t abs_offset = code_start + reloc->offset; + if (ctx->last_opcode_end > abs_offset) { + printf(" %06" PRIzx ": %s\n", abs_offset, + wasm_get_reloc_type_name(reloc->type)); + ctx->next_reloc++; + } + } + } } static WasmResult on_opcode_bare(WasmBinaryReaderContext* ctx) { @@ -380,13 +393,18 @@ static WasmResult on_function_signature(uint32_t index, return WASM_OK; } -static WasmResult begin_function_body(uint32_t index, void* user_data) { - Context* ctx = user_data; +static WasmResult begin_function_body(WasmBinaryReaderContext* context, + uint32_t index) { + Context* ctx = context->user_data; - if (should_print_details(ctx)) - printf(" - func %d\n", index); - if (ctx->options->mode == WASM_DUMP_DISASSEMBLE) - printf("func %d\n", index); + if (ctx->options->mode == WASM_DUMP_DISASSEMBLE) { + if (index < ctx->options->function_names.size) + printf("%06" PRIzx " <" PRIstringslice ">:\n", context->offset, + WASM_PRINTF_STRING_SLICE_ARG( + ctx->options->function_names.data[index])); + else + printf("%06" PRIzx " func[%d]:\n", context->offset, index); + } ctx->last_opcode_end = 0; return WASM_OK; @@ -558,8 +576,12 @@ static WasmResult on_init_expr_i64_const_expr(uint32_t index, static WasmResult on_function_name(uint32_t index, WasmStringSlice name, void* user_data) { - print_details(user_data, " - func[%d] " PRIstringslice "\n", index, + Context* ctx = user_data; + print_details(ctx, " - func[%d] " PRIstringslice "\n", index, WASM_PRINTF_STRING_SLICE_ARG(name)); + if (ctx->options->mode == WASM_DUMP_PREPASS) + wasm_append_string_slice_value(ctx->allocator, + &ctx->options->function_names, &name); return WASM_OK; } @@ -592,6 +614,14 @@ WasmResult on_reloc(WasmRelocType type, uint32_t total_offset = ctx->section_starts[ctx->reloc_section] + offset; print_details(user_data, " - %-18s offset=%#x (%#x)\n", wasm_get_reloc_type_name(type), total_offset, offset); + if (ctx->options->mode == WASM_DUMP_PREPASS && + ctx->reloc_section == WASM_BINARY_SECTION_CODE) { + WasmReloc reloc; + reloc.offset = offset; + reloc.type = type; + wasm_append_reloc_value(ctx->allocator, &ctx->options->code_relocations, + &reloc); + } return WASM_OK; } @@ -699,10 +729,7 @@ static WasmBinaryReader s_binary_reader = { WasmResult wasm_read_binary_objdump(struct WasmAllocator* allocator, const uint8_t* data, size_t size, - const WasmObjdumpOptions* options) { - WasmBinaryReader reader; - WASM_ZERO_MEMORY(reader); - reader = s_binary_reader; + WasmObjdumpOptions* options) { Context context; WASM_ZERO_MEMORY(context); context.allocator = allocator; @@ -714,6 +741,16 @@ WasmResult wasm_read_binary_objdump(struct WasmAllocator* allocator, context.options = options; context.out_stream = wasm_init_stdout_stream(); + WasmBinaryReader reader; + WASM_ZERO_MEMORY(reader); + if (options->mode == WASM_DUMP_PREPASS) { + reader.on_function_name = on_function_name; + reader.on_reloc_count = on_reloc_count; + reader.on_reloc = on_reloc; + } else { + reader = s_binary_reader; + } + if (options->mode == WASM_DUMP_DISASSEMBLE) { reader.on_opcode = on_opcode; reader.on_opcode_bare = on_opcode_bare; @@ -728,8 +765,8 @@ WasmResult wasm_read_binary_objdump(struct WasmAllocator* allocator, } reader.user_data = &context; + WasmReadBinaryOptions read_options = WASM_READ_BINARY_OPTIONS_DEFAULT; read_options.read_debug_names = WASM_TRUE; - return wasm_read_binary(allocator, data, size, &reader, 1, &read_options); } diff --git a/src/binary-reader-objdump.h b/src/binary-reader-objdump.h index 5e8274f7..d39b42d7 100644 --- a/src/binary-reader-objdump.h +++ b/src/binary-reader-objdump.h @@ -19,12 +19,22 @@ #include "common.h" #include "stream.h" +#include "vector.h" struct WasmAllocator; struct WasmModule; struct WasmReadBinaryOptions; +typedef struct WasmReloc { + WasmRelocType type; + size_t offset; +} WasmReloc; +WASM_DEFINE_VECTOR(reloc, WasmReloc); + +WASM_DEFINE_VECTOR(string_slice, WasmStringSlice); + typedef enum WasmObjdumpMode { + WASM_DUMP_PREPASS, WASM_DUMP_HEADERS, WASM_DUMP_DETAILS, WASM_DUMP_DISASSEMBLE, @@ -37,10 +47,13 @@ typedef struct WasmObjdumpOptions { WasmBool raw; WasmBool disassemble; WasmBool debug; + WasmBool relocs; WasmObjdumpMode mode; const char* infile; const char* section_name; WasmBool print_header; + WasmStringSliceVector function_names; + WasmRelocVector code_relocations; } WasmObjdumpOptions; WASM_EXTERN_C_BEGIN @@ -48,7 +61,7 @@ WASM_EXTERN_C_BEGIN WasmResult wasm_read_binary_objdump(struct WasmAllocator* allocator, const uint8_t* data, size_t size, - const WasmObjdumpOptions* options); + WasmObjdumpOptions* options); WASM_EXTERN_C_END diff --git a/src/binary-reader.c b/src/binary-reader.c index e98def74..ebb3b69f 100644 --- a/src/binary-reader.c +++ b/src/binary-reader.c @@ -507,6 +507,14 @@ static WasmResult logging_begin_custom_section(WasmBinaryReaderContext* context, FORWARD(name, value); \ } +#define LOGGING_UINT32_CTX(name) \ + static WasmResult logging_##name(WasmBinaryReaderContext* context, \ + uint32_t value) { \ + LoggingContext* ctx = context->user_data; \ + LOGF(#name "(%u)\n", value); \ + FORWARD_CTX(name, value); \ + } + #define LOGGING_UINT32_DESC(name, desc) \ static WasmResult logging_##name(uint32_t value, void* user_data) { \ LoggingContext* ctx = user_data; \ @@ -577,7 +585,7 @@ LOGGING_UINT32(on_start_function) LOGGING_END(start_section) LOGGING_BEGIN(function_bodies_section) LOGGING_UINT32(on_function_bodies_count) -LOGGING_UINT32(begin_function_body) +LOGGING_UINT32_CTX(begin_function_body) LOGGING_UINT32(end_function_body) LOGGING_UINT32(on_local_decl_count) LOGGING_OPCODE(on_binary_expr) @@ -1985,7 +1993,7 @@ static void read_code_section(Context* ctx, uint32_t section_size) { uint32_t func_index = ctx->num_func_imports + i; uint32_t func_offset = ctx->offset; ctx->offset = func_offset; - CALLBACK(begin_function_body, func_index); + CALLBACK_CTX(begin_function_body, func_index); uint32_t body_size; in_u32_leb128(ctx, &body_size, "function body size"); uint32_t body_start_offset = ctx->offset; diff --git a/src/binary-reader.h b/src/binary-reader.h index 6224f7f1..efae1579 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -167,7 +167,8 @@ typedef struct WasmBinaryReader { WasmResult (*begin_function_body_pass)(uint32_t index, uint32_t pass, void* user_data); - WasmResult (*begin_function_body)(uint32_t index, void* user_data); + WasmResult (*begin_function_body)(WasmBinaryReaderContext* ctx, + uint32_t index); WasmResult (*on_local_decl_count)(uint32_t count, void* user_data); WasmResult (*on_local_decl)(uint32_t decl_index, uint32_t count, diff --git a/src/tools/wasmdump.c b/src/tools/wasmdump.c index a9452f8f..9ee96828 100644 --- a/src/tools/wasmdump.c +++ b/src/tools/wasmdump.c @@ -38,6 +38,7 @@ enum { FLAG_DISASSEMBLE, FLAG_DEBUG, FLAG_DETAILS, + FLAG_RELOCS, FLAG_HELP, NUM_FLAGS }; @@ -56,6 +57,8 @@ static WasmOption s_options[] = { "disassemble function bodies"}, {FLAG_DEBUG, '\0', "debug", NULL, NOPE, "disassemble function bodies"}, {FLAG_DETAILS, 'x', "details", NULL, NOPE, "Show section details"}, + {FLAG_RELOCS, 'r', "reloc", NULL, NOPE, + "show relocations inline with disassembly"}, {FLAG_HELP, 'h', "help", NULL, NOPE, "print this help message"}, }; @@ -90,6 +93,10 @@ static void on_option(struct WasmOptionParser* parser, s_objdump_options.details = WASM_TRUE; break; + case FLAG_RELOCS: + s_objdump_options.relocs = WASM_TRUE; + break; + case FLAG_SECTION: s_objdump_options.section_name = argument; break; @@ -157,6 +164,11 @@ int main(int argc, char** argv) { return 1; } + s_objdump_options.mode = WASM_DUMP_PREPASS; + result = wasm_read_binary_objdump(allocator, data, size, &s_objdump_options); + if (WASM_FAILED(result)) + goto done; + // Pass 1: Print the section headers if (s_objdump_options.headers) { s_objdump_options.mode = WASM_DUMP_HEADERS; |