From e8e45aeecd1b3e35205767dc85825299a910d458 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Fri, 8 May 2020 12:38:59 +0800 Subject: [PATCH] Refine aot stack overflow check and enhance wasm loader malformed checks (#248) And separate global data from wasm memory instance --- core/iwasm/aot/aot_loader.c | 14 +- core/iwasm/aot/aot_runtime.c | 18 +- core/iwasm/compilation/aot.c | 2 + core/iwasm/compilation/aot.h | 2 + core/iwasm/compilation/aot_emit_function.c | 26 +- core/iwasm/interpreter/wasm_interp_classic.c | 3 +- core/iwasm/interpreter/wasm_interp_fast.c | 3 +- core/iwasm/interpreter/wasm_loader.c | 225 ++++++++++++------ core/iwasm/interpreter/wasm_runtime.c | 80 +++---- core/iwasm/interpreter/wasm_runtime.h | 9 +- .../platform/android/platform_internal.h | 4 +- .../platform/common/posix/posix_thread.c | 3 +- .../platform/darwin/platform_internal.h | 4 +- .../shared/platform/linux/platform_internal.h | 4 +- .../platform/vxworks/platform_internal.h | 4 +- .../src/platform/zephyr/iwasm_main.c | 2 +- 16 files changed, 241 insertions(+), 162 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index a68f8e96c..560030d56 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1959,12 +1959,14 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx, module->start_func_index = comp_data->start_func_index; if (comp_data->start_func_index != (uint32)-1) { - bh_assert(comp_data->start_func_index >= module->import_func_count - && comp_data->start_func_index < module->import_func_count - + module->func_count); - module->start_function = - module->func_ptrs[comp_data->start_func_index - - module->import_func_count]; + bh_assert(comp_data->start_func_index < module->import_func_count + + module->func_count); + /* TODO: fix issue that start func cannot be import func */ + if (comp_data->start_func_index >= module->import_func_count) { + module->start_function = + module->func_ptrs[comp_data->start_func_index + - module->import_func_count]; + } } else { module->start_function = NULL; diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 308e545c8..a57f8e8d4 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -897,6 +897,15 @@ aot_call_indirect(WASMExecEnv *exec_env, void *attachment = NULL; char buf[128]; + /* this function is called from native code, so exec_env->handle and + exec_env->native_stack_boundary must have been set, we don't set + it again */ + + if ((uint8*)&module_inst < exec_env->native_stack_boundary) { + aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW); + return false; + } + if (table_elem_idx >= table_size) { aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT); return false; @@ -941,15 +950,6 @@ aot_call_indirect(WASMExecEnv *exec_env, } } - /* this function is called from native code, so exec_env->handle and - exec_env->native_stack_boundary must have been set, we don't set - it again */ - - if ((uint8*)&module_inst < exec_env->native_stack_boundary) { - aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW); - return false; - } - return wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature, attachment, argv, argc, argv); diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index ee431fd4f..a130ba7a6 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -327,6 +327,8 @@ aot_create_funcs(const WASMModule *module) /* Resolve local variable info and code info */ funcs[i]->local_count = func->local_count; funcs[i]->local_types = func->local_types; + funcs[i]->param_cell_num = func->param_cell_num; + funcs[i]->local_cell_num = func->local_cell_num; funcs[i]->code = func->code; funcs[i]->code_size = func->code_size; } diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 22ccff60e..ede02b434 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -98,6 +98,8 @@ typedef struct AOTFunc { uint32 func_type_index; uint32 local_count; uint8 *local_types; + uint16 param_cell_num; + uint16 local_cell_num; uint32 code_size; uint8 *code; } AOTFunc; diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 2228177a1..3c1708928 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -256,11 +256,25 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } static bool -check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) +check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, + uint32 callee_cell_num) { LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder); LLVMBasicBlockRef check_stack; - LLVMValueRef cmp; + LLVMValueRef callee_local_size, stack_bound, cmp; + + if (!(callee_local_size = I32_CONST(callee_cell_num * 4))) { + aot_set_last_error("llvm build const failed."); + return false; + } + + if (!(stack_bound = LLVMBuildInBoundsGEP(comp_ctx->builder, + func_ctx->native_stack_bound, + &callee_local_size, 1, + "stack_bound"))) { + aot_set_last_error("llvm build inbound gep failed."); + return false; + } if (!(check_stack = LLVMAppendBasicBlockInContext(comp_ctx->context, func_ctx->func, @@ -272,7 +286,7 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) LLVMMoveBasicBlockAfter(check_stack, block_curr); if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT, - func_ctx->last_alloca, func_ctx->native_stack_bound, + func_ctx->last_alloca, stack_bound, "cmp"))) { aot_set_last_error("llvm build icmp failed."); return false; @@ -297,11 +311,13 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint32 func_count = comp_ctx->func_ctx_count, param_cell_num = 0; AOTFuncContext **func_ctxes = comp_ctx->func_ctxes; AOTFuncType *func_type; + AOTFunc *aot_func; LLVMTypeRef *param_types = NULL, ret_type; LLVMValueRef *param_values = NULL, value_ret = NULL, func; LLVMValueRef import_func_idx, res; int32 i, j = 0, param_count; uint64 total_size; + uint32 callee_cell_num; uint8 wasm_ret_type; bool ret = false; @@ -379,8 +395,10 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } else { func = func_ctxes[func_idx - import_func_count]->func; + aot_func = func_ctxes[func_idx - import_func_count]->aot_func; + callee_cell_num = aot_func->param_cell_num + aot_func->local_cell_num + 1; - if (!check_stack_boundary(comp_ctx, func_ctx)) + if (!check_stack_boundary(comp_ctx, func_ctx, callee_cell_num)) goto fail; /* Call the function */ diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index dea86c1bc..54fb7ccb2 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -901,7 +901,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count - heap_base_offset : 0; - uint8 *global_data = memory ? memory->global_data : NULL; + uint8 *global_data = module->global_data; WASMTableInstance *table = module->default_table; WASMGlobalInstance *globals = module->globals; uint8 opcode_IMPDEP = WASM_OP_IMPDEP; @@ -1521,7 +1521,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, memory = module->default_memory; total_mem_size = num_bytes_per_page * memory->cur_page_count - heap_base_offset; - global_data = memory->global_data; } (void)reserved; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index ae4cbb3eb..60a04dc50 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -893,7 +893,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0; uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count - heap_base_offset : 0; - uint8 *global_data = memory ? memory->global_data : NULL; + uint8 *global_data = module->global_data; WASMTableInstance *table = module->default_table; WASMGlobalInstance *globals = module->globals; uint8 opcode_IMPDEP = WASM_OP_IMPDEP; @@ -1429,7 +1429,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, memory = module->default_memory; total_mem_size = num_bytes_per_page * memory->cur_page_count - heap_base_offset; - global_data = memory->global_data; } (void)reserved; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 24d02d0b8..5c882e9df 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -467,6 +467,18 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return true; } +static bool +check_table_max_size(uint32 init_size, uint32 max_size, + char *error_buf, uint32 error_buf_size) +{ + if (max_size < init_size) { + set_error_buf(error_buf, error_buf_size, + "size minimum must not be greater than maximum"); + return false; + } + return true; +} + static bool load_table_import(const uint8 **p_buf, const uint8 *buf_end, WASMTableImport *table, @@ -480,8 +492,12 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC); read_leb_uint32(p, p_end, table->flags); read_leb_uint32(p, p_end, table->init_size); - if (table->flags & 1) + if (table->flags & 1) { read_leb_uint32(p, p_end, table->max_size); + if (!check_table_max_size(table->init_size, table->max_size, + error_buf, error_buf_size)) + return false; + } else table->max_size = 0x10000; @@ -573,8 +589,12 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table, bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC); read_leb_uint32(p, p_end, table->flags); read_leb_uint32(p, p_end, table->init_size); - if (table->flags & 1) + if (table->flags & 1) { read_leb_uint32(p, p_end, table->max_size); + if (!check_table_max_size(table->init_size, table->max_size, + error_buf, error_buf_size)) + return false; + } else table->max_size = 0x10000; @@ -1065,7 +1085,6 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, WASMTable *table; read_leb_uint32(p, p_end, table_count); - bh_assert(table_count == 1); if (table_count) { if (table_count > 1) { @@ -2419,6 +2438,7 @@ typedef struct BranchBlock { uint8 block_type; uint8 return_type; bool is_block_reachable; + bool skip_else_branch; uint8 *start_addr; uint8 *else_addr; uint8 *end_addr; @@ -2590,10 +2610,13 @@ check_stack_pop(WASMLoaderContext *ctx, uint8 type, char *error_buf, uint32 error_buf_size, const char *type_str) { + uint32 block_stack_cell_num = ctx->stack_cell_num + - (ctx->frame_csp - 1)->stack_cell_num; + if (((type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32) - && ctx->stack_cell_num < 1) + && block_stack_cell_num < 1) || ((type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64) - && ctx->stack_cell_num < 2)) { + && block_stack_cell_num < 2)) { set_error_buf(error_buf, error_buf_size, "WASM module load failed: " "type mismatch: expect data but stack was empty"); @@ -2766,7 +2789,17 @@ static bool wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf, uint32 error_buf_size) { + uint8 block_return_type; + CHECK_CSP_POP(); + + block_return_type = (ctx->frame_csp - 1)->return_type; + if (!wasm_loader_pop_frame_ref(ctx, block_return_type, + error_buf, error_buf_size) + || !wasm_loader_push_frame_ref(ctx, block_return_type, + error_buf, error_buf_size)) + goto fail; + ctx->frame_csp--; ctx->csp_num--; return true; @@ -3476,7 +3509,6 @@ fail: goto fail; \ } while (0) - #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() do { \ read_leb_uint32(p, p_end, local_idx); \ if (local_idx >= param_count + local_count) { \ @@ -3515,11 +3547,6 @@ check_memory(WASMModule *module, goto fail; \ } while (0) -#if WASM_ENABLE_FAST_INTERP != 0 - - -#endif /* WASM_ENABLE_FAST_INTERP */ - static bool is_block_type_valid(uint8 type) { @@ -3538,6 +3565,44 @@ is_block_type_valid(uint8 type) } \ } while (0) +static BranchBlock * +check_branch_block(WASMLoaderContext *loader_ctx, + uint8 **p_buf, uint8 *buf_end, + char *error_buf, uint32 error_buf_size) +{ + uint8 *p = *p_buf, *p_end = buf_end; + BranchBlock *frame_csp_tmp; + uint32 depth; + + read_leb_uint32(p, p_end, depth); + CHECK_BR(depth); + frame_csp_tmp = loader_ctx->frame_csp - depth - 1; +#if WASM_ENABLE_FAST_INTERP != 0 + emit_br_info(frame_csp_tmp); +#endif + + *p_buf = p; + return frame_csp_tmp; +fail: + return NULL; +} + +static bool +check_branch_block_ret(WASMLoaderContext *loader_ctx, + BranchBlock *frame_csp_tmp, + char *error_buf, uint32 error_buf_size) +{ + frame_csp_tmp->is_block_reachable = true; + if (frame_csp_tmp->block_type != BLOCK_TYPE_LOOP) { + uint8 block_return_type = frame_csp_tmp->return_type; + POP_TYPE(block_return_type); + PUSH_TYPE(block_return_type); + } + return true; +fail: + return false; +} + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, BlockAddr *block_addr_cache, @@ -3547,7 +3612,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 param_count, local_count, global_count; uint8 *param_types, ret_type, *local_types, local_type, global_type; uint16 *local_offsets, local_offset; - uint32 count, i, local_idx, global_idx, depth, u32, align, mem_offset; + uint32 count, i, local_idx, global_idx, u32, align, mem_offset; uint32 cache_index, item_index; int32 i32, i32_const = 0; int64 i64; @@ -3555,6 +3620,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, bool return_value = false, is_i32_const = false; BlockAddr *cache_items; WASMLoaderContext *loader_ctx; + BranchBlock *frame_csp_tmp; #if WASM_ENABLE_FAST_INTERP != 0 uint8 *func_const_end, *func_const; int16 operand_offset; @@ -3657,32 +3723,32 @@ re_scan: if (!is_i32_const) (loader_ctx->frame_csp - 1)->is_block_reachable = true; else { - if (!i32_const) { - cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr) - & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1); - cache_items = block_addr_cache + - BLOCK_ADDR_CONFLICT_SIZE * cache_index; - for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; - item_index++) { - if (cache_items[item_index].start_addr == - (loader_ctx->frame_csp - 1)->start_addr) { - (loader_ctx->frame_csp - 1)->else_addr = - cache_items[item_index].else_addr; - (loader_ctx->frame_csp - 1)->end_addr = - cache_items[item_index].end_addr; - break; - } + cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr) + & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1); + cache_items = block_addr_cache + + BLOCK_ADDR_CONFLICT_SIZE * cache_index; + for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE; + item_index++) { + if (cache_items[item_index].start_addr == + (loader_ctx->frame_csp - 1)->start_addr) { + (loader_ctx->frame_csp - 1)->else_addr = + cache_items[item_index].else_addr; + (loader_ctx->frame_csp - 1)->end_addr = + cache_items[item_index].end_addr; + break; } - if (item_index == BLOCK_ADDR_CONFLICT_SIZE - && !wasm_loader_find_block_addr(block_addr_cache, - (loader_ctx->frame_csp - 1)->start_addr, - p_end, - (loader_ctx->frame_csp - 1)->block_type, - &(loader_ctx->frame_csp - 1)->else_addr, - &(loader_ctx->frame_csp - 1)->end_addr, - error_buf, error_buf_size)) - goto fail; + } + if (item_index == BLOCK_ADDR_CONFLICT_SIZE + && !wasm_loader_find_block_addr(block_addr_cache, + (loader_ctx->frame_csp - 1)->start_addr, + p_end, + (loader_ctx->frame_csp - 1)->block_type, + &(loader_ctx->frame_csp - 1)->else_addr, + &(loader_ctx->frame_csp - 1)->end_addr, + error_buf, error_buf_size)) + goto fail; + if (!i32_const) { if ((loader_ctx->frame_csp - 1)->else_addr) { #if WASM_ENABLE_FAST_INTERP != 0 loader_ctx->frame_offset = loader_ctx->frame_offset_bottom + @@ -3698,6 +3764,10 @@ re_scan: is_i32_const = false; continue; } + else { + /* The else branch cannot be reached, ignored it. */ + (loader_ctx->frame_csp - 1)->skip_else_branch = true; + } } break; @@ -3710,6 +3780,16 @@ re_scan: goto fail; } + if ((loader_ctx->frame_csp - 1)->skip_else_branch) { + /* The else branch is ignored. */ + is_i32_const = false; + p = (loader_ctx->frame_csp - 1)->end_addr; +#if WASM_ENABLE_FAST_INTERP != 0 + skip_label(); +#endif + continue; + } + (loader_ctx->frame_csp - 1)->else_addr = p - 1; loader_ctx->stack_cell_num = (loader_ctx->frame_csp - 1)->stack_cell_num; loader_ctx->frame_ref = loader_ctx->frame_ref_bottom + @@ -3748,9 +3828,6 @@ re_scan: { POP_CSP(); - POP_TYPE(loader_ctx->frame_csp->return_type); - PUSH_TYPE(loader_ctx->frame_csp->return_type); - #if WASM_ENABLE_FAST_INTERP != 0 skip_label(); // copy the result to the block return address @@ -3800,16 +3877,13 @@ re_scan: case WASM_OP_BR: { -#if WASM_ENABLE_FAST_INTERP != 0 - BranchBlock *frame_csp_tmp; -#endif - read_leb_uint32(p, p_end, depth); - CHECK_BR(depth); + if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, + error_buf, error_buf_size))) + goto fail; -#if WASM_ENABLE_FAST_INTERP != 0 - frame_csp_tmp = loader_ctx->frame_csp - depth - 1; - emit_br_info(frame_csp_tmp); -#endif + if (!check_branch_block_ret(loader_ctx, frame_csp_tmp, + error_buf, error_buf_size)) + goto fail; handle_next_reachable_block: for (i = 1; i <= loader_ctx->csp_num; i++) @@ -3870,31 +3944,25 @@ handle_next_reachable_block: case WASM_OP_BR_IF: { -#if WASM_ENABLE_FAST_INTERP != 0 - BranchBlock *frame_csp_tmp; -#endif - read_leb_uint32(p, p_end, depth); POP_I32(); - CHECK_BR(depth); -#if WASM_ENABLE_FAST_INTERP != 0 - frame_csp_tmp = loader_ctx->frame_csp - depth - 1; - emit_br_info(frame_csp_tmp); -#endif - if (!is_i32_const) - (loader_ctx->frame_csp - (depth + 1))->is_block_reachable = true; - else { - if (i32_const) - goto handle_next_reachable_block; + + if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, + error_buf, error_buf_size))) + goto fail; + + if (!is_i32_const || i32_const) { + /* The branch can be reached */ + if (!check_branch_block_ret(loader_ctx, frame_csp_tmp, + error_buf, error_buf_size)) + goto fail; } + if (is_i32_const && i32_const) + goto handle_next_reachable_block; break; } case WASM_OP_BR_TABLE: { -#if WASM_ENABLE_FAST_INTERP != 0 - BranchBlock *frame_csp_tmp; -#endif - read_leb_uint32(p, p_end, count); #if WASM_ENABLE_FAST_INTERP != 0 emit_const(count); @@ -3903,12 +3971,13 @@ handle_next_reachable_block: /* TODO: check the const */ for (i = 0; i <= count; i++) { - read_leb_uint32(p, p_end, depth); - CHECK_BR(depth); -#if WASM_ENABLE_FAST_INTERP != 0 - frame_csp_tmp = loader_ctx->frame_csp - depth - 1; - emit_br_info(frame_csp_tmp); -#endif + if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, + error_buf, error_buf_size))) + goto fail; + + if (!check_branch_block_ret(loader_ctx, frame_csp_tmp, + error_buf, error_buf_size)) + goto fail; } goto handle_next_reachable_block; @@ -4037,10 +4106,12 @@ handle_next_reachable_block: case WASM_OP_DROP: case WASM_OP_DROP_64: { - if (loader_ctx->stack_cell_num <= 0) { + if (loader_ctx->stack_cell_num + - (loader_ctx->frame_csp - 1)->stack_cell_num <= 0) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " - "opcode drop was found but stack was empty"); + "type mismatch, opcode drop was found " + "but stack was empty"); goto fail; } @@ -4057,10 +4128,12 @@ handle_next_reachable_block: #endif } else { - if (loader_ctx->stack_cell_num <= 1) { + if (loader_ctx->stack_cell_num + - (loader_ctx->frame_csp - 1)->stack_cell_num <= 0) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " - "opcode drop was found but stack was empty"); + "type mismatch, opcode drop was found " + "but stack was empty"); goto fail; } loader_ctx->frame_ref -= 2; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 84785804d..9bf28c239 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -60,15 +60,13 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count) static WASMMemoryInstance* memory_instantiate(uint32 num_bytes_per_page, uint32 init_page_count, uint32 max_page_count, - uint32 global_data_size, uint32 heap_size, char *error_buf, uint32 error_buf_size) { WASMMemoryInstance *memory; uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + (uint64)heap_size + - num_bytes_per_page * (uint64)init_page_count + - global_data_size; + num_bytes_per_page * (uint64)init_page_count; /* Allocate memory space, addr data and global data */ if (total_size >= UINT32_MAX @@ -85,10 +83,8 @@ memory_instantiate(uint32 num_bytes_per_page, memory->heap_data = memory->base_addr; memory->memory_data = memory->heap_data + heap_size; - memory->global_data = memory->memory_data + + memory->end_addr = memory->memory_data + num_bytes_per_page * memory->cur_page_count; - memory->global_data_size = global_data_size; - memory->end_addr = memory->global_data + global_data_size; bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size); @@ -112,7 +108,7 @@ memory_instantiate(uint32 num_bytes_per_page, */ static WASMMemoryInstance** memories_instantiate(const WASMModule *module, - uint32 global_data_size, uint32 heap_size, + uint32 heap_size, char *error_buf, uint32 error_buf_size) { WASMImport *import; @@ -121,9 +117,6 @@ memories_instantiate(const WASMModule *module, uint64 total_size; WASMMemoryInstance **memories, *memory; - if (memory_count == 0 && global_data_size > 0) - memory_count = 1; - total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count; if (total_size >= UINT32_MAX @@ -143,7 +136,6 @@ memories_instantiate(const WASMModule *module, memory_instantiate(import->u.memory.num_bytes_per_page, import->u.memory.init_page_count, import->u.memory. max_page_count, - global_data_size, heap_size, error_buf, error_buf_size))) { set_error_buf(error_buf, error_buf_size, "Instantiate memory failed: " @@ -159,7 +151,6 @@ memories_instantiate(const WASMModule *module, memory_instantiate(module->memories[i].num_bytes_per_page, module->memories[i].init_page_count, module->memories[i].max_page_count, - global_data_size, heap_size, error_buf, error_buf_size))) { set_error_buf(error_buf, error_buf_size, "Instantiate memory failed: " @@ -172,8 +163,8 @@ memories_instantiate(const WASMModule *module, if (mem_index == 0) { /* no import memory and define memory, but has global variables */ if (!(memory = memories[mem_index++] = - memory_instantiate(0, 0, 0, global_data_size, - heap_size, error_buf, error_buf_size))) { + memory_instantiate(0, 0, 0, heap_size, + error_buf, error_buf_size))) { set_error_buf(error_buf, error_buf_size, "Instantiate memory failed: " "allocate memory failed.\n"); @@ -608,11 +599,20 @@ wasm_instantiate(WASMModule *module, module->import_function_count + module->function_count; module_inst->export_func_count = get_export_function_count(module); + if (global_count > 0) { + if (!(module_inst->global_data = + wasm_runtime_malloc(global_data_size))) { + wasm_deinstantiate(module_inst); + return NULL; + } + memset(module_inst->global_data, 0, global_data_size); + } + /* Instantiate memories/tables/functions */ - if (((module_inst->memory_count > 0 || global_count > 0) + if ((module_inst->memory_count > 0 && !(module_inst->memories = - memories_instantiate(module, global_data_size, - heap_size, error_buf, error_buf_size))) + memories_instantiate(module, heap_size, + error_buf, error_buf_size))) || (module_inst->table_count > 0 && !(module_inst->tables = tables_instantiate(module, error_buf, @@ -629,13 +629,8 @@ wasm_instantiate(WASMModule *module, return NULL; } - if (module_inst->memory_count || global_count > 0) { - WASMMemoryInstance *memory; - - memory = module_inst->default_memory = module_inst->memories[0]; - memory_data = module_inst->default_memory->memory_data; - - /* fix import memoryBase */ + if (global_count > 0) { + /* fix globals */ if (!globals_instantiate_fix(globals, module, module_inst, error_buf, error_buf_size)) { wasm_deinstantiate(module_inst); @@ -643,7 +638,7 @@ wasm_instantiate(WASMModule *module, } /* Initialize the global data */ - global_data = memory->global_data; + global_data = module_inst->global_data; global_data_end = global_data + global_data_size; global = globals; for (i = 0; i < global_count; i++, global++) { @@ -665,8 +660,16 @@ wasm_instantiate(WASMModule *module, } bh_assert(global_data == global_data_end); + } + + if (module_inst->memory_count) { + WASMMemoryInstance *memory; + + memory = module_inst->default_memory = module_inst->memories[0]; + memory_data = module_inst->default_memory->memory_data; + /* Initialize the memory data with data segment section */ - if (module_inst->default_memory->cur_page_count > 0) { + if (memory->cur_page_count > 0) { for (i = 0; i < module->data_seg_count; i++) { data_seg = module->data_segments[i]; bh_assert(data_seg->memory_index == 0); @@ -685,8 +688,8 @@ wasm_instantiate(WASMModule *module, base_offset = (uint32)data_seg->base_offset.u.i32; length = data_seg->data_length; - memory_size = module_inst->default_memory->num_bytes_per_page - * module_inst->default_memory->cur_page_count; + memory_size = memory->num_bytes_per_page + * memory->cur_page_count; if (length > 0 && (base_offset >= memory_size @@ -825,6 +828,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst) globals_deinstantiate(module_inst->globals); export_functions_deinstantiate(module_inst->export_functions); + if (module_inst->global_data) + wasm_runtime_free(module_inst->global_data); + wasm_runtime_free(module_inst); } @@ -1057,14 +1063,11 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) { WASMMemoryInstance *memory = module->default_memory, *new_memory; uint32 heap_size = memory->memory_data - memory->heap_data; - uint32 old_page_count = memory->cur_page_count; uint32 total_size_old = memory->end_addr - (uint8*)memory; uint32 total_page_count = inc_page_count + memory->cur_page_count; uint64 total_size = offsetof(WASMMemoryInstance, base_addr) + (uint64)heap_size - + memory->num_bytes_per_page * (uint64)total_page_count - + memory->global_data_size; - uint8 *global_data_old; + + memory->num_bytes_per_page * (uint64)total_page_count; void *heap_handle_old = memory->heap_handle; if (inc_page_count <= 0) @@ -1111,17 +1114,8 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) new_memory->cur_page_count = total_page_count; new_memory->heap_data = new_memory->base_addr; new_memory->memory_data = new_memory->base_addr + heap_size; - new_memory->global_data = new_memory->memory_data + - new_memory->num_bytes_per_page * total_page_count; - new_memory->end_addr = new_memory->global_data + new_memory->global_data_size; - - global_data_old = new_memory->memory_data + - new_memory->num_bytes_per_page * old_page_count; - - /* Copy global data */ - bh_memcpy_s(new_memory->global_data, new_memory->global_data_size, - global_data_old, new_memory->global_data_size); - memset(global_data_old, 0, new_memory->global_data_size); + new_memory->end_addr = new_memory->memory_data + + new_memory->num_bytes_per_page * total_page_count; module->memories[0] = module->default_memory = new_memory; return true; diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 102db8795..03268e63d 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -33,17 +33,12 @@ typedef struct WASMMemoryInstance { /* Memory data */ uint8 *memory_data; - /* Global data of global instances */ - uint8 *global_data; - uint32 global_data_size; - /* End address of memory */ uint8 *end_addr; /* Base address, the layout is: - heap_data + memory data + global data + heap_data + memory data memory data init size is: num_bytes_per_page * cur_page_count - global data size is calculated in module instantiating Note: when memory is re-allocated, the heap data and memory data must be copied to new memory also. */ @@ -127,6 +122,8 @@ typedef struct WASMModuleInstance { WASMMemoryInstance *default_memory; WASMTableInstance *default_table; + /* Global data of global instances */ + uint8 *global_data; WASMFunctionInstance *start_function; diff --git a/core/shared/platform/android/platform_internal.h b/core/shared/platform/android/platform_internal.h index 5754daf7d..bf1248a25 100644 --- a/core/shared/platform/android/platform_internal.h +++ b/core/shared/platform/android/platform_internal.h @@ -37,10 +37,8 @@ extern "C" { #define BH_PLATFORM_ANDROID #endif -#define _STACK_SIZE_ADJUSTMENT (32 * 1024) - /* Stack size of applet threads's native part. */ -#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) +#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index cb01a912d..1a32b1502 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -233,7 +233,8 @@ uint8 *os_thread_get_stack_boundary() } if (addr) - return (uint8*)addr + _STACK_SIZE_ADJUSTMENT; + /* Reserved 4 KB for safety */ + return (uint8*)addr + 4 * 1024; else return NULL; } diff --git a/core/shared/platform/darwin/platform_internal.h b/core/shared/platform/darwin/platform_internal.h index de2eb2051..55622028b 100644 --- a/core/shared/platform/darwin/platform_internal.h +++ b/core/shared/platform/darwin/platform_internal.h @@ -37,10 +37,8 @@ extern "C" { #define BH_PLATFORM_DARWIN #endif -#define _STACK_SIZE_ADJUSTMENT (32 * 1024) - /* Stack size of applet threads's native part. */ -#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) +#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 diff --git a/core/shared/platform/linux/platform_internal.h b/core/shared/platform/linux/platform_internal.h index 343172bef..445d881fd 100644 --- a/core/shared/platform/linux/platform_internal.h +++ b/core/shared/platform/linux/platform_internal.h @@ -37,10 +37,8 @@ extern "C" { #define BH_PLATFORM_LINUX #endif -#define _STACK_SIZE_ADJUSTMENT (32 * 1024) - /* Stack size of applet threads's native part. */ -#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) +#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 diff --git a/core/shared/platform/vxworks/platform_internal.h b/core/shared/platform/vxworks/platform_internal.h index 266c804c5..06b4d3ae4 100644 --- a/core/shared/platform/vxworks/platform_internal.h +++ b/core/shared/platform/vxworks/platform_internal.h @@ -36,10 +36,8 @@ extern "C" { #define BH_PLATFORM_VXWORKS #endif -#define _STACK_SIZE_ADJUSTMENT (32 * 1024) - /* Stack size of applet threads's native part. */ -#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT) +#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024) /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c index 217639752..cc0111eb3 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c @@ -74,7 +74,7 @@ host_interface interface = { timer_ctx_t timer_ctx; -static char global_heap_buf[370 * 1024] = { 0 }; +static char global_heap_buf[368 * 1024] = { 0 }; static NativeSymbol native_symbols[] = { EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"),