diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index bb34e29f01..7baf13026c 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -197,7 +197,6 @@ check_buf1(const uint8 *buf, const uint8 *buf_end, uint32 length, res = (int32)res64; \ } while (0) -#define read_leb_memidx(p, p_end, res) read_leb_uint32(p, p_end, res) #if WASM_ENABLE_MULTI_MEMORY != 0 #define check_memidx(module, memidx) \ do { \ @@ -10921,6 +10920,83 @@ DEFINE_GOTO_TABLE(const char *, op_mnemonics); #undef HANDLE_OPCODE #endif +#if WASM_ENABLE_FAST_INTERP == 0 + +#define pb_read_leb_uint32 read_leb_uint32 +#define pb_read_leb_int32 read_leb_int32 +#define pb_read_leb_int64 read_leb_int64 +#define pb_read_leb_memarg read_leb_memarg +#define pb_read_leb_mem_offset read_leb_mem_offset + +#else + +/* Read leb without malformed format check */ +static uint64 +read_leb_quick(uint8 **p_buf, uint32 maxbits, bool sign) +{ + uint8 *buf = *p_buf; + uint64 result = 0, byte = 0; + uint32 shift = 0; + + do { + byte = *buf++; + result |= ((byte & 0x7f) << shift); + shift += 7; + } while (byte & 0x80); + + if (sign && (shift < maxbits) && (byte & 0x40)) { + /* Sign extend */ + result |= (~((uint64)0)) << shift; + } + + *p_buf = buf; + return result; +} + +#define pb_read_leb_uint32(p, p_end, res) \ + do { \ + if (!loader_ctx->p_code_compiled) \ + /* Enable format check in the first scan */ \ + read_leb_uint32(p, p_end, res); \ + else \ + /* Disable format check in the second scan */ \ + res = (uint32)read_leb_quick(&p, 32, false); \ + } while (0) + +#define pb_read_leb_int32(p, p_end, res) \ + do { \ + if (!loader_ctx->p_code_compiled) \ + /* Enable format check in the first scan */ \ + read_leb_int32(p, p_end, res); \ + else \ + /* Disable format check in the second scan */ \ + res = (int32)read_leb_quick(&p, 32, true); \ + } while (0) + +#define pb_read_leb_int64(p, p_end, res) \ + do { \ + if (!loader_ctx->p_code_compiled) \ + /* Enable format check in the first scan */ \ + read_leb_int64(p, p_end, res); \ + else \ + /* Disable format check in the second scan */ \ + res = (int64)read_leb_quick(&p, 64, true); \ + } while (0) + +#if WASM_ENABLE_MULTI_MEMORY != 0 +#define pb_read_leb_memarg read_leb_memarg +#else +#define pb_read_leb_memarg pb_read_leb_uint32 +#endif + +#if WASM_ENABLE_MEMORY64 != 0 +#define pb_read_leb_mem_offset read_leb_mem_offset +#else +#define pb_read_leb_mem_offset pb_read_leb_uint32 +#endif + +#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */ + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 cur_func_idx, char *error_buf, @@ -11150,7 +11226,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, /* Resolve the leb128 encoded type index as block type */ p--; p_org = p - 1; - read_leb_int32(p, p_end, type_index); + pb_read_leb_int32(p, p_end, type_index); if ((uint32)type_index >= module->type_count) { set_error_buf(error_buf, error_buf_size, "unknown type"); @@ -11359,7 +11435,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 label_type = cur_block->label_type; uint32 tag_index = 0; - read_leb_int32(p, p_end, tag_index); + pb_read_leb_int32(p, p_end, tag_index); /* check validity of tag_index against module->tag_count */ /* check tag index is within the tag index space */ @@ -11503,7 +11579,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 label_type = cur_block->label_type; uint32 tag_index = 0; - read_leb_int32(p, p_end, tag_index); + pb_read_leb_int32(p, p_end, tag_index); /* check validity of tag_index against module->tag_count */ /* check tag index is within the tag index space */ @@ -11770,7 +11846,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 j; #endif - read_leb_uint32(p, p_end, count); + pb_read_leb_uint32(p, p_end, count); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, count); #endif @@ -11779,7 +11855,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, /* Get each depth and check it */ p_org = p; for (i = 0; i <= count; i++) { - read_leb_uint32(p, p_end, depth); + pb_read_leb_uint32(p, p_end, depth); bh_assert(loader_ctx->csp_num > 0); if (loader_ctx->csp_num - 1 < depth) { set_error_buf(error_buf, error_buf_size, @@ -11801,7 +11877,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif for (i = 0; i <= count; i++) { p_org = p; - read_leb_uint32(p, p_end, depth); + pb_read_leb_uint32(p, p_end, depth); p = p_org; /* Get the target block's arity and check it */ @@ -11935,7 +12011,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #if WASM_ENABLE_GC != 0 if (opcode == WASM_OP_CALL_REF || opcode == WASM_OP_RETURN_CALL_REF) { - read_leb_uint32(p, p_end, type_idx1); + pb_read_leb_uint32(p, p_end, type_idx1); if (!check_type_index(module, module->type_count, type_idx1, error_buf, error_buf_size)) { goto fail; @@ -11974,7 +12050,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, else #endif { - read_leb_uint32(p, p_end, func_idx); + pb_read_leb_uint32(p, p_end, func_idx); #if WASM_ENABLE_FAST_INTERP != 0 /* we need to emit func_idx before arguments */ emit_uint32(loader_ctx, func_idx); @@ -12110,7 +12186,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMRefType *elem_ref_type = NULL; #endif - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 #if WASM_ENABLE_WAMR_COMPILER != 0 if (p + 1 < p_end && *p != 0x00) { @@ -12122,7 +12198,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, module->is_ref_types_used = true; } #endif - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); #else CHECK_BUF(p, p_end, 1); table_idx = read_uint8(p); @@ -12441,7 +12517,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled; #endif - read_leb_uint32(p, p_end, vec_len); + pb_read_leb_uint32(p, p_end, vec_len); if (vec_len != 1) { /* typed select must have exactly one result */ set_error_buf(error_buf, error_buf_size, @@ -12571,7 +12647,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMRefType *ref_type; #endif - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); if (!get_table_elem_type(module, table_idx, &decl_ref_type, #if WASM_ENABLE_GC != 0 (void **)&ref_type, @@ -12632,7 +12708,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, goto fail; } #else - read_leb_int32(p, p_end, heap_type); + pb_read_leb_int32(p, p_end, heap_type); if (heap_type >= 0) { if (!check_type_index(module, module->type_count, heap_type, error_buf, error_buf_size)) { @@ -12719,7 +12795,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_REF_FUNC: { - read_leb_uint32(p, p_end, func_idx); + pb_read_leb_uint32(p, p_end, func_idx); if (!check_function_index(module, func_idx, error_buf, error_buf_size)) { @@ -13115,7 +13191,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif p_org = p - 1; - read_leb_uint32(p, p_end, global_idx); + pb_read_leb_uint32(p, p_end, global_idx); if (global_idx >= global_count) { set_error_buf(error_buf, error_buf_size, "unknown global"); goto fail; @@ -13175,7 +13251,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif p_org = p - 1; - read_leb_uint32(p, p_end, global_idx); + pb_read_leb_uint32(p, p_end, global_idx); if (global_idx >= global_count) { set_error_buf(error_buf, error_buf_size, "unknown global"); goto fail; @@ -13310,8 +13386,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } #endif CHECK_MEMORY(); - read_leb_memarg(p, p_end, align); /* align */ - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_memarg(p, p_end, align); /* align */ + pb_read_leb_mem_offset(p, p_end, mem_offset); /* offset */ if (!check_memory_access_align(opcode, align, error_buf, error_buf_size)) { goto fail; @@ -13376,7 +13452,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_MEMORY_SIZE: CHECK_MEMORY(); - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); check_memidx(module, memidx); PUSH_PAGE_COUNT(); @@ -13388,7 +13464,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_MEMORY_GROW: CHECK_MEMORY(); - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); check_memidx(module, memidx); POP_AND_PUSH(mem_offset_type, mem_offset_type); @@ -13403,7 +13479,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_I32_CONST: - read_leb_int32(p, p_end, i32_const); + pb_read_leb_int32(p, p_end, i32_const); #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); disable_emit = true; @@ -13421,7 +13497,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_I64_CONST: - read_leb_int64(p, p_end, i64_const); + pb_read_leb_int64(p, p_end, i64_const); #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); disable_emit = true; @@ -13704,7 +13780,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 opcode1; - read_leb_uint32(p, p_end, opcode1); + pb_read_leb_uint32(p, p_end, opcode1); #if WASM_ENABLE_FAST_INTERP != 0 emit_byte(loader_ctx, ((uint8)opcode1)); #endif @@ -13713,7 +13789,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_STRUCT_NEW: case WASM_OP_STRUCT_NEW_DEFAULT: { - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, type_idx); #endif @@ -13800,7 +13876,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 field_idx; uint8 field_type; - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, type_idx); #endif @@ -13817,7 +13893,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } struct_type = (WASMStructType *)module->types[type_idx]; - read_leb_uint32(p, p_end, field_idx); + pb_read_leb_uint32(p, p_end, field_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, field_idx); #endif @@ -13893,14 +13969,14 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 elem_type; uint32 u32 = 0; - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, type_idx); #endif if (opcode1 == WASM_OP_ARRAY_NEW_FIXED || opcode1 == WASM_OP_ARRAY_NEW_DATA || opcode1 == WASM_OP_ARRAY_NEW_ELEM) { - read_leb_uint32(p, p_end, u32); + pb_read_leb_uint32(p, p_end, u32); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, u32); #endif @@ -14003,7 +14079,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMArrayType *array_type; WASMRefType *ref_type = NULL; - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, type_idx); #endif @@ -14075,7 +14151,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMArrayType *array_type; uint8 elem_type; /* typeidx */ - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, type_idx); #endif @@ -14121,12 +14197,12 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMArrayType *array_type; /* typeidx1 */ - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, type_idx); #endif /* typeidx2 */ - read_leb_uint32(p, p_end, src_type_idx); + pb_read_leb_uint32(p, p_end, src_type_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, src_type_idx); #endif @@ -14213,7 +14289,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint8 type; - read_leb_int32(p, p_end, heap_type); + pb_read_leb_int32(p, p_end, heap_type); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, (uint32)heap_type); #endif @@ -14274,13 +14350,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif p_org = p; - read_leb_uint32(p, p_end, depth); - read_leb_int32(p, p_end, heap_type); + pb_read_leb_uint32(p, p_end, depth); + pb_read_leb_int32(p, p_end, heap_type); #if WASM_ENABLE_FAST_INTERP != 0 /* Emit heap_type firstly */ emit_uint32(loader_ctx, (uint32)heap_type); #endif - read_leb_int32(p, p_end, heap_type_dst); + pb_read_leb_int32(p, p_end, heap_type_dst); #if WASM_ENABLE_FAST_INTERP != 0 /* Emit heap_type firstly */ emit_uint32(loader_ctx, (uint32)heap_type_dst); @@ -14482,7 +14558,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, func->has_memory_operations = true; #endif - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, (uint32)memidx); #endif @@ -14496,7 +14572,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 contents; - read_leb_uint32(p, p_end, contents); + pb_read_leb_uint32(p, p_end, contents); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, (uint32)contents); #endif @@ -14523,7 +14599,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, func->has_memory_operations = true; #endif - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, (uint32)memidx); #endif @@ -14577,7 +14653,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, func->has_memory_operations = true; #endif - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, (uint32)memidx); #endif @@ -14625,7 +14701,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, func->has_memory_operations = true; #endif - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, (uint32)memidx); #endif @@ -14709,7 +14785,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 opcode1; - read_leb_uint32(p, p_end, opcode1); + pb_read_leb_uint32(p, p_end, opcode1); #if WASM_ENABLE_FAST_INTERP != 0 emit_byte(loader_ctx, ((uint8)opcode1)); #endif @@ -14733,7 +14809,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #if WASM_ENABLE_BULK_MEMORY != 0 case WASM_OP_MEMORY_INIT: { - read_leb_uint32(p, p_end, data_seg_idx); + pb_read_leb_uint32(p, p_end, data_seg_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, data_seg_idx); #endif @@ -14741,7 +14817,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, && module->memory_count == 0) goto fail_unknown_memory; - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); check_memidx(module, memidx); if (data_seg_idx >= module->data_seg_count) { @@ -14767,7 +14843,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_DATA_DROP: { - read_leb_uint32(p, p_end, data_seg_idx); + pb_read_leb_uint32(p, p_end, data_seg_idx); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, data_seg_idx); #endif @@ -14792,9 +14868,9 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { CHECK_BUF(p, p_end, sizeof(int16)); /* check both src and dst memory index */ - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); check_memidx(module, memidx); - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); check_memidx(module, memidx); if (module->import_memory_count == 0 @@ -14814,7 +14890,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_MEMORY_FILL: { - read_leb_uint32(p, p_end, memidx); + pb_read_leb_uint32(p, p_end, memidx); check_memidx(module, memidx); if (module->import_memory_count == 0 && module->memory_count == 0) { @@ -14849,8 +14925,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMRefType *seg_ref_type = NULL, *tbl_ref_type = NULL; #endif - read_leb_uint32(p, p_end, table_seg_idx); - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_seg_idx); + pb_read_leb_uint32(p, p_end, table_idx); if (!get_table_elem_type(module, table_idx, &tbl_type, #if WASM_ENABLE_GC != 0 @@ -14907,7 +14983,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_ELEM_DROP: { - read_leb_uint32(p, p_end, table_seg_idx); + pb_read_leb_uint32(p, p_end, table_seg_idx); if (!get_table_seg_elem_type(module, table_seg_idx, NULL, NULL, error_buf, error_buf_size)) @@ -14930,7 +15006,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif uint32 src_tbl_idx, dst_tbl_idx; - read_leb_uint32(p, p_end, dst_tbl_idx); + pb_read_leb_uint32(p, p_end, dst_tbl_idx); if (!get_table_elem_type(module, dst_tbl_idx, &dst_type, #if WASM_ENABLE_GC != 0 (void **)&dst_ref_type, @@ -14940,7 +15016,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, error_buf, error_buf_size)) goto fail; - read_leb_uint32(p, p_end, src_tbl_idx); + pb_read_leb_uint32(p, p_end, src_tbl_idx); if (!get_table_elem_type(module, src_tbl_idx, &src_type, #if WASM_ENABLE_GC != 0 (void **)&src_ref_type, @@ -15003,7 +15079,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_TABLE_SIZE: { - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); /* TODO: shall we create a new function to check table idx instead of using below function? */ if (!get_table_elem_type(module, table_idx, NULL, NULL, @@ -15034,7 +15110,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMRefType *ref_type = NULL; #endif - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); if (!get_table_elem_type(module, table_idx, &decl_type, #if WASM_ENABLE_GC != 0 (void **)&ref_type, @@ -15109,7 +15185,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, module->is_simd_used = true; #endif - read_leb_uint32(p, p_end, opcode1); + pb_read_leb_uint32(p, p_end, opcode1); /* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h */ @@ -15129,13 +15205,14 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { CHECK_MEMORY(); - read_leb_uint32(p, p_end, align); /* align */ + pb_read_leb_uint32(p, p_end, align); /* align */ if (!check_simd_memory_access_align( opcode1, align, error_buf, error_buf_size)) { goto fail; } - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_mem_offset(p, p_end, + mem_offset); /* offset */ POP_AND_PUSH(mem_offset_type, VALUE_TYPE_V128); #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 @@ -15148,13 +15225,14 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { CHECK_MEMORY(); - read_leb_uint32(p, p_end, align); /* align */ + pb_read_leb_uint32(p, p_end, align); /* align */ if (!check_simd_memory_access_align( opcode1, align, error_buf, error_buf_size)) { goto fail; } - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_mem_offset(p, p_end, + mem_offset); /* offset */ POP_V128(); POP_MEM_OFFSET(); @@ -15366,13 +15444,14 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, CHECK_MEMORY(); - read_leb_uint32(p, p_end, align); /* align */ + pb_read_leb_uint32(p, p_end, align); /* align */ if (!check_simd_memory_access_align( opcode1, align, error_buf, error_buf_size)) { goto fail; } - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_mem_offset(p, p_end, + mem_offset); /* offset */ CHECK_BUF(p, p_end, 1); lane = read_uint8(p); @@ -15397,13 +15476,14 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { CHECK_MEMORY(); - read_leb_uint32(p, p_end, align); /* align */ + pb_read_leb_uint32(p, p_end, align); /* align */ if (!check_simd_memory_access_align( opcode1, align, error_buf, error_buf_size)) { goto fail; } - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_mem_offset(p, p_end, + mem_offset); /* offset */ POP_AND_PUSH(mem_offset_type, VALUE_TYPE_V128); #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 @@ -15761,15 +15841,15 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 opcode1; - read_leb_uint32(p, p_end, opcode1); + pb_read_leb_uint32(p, p_end, opcode1); #if WASM_ENABLE_FAST_INTERP != 0 emit_byte(loader_ctx, opcode1); #endif if (opcode1 != WASM_OP_ATOMIC_FENCE) { CHECK_MEMORY(); - read_leb_uint32(p, p_end, align); /* align */ - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_uint32(p, p_end, align); /* align */ + pb_read_leb_mem_offset(p, p_end, mem_offset); /* offset */ if (!check_memory_align_equal(opcode1, align, error_buf, error_buf_size)) { goto fail; diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index f994f0defa..54f371f48c 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -6047,6 +6047,86 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, char *error_buf, } \ } while (0) +#if WASM_ENABLE_FAST_INTERP == 0 + +#define pb_read_leb_uint32 read_leb_uint32 +#define pb_read_leb_int32 read_leb_int32 +#define pb_read_leb_int64 read_leb_int64 +#define pb_read_leb_memarg read_leb_memarg +#define pb_read_leb_mem_offset read_leb_mem_offset +#define pb_read_leb_memidx read_leb_memidx + +#else + +/* Read leb without malformed format check */ +static uint64 +read_leb_quick(uint8 **p_buf, uint32 maxbits, bool sign) +{ + uint8 *buf = *p_buf; + uint64 result = 0, byte = 0; + uint32 shift = 0; + + do { + byte = *buf++; + result |= ((byte & 0x7f) << shift); + shift += 7; + } while (byte & 0x80); + + if (sign && (shift < maxbits) && (byte & 0x40)) { + /* Sign extend */ + result |= (~((uint64)0)) << shift; + } + + *p_buf = buf; + return result; +} + +#define pb_read_leb_uint32(p, p_end, res) \ + do { \ + if (!loader_ctx->p_code_compiled) \ + /* Enable format check in the first scan */ \ + read_leb_uint32(p, p_end, res); \ + else \ + /* Disable format check in the second scan */ \ + res = (uint32)read_leb_quick(&p, 32, false); \ + } while (0) + +#define pb_read_leb_int32(p, p_end, res) \ + do { \ + if (!loader_ctx->p_code_compiled) \ + /* Enable format check in the first scan */ \ + read_leb_int32(p, p_end, res); \ + else \ + /* Disable format check in the second scan */ \ + res = (int32)read_leb_quick(&p, 32, true); \ + } while (0) + +#define pb_read_leb_int64(p, p_end, res) \ + do { \ + if (!loader_ctx->p_code_compiled) \ + /* Enable format check in the first scan */ \ + read_leb_int64(p, p_end, res); \ + else \ + /* Disable format check in the second scan */ \ + res = (int64)read_leb_quick(&p, 64, true); \ + } while (0) + +#if WASM_ENABLE_MULTI_MEMORY != 0 +#define pb_read_leb_memarg read_leb_memarg +#else +#define pb_read_leb_memarg pb_read_leb_uint32 +#endif + +#if WASM_ENABLE_MEMORY64 != 0 +#define pb_read_leb_mem_offset read_leb_mem_offset +#else +#define pb_read_leb_mem_offset pb_read_leb_uint32 +#endif + +#define pb_read_leb_memidx pb_read_leb_uint32 + +#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */ + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 cur_func_idx, char *error_buf, @@ -6194,7 +6274,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, int32 type_index; /* Resolve the leb128 encoded type index as block type */ p--; - read_leb_int32(p, p_end, type_index); + pb_read_leb_int32(p, p_end, type_index); bh_assert((uint32)type_index < module->type_count); block_type.is_value_type = false; block_type.u.type = module->types[type_index]; @@ -6507,7 +6587,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 j; #endif - read_leb_uint32(p, p_end, count); + pb_read_leb_uint32(p, p_end, count); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, count); #endif @@ -6516,7 +6596,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, /* Get each depth and check it */ p_org = p; for (i = 0; i <= count; i++) { - read_leb_uint32(p, p_end, depth); + pb_read_leb_uint32(p, p_end, depth); bh_assert(loader_ctx->csp_num > 0); bh_assert(loader_ctx->csp_num - 1 >= depth); (void)depth; @@ -6614,7 +6694,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 func_idx; int32 idx; - read_leb_uint32(p, p_end, func_idx); + pb_read_leb_uint32(p, p_end, func_idx); #if WASM_ENABLE_FAST_INTERP != 0 /* we need to emit func_idx before arguments */ emit_uint32(loader_ctx, func_idx); @@ -6687,10 +6767,10 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, bh_assert(module->import_table_count + module->table_count > 0); - read_leb_uint32(p, p_end, type_idx); + pb_read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_REF_TYPES != 0 - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); #else CHECK_BUF(p, p_end, 1); table_idx = read_uint8(p); @@ -6930,7 +7010,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled; #endif - read_leb_uint32(p, p_end, vec_len); + pb_read_leb_uint32(p, p_end, vec_len); if (vec_len != 1) { /* typed select must have exactly one result */ set_error_buf(error_buf, error_buf_size, @@ -7005,7 +7085,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 decl_ref_type; uint32 table_idx; - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); if (!get_table_elem_type(module, table_idx, &decl_ref_type, error_buf, error_buf_size)) goto fail; @@ -7099,7 +7179,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_REF_FUNC: { uint32 func_idx = 0; - read_leb_uint32(p, p_end, func_idx); + pb_read_leb_uint32(p, p_end, func_idx); if (!check_function_index(module, func_idx, error_buf, error_buf_size)) { @@ -7316,7 +7396,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_GET_GLOBAL: { p_org = p - 1; - read_leb_uint32(p, p_end, global_idx); + pb_read_leb_uint32(p, p_end, global_idx); bh_assert(global_idx < global_count); global_type = global_idx < module->import_global_count @@ -7350,7 +7430,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, bool is_mutable = false; p_org = p - 1; - read_leb_uint32(p, p_end, global_idx); + pb_read_leb_uint32(p, p_end, global_idx); bh_assert(global_idx < global_count); is_mutable = global_idx < module->import_global_count @@ -7447,8 +7527,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } #endif CHECK_MEMORY(); - read_leb_memarg(p, p_end, align); /* align */ - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_memarg(p, p_end, align); /* align */ + pb_read_leb_mem_offset(p, p_end, mem_offset); /* offset */ #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, mem_offset); #endif @@ -7509,7 +7589,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_MEMORY_SIZE: CHECK_MEMORY(); - read_leb_memidx(p, p_end, memidx); + pb_read_leb_memidx(p, p_end, memidx); check_memidx(module, memidx); PUSH_PAGE_COUNT(); @@ -7521,7 +7601,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_MEMORY_GROW: CHECK_MEMORY(); - read_leb_memidx(p, p_end, memidx); + pb_read_leb_memidx(p, p_end, memidx); check_memidx(module, memidx); POP_AND_PUSH(mem_offset_type, mem_offset_type); @@ -7536,7 +7616,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_I32_CONST: - read_leb_int32(p, p_end, i32_const); + pb_read_leb_int32(p, p_end, i32_const); #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); disable_emit = true; @@ -7554,7 +7634,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; case WASM_OP_I64_CONST: - read_leb_int64(p, p_end, i64_const); + pb_read_leb_int64(p, p_end, i64_const); #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); disable_emit = true; @@ -7836,7 +7916,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 opcode1; - read_leb_uint32(p, p_end, opcode1); + pb_read_leb_uint32(p, p_end, opcode1); #if WASM_ENABLE_FAST_INTERP != 0 emit_byte(loader_ctx, ((uint8)opcode1)); #endif @@ -7861,11 +7941,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_MEMORY_INIT: { CHECK_MEMORY(); - read_leb_uint32(p, p_end, segment_index); + pb_read_leb_uint32(p, p_end, segment_index); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, segment_index); #endif - read_leb_memidx(p, p_end, memidx); + pb_read_leb_memidx(p, p_end, memidx); check_memidx(module, memidx); bh_assert(segment_index < module->data_seg_count); @@ -7881,7 +7961,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, } case WASM_OP_DATA_DROP: { - read_leb_uint32(p, p_end, segment_index); + pb_read_leb_uint32(p, p_end, segment_index); #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, segment_index); #endif @@ -7897,9 +7977,9 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, CHECK_MEMORY(); CHECK_BUF(p, p_end, sizeof(int16)); /* check both src and dst memory index */ - read_leb_memidx(p, p_end, memidx); + pb_read_leb_memidx(p, p_end, memidx); check_memidx(module, memidx); - read_leb_memidx(p, p_end, memidx); + pb_read_leb_memidx(p, p_end, memidx); check_memidx(module, memidx); POP_MEM_OFFSET(); @@ -7913,7 +7993,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_MEMORY_FILL: { CHECK_MEMORY(); - read_leb_memidx(p, p_end, memidx); + pb_read_leb_memidx(p, p_end, memidx); check_memidx(module, memidx); POP_MEM_OFFSET(); @@ -7931,8 +8011,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 seg_ref_type, tbl_ref_type; uint32 table_seg_idx, table_idx; - read_leb_uint32(p, p_end, table_seg_idx); - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_seg_idx); + pb_read_leb_uint32(p, p_end, table_idx); if (!get_table_elem_type(module, table_idx, &tbl_ref_type, error_buf, @@ -7967,7 +8047,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, case WASM_OP_ELEM_DROP: { uint32 table_seg_idx; - read_leb_uint32(p, p_end, table_seg_idx); + pb_read_leb_uint32(p, p_end, table_seg_idx); if (!get_table_seg_elem_type(module, table_seg_idx, NULL, error_buf, error_buf_size)) @@ -7983,13 +8063,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 src_tbl_idx, dst_tbl_idx, src_tbl_idx_type, dst_tbl_idx_type, min_tbl_idx_type; - read_leb_uint32(p, p_end, src_tbl_idx); + pb_read_leb_uint32(p, p_end, src_tbl_idx); if (!get_table_elem_type(module, src_tbl_idx, &src_ref_type, error_buf, error_buf_size)) goto fail; - read_leb_uint32(p, p_end, dst_tbl_idx); + pb_read_leb_uint32(p, p_end, dst_tbl_idx); if (!get_table_elem_type(module, dst_tbl_idx, &dst_ref_type, error_buf, error_buf_size)) @@ -8036,7 +8116,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 table_idx; - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); /* TODO: shall we create a new function to check table idx instead of using below function? */ if (!get_table_elem_type(module, table_idx, NULL, @@ -8061,7 +8141,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint8 decl_ref_type; uint32 table_idx; - read_leb_uint32(p, p_end, table_idx); + pb_read_leb_uint32(p, p_end, table_idx); if (!get_table_elem_type(module, table_idx, &decl_ref_type, error_buf, error_buf_size)) @@ -8113,15 +8193,15 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, { uint32 opcode1; - read_leb_uint32(p, p_end, opcode1); + pb_read_leb_uint32(p, p_end, opcode1); #if WASM_ENABLE_FAST_INTERP != 0 emit_byte(loader_ctx, opcode1); #endif if (opcode1 != WASM_OP_ATOMIC_FENCE) { CHECK_MEMORY(); - read_leb_uint32(p, p_end, align); /* align */ - read_leb_mem_offset(p, p_end, mem_offset); /* offset */ + pb_read_leb_uint32(p, p_end, align); /* align */ + pb_read_leb_mem_offset(p, p_end, mem_offset); /* offset */ #if WASM_ENABLE_FAST_INTERP != 0 emit_uint32(loader_ctx, mem_offset); #endif