diff options
Diffstat (limited to 'src/binary-reader-linker.cc')
-rw-r--r-- | src/binary-reader-linker.cc | 305 |
1 files changed, 149 insertions, 156 deletions
diff --git a/src/binary-reader-linker.cc b/src/binary-reader-linker.cc index 026c2f9d..40d3c420 100644 --- a/src/binary-reader-linker.cc +++ b/src/binary-reader-linker.cc @@ -18,7 +18,7 @@ #include <vector> -#include "binary-reader.h" +#include "binary-reader-nop.h" #include "wasm-link.h" #define RELOC_SIZE 5 @@ -28,21 +28,74 @@ namespace link { namespace { -struct Context { +class BinaryReaderLinker : public BinaryReaderNop { + public: + explicit BinaryReaderLinker(LinkerInputBinary* binary); + + virtual Result BeginSection(BinarySection section_type, uint32_t size); + + virtual Result BeginCustomSection(uint32_t size, StringSlice section_name); + + virtual Result OnImport(uint32_t index, + StringSlice module_name, + StringSlice field_name); + virtual Result OnImportFunc(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t func_index, + uint32_t sig_index); + virtual Result OnImportGlobal(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t global_index, + Type type, + bool mutable_); + + virtual Result OnTable(uint32_t index, + Type elem_type, + const Limits* elem_limits); + + virtual Result OnMemory(uint32_t index, const Limits* limits); + + virtual Result OnExport(uint32_t index, + ExternalKind kind, + uint32_t item_index, + StringSlice name); + + virtual Result OnElemSegmentFunctionIndexCount(uint32_t index, + 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 OnRelocCount(uint32_t count, + BinarySection section_code, + StringSlice section_name); + virtual Result OnReloc(RelocType type, + uint32_t offset, + uint32_t index, + int32_t addend); + + virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value); + + private: LinkerInputBinary* binary; - Section* reloc_section; - Section* current_section; + Section* reloc_section = nullptr; + Section* current_section = nullptr; }; -} // namespace +BinaryReaderLinker::BinaryReaderLinker(LinkerInputBinary* binary) + : binary(binary) {} -static Result on_reloc_count(uint32_t count, - BinarySection section_code, - StringSlice section_name, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - LinkerInputBinary* binary = ctx->binary; +Result BinaryReaderLinker::OnRelocCount(uint32_t count, + BinarySection section_code, + StringSlice section_name) { if (section_code == BinarySection::Custom) { WABT_FATAL("relocation for custom sections not yet supported\n"); } @@ -50,7 +103,7 @@ static Result on_reloc_count(uint32_t count, for (const std::unique_ptr<Section>& section : binary->sections) { if (section->section_code != section_code) continue; - ctx->reloc_section = section.get(); + reloc_section = section.get(); return Result::Ok; } @@ -58,26 +111,22 @@ static Result on_reloc_count(uint32_t count, return Result::Error; } -static Result on_reloc(RelocType type, - uint32_t offset, - uint32_t index, - int32_t addend, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - - if (offset + RELOC_SIZE > ctx->reloc_section->size) { +Result BinaryReaderLinker::OnReloc(RelocType type, + uint32_t offset, + uint32_t index, + int32_t addend) { + if (offset + RELOC_SIZE > reloc_section->size) { WABT_FATAL("invalid relocation offset: %#x\n", offset); } - ctx->reloc_section->relocations.emplace_back(type, offset, index, addend); + reloc_section->relocations.emplace_back(type, offset, index, addend); return Result::Ok; } -static Result on_import(uint32_t index, - StringSlice module_name, - StringSlice field_name, - void* user_data) { +Result BinaryReaderLinker::OnImport(uint32_t index, + StringSlice module_name, + StringSlice field_name) { if (!string_slice_eq_cstr(&module_name, WABT_LINK_MODULE_NAME)) { WABT_FATAL("unsupported import module: " PRIstringslice, WABT_PRINTF_STRING_SLICE_ARG(module_name)); @@ -85,50 +134,43 @@ static Result on_import(uint32_t index, return Result::Ok; } -static Result on_import_func(uint32_t import_index, - StringSlice module_name, - StringSlice field_name, - uint32_t global_index, - uint32_t sig_index, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - ctx->binary->function_imports.emplace_back(); - FunctionImport* import = &ctx->binary->function_imports.back(); +Result BinaryReaderLinker::OnImportFunc(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t global_index, + uint32_t sig_index) { + binary->function_imports.emplace_back(); + FunctionImport* import = &binary->function_imports.back(); import->name = field_name; import->sig_index = sig_index; import->active = true; - ctx->binary->active_function_imports++; + binary->active_function_imports++; 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); - ctx->binary->global_imports.emplace_back(); - GlobalImport* import = &ctx->binary->global_imports.back(); +Result BinaryReaderLinker::OnImportGlobal(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t global_index, + Type type, + bool mutable_) { + binary->global_imports.emplace_back(); + GlobalImport* import = &binary->global_imports.back(); import->name = field_name; import->type = type; import->mutable_ = mutable_; - ctx->binary->active_global_imports++; + binary->active_global_imports++; return Result::Ok; } -static Result begin_section(BinaryReaderContext* ctx, - BinarySection section_code, - uint32_t size) { - Context* context = static_cast<Context*>(ctx->user_data); - LinkerInputBinary* binary = context->binary; +Result BinaryReaderLinker::BeginSection(BinarySection section_code, + uint32_t size) { Section* sec = new Section(); binary->sections.emplace_back(sec); - context->current_section = sec; + current_section = sec; sec->section_code = section_code; sec->size = size; - sec->offset = ctx->offset; + sec->offset = state->offset; sec->binary = binary; if (sec->section_code != BinarySection::Custom && @@ -143,16 +185,13 @@ 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); - LinkerInputBinary* binary = context->binary; - Section* sec = context->current_section; - sec->data_custom.name = section_name; +Result BinaryReaderLinker::BeginCustomSection(uint32_t size, + StringSlice section_name) { + Section* sec = current_section; + sec->data.custom.name = section_name; /* Modify section size and offset to not include the name itself. */ - size_t delta = ctx->offset - sec->offset; + size_t delta = state->offset - sec->offset; sec->offset = sec->offset + delta; sec->size = sec->size - delta; sec->payload_offset = sec->offset; @@ -164,7 +203,8 @@ static Result begin_custom_section(BinaryReaderContext* ctx, size_t bytes_read = read_u32_leb128( &binary->data[sec->offset], &binary->data[binary->size], &name_type); - if (static_cast<NameSectionSubsection>(name_type) != NameSectionSubsection::Function) { + if (static_cast<NameSectionSubsection>(name_type) != + NameSectionSubsection::Function) { WABT_FATAL("no function name section"); } @@ -172,14 +212,14 @@ static Result begin_custom_section(BinaryReaderContext* ctx, sec->payload_size -= bytes_read; uint32_t subsection_size; - bytes_read = read_u32_leb128( - &binary->data[sec->offset], &binary->data[binary->size], &subsection_size); + bytes_read = read_u32_leb128(&binary->data[sec->offset], + &binary->data[binary->size], &subsection_size); sec->payload_offset += bytes_read; sec->payload_size -= bytes_read; - bytes_read = read_u32_leb128( - &binary->data[sec->payload_offset], &binary->data[binary->size], &sec->count); + bytes_read = read_u32_leb128(&binary->data[sec->payload_offset], + &binary->data[binary->size], &sec->count); sec->payload_offset += bytes_read; sec->payload_size -= bytes_read; @@ -201,144 +241,97 @@ static Result begin_custom_section(BinaryReaderContext* ctx, return Result::Ok; } -static Result on_table(uint32_t index, - Type elem_type, - const Limits* elem_limits, - void* user_data) { +Result BinaryReaderLinker::OnTable(uint32_t index, + Type elem_type, + const Limits* elem_limits) { if (elem_limits->has_max && (elem_limits->max != elem_limits->initial)) WABT_FATAL("Tables with max != initial not supported by wabt-link\n"); - Context* ctx = static_cast<Context*>(user_data); - ctx->binary->table_elem_count = elem_limits->initial; + binary->table_elem_count = elem_limits->initial; return Result::Ok; } -static Result on_elem_segment_function_index_count(BinaryReaderContext* ctx, - uint32_t index, - uint32_t count) { - Context* context = static_cast<Context*>(ctx->user_data); - Section* sec = context->current_section; +Result BinaryReaderLinker::OnElemSegmentFunctionIndexCount(uint32_t index, + uint32_t count) { + Section* sec = current_section; /* Modify the payload to include only the actual function indexes */ - size_t delta = ctx->offset - sec->payload_offset; + size_t delta = state->offset - sec->payload_offset; sec->payload_offset += delta; sec->payload_size -= delta; return Result::Ok; } -static Result on_memory(uint32_t index, - const Limits* page_limits, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - Section* sec = ctx->current_section; - sec->memory_limits = *page_limits; - ctx->binary->memory_page_count = page_limits->initial; +Result BinaryReaderLinker::OnMemory(uint32_t index, const Limits* page_limits) { + Section* sec = current_section; + sec->data.memory_limits = *page_limits; + binary->memory_page_count = page_limits->initial; return Result::Ok; } -static Result begin_data_segment(uint32_t index, - uint32_t memory_index, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - Section* sec = ctx->current_section; - if (!sec->data_segments) { - sec->data_segments = new std::vector<DataSegment>(); +Result BinaryReaderLinker::BeginDataSegment(uint32_t index, + uint32_t memory_index) { + Section* sec = current_section; + if (!sec->data.data_segments) { + sec->data.data_segments = new std::vector<DataSegment>(); } - sec->data_segments->emplace_back(); - DataSegment& segment = sec->data_segments->back(); + sec->data.data_segments->emplace_back(); + DataSegment& segment = sec->data.data_segments->back(); segment.memory_index = memory_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); - Section* sec = ctx->current_section; +Result BinaryReaderLinker::OnInitExprI32ConstExpr(uint32_t index, + uint32_t value) { + Section* sec = current_section; if (sec->section_code != BinarySection::Data) return Result::Ok; - DataSegment& segment = sec->data_segments->back(); + DataSegment& segment = sec->data.data_segments->back(); segment.offset = value; 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); - Section* sec = ctx->current_section; - DataSegment& segment = sec->data_segments->back(); +Result BinaryReaderLinker::OnDataSegmentData(uint32_t index, + const void* src_data, + uint32_t size) { + Section* sec = current_section; + DataSegment& segment = sec->data.data_segments->back(); segment.data = static_cast<const uint8_t*>(src_data); segment.size = size; 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); - ctx->binary->exports.emplace_back(); - Export* export_ = &ctx->binary->exports.back(); +Result BinaryReaderLinker::OnExport(uint32_t index, + ExternalKind kind, + uint32_t item_index, + StringSlice name) { + binary->exports.emplace_back(); + Export* export_ = &binary->exports.back(); export_->name = name; export_->kind = kind; export_->index = item_index; return Result::Ok; } -static Result on_function_name(uint32_t index, - StringSlice name, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - while (ctx->binary->debug_names.size() < index) { - ctx->binary->debug_names.emplace_back(); +Result BinaryReaderLinker::OnFunctionName(uint32_t index, StringSlice name) { + while (binary->debug_names.size() < index) { + binary->debug_names.emplace_back(); } - if (ctx->binary->debug_names.size() == index) { - ctx->binary->debug_names.push_back(string_slice_to_string(name)); + if (binary->debug_names.size() == index) { + binary->debug_names.push_back(string_slice_to_string(name)); } return Result::Ok; } -Result read_binary_linker(LinkerInputBinary* input_info, - LinkOptions* options) { - Context context; - WABT_ZERO_MEMORY(context); - context.binary = input_info; - - BinaryReader reader; - WABT_ZERO_MEMORY(reader); - reader.user_data = &context; - reader.begin_section = begin_section; - reader.begin_custom_section = begin_custom_section; - - reader.on_reloc_count = on_reloc_count; - reader.on_reloc = on_reloc; - - reader.on_import = on_import; - reader.on_import_func = on_import_func; - reader.on_import_global = on_import_global; - - reader.on_export = on_export; - - reader.on_table = on_table; - - reader.on_memory = on_memory; - - reader.begin_data_segment = begin_data_segment; - reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr; - reader.on_data_segment_data = on_data_segment_data; - - reader.on_elem_segment_function_index_count = - on_elem_segment_function_index_count; +} // namespace - reader.on_function_name = on_function_name; +Result read_binary_linker(LinkerInputBinary* input_info, LinkOptions* options) { + BinaryReaderLinker reader(input_info); ReadBinaryOptions read_options = WABT_READ_BINARY_OPTIONS_DEFAULT; read_options.read_debug_names = true; read_options.log_stream = options->log_stream; - return read_binary(input_info->data, input_info->size, &reader, 1, + return read_binary(input_info->data, input_info->size, &reader, &read_options); } |