summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-linker.cc8
-rw-r--r--src/binary-reader-objdump.cc12
-rw-r--r--src/binary-reader-objdump.h4
-rw-r--r--src/binary-reader.cc26
-rw-r--r--src/binary-reader.h6
-rw-r--r--src/binary-writer.cc34
-rw-r--r--src/common.cc12
-rw-r--r--src/common.h24
-rw-r--r--src/tools/wasm-link.cc7
-rw-r--r--src/wasm-link.h4
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 {