From a5188f5574a0f0aed7d178ca3774ff8657f4ac95 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Thu, 28 Jan 2021 02:16:02 -0600 Subject: [PATCH] Add checks to avoid wasm_runtime_malloc memory with size 0 (#507) In some platforms, allocating memory with size 0 may return NULL but not an empty memory block, which causes runtime load, instantiate or execute wasm/aot file failed. We add checks to try to avoid allocating memory in runtime if the size is 0. And in wasm_runtime_malloc/free, output warning if allocate memory with size 0 and free memory with NULL ptr. Also fix some coding style issues, fix handle riscv32 ilp32d issue, and fix several wasm-c-api issues. Signed-off-by: Wenyong Huang --- core/iwasm/aot/aot_loader.c | 26 +++-- core/iwasm/aot/aot_runtime.c | 43 +++++--- core/iwasm/common/wasm_c_api.c | 100 ++++++++++-------- core/iwasm/common/wasm_memory.c | 14 ++- core/iwasm/common/wasm_runtime_common.c | 15 ++- core/iwasm/compilation/aot.h | 2 +- core/iwasm/compilation/aot_emit_aot_file.c | 14 +-- core/iwasm/compilation/aot_emit_function.c | 16 +-- core/iwasm/compilation/aot_emit_memory.c | 24 +++-- core/iwasm/compilation/aot_llvm.c | 38 ++++++- core/iwasm/compilation/aot_llvm.h | 1 + .../compilation/simd/simd_access_lanes.c | 2 +- core/iwasm/interpreter/wasm_loader.c | 10 +- core/iwasm/interpreter/wasm_mini_loader.c | 10 +- core/iwasm/interpreter/wasm_runtime.c | 29 +++-- .../sandboxed-system-primitives/src/posix.c | 3 +- core/shared/utils/bh_log.h | 4 +- core/shared/utils/uncommon/bh_read_file.c | 14 ++- samples/wasm-c-api/CMakeLists.txt | 2 +- .../workload/meshoptimizer/codecbench.patch | 4 +- 20 files changed, 240 insertions(+), 131 deletions(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index eb9f198f..769e47d6 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -1117,8 +1117,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, uint64 size, text_offset; size = sizeof(void*) * (uint64)module->func_count; - if (!(module->func_ptrs = loader_malloc - (size, error_buf, error_buf_size))) { + if (size > 0 + && !(module->func_ptrs = loader_malloc + (size, error_buf, error_buf_size))) { return false; } @@ -1158,8 +1159,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, } size = sizeof(uint32) * (uint64)module->func_count; - if (!(module->func_type_indexes = loader_malloc - (size, error_buf, error_buf_size))) { + if (size > 0 + && !(module->func_type_indexes = loader_malloc + (size, error_buf, error_buf_size))) { return false; } @@ -1498,7 +1500,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, /* Allocate memory for relocation groups */ size = sizeof(AOTRelocationGroup) * (uint64)group_count; - if (!(groups = loader_malloc(size, error_buf, error_buf_size))) { + if (size > 0 + && !(groups = loader_malloc(size, error_buf, error_buf_size))) { goto fail; } @@ -2065,8 +2068,9 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx, /* Allocate memory for function pointers */ size = (uint64)module->func_count * sizeof(void *); - if (!(module->func_ptrs = - loader_malloc(size, error_buf, error_buf_size))) { + if (size > 0 + && !(module->func_ptrs = + loader_malloc(size, error_buf, error_buf_size))) { goto fail2; } @@ -2085,8 +2089,9 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx, /* Allocation memory for function type indexes */ size = (uint64)module->func_count * sizeof(uint32); - if (!(module->func_type_indexes = - loader_malloc(size, error_buf, error_buf_size))) { + if (size > 0 + && !(module->func_type_indexes = + loader_malloc(size, error_buf, error_buf_size))) { goto fail3; } for (i = 0; i < comp_data->func_count; i++) @@ -2135,7 +2140,8 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx, return module; fail3: - wasm_runtime_free(module->func_ptrs); + if (module->func_ptrs) + wasm_runtime_free(module->func_ptrs); fail2: if (module->memory_count > 0) wasm_runtime_free(module->memories); diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 18518e0b..f52e4eb2 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -176,7 +176,7 @@ memories_deinstantiate(AOTModuleInstance *module_inst) wasm_runtime_free(memory_inst->heap_handle.ptr); } - if (memory_inst->heap_data.ptr) { + if (memory_inst->memory_data.ptr) { #ifndef OS_ENABLE_HW_BOUND_CHECK wasm_runtime_free(memory_inst->memory_data.ptr); #else @@ -202,7 +202,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, uint32 bytes_of_last_page, bytes_to_page_end; uint32 heap_offset = num_bytes_per_page *init_page_count; uint64 total_size; - uint8 *p, *global_addr; + uint8 *p = NULL, *global_addr; #ifdef OS_ENABLE_HW_BOUND_CHECK uint8 *mapped_mem; uint64 map_size = 8 * (uint64)BH_GB; @@ -321,7 +321,8 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module, #ifndef OS_ENABLE_HW_BOUND_CHECK /* Allocate memory */ - if (!(p = runtime_malloc(total_size, error_buf, error_buf_size))) { + if (total_size > 0 + && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) { return NULL; } #else @@ -420,7 +421,8 @@ fail2: wasm_runtime_free(memory_inst->heap_handle.ptr); fail1: #ifndef OS_ENABLE_HW_BOUND_CHECK - wasm_runtime_free(memory_inst->memory_data.ptr); + if (memory_inst->memory_data.ptr) + wasm_runtime_free(memory_inst->memory_data.ptr); #else os_munmap(mapped_mem, map_size); #endif @@ -504,7 +506,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module, } /* Copy memory data */ - bh_assert(memory_inst->memory_data.ptr); + bh_assert(memory_inst->memory_data.ptr + || memory_inst->memory_data_size == 0); /* Check memory data */ /* check offset since length might negative */ @@ -526,9 +529,11 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module, return false; } - bh_memcpy_s((uint8*)memory_inst->memory_data.ptr + base_offset, - memory_inst->memory_data_size - base_offset, - data_seg->bytes, length); + if (memory_inst->memory_data.ptr) { + bh_memcpy_s((uint8*)memory_inst->memory_data.ptr + base_offset, + memory_inst->memory_data_size - base_offset, + data_seg->bytes, length); + } } return true; @@ -543,6 +548,9 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, uint64 total_size = ((uint64)module->import_func_count + module->func_count) * sizeof(void*); + if (module->import_func_count + module->func_count == 0) + return true; + /* Allocate memory */ if (!(module_inst->func_ptrs.ptr = runtime_malloc (total_size, error_buf, error_buf_size))) { @@ -562,7 +570,8 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module, } /* Set defined function pointers */ - memcpy(func_ptrs, module->func_ptrs, module->func_count * sizeof(void*)); + bh_memcpy_s(func_ptrs, sizeof(void*) * module->func_count, + module->func_ptrs, sizeof(void*) * module->func_count); return true; } @@ -575,6 +584,9 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module, uint64 total_size = ((uint64)module->import_func_count + module->func_count) * sizeof(uint32); + if (module->import_func_count + module->func_count == 0) + return true; + /* Allocate memory */ if (!(module_inst->func_type_indexes.ptr = runtime_malloc(total_size, error_buf, error_buf_size))) { @@ -586,9 +598,8 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module, for (i = 0; i < module->import_func_count; i++, func_type_index++) *func_type_index = module->import_funcs[i].func_type_index; - memcpy(func_type_index, module->func_type_indexes, - module->func_count * sizeof(uint32)); - + bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count, + module->func_type_indexes, sizeof(uint32) * module->func_count); return true; } @@ -1688,9 +1699,11 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count) if (!(memory_data = wasm_runtime_malloc((uint32)total_size))) { return false; } - bh_memcpy_s(memory_data, (uint32)total_size, - memory_data_old, total_size_old); - wasm_runtime_free(memory_data_old); + if (memory_data_old) { + bh_memcpy_s(memory_data, (uint32)total_size, + memory_data_old, total_size_old); + wasm_runtime_free(memory_data_old); + } } memset(memory_data + total_size_old, diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index cc1082b9..9e65989b 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -23,7 +23,7 @@ void wasm_instance_delete_internal(wasm_instance_t *); static void * -malloc_internal(size_t size) +malloc_internal(uint64 size) { void *mem = NULL; @@ -47,8 +47,7 @@ malloc_internal(size_t size) /* Vectors */ #define INIT_VEC(vector_p, func_prefix, size) \ do { \ - vector_p = malloc_internal(sizeof(*(vector_p))); \ - if (!vector_p) { \ + if (!(vector_p = malloc_internal(sizeof(*(vector_p))))) { \ goto failed; \ } \ func_prefix##_new_uninitialized(vector_p, size); \ @@ -75,7 +74,8 @@ malloc_internal(size_t size) static inline void generic_vec_init_data(Vector *out, size_t num_of_elems, size_t size_of_elem) { - if (!bh_vector_init(out, num_of_elems, size_of_elem)) { + /* size 0 is meaningless for a elemment */ + if (!size_of_elem || !bh_vector_init(out, num_of_elems, size_of_elem)) { out->data = NULL; out->max_elems = 0; out->num_elems = 0; @@ -99,7 +99,7 @@ wasm_byte_vec_copy(wasm_byte_vec_t *out, const wasm_byte_vec_t *src) bh_assert(out && src); - generic_vec_init_data((Vector *)out, src->size, src->size_of_elem); + generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_byte_t)); if (!out->data) { goto failed; } @@ -187,7 +187,7 @@ wasm_engine_new_internal(mem_alloc_type_t type, goto failed; } -#if BH_DEBUG == 1 +#if BH_DEBUG != 0 bh_log_set_verbose_level(5); #else bh_log_set_verbose_level(3); @@ -459,7 +459,7 @@ wasm_valtype_vec_copy(wasm_valtype_vec_t *out, const wasm_valtype_vec_t *src) bh_assert(out && src); - generic_vec_init_data((Vector *)out, src->size, src->size_of_elem); + generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_valtype_t *)); if (!out->data) { goto failed; } @@ -1116,33 +1116,41 @@ failed: static void native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) { - wasm_val_t *params = NULL; - wasm_val_t *results = NULL; + wasm_val_t *params = NULL, *results = NULL; uint32 argc = 0; const wasm_func_t *func = NULL; wasm_trap_t *trap = NULL; - - bh_assert(argv); + size_t param_count, result_count; func = wasm_runtime_get_function_attachment(exec_env); bh_assert(func); - params = malloc_internal(wasm_func_param_arity(func) * sizeof(wasm_val_t)); - if (!params) { - goto failed; + param_count = wasm_func_param_arity(func); + if (param_count) { + if (!argv) { + goto failed; + } + + if (!(params = malloc_internal(param_count * sizeof(wasm_val_t)))) { + goto failed; + } + + /* argv -> const wasm_val_t params[] */ + if (!(argc = argv_to_params( + argv, wasm_functype_params(wasm_func_type(func)), params))) { + goto failed; + } } - results = - malloc_internal(wasm_func_result_arity(func) * sizeof(wasm_val_t)); - if (!results) { - goto failed; - } + result_count = wasm_func_result_arity(func); + if (result_count) { + if (!argv) { + goto failed; + } - /* argv -> const wasm_val_t params[] */ - argc = - argv_to_params(argv, wasm_functype_params(wasm_func_type(func)), params); - if (wasm_func_param_arity(func) && !argc) { - goto failed; + if (!(results = malloc_internal(result_count * sizeof(wasm_val_t)))) { + goto failed; + } } if (func->with_env) { @@ -1164,16 +1172,17 @@ native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) } } - /* there is no result or there is an exception */ - if (trap || !wasm_func_result_arity(func)) { + if (argv) { memset(argv, 0, wasm_func_param_arity(func) * sizeof(uint64)); } - /* wasm_val_t results[] -> argv */ - argc = results_to_argv(results, - wasm_functype_results(wasm_func_type(func)), argv); - if (wasm_func_result_arity(func) && !argc) { - goto failed; + /* there is no trap and there is return values */ + if (!trap && result_count) { + /* wasm_val_t results[] -> argv */ + if (!(argc = results_to_argv( + results, wasm_functype_results(wasm_func_type(func)), argv))) { + goto failed; + } } failed: @@ -1503,8 +1512,7 @@ wasm_func_call(const wasm_func_t *func, /* a parameter list and a return value list */ uint32 *argv = NULL; WASMFunctionInstanceCommon *func_comm_rt = NULL; - size_t param_count = 0; - size_t result_count = 0; + size_t param_count, result_count, alloc_count; bh_assert(func && func->func_type && func->inst_comm_rt); @@ -1527,17 +1535,18 @@ wasm_func_call(const wasm_func_t *func, param_count = wasm_func_param_arity(func); result_count = wasm_func_result_arity(func); - argv = malloc_internal( - sizeof(uint64) - * (param_count > result_count ? param_count : result_count)); - if (!argv) { - goto failed; + alloc_count = (param_count > result_count) ? param_count : result_count; + if (alloc_count) { + if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) { + goto failed; + } } /* copy parametes */ - argc = params_to_argv(params, wasm_functype_params(wasm_func_type(func)), - wasm_func_param_arity(func), argv); - if (wasm_func_param_arity(func) && !argc) { + if (param_count + && !(argc = params_to_argv(params, + wasm_functype_params(wasm_func_type(func)), + wasm_func_param_arity(func), argv))) { goto failed; } @@ -1548,9 +1557,10 @@ wasm_func_call(const wasm_func_t *func, } /* copy results */ - argc = argv_to_results(argv, wasm_functype_results(wasm_func_type(func)), - wasm_func_result_arity(func), results); - if (wasm_func_result_arity(func) && !argc) { + if (result_count + && !(argc = argv_to_results( + argv, wasm_functype_results(wasm_func_type(func)), + wasm_func_result_arity(func), results))) { goto failed; } @@ -2734,7 +2744,7 @@ wasm_extern_vec_copy(wasm_extern_vec_t *out, const wasm_extern_vec_t *src) size_t i = 0; bh_assert(out && src); - generic_vec_init_data((Vector *)out, src->size, src->size_of_elem); + generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_extern_t *)); if (!out->data) { goto failed; } diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index 0b94beeb..1d8faffb 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -161,8 +161,14 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size) static inline void wasm_runtime_free_internal(void *ptr) { + if (!ptr) { + LOG_WARNING("warning: wasm_runtime_free with NULL pointer\n"); + return; + } + if (memory_mode == MEMORY_MODE_UNKNOWN) { - LOG_WARNING("wasm_runtime_free failed: memory hasn't been initialize.\n"); + LOG_WARNING("warning: wasm_runtime_free failed: " + "memory hasn't been initialize.\n"); } else if (memory_mode == MEMORY_MODE_POOL) { mem_allocator_free(pool_allocator, ptr); @@ -175,6 +181,12 @@ wasm_runtime_free_internal(void *ptr) void * wasm_runtime_malloc(unsigned int size) { + if (size == 0) { + LOG_WARNING("warning: wasm_runtime_malloc with size zero\n"); + /* At lease alloc 1 byte to avoid malloc failed */ + size = 1; + } + return wasm_runtime_malloc_internal(size); } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 65ab805c..56e90e19 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1712,9 +1712,11 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, total_size = sizeof(char *) * (uint64)argc; if (total_size >= UINT32_MAX - || !(argv_list = wasm_runtime_malloc((uint32)total_size)) + || (total_size > 0 && + !(argv_list = wasm_runtime_malloc((uint32)total_size))) || argv_buf_size >= UINT32_MAX - || !(argv_buf = wasm_runtime_malloc((uint32)argv_buf_size))) { + || (argv_buf_size > 0 && + !(argv_buf = wasm_runtime_malloc((uint32)argv_buf_size)))) { set_error_buf(error_buf, error_buf_size, "Init wasi environment failed: allocate memory failed"); goto fail; @@ -1730,11 +1732,13 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, for (i = 0; i < env_count; i++) env_buf_size += strlen(env[i]) + 1; - total_size = sizeof(char *) * (uint64)argc; + total_size = sizeof(char *) * (uint64)env_count; if (total_size >= UINT32_MAX - || !(env_list = wasm_runtime_malloc((uint32)total_size)) + || (total_size > 0 + && !(env_list = wasm_runtime_malloc((uint32)total_size))) || env_buf_size >= UINT32_MAX - || !(env_buf = wasm_runtime_malloc((uint32)env_buf_size))) { + || (env_buf_size > 0 + && !(env_buf = wasm_runtime_malloc((uint32)env_buf_size)))) { set_error_buf(error_buf, error_buf_size, "Init wasi environment failed: allocate memory failed"); goto fail; @@ -2842,6 +2846,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, n_stacks++; n_stacks += 2; } + break; #endif /* BUILD_TARGET_RISCV32_ILP32D */ default: bh_assert(0); diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 63379236..32f8da2c 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -234,7 +234,7 @@ aot_set_last_error(const char *error); void aot_set_last_error_v(const char *format, ...); -#if BH_DEBUG == 1 +#if BH_DEBUG != 0 #define HANDLE_FAILURE(callee) do { \ aot_set_last_error_v("call %s failed in %s:%d", (callee),\ __FUNCTION__, __LINE__); \ diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 17cc3262..b194c2ac 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -1751,16 +1751,18 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data) AOTObjectFunc *func; LLVMSymbolIteratorRef sym_itr; char *name, *prefix = AOT_FUNC_PREFIX; - uint32 func_index; + uint32 func_index, total_size; /* allocate memory for aot function */ obj_data->func_count = comp_ctx->comp_data->func_count; - if (!(obj_data->funcs - = wasm_runtime_malloc((uint32)sizeof(AOTObjectFunc) * obj_data->func_count))) { - aot_set_last_error("allocate memory for functions failed."); - return false; + if (obj_data->func_count) { + total_size = (uint32)sizeof(AOTObjectFunc) * obj_data->func_count; + if (!(obj_data->funcs = wasm_runtime_malloc(total_size))) { + aot_set_last_error("allocate memory for functions failed."); + return false; + } + memset(obj_data->funcs, 0, total_size); } - memset(obj_data->funcs, 0, sizeof(AOTObjectFunc) * obj_data->func_count); if (!(sym_itr = LLVMObjectFileCopySymbolIterator(obj_data->binary))) { aot_set_last_error("llvm get symbol iterator failed."); diff --git a/core/iwasm/compilation/aot_emit_function.c b/core/iwasm/compilation/aot_emit_function.c index 57cac163..32cb4015 100644 --- a/core/iwasm/compilation/aot_emit_function.c +++ b/core/iwasm/compilation/aot_emit_function.c @@ -792,7 +792,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, uint8 wasm_ret_type, *wasm_ret_types; uint64 total_size; char buf[32]; - bool ret; + bool ret = false; /* Check function type index */ if (type_idx >= comp_ctx->comp_data->func_type_count) { @@ -1105,13 +1105,15 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVMPositionBuilderAtEnd(comp_ctx->builder, block_call_import); /* Allocate memory for result values */ - total_size = sizeof(LLVMValueRef) * (uint64)func_result_count; - if (total_size >= UINT32_MAX - || !(value_rets = wasm_runtime_malloc((uint32)total_size))) { - aot_set_last_error("allocate memory failed."); - goto fail; + if (func_result_count > 0) { + total_size = sizeof(LLVMValueRef) * (uint64)func_result_count; + if (total_size >= UINT32_MAX + || !(value_rets = wasm_runtime_malloc((uint32)total_size))) { + aot_set_last_error("allocate memory failed."); + goto fail; + } + memset(value_rets, 0, (uint32)total_size); } - memset(value_rets, 0, total_size); param_cell_num = func_type->param_cell_num; wasm_ret_types = func_type->types + func_type->param_count; diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index 99d6593d..883f4b9d 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -74,7 +74,7 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } static LLVMValueRef -get_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); +get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); LLVMValueRef aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, @@ -171,7 +171,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (init_page_count == 0) { LLVMValueRef mem_size; - if (!(mem_size = get_memory_size(comp_ctx, func_ctx))) { + if (!(mem_size = get_memory_curr_page_count(comp_ctx, func_ctx))) { goto fail; } BUILD_ICMP(LLVMIntEQ, mem_size, I32_ZERO, cmp, "is_zero"); @@ -611,7 +611,7 @@ fail: } static LLVMValueRef -get_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) +get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) { LLVMValueRef mem_size; @@ -636,7 +636,7 @@ fail: bool aot_compile_op_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) { - LLVMValueRef mem_size = get_memory_size(comp_ctx, func_ctx); + LLVMValueRef mem_size = get_memory_curr_page_count(comp_ctx, func_ctx); if (mem_size) PUSH_I32(mem_size); @@ -648,7 +648,7 @@ fail: bool aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) { - LLVMValueRef mem_size = get_memory_size(comp_ctx, func_ctx); + LLVMValueRef mem_size = get_memory_curr_page_count(comp_ctx, func_ctx); LLVMValueRef delta, param_values[2], ret_value, func, value; LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type; @@ -801,9 +801,17 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, } } - /* mem_size_offset = aot_inst + off */ - if (!(mem_size = get_memory_size(comp_ctx, func_ctx))) { - goto fail; + if (func_ctx->mem_space_unchanged) { + mem_size = func_ctx->mem_info[0].mem_data_size_addr; + } + else { + if (!(mem_size = + LLVMBuildLoad(comp_ctx->builder, + func_ctx->mem_info[0].mem_data_size_addr, + "mem_size"))) { + aot_set_last_error("llvm build load failed."); + goto fail; + } } ADD_BASIC_BLOCK(check_succ, "check_succ"); diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 15ca7e56..7c7e73a0 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -262,6 +262,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build in bounds gep failed"); return false; } + offset = I32_CONST(offsetof(AOTMemoryInstance, memory_data_size)); + if (!(func_ctx->mem_info[0].mem_data_size_addr = + LLVMBuildInBoundsGEP(comp_ctx->builder, shared_mem_addr, + &offset, 1, "mem_data_size_offset"))) { + aot_set_last_error("llvm build in bounds gep failed"); + return false; + } } else #endif @@ -282,6 +289,14 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build in bounds gep failed"); return false; } + offset = I32_CONST(offsetof(AOTModuleInstance, global_table_data) + + offsetof(AOTMemoryInstance, memory_data_size)); + if (!(func_ctx->mem_info[0].mem_data_size_addr = + LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst, + &offset, 1, "mem_data_size_offset"))) { + aot_set_last_error("llvm build in bounds gep failed"); + return false; + } } /* Store mem info base address before cast */ mem_info_base = func_ctx->mem_info[0].mem_base_addr; @@ -300,6 +315,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, aot_set_last_error("llvm build bit cast failed"); return false; } + if (!(func_ctx->mem_info[0].mem_data_size_addr = + LLVMBuildBitCast(comp_ctx->builder, + func_ctx->mem_info[0].mem_data_size_addr, + INT32_PTR_TYPE, "mem_data_size_ptr"))) { + aot_set_last_error("llvm build bit cast failed"); + return false; + } if (mem_space_unchanged) { if (!(func_ctx->mem_info[0].mem_base_addr = LLVMBuildLoad(comp_ctx->builder, @@ -311,7 +333,14 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (!(func_ctx->mem_info[0].mem_cur_page_count_addr = LLVMBuildLoad(comp_ctx->builder, func_ctx->mem_info[0].mem_cur_page_count_addr, - "mem_cur_page_count_addr"))) { + "mem_cur_page_count"))) { + aot_set_last_error("llvm build load failed"); + return false; + } + if (!(func_ctx->mem_info[0].mem_data_size_addr = + LLVMBuildLoad(comp_ctx->builder, + func_ctx->mem_info[0].mem_data_size_addr, + "mem_data_size"))) { aot_set_last_error("llvm build load failed"); return false; } @@ -1476,7 +1505,9 @@ aot_create_comp_context(AOTCompData *comp_data, /* Create function context for each function */ comp_ctx->func_ctx_count = comp_data->func_count; - if (!(comp_ctx->func_ctxes = aot_create_func_contexts(comp_data, comp_ctx))) + if (comp_data->func_count > 0 + && !(comp_ctx->func_ctxes = + aot_create_func_contexts(comp_data, comp_ctx))) goto fail; ret = comp_ctx; @@ -1521,7 +1552,8 @@ aot_destroy_comp_context(AOTCompContext *comp_ctx) LLVMContextDispose(comp_ctx->context); if (comp_ctx->func_ctxes) - aot_destroy_func_contexts(comp_ctx->func_ctxes, comp_ctx->func_ctx_count); + aot_destroy_func_contexts(comp_ctx->func_ctxes, + comp_ctx->func_ctx_count); wasm_runtime_free(comp_ctx); } diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 02b24928..0fa11ed3 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -103,6 +103,7 @@ typedef struct AOTCheckedAddr { typedef struct AOTMemInfo { LLVMValueRef mem_base_addr; + LLVMValueRef mem_data_size_addr; LLVMValueRef mem_cur_page_count_addr; LLVMValueRef mem_bound_check_1byte; LLVMValueRef mem_bound_check_2bytes; diff --git a/core/iwasm/compilation/simd/simd_access_lanes.c b/core/iwasm/compilation/simd/simd_access_lanes.c index 4778d636..eef22ea8 100644 --- a/core/iwasm/compilation/simd/simd_access_lanes.c +++ b/core/iwasm/compilation/simd/simd_access_lanes.c @@ -83,7 +83,7 @@ fail: return false; } -// TODO: instructions for other CPUs +/* TODO: instructions for other CPUs */ /* shufflevector is not an option, since it requires *mask as a const */ bool aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index a83e0210..a95c0009 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2148,7 +2148,8 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m read_leb_uint32(p, p_end, function_count); table_segment->function_count = function_count; total_size = sizeof(uint32) * (uint64)function_count; - if (!(table_segment->func_indexes = (uint32 *) + if (total_size > 0 + && !(table_segment->func_indexes = (uint32 *) loader_malloc(total_size, error_buf, error_buf_size))) { return false; } @@ -2444,7 +2445,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, previous_func_index = func_index; read_leb_uint32(p, p_end, func_name_len); CHECK_BUF(p, p_end, func_name_len); - // Skip the import functions + /* Skip the import functions */ if (func_index >= module->import_count) { func_index -= module->import_count; if (func_index >= module->function_count) { @@ -5697,7 +5698,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 segment_index; #endif #if WASM_ENABLE_FAST_INTERP != 0 - uint8 *func_const_end, *func_const; + uint8 *func_const_end, *func_const = NULL; int16 operand_offset; uint8 last_op = 0; bool disable_emit, preserve_local = false; @@ -7710,7 +7711,8 @@ fail_data_cnt_sec_require: goto re_scan; func->const_cell_num = loader_ctx->const_cell_num; - if (!(func->consts = func_const = + if (func->const_cell_num > 0 + && !(func->consts = func_const = loader_malloc(func->const_cell_num * 4, 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 f2c19bcd..36ab505a 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -1167,7 +1167,8 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m read_leb_uint32(p, p_end, function_count); table_segment->function_count = function_count; total_size = sizeof(uint32) * (uint64)function_count; - if (!(table_segment->func_indexes = (uint32 *) + if (total_size > 0 + && !(table_segment->func_indexes = (uint32 *) loader_malloc(total_size, error_buf, error_buf_size))) { return false; } @@ -1391,7 +1392,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, previous_func_index = func_index; read_leb_uint32(p, p_end, func_name_len); CHECK_BUF(p, p_end, func_name_len); - // Skip the import functions + /* Skip the import functions */ if (func_index >= module->import_count) { func_index -= module->import_count; bh_assert(func_index < module->function_count); @@ -4257,7 +4258,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 segment_index; #endif #if WASM_ENABLE_FAST_INTERP != 0 - uint8 *func_const_end, *func_const; + uint8 *func_const_end, *func_const = NULL; int16 operand_offset; uint8 last_op = 0; bool disable_emit, preserve_local = false; @@ -5733,7 +5734,8 @@ handle_op_block_and_loop: goto re_scan; func->const_cell_num = loader_ctx->const_cell_num; - if (!(func->consts = func_const = + if (func->const_cell_num > 0 + && !(func->consts = func_const = loader_malloc(func->const_cell_num * 4, error_buf, error_buf_size))) { goto fail; diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 6a371e5e..ca28af03 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -110,7 +110,8 @@ memories_deinstantiate(WASMModuleInstance *module_inst, wasm_runtime_free(memories[i]->heap_handle); memories[i]->heap_handle = NULL; } - wasm_runtime_free(memories[i]->memory_data); + if (memories[i]->memory_data) + wasm_runtime_free(memories[i]->memory_data); wasm_runtime_free(memories[i]); } } @@ -248,8 +249,10 @@ memory_instantiate(WASMModuleInstance *module_inst, return NULL; } - if (!(memory->memory_data = - runtime_malloc(memory_data_size, error_buf, error_buf_size))) { + if (memory_data_size > 0 + && !(memory->memory_data = + runtime_malloc(memory_data_size, + error_buf, error_buf_size))) { goto fail1; } @@ -307,7 +310,8 @@ fail3: if (heap_size > 0) wasm_runtime_free(memory->heap_handle); fail2: - wasm_runtime_free(memory->memory_data); + if (memory->memory_data) + wasm_runtime_free(memory->memory_data); fail1: wasm_runtime_free(memory); return NULL; @@ -1293,9 +1297,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, bh_assert(memory); memory_data = memory->memory_data; - bh_assert(memory_data); - memory_size = memory->num_bytes_per_page * memory->cur_page_count; + bh_assert(memory_data || memory_size == 0); bh_assert(data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST @@ -1337,8 +1340,10 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, goto fail; } - bh_memcpy_s(memory_data + base_offset, memory_size - base_offset, - data_seg->data, length); + if (memory_data) { + bh_memcpy_s(memory_data + base_offset, memory_size - base_offset, + data_seg->data, length); + } } /* Initialize the table data with table segment section */ @@ -1970,9 +1975,11 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count) if (!(new_memory_data = wasm_runtime_malloc((uint32)total_size))) { return false; } - bh_memcpy_s(new_memory_data, (uint32)total_size, - memory_data, total_size_old); - wasm_runtime_free(memory_data); + if (memory_data) { + bh_memcpy_s(new_memory_data, (uint32)total_size, + memory_data, total_size_old); + wasm_runtime_free(memory_data); + } } memset(new_memory_data + total_size_old, diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index df31ea3f..9e4d989f 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -1652,7 +1652,8 @@ static __wasi_errno_t path_get_nofollow( static void path_put( struct path_access *pa ) UNLOCKS(pa->fd_object->refcount) { - wasm_runtime_free(pa->path_start); + if (pa->path_start) + wasm_runtime_free(pa->path_start); if (fd_number(pa->fd_object) != pa->fd) close(pa->fd); fd_object_release(pa->fd_object); diff --git a/core/shared/utils/bh_log.h b/core/shared/utils/bh_log.h index e0720964..dd24dc04 100644 --- a/core/shared/utils/bh_log.h +++ b/core/shared/utils/bh_log.h @@ -51,7 +51,7 @@ bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...); #endif -#if BH_DEBUG == 1 +#if BH_DEBUG != 0 #define LOG_FATAL(...) bh_log(BH_LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__) #else #define LOG_FATAL(...) bh_log(BH_LOG_LEVEL_FATAL, __FUNCTION__, __LINE__, __VA_ARGS__) @@ -61,7 +61,7 @@ bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...); #define LOG_WARNING(...) bh_log(BH_LOG_LEVEL_WARNING, NULL, 0, __VA_ARGS__) #define LOG_VERBOSE(...) bh_log(BH_LOG_LEVEL_VERBOSE, NULL, 0, __VA_ARGS__) -#if BH_DEBUG == 1 +#if BH_DEBUG != 0 #define LOG_DEBUG(...) bh_log(BH_LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__) #else #define LOG_DEBUG(...) (void)0 diff --git a/core/shared/utils/uncommon/bh_read_file.c b/core/shared/utils/uncommon/bh_read_file.c index ce616743..5513fe52 100644 --- a/core/shared/utils/uncommon/bh_read_file.c +++ b/core/shared/utils/uncommon/bh_read_file.c @@ -14,7 +14,7 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size) { char *buffer; int file; - uint32 file_size, read_size; + uint32 file_size, buf_size, read_size; struct stat stat_buf; if (!filename || !ret_size) { @@ -36,7 +36,10 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size) } file_size = (uint32)stat_buf.st_size; - if (!(buffer = (char *)BH_MALLOC(file_size))) { + /* At lease alloc 1 byte to avoid malloc failed */ + buf_size = file_size > 0 ? file_size : 1; + + if (!(buffer = (char *)BH_MALLOC(buf_size))) { printf("Read file to buffer failed: alloc memory failed.\n"); _close(file); return NULL; @@ -63,7 +66,7 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size) { char *buffer; int file; - uint32 file_size, read_size; + uint32 file_size, buf_size, read_size; struct stat stat_buf; if (!filename || !ret_size) { @@ -86,7 +89,10 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size) file_size = (uint32)stat_buf.st_size; - if (!(buffer = BH_MALLOC(file_size))) { + /* At lease alloc 1 byte to avoid malloc failed */ + buf_size = file_size > 0 ? file_size : 1; + + if (!(buffer = BH_MALLOC(buf_size))) { printf("Read file to buffer failed: alloc memory failed.\n"); close(file); return NULL; diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index 46b30ce9..93235eaf 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -74,7 +74,7 @@ endif() ## locate wat2wasm find_program(WAT2WASM wat2wasm - PATHS /opt/wabt/bin /opt/wabt-1.0.18/bin + PATHS /opt/wabt/bin REQUIRED ) diff --git a/samples/workload/meshoptimizer/codecbench.patch b/samples/workload/meshoptimizer/codecbench.patch index 2d6e9d4f..d739558a 100644 --- a/samples/workload/meshoptimizer/codecbench.patch +++ b/samples/workload/meshoptimizer/codecbench.patch @@ -1,5 +1,5 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index ffdb4da..536a5c8 100644 +index ffdb4da..a397427 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,3 +127,43 @@ install(FILES @@ -24,7 +24,7 @@ index ffdb4da..536a5c8 100644 + +target_link_options(codecbench + PUBLIC -+ LINKER:-allow-undefined,--demangle ++ LINKER:-allow-undefined,--demangle,--export=malloc,--export=free +) + +find_program(WASM_OPT