diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-reader-linker.cc | 8 | ||||
-rw-r--r-- | src/binary-reader-objdump.cc | 12 | ||||
-rw-r--r-- | src/binary-reader-objdump.h | 4 | ||||
-rw-r--r-- | src/binary-reader.cc | 26 | ||||
-rw-r--r-- | src/binary-reader.h | 6 | ||||
-rw-r--r-- | src/binary-writer.cc | 34 | ||||
-rw-r--r-- | src/common.cc | 12 | ||||
-rw-r--r-- | src/common.h | 24 | ||||
-rw-r--r-- | src/tools/wasm-link.cc | 7 | ||||
-rw-r--r-- | src/wasm-link.h | 4 |
10 files changed, 93 insertions, 44 deletions
diff --git a/src/binary-reader-linker.cc b/src/binary-reader-linker.cc index 5d652951..dc537259 100644 --- a/src/binary-reader-linker.cc +++ b/src/binary-reader-linker.cc @@ -52,7 +52,11 @@ static Result on_reloc_count(uint32_t count, return Result::Error; } -static Result on_reloc(RelocType type, uint32_t offset, void* user_data) { +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) { @@ -62,6 +66,8 @@ static Result on_reloc(RelocType type, uint32_t offset, void* user_data) { Reloc* reloc = append_reloc(&ctx->reloc_section->relocations); reloc->type = type; reloc->offset = offset; + reloc->index = index; + reloc->addend = addend; return Result::Ok; } diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index a29f893b..fde0bbe0 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -249,8 +249,8 @@ static void log_opcode(Context* ctx, ctx->section_starts[static_cast<size_t>(BinarySection::Code)]; size_t abs_offset = code_start + reloc->offset; if (ctx->last_opcode_end > abs_offset) { - printf(" %06" PRIzx ": %s\n", abs_offset, - get_reloc_type_name(reloc->type)); + printf(" %06" PRIzx ": %s\t%d\n", abs_offset, + get_reloc_type_name(reloc->type), reloc->index); ctx->next_reloc++; } } @@ -615,7 +615,11 @@ Result on_reloc_count(uint32_t count, return Result::Ok; } -Result on_reloc(RelocType type, uint32_t offset, void* user_data) { +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; @@ -626,6 +630,8 @@ Result on_reloc(RelocType type, uint32_t offset, void* user_data) { Reloc reloc; reloc.offset = offset; reloc.type = type; + reloc.index = index; + reloc.addend = addend; append_reloc_value(&ctx->options->code_relocations, &reloc); } return Result::Ok; diff --git a/src/binary-reader-objdump.h b/src/binary-reader-objdump.h index 884ac761..e3880484 100644 --- a/src/binary-reader-objdump.h +++ b/src/binary-reader-objdump.h @@ -26,10 +26,6 @@ namespace wabt { struct Module; struct ReadBinaryOptions; -struct Reloc { - RelocType type; - size_t offset; -}; WABT_DEFINE_VECTOR(reloc, Reloc); WABT_DEFINE_VECTOR(string_slice, StringSlice); diff --git a/src/binary-reader.cc b/src/binary-reader.cc index 7c818113..8237b43a 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -1028,10 +1028,15 @@ static Result logging_on_reloc_count(uint32_t count, FORWARD(on_reloc_count, count, section_code, section_name); } -static Result logging_on_reloc(RelocType type, uint32_t offset, void* user_data) { +static Result logging_on_reloc(RelocType type, + uint32_t offset, + uint32_t index, + int32_t addend, + void* user_data) { LoggingContext* ctx = static_cast<LoggingContext*>(user_data); - LOGF("on_reloc(type: %d, offset: %d)\n", static_cast<int>(type), offset); - FORWARD(on_reloc, type, offset); + LOGF("on_reloc(type: %s, offset: %u, index: %u, addend: %d)\n", + get_reloc_type_name(type), offset, index, addend); + FORWARD(on_reloc, type, offset, index, addend); } static void read_init_expr(Context* ctx, uint32_t index) { @@ -1650,10 +1655,21 @@ static void read_custom_section(Context* ctx, uint32_t section_size) { CALLBACK(on_reloc_count, num_relocs, static_cast<BinarySection>(section), section_name); for (uint32_t i = 0; i < num_relocs; ++i) { - uint32_t reloc_type, offset; + uint32_t reloc_type, offset, index, addend = 0; in_u32_leb128(ctx, &reloc_type, "relocation type"); in_u32_leb128(ctx, &offset, "offset"); - CALLBACK(on_reloc, static_cast<RelocType>(reloc_type), offset); + in_u32_leb128(ctx, &index, "index"); + RelocType type = static_cast<RelocType>(reloc_type); + switch (type) { + case RelocType::MemoryAddressLEB: + case RelocType::MemoryAddressSLEB: + case RelocType::MemoryAddressI32: + in_u32_leb128(ctx, &addend, "addend"); + break; + default: + break; + } + CALLBACK(on_reloc, type, offset, index, addend); } CALLBACK_CTX0(end_reloc_section); } else { diff --git a/src/binary-reader.h b/src/binary-reader.h index 70cca969..27478eba 100644 --- a/src/binary-reader.h +++ b/src/binary-reader.h @@ -299,7 +299,11 @@ struct BinaryReader { BinarySection section_code, StringSlice section_name, void* user_data); - Result (*on_reloc)(RelocType type, uint32_t offset, void* user_data); + Result (*on_reloc)(RelocType type, + uint32_t offset, + uint32_t index, + int32_t addend, + void* user_data); Result (*end_reloc_section)(BinaryReaderContext* ctx); /* init_expr - used by elem, data and global sections; these functions are diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 14c297d7..235c3c9b 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -42,10 +42,6 @@ static const size_t LEB_SECTION_SIZE_GUESS = 1; #define ALLOC_FAILURE \ fprintf(stderr, "%s:%d: allocation failed\n", __FILE__, __LINE__) -struct Reloc { - RelocType type; - size_t offset; -}; WABT_DEFINE_VECTOR(reloc, Reloc); struct RelocSection { @@ -334,7 +330,7 @@ static void write_expr_list(Context* ctx, const Func* func, const Expr* first_expr); -static void add_reloc(Context* ctx, RelocType reloc_type) { +static void add_reloc(Context* ctx, RelocType reloc_type, uint32_t index) { // Add a new reloc section if needed if (!ctx->current_reloc_section || ctx->current_reloc_section->section_code != ctx->last_section_type) { @@ -347,17 +343,19 @@ static void add_reloc(Context* ctx, RelocType reloc_type) { Reloc* r = append_reloc(&ctx->current_reloc_section->relocations); r->type = reloc_type; r->offset = ctx->stream.offset - ctx->last_section_payload_offset; + r->index = index; + r->addend = 0; } static void write_u32_leb128_with_reloc(Context* ctx, - uint32_t value, + uint32_t index, const char* desc, RelocType reloc_type) { if (ctx->options->relocatable) { - add_reloc(ctx, reloc_type); - write_fixed_u32_leb128(&ctx->stream, value, desc); + add_reloc(ctx, reloc_type, index); + write_fixed_u32_leb128(&ctx->stream, index, desc); } else { - write_u32_leb128(&ctx->stream, value, desc); + write_u32_leb128(&ctx->stream, index, desc); } } @@ -402,7 +400,7 @@ static void write_expr(Context* ctx, int index = get_func_index_by_var(module, &expr->call.var); write_opcode(&ctx->stream, Opcode::Call); write_u32_leb128_with_reloc(ctx, index, "function index", - RelocType::FuncIndexLeb); + RelocType::FuncIndexLEB); break; } case ExprType::CallIndirect: { @@ -452,7 +450,7 @@ static void write_expr(Context* ctx, int index = get_global_index_by_var(module, &expr->get_global.var); write_opcode(&ctx->stream, Opcode::GetGlobal); write_u32_leb128_with_reloc(ctx, index, "global index", - RelocType::GlobalIndexLeb); + RelocType::GlobalIndexLEB); break; } case ExprType::GetLocal: { @@ -502,7 +500,7 @@ static void write_expr(Context* ctx, int index = get_global_index_by_var(module, &expr->get_global.var); write_opcode(&ctx->stream, Opcode::SetGlobal); write_u32_leb128_with_reloc(ctx, index, "global index", - RelocType::GlobalIndexLeb); + RelocType::GlobalIndexLEB); break; } case ExprType::SetLocal: { @@ -635,6 +633,16 @@ static void write_reloc_section(Context* ctx, RelocSection* reloc_section) { for (size_t i = 0; i < relocs->size; i++) { write_u32_leb128_enum(&ctx->stream, relocs->data[i].type, "reloc type"); write_u32_leb128(&ctx->stream, relocs->data[i].offset, "reloc offset"); + write_u32_leb128(&ctx->stream, relocs->data[i].index, "reloc index"); + switch (relocs->data[i].type) { + case RelocType::MemoryAddressLEB: + case RelocType::MemoryAddressSLEB: + case RelocType::MemoryAddressI32: + write_u32_leb128(&ctx->stream, relocs->data[i].addend, "reloc addend"); + break; + default: + break; + } } end_section(ctx); @@ -818,7 +826,7 @@ static Result write_module(Context* ctx, const Module* module) { for (size_t j = 0; j < segment->vars.size; ++j) { int index = get_func_index_by_var(module, &segment->vars.data[j]); write_u32_leb128_with_reloc(ctx, index, "function index", - RelocType::FuncIndexLeb); + RelocType::FuncIndexLEB); } } end_section(ctx); diff --git a/src/common.cc b/src/common.cc index d9489270..f2211c77 100644 --- a/src/common.cc +++ b/src/common.cc @@ -55,9 +55,15 @@ void init_opcode_info(void) { const char* g_kind_name[] = {"func", "table", "memory", "global"}; WABT_STATIC_ASSERT(WABT_ARRAY_SIZE(g_kind_name) == kExternalKindCount); -const char* g_reloc_type_name[] = {"R_FUNC_INDEX_LEB", "R_TABLE_INDEX_SLEB", - "R_TABLE_INDEX_I32", "R_GLOBAL_INDEX_LEB", - "R_DATA"}; +const char* g_reloc_type_name[] = {"R_FUNC_INDEX_LEB", + "R_TABLE_INDEX_SLEB", + "R_TABLE_INDEX_I32", + "R_MEMORY_ADDR_LEB", + "R_MEMORY_ADDR_SLEB", + "R_MEMORY_ADDR_I32", + "R_TYPE_INDEX_LEB", + "R_GLOBAL_INDEX_LEB", + }; WABT_STATIC_ASSERT(WABT_ARRAY_SIZE(g_reloc_type_name) == kRelocTypeCount); bool is_naturally_aligned(Opcode opcode, uint32_t alignment) { diff --git a/src/common.h b/src/common.h index 704fb829..9b2f7c07 100644 --- a/src/common.h +++ b/src/common.h @@ -156,17 +156,27 @@ enum class Type { }; enum class RelocType { - FuncIndexLeb = 0, /* e.g. immediate of call instruction */ - TableIndexSleb = 1, /* e.g. loading address of function */ + FuncIndexLEB = 0, /* e.g. immediate of call instruction */ + TableIndexSLEB = 1, /* e.g. loading address of function */ TableIndexI32 = 2, /* e.g. function address in DATA */ - GlobalIndexLeb = 3, /* e.g immediate of get_global inst */ - Data = 4, - - First = FuncIndexLeb, - Last = Data, + MemoryAddressLEB = 3, + MemoryAddressSLEB = 4, + MemoryAddressI32 = 5, + TypeIndexLEB = 6, /* e.g immediate type in call_indirect */ + GlobalIndexLEB = 7, /* e.g immediate of get_global inst */ + + First = FuncIndexLEB, + Last = GlobalIndexLEB, }; static const int kRelocTypeCount = WABT_ENUM_COUNT(RelocType); +struct Reloc { + RelocType type; + size_t offset; + uint32_t index; + int32_t addend; +}; + /* matches binary format, do not change */ enum class ExternalKind { Func = 0, diff --git a/src/tools/wasm-link.cc b/src/tools/wasm-link.cc index 256ee6ca..a979dc03 100644 --- a/src/tools/wasm-link.cc +++ b/src/tools/wasm-link.cc @@ -170,16 +170,16 @@ static void apply_relocation(Section* section, Reloc* r) { uint32_t offset = 0; switch (r->type) { - case RelocType::FuncIndexLeb: + case RelocType::FuncIndexLEB: new_value = relocate_func_index(binary, cur_value); break; - case RelocType::TableIndexSleb: + case RelocType::TableIndexSLEB: printf("%s: table index reloc: %d offset=%d\n", binary->filename, cur_value, binary->table_index_offset); offset = binary->table_index_offset; new_value = cur_value + offset; break; - case RelocType::GlobalIndexLeb: + case RelocType::GlobalIndexLEB: if (cur_value >= binary->global_imports.size) { offset = binary->global_index_offset; } else { @@ -529,6 +529,7 @@ static void write_reloc_section(Context* ctx, write_u32_leb128_enum(&ctx->stream, relocs->data[j].type, "reloc type"); uint32_t new_offset = relocs->data[j].offset + sec->output_payload_offset; write_u32_leb128(&ctx->stream, new_offset, "reloc offset"); + write_u32_leb128(&ctx->stream, relocs->data[j].index, "reloc index"); } } diff --git a/src/wasm-link.h b/src/wasm-link.h index 9e2d58c1..e6831726 100644 --- a/src/wasm-link.h +++ b/src/wasm-link.h @@ -51,10 +51,6 @@ struct DataSegment { }; WABT_DEFINE_VECTOR(data_segment, DataSegment); -struct Reloc { - RelocType type; - size_t offset; -}; WABT_DEFINE_VECTOR(reloc, Reloc); struct Export { |