summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-ast.c5
-rw-r--r--src/binary-reader-interpreter.c5
-rw-r--r--src/binary-reader-objdump.c119
-rw-r--r--src/binary-reader-objdump.h15
-rw-r--r--src/binary-reader.c12
-rw-r--r--src/binary-reader.h3
-rw-r--r--src/tools/wasmdump.c12
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;