summaryrefslogtreecommitdiff
path: root/src/binary-reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/binary-reader.c')
-rw-r--r--src/binary-reader.c71
1 files changed, 50 insertions, 21 deletions
diff --git a/src/binary-reader.c b/src/binary-reader.c
index 5fe7977a..a8bc2fd6 100644
--- a/src/binary-reader.c
+++ b/src/binary-reader.c
@@ -200,72 +200,88 @@ static void in_f64(Context* ctx, uint64_t* out_value, const char* desc) {
((type)((value) << SHIFT_AMOUNT(type, sign_bit)) >> \
SHIFT_AMOUNT(type, sign_bit))
-static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
- const uint8_t* p = ctx->data + ctx->offset;
- const uint8_t* end = ctx->data + ctx->section_end;
-
+size_t wasm_read_u32_leb128(const uint8_t* p,
+ const uint8_t* end,
+ uint32_t* out_value) {
if (p < end && (p[0] & 0x80) == 0) {
*out_value = LEB128_1(uint32_t);
- ctx->offset += 1;
+ return 1;
} else if (p + 1 < end && (p[1] & 0x80) == 0) {
*out_value = LEB128_2(uint32_t);
- ctx->offset += 2;
+ return 2;
} else if (p + 2 < end && (p[2] & 0x80) == 0) {
*out_value = LEB128_3(uint32_t);
- ctx->offset += 3;
+ return 3;
} else if (p + 3 < end && (p[3] & 0x80) == 0) {
*out_value = LEB128_4(uint32_t);
- ctx->offset += 4;
+ return 4;
} else if (p + 4 < end && (p[4] & 0x80) == 0) {
/* the top bits set represent values > 32 bits */
if (p[4] & 0xf0)
- RAISE_ERROR("invalid u32 leb128: %s", desc);
+ return 0;
*out_value = LEB128_5(uint32_t);
- ctx->offset += 5;
+ return 5;
} else {
/* past the end */
*out_value = 0;
- RAISE_ERROR("unable to read u32 leb128: %s", desc);
+ return 0;
}
}
-static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
+static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
const uint8_t* p = ctx->data + ctx->offset;
const uint8_t* end = ctx->data + ctx->section_end;
+ size_t bytes_read = wasm_read_u32_leb128(p, end, out_value);
+ if (!bytes_read)
+ RAISE_ERROR("unable to read u32 leb128: %s", desc);
+ ctx->offset += bytes_read;
+}
+size_t wasm_read_i32_leb128(const uint8_t* p,
+ const uint8_t* end,
+ uint32_t* out_value) {
if (p < end && (p[0] & 0x80) == 0) {
uint32_t result = LEB128_1(uint32_t);
*out_value = SIGN_EXTEND(int32_t, result, 6);
- ctx->offset += 1;
+ return 1;
} else if (p + 1 < end && (p[1] & 0x80) == 0) {
uint32_t result = LEB128_2(uint32_t);
*out_value = SIGN_EXTEND(int32_t, result, 13);
- ctx->offset += 2;
+ return 2;
} else if (p + 2 < end && (p[2] & 0x80) == 0) {
uint32_t result = LEB128_3(uint32_t);
*out_value = SIGN_EXTEND(int32_t, result, 20);
- ctx->offset += 3;
+ return 3;
} else if (p + 3 < end && (p[3] & 0x80) == 0) {
uint32_t result = LEB128_4(uint32_t);
*out_value = SIGN_EXTEND(int32_t, result, 27);
- ctx->offset += 4;
+ return 4;
} else if (p + 4 < end && (p[4] & 0x80) == 0) {
/* the top bits should be a sign-extension of the sign bit */
WasmBool sign_bit_set = (p[4] & 0x8);
int top_bits = p[4] & 0xf0;
if ((sign_bit_set && top_bits != 0x70) ||
(!sign_bit_set && top_bits != 0)) {
- RAISE_ERROR("invalid i32 leb128: %s", desc);
+ return 0;
}
uint32_t result = LEB128_5(uint32_t);
*out_value = result;
- ctx->offset += 5;
+ return 5;
} else {
/* past the end */
- RAISE_ERROR("unable to read i32 leb128: %s", desc);
+ return 0;
}
}
+static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
+ const uint8_t* p = ctx->data + ctx->offset;
+ const uint8_t* end = ctx->data + ctx->section_end;
+ size_t bytes_read = wasm_read_i32_leb128(p, end, out_value);
+ if (!bytes_read)
+ RAISE_ERROR("unable to read i32 leb128: %s", desc);
+ ctx->offset += bytes_read;
+}
+
static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) {
const uint8_t* p = ctx->data + ctx->offset;
const uint8_t* end = ctx->data + ctx->section_end;
@@ -465,6 +481,7 @@ static WasmBool skip_until_section(Context* ctx,
RAISE_ERROR("invalid section size: extends past end");
if (section_code == WASM_BINARY_SECTION_CUSTOM) {
+ CALLBACK_CTX(begin_section, section_code, *section_size);
WasmStringSlice section_name;
in_str(ctx, &section_name, "section name");
handle_custom_section(ctx, &section_name, *section_size);
@@ -478,6 +495,7 @@ static WasmBool skip_until_section(Context* ctx,
}
if (section_code == expected_code) {
+ CALLBACK_CTX(begin_section, section_code, *section_size);
return WASM_TRUE;
} else if (section_code < expected_code) {
RAISE_ERROR("section %s out of order", s_section_name[section_code]);
@@ -588,6 +606,14 @@ static WasmResult logging_begin_custom_section(WasmBinaryReaderContext* context,
FORWARD(name, value0, value1); \
}
+#define LOGGING_UINT32_UINT32_CTX(name, desc0, desc1) \
+ static WasmResult logging_##name(WasmBinaryReaderContext* context, \
+ uint32_t value0, uint32_t value1) { \
+ LoggingContext* ctx = context->user_data; \
+ LOGF(#name "(" desc0 ": %u, " desc1 ": %u)\n", value0, value1); \
+ FORWARD_CTX(name, value0, value1); \
+ }
+
#define LOGGING_OPCODE(name) \
static WasmResult logging_##name(WasmOpcode opcode, void* user_data) { \
LoggingContext* ctx = user_data; \
@@ -666,7 +692,9 @@ LOGGING_UINT32(on_elem_segment_count)
LOGGING_UINT32_UINT32(begin_elem_segment, "index", "table_index")
LOGGING_UINT32(begin_elem_segment_init_expr)
LOGGING_UINT32(end_elem_segment_init_expr)
-LOGGING_UINT32_UINT32(on_elem_segment_function_index_count, "index", "count")
+LOGGING_UINT32_UINT32_CTX(on_elem_segment_function_index_count,
+ "index",
+ "count")
LOGGING_UINT32_UINT32(on_elem_segment_function_index, "index", "func_index")
LOGGING_UINT32(end_elem_segment)
LOGGING_END(elem_section)
@@ -1982,7 +2010,8 @@ WasmResult wasm_read_binary(WasmAllocator* allocator,
uint32_t j, num_function_indexes;
in_u32_leb128(ctx, &num_function_indexes,
"elem segment function index count");
- CALLBACK(on_elem_segment_function_index_count, i, num_function_indexes);
+ CALLBACK_CTX(on_elem_segment_function_index_count, i,
+ num_function_indexes);
for (j = 0; j < num_function_indexes; ++j) {
uint32_t func_index;
in_u32_leb128(ctx, &func_index, "elem segment function index");