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 <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang 2021-01-28 02:16:02 -06:00 committed by GitHub
parent efd648959c
commit a5188f5574
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 240 additions and 131 deletions

View File

@ -1117,8 +1117,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
uint64 size, text_offset; uint64 size, text_offset;
size = sizeof(void*) * (uint64)module->func_count; size = sizeof(void*) * (uint64)module->func_count;
if (!(module->func_ptrs = loader_malloc if (size > 0
(size, error_buf, error_buf_size))) { && !(module->func_ptrs = loader_malloc
(size, error_buf, error_buf_size))) {
return false; return false;
} }
@ -1158,8 +1159,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
} }
size = sizeof(uint32) * (uint64)module->func_count; size = sizeof(uint32) * (uint64)module->func_count;
if (!(module->func_type_indexes = loader_malloc if (size > 0
(size, error_buf, error_buf_size))) { && !(module->func_type_indexes = loader_malloc
(size, error_buf, error_buf_size))) {
return false; return false;
} }
@ -1498,7 +1500,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
/* Allocate memory for relocation groups */ /* Allocate memory for relocation groups */
size = sizeof(AOTRelocationGroup) * (uint64)group_count; 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; goto fail;
} }
@ -2065,8 +2068,9 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
/* Allocate memory for function pointers */ /* Allocate memory for function pointers */
size = (uint64)module->func_count * sizeof(void *); size = (uint64)module->func_count * sizeof(void *);
if (!(module->func_ptrs = if (size > 0
loader_malloc(size, error_buf, error_buf_size))) { && !(module->func_ptrs =
loader_malloc(size, error_buf, error_buf_size))) {
goto fail2; goto fail2;
} }
@ -2085,8 +2089,9 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
/* Allocation memory for function type indexes */ /* Allocation memory for function type indexes */
size = (uint64)module->func_count * sizeof(uint32); size = (uint64)module->func_count * sizeof(uint32);
if (!(module->func_type_indexes = if (size > 0
loader_malloc(size, error_buf, error_buf_size))) { && !(module->func_type_indexes =
loader_malloc(size, error_buf, error_buf_size))) {
goto fail3; goto fail3;
} }
for (i = 0; i < comp_data->func_count; i++) 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; return module;
fail3: fail3:
wasm_runtime_free(module->func_ptrs); if (module->func_ptrs)
wasm_runtime_free(module->func_ptrs);
fail2: fail2:
if (module->memory_count > 0) if (module->memory_count > 0)
wasm_runtime_free(module->memories); wasm_runtime_free(module->memories);

View File

@ -176,7 +176,7 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
wasm_runtime_free(memory_inst->heap_handle.ptr); 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 #ifndef OS_ENABLE_HW_BOUND_CHECK
wasm_runtime_free(memory_inst->memory_data.ptr); wasm_runtime_free(memory_inst->memory_data.ptr);
#else #else
@ -202,7 +202,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint32 bytes_of_last_page, bytes_to_page_end; uint32 bytes_of_last_page, bytes_to_page_end;
uint32 heap_offset = num_bytes_per_page *init_page_count; uint32 heap_offset = num_bytes_per_page *init_page_count;
uint64 total_size; uint64 total_size;
uint8 *p, *global_addr; uint8 *p = NULL, *global_addr;
#ifdef OS_ENABLE_HW_BOUND_CHECK #ifdef OS_ENABLE_HW_BOUND_CHECK
uint8 *mapped_mem; uint8 *mapped_mem;
uint64 map_size = 8 * (uint64)BH_GB; uint64 map_size = 8 * (uint64)BH_GB;
@ -321,7 +321,8 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
#ifndef OS_ENABLE_HW_BOUND_CHECK #ifndef OS_ENABLE_HW_BOUND_CHECK
/* Allocate memory */ /* 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; return NULL;
} }
#else #else
@ -420,7 +421,8 @@ fail2:
wasm_runtime_free(memory_inst->heap_handle.ptr); wasm_runtime_free(memory_inst->heap_handle.ptr);
fail1: fail1:
#ifndef OS_ENABLE_HW_BOUND_CHECK #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 #else
os_munmap(mapped_mem, map_size); os_munmap(mapped_mem, map_size);
#endif #endif
@ -504,7 +506,8 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
} }
/* Copy memory data */ /* 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 memory data */
/* check offset since length might negative */ /* check offset since length might negative */
@ -526,9 +529,11 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
return false; return false;
} }
bh_memcpy_s((uint8*)memory_inst->memory_data.ptr + base_offset, if (memory_inst->memory_data.ptr) {
memory_inst->memory_data_size - base_offset, bh_memcpy_s((uint8*)memory_inst->memory_data.ptr + base_offset,
data_seg->bytes, length); memory_inst->memory_data_size - base_offset,
data_seg->bytes, length);
}
} }
return true; return true;
@ -543,6 +548,9 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
uint64 total_size = uint64 total_size =
((uint64)module->import_func_count + module->func_count) * sizeof(void*); ((uint64)module->import_func_count + module->func_count) * sizeof(void*);
if (module->import_func_count + module->func_count == 0)
return true;
/* Allocate memory */ /* Allocate memory */
if (!(module_inst->func_ptrs.ptr = runtime_malloc if (!(module_inst->func_ptrs.ptr = runtime_malloc
(total_size, error_buf, error_buf_size))) { (total_size, error_buf, error_buf_size))) {
@ -562,7 +570,8 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
} }
/* Set defined function pointers */ /* 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; return true;
} }
@ -575,6 +584,9 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
uint64 total_size = uint64 total_size =
((uint64)module->import_func_count + module->func_count) * sizeof(uint32); ((uint64)module->import_func_count + module->func_count) * sizeof(uint32);
if (module->import_func_count + module->func_count == 0)
return true;
/* Allocate memory */ /* Allocate memory */
if (!(module_inst->func_type_indexes.ptr = if (!(module_inst->func_type_indexes.ptr =
runtime_malloc(total_size, error_buf, error_buf_size))) { 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++) for (i = 0; i < module->import_func_count; i++, func_type_index++)
*func_type_index = module->import_funcs[i].func_type_index; *func_type_index = module->import_funcs[i].func_type_index;
memcpy(func_type_index, module->func_type_indexes, bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
module->func_count * sizeof(uint32)); module->func_type_indexes, sizeof(uint32) * module->func_count);
return true; 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))) { if (!(memory_data = wasm_runtime_malloc((uint32)total_size))) {
return false; return false;
} }
bh_memcpy_s(memory_data, (uint32)total_size, if (memory_data_old) {
memory_data_old, total_size_old); bh_memcpy_s(memory_data, (uint32)total_size,
wasm_runtime_free(memory_data_old); memory_data_old, total_size_old);
wasm_runtime_free(memory_data_old);
}
} }
memset(memory_data + total_size_old, memset(memory_data + total_size_old,

View File

@ -23,7 +23,7 @@ void
wasm_instance_delete_internal(wasm_instance_t *); wasm_instance_delete_internal(wasm_instance_t *);
static void * static void *
malloc_internal(size_t size) malloc_internal(uint64 size)
{ {
void *mem = NULL; void *mem = NULL;
@ -47,8 +47,7 @@ malloc_internal(size_t size)
/* Vectors */ /* Vectors */
#define INIT_VEC(vector_p, func_prefix, size) \ #define INIT_VEC(vector_p, func_prefix, size) \
do { \ do { \
vector_p = malloc_internal(sizeof(*(vector_p))); \ if (!(vector_p = malloc_internal(sizeof(*(vector_p))))) { \
if (!vector_p) { \
goto failed; \ goto failed; \
} \ } \
func_prefix##_new_uninitialized(vector_p, size); \ func_prefix##_new_uninitialized(vector_p, size); \
@ -75,7 +74,8 @@ malloc_internal(size_t size)
static inline void static inline void
generic_vec_init_data(Vector *out, size_t num_of_elems, size_t size_of_elem) 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->data = NULL;
out->max_elems = 0; out->max_elems = 0;
out->num_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); 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) { if (!out->data) {
goto failed; goto failed;
} }
@ -187,7 +187,7 @@ wasm_engine_new_internal(mem_alloc_type_t type,
goto failed; goto failed;
} }
#if BH_DEBUG == 1 #if BH_DEBUG != 0
bh_log_set_verbose_level(5); bh_log_set_verbose_level(5);
#else #else
bh_log_set_verbose_level(3); 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); 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) { if (!out->data) {
goto failed; goto failed;
} }
@ -1116,33 +1116,41 @@ failed:
static void static void
native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv)
{ {
wasm_val_t *params = NULL; wasm_val_t *params = NULL, *results = NULL;
wasm_val_t *results = NULL;
uint32 argc = 0; uint32 argc = 0;
const wasm_func_t *func = NULL; const wasm_func_t *func = NULL;
wasm_trap_t *trap = NULL; wasm_trap_t *trap = NULL;
size_t param_count, result_count;
bh_assert(argv);
func = wasm_runtime_get_function_attachment(exec_env); func = wasm_runtime_get_function_attachment(exec_env);
bh_assert(func); bh_assert(func);
params = malloc_internal(wasm_func_param_arity(func) * sizeof(wasm_val_t)); param_count = wasm_func_param_arity(func);
if (!params) { if (param_count) {
goto failed; 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 = result_count = wasm_func_result_arity(func);
malloc_internal(wasm_func_result_arity(func) * sizeof(wasm_val_t)); if (result_count) {
if (!results) { if (!argv) {
goto failed; goto failed;
} }
/* argv -> const wasm_val_t params[] */ if (!(results = malloc_internal(result_count * sizeof(wasm_val_t)))) {
argc = goto failed;
argv_to_params(argv, wasm_functype_params(wasm_func_type(func)), params); }
if (wasm_func_param_arity(func) && !argc) {
goto failed;
} }
if (func->with_env) { 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 (argv) {
if (trap || !wasm_func_result_arity(func)) {
memset(argv, 0, wasm_func_param_arity(func) * sizeof(uint64)); memset(argv, 0, wasm_func_param_arity(func) * sizeof(uint64));
} }
/* wasm_val_t results[] -> argv */ /* there is no trap and there is return values */
argc = results_to_argv(results, if (!trap && result_count) {
wasm_functype_results(wasm_func_type(func)), argv); /* wasm_val_t results[] -> argv */
if (wasm_func_result_arity(func) && !argc) { if (!(argc = results_to_argv(
goto failed; results, wasm_functype_results(wasm_func_type(func)), argv))) {
goto failed;
}
} }
failed: failed:
@ -1503,8 +1512,7 @@ wasm_func_call(const wasm_func_t *func,
/* a parameter list and a return value list */ /* a parameter list and a return value list */
uint32 *argv = NULL; uint32 *argv = NULL;
WASMFunctionInstanceCommon *func_comm_rt = NULL; WASMFunctionInstanceCommon *func_comm_rt = NULL;
size_t param_count = 0; size_t param_count, result_count, alloc_count;
size_t result_count = 0;
bh_assert(func && func->func_type && func->inst_comm_rt); 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); param_count = wasm_func_param_arity(func);
result_count = wasm_func_result_arity(func); result_count = wasm_func_result_arity(func);
argv = malloc_internal( alloc_count = (param_count > result_count) ? param_count : result_count;
sizeof(uint64) if (alloc_count) {
* (param_count > result_count ? param_count : result_count)); if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) {
if (!argv) { goto failed;
goto failed; }
} }
/* copy parametes */ /* copy parametes */
argc = params_to_argv(params, wasm_functype_params(wasm_func_type(func)), if (param_count
wasm_func_param_arity(func), argv); && !(argc = params_to_argv(params,
if (wasm_func_param_arity(func) && !argc) { wasm_functype_params(wasm_func_type(func)),
wasm_func_param_arity(func), argv))) {
goto failed; goto failed;
} }
@ -1548,9 +1557,10 @@ wasm_func_call(const wasm_func_t *func,
} }
/* copy results */ /* copy results */
argc = argv_to_results(argv, wasm_functype_results(wasm_func_type(func)), if (result_count
wasm_func_result_arity(func), results); && !(argc = argv_to_results(
if (wasm_func_result_arity(func) && !argc) { argv, wasm_functype_results(wasm_func_type(func)),
wasm_func_result_arity(func), results))) {
goto failed; 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; size_t i = 0;
bh_assert(out && 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_extern_t *));
if (!out->data) { if (!out->data) {
goto failed; goto failed;
} }

View File

@ -161,8 +161,14 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size)
static inline void static inline void
wasm_runtime_free_internal(void *ptr) 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) { 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) { else if (memory_mode == MEMORY_MODE_POOL) {
mem_allocator_free(pool_allocator, ptr); mem_allocator_free(pool_allocator, ptr);
@ -175,6 +181,12 @@ wasm_runtime_free_internal(void *ptr)
void * void *
wasm_runtime_malloc(unsigned int size) 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); return wasm_runtime_malloc_internal(size);
} }

View File

@ -1712,9 +1712,11 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
total_size = sizeof(char *) * (uint64)argc; total_size = sizeof(char *) * (uint64)argc;
if (total_size >= UINT32_MAX 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_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, set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: allocate memory failed"); "Init wasi environment failed: allocate memory failed");
goto fail; goto fail;
@ -1730,11 +1732,13 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
for (i = 0; i < env_count; i++) for (i = 0; i < env_count; i++)
env_buf_size += strlen(env[i]) + 1; 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 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_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, set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: allocate memory failed"); "Init wasi environment failed: allocate memory failed");
goto fail; goto fail;
@ -2842,6 +2846,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
n_stacks++; n_stacks++;
n_stacks += 2; n_stacks += 2;
} }
break;
#endif /* BUILD_TARGET_RISCV32_ILP32D */ #endif /* BUILD_TARGET_RISCV32_ILP32D */
default: default:
bh_assert(0); bh_assert(0);

View File

@ -234,7 +234,7 @@ aot_set_last_error(const char *error);
void void
aot_set_last_error_v(const char *format, ...); aot_set_last_error_v(const char *format, ...);
#if BH_DEBUG == 1 #if BH_DEBUG != 0
#define HANDLE_FAILURE(callee) do { \ #define HANDLE_FAILURE(callee) do { \
aot_set_last_error_v("call %s failed in %s:%d", (callee),\ aot_set_last_error_v("call %s failed in %s:%d", (callee),\
__FUNCTION__, __LINE__); \ __FUNCTION__, __LINE__); \

View File

@ -1751,16 +1751,18 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
AOTObjectFunc *func; AOTObjectFunc *func;
LLVMSymbolIteratorRef sym_itr; LLVMSymbolIteratorRef sym_itr;
char *name, *prefix = AOT_FUNC_PREFIX; char *name, *prefix = AOT_FUNC_PREFIX;
uint32 func_index; uint32 func_index, total_size;
/* allocate memory for aot function */ /* allocate memory for aot function */
obj_data->func_count = comp_ctx->comp_data->func_count; obj_data->func_count = comp_ctx->comp_data->func_count;
if (!(obj_data->funcs if (obj_data->func_count) {
= wasm_runtime_malloc((uint32)sizeof(AOTObjectFunc) * obj_data->func_count))) { total_size = (uint32)sizeof(AOTObjectFunc) * obj_data->func_count;
aot_set_last_error("allocate memory for functions failed."); if (!(obj_data->funcs = wasm_runtime_malloc(total_size))) {
return false; 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))) { if (!(sym_itr = LLVMObjectFileCopySymbolIterator(obj_data->binary))) {
aot_set_last_error("llvm get symbol iterator failed."); aot_set_last_error("llvm get symbol iterator failed.");

View File

@ -792,7 +792,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint8 wasm_ret_type, *wasm_ret_types; uint8 wasm_ret_type, *wasm_ret_types;
uint64 total_size; uint64 total_size;
char buf[32]; char buf[32];
bool ret; bool ret = false;
/* Check function type index */ /* Check function type index */
if (type_idx >= comp_ctx->comp_data->func_type_count) { 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); LLVMPositionBuilderAtEnd(comp_ctx->builder, block_call_import);
/* Allocate memory for result values */ /* Allocate memory for result values */
total_size = sizeof(LLVMValueRef) * (uint64)func_result_count; if (func_result_count > 0) {
if (total_size >= UINT32_MAX total_size = sizeof(LLVMValueRef) * (uint64)func_result_count;
|| !(value_rets = wasm_runtime_malloc((uint32)total_size))) { if (total_size >= UINT32_MAX
aot_set_last_error("allocate memory failed."); || !(value_rets = wasm_runtime_malloc((uint32)total_size))) {
goto fail; 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; param_cell_num = func_type->param_cell_num;
wasm_ret_types = func_type->types + func_type->param_count; wasm_ret_types = func_type->types + func_type->param_count;

View File

@ -74,7 +74,7 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
} }
static LLVMValueRef static LLVMValueRef
get_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx); get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
LLVMValueRef LLVMValueRef
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, 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) { if (init_page_count == 0) {
LLVMValueRef mem_size; 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; goto fail;
} }
BUILD_ICMP(LLVMIntEQ, mem_size, I32_ZERO, cmp, "is_zero"); BUILD_ICMP(LLVMIntEQ, mem_size, I32_ZERO, cmp, "is_zero");
@ -611,7 +611,7 @@ fail:
} }
static LLVMValueRef 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; LLVMValueRef mem_size;
@ -636,7 +636,7 @@ fail:
bool bool
aot_compile_op_memory_size(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) 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) if (mem_size)
PUSH_I32(mem_size); PUSH_I32(mem_size);
@ -648,7 +648,7 @@ fail:
bool bool
aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) 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; LLVMValueRef delta, param_values[2], ret_value, func, value;
LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type; 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 (func_ctx->mem_space_unchanged) {
if (!(mem_size = get_memory_size(comp_ctx, func_ctx))) { mem_size = func_ctx->mem_info[0].mem_data_size_addr;
goto fail; }
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"); ADD_BASIC_BLOCK(check_succ, "check_succ");

View File

@ -262,6 +262,13 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; 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 else
#endif #endif
@ -282,6 +289,14 @@ create_memory_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build in bounds gep failed"); aot_set_last_error("llvm build in bounds gep failed");
return false; 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 */ /* Store mem info base address before cast */
mem_info_base = func_ctx->mem_info[0].mem_base_addr; 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"); aot_set_last_error("llvm build bit cast failed");
return false; 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 (mem_space_unchanged) {
if (!(func_ctx->mem_info[0].mem_base_addr = if (!(func_ctx->mem_info[0].mem_base_addr =
LLVMBuildLoad(comp_ctx->builder, 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 = if (!(func_ctx->mem_info[0].mem_cur_page_count_addr =
LLVMBuildLoad(comp_ctx->builder, LLVMBuildLoad(comp_ctx->builder,
func_ctx->mem_info[0].mem_cur_page_count_addr, 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"); aot_set_last_error("llvm build load failed");
return false; return false;
} }
@ -1476,7 +1505,9 @@ aot_create_comp_context(AOTCompData *comp_data,
/* Create function context for each function */ /* Create function context for each function */
comp_ctx->func_ctx_count = comp_data->func_count; 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; goto fail;
ret = comp_ctx; ret = comp_ctx;
@ -1521,7 +1552,8 @@ aot_destroy_comp_context(AOTCompContext *comp_ctx)
LLVMContextDispose(comp_ctx->context); LLVMContextDispose(comp_ctx->context);
if (comp_ctx->func_ctxes) 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); wasm_runtime_free(comp_ctx);
} }

View File

@ -103,6 +103,7 @@ typedef struct AOTCheckedAddr {
typedef struct AOTMemInfo { typedef struct AOTMemInfo {
LLVMValueRef mem_base_addr; LLVMValueRef mem_base_addr;
LLVMValueRef mem_data_size_addr;
LLVMValueRef mem_cur_page_count_addr; LLVMValueRef mem_cur_page_count_addr;
LLVMValueRef mem_bound_check_1byte; LLVMValueRef mem_bound_check_1byte;
LLVMValueRef mem_bound_check_2bytes; LLVMValueRef mem_bound_check_2bytes;

View File

@ -83,7 +83,7 @@ fail:
return false; return false;
} }
// TODO: instructions for other CPUs /* TODO: instructions for other CPUs */
/* shufflevector is not an option, since it requires *mask as a const */ /* shufflevector is not an option, since it requires *mask as a const */
bool bool
aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) aot_compile_simd_swizzle(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)

View File

@ -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); read_leb_uint32(p, p_end, function_count);
table_segment->function_count = function_count; table_segment->function_count = function_count;
total_size = sizeof(uint32) * (uint64)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))) { loader_malloc(total_size, error_buf, error_buf_size))) {
return false; return false;
} }
@ -2444,7 +2445,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end,
previous_func_index = func_index; previous_func_index = func_index;
read_leb_uint32(p, p_end, func_name_len); read_leb_uint32(p, p_end, func_name_len);
CHECK_BUF(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) { if (func_index >= module->import_count) {
func_index -= module->import_count; func_index -= module->import_count;
if (func_index >= module->function_count) { if (func_index >= module->function_count) {
@ -5697,7 +5698,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
uint32 segment_index; uint32 segment_index;
#endif #endif
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
uint8 *func_const_end, *func_const; uint8 *func_const_end, *func_const = NULL;
int16 operand_offset; int16 operand_offset;
uint8 last_op = 0; uint8 last_op = 0;
bool disable_emit, preserve_local = false; bool disable_emit, preserve_local = false;
@ -7710,7 +7711,8 @@ fail_data_cnt_sec_require:
goto re_scan; goto re_scan;
func->const_cell_num = loader_ctx->const_cell_num; 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, loader_malloc(func->const_cell_num * 4,
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
goto fail; goto fail;

View File

@ -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); read_leb_uint32(p, p_end, function_count);
table_segment->function_count = function_count; table_segment->function_count = function_count;
total_size = sizeof(uint32) * (uint64)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))) { loader_malloc(total_size, error_buf, error_buf_size))) {
return false; return false;
} }
@ -1391,7 +1392,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end,
previous_func_index = func_index; previous_func_index = func_index;
read_leb_uint32(p, p_end, func_name_len); read_leb_uint32(p, p_end, func_name_len);
CHECK_BUF(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) { if (func_index >= module->import_count) {
func_index -= module->import_count; func_index -= module->import_count;
bh_assert(func_index < module->function_count); bh_assert(func_index < module->function_count);
@ -4257,7 +4258,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
uint32 segment_index; uint32 segment_index;
#endif #endif
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
uint8 *func_const_end, *func_const; uint8 *func_const_end, *func_const = NULL;
int16 operand_offset; int16 operand_offset;
uint8 last_op = 0; uint8 last_op = 0;
bool disable_emit, preserve_local = false; bool disable_emit, preserve_local = false;
@ -5733,7 +5734,8 @@ handle_op_block_and_loop:
goto re_scan; goto re_scan;
func->const_cell_num = loader_ctx->const_cell_num; 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, loader_malloc(func->const_cell_num * 4,
error_buf, error_buf_size))) { error_buf, error_buf_size))) {
goto fail; goto fail;

View File

@ -110,7 +110,8 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
wasm_runtime_free(memories[i]->heap_handle); wasm_runtime_free(memories[i]->heap_handle);
memories[i]->heap_handle = NULL; 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]); wasm_runtime_free(memories[i]);
} }
} }
@ -248,8 +249,10 @@ memory_instantiate(WASMModuleInstance *module_inst,
return NULL; return NULL;
} }
if (!(memory->memory_data = if (memory_data_size > 0
runtime_malloc(memory_data_size, error_buf, error_buf_size))) { && !(memory->memory_data =
runtime_malloc(memory_data_size,
error_buf, error_buf_size))) {
goto fail1; goto fail1;
} }
@ -307,7 +310,8 @@ fail3:
if (heap_size > 0) if (heap_size > 0)
wasm_runtime_free(memory->heap_handle); wasm_runtime_free(memory->heap_handle);
fail2: fail2:
wasm_runtime_free(memory->memory_data); if (memory->memory_data)
wasm_runtime_free(memory->memory_data);
fail1: fail1:
wasm_runtime_free(memory); wasm_runtime_free(memory);
return NULL; return NULL;
@ -1293,9 +1297,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
bh_assert(memory); bh_assert(memory);
memory_data = memory->memory_data; memory_data = memory->memory_data;
bh_assert(memory_data);
memory_size = memory->num_bytes_per_page * memory->cur_page_count; 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 bh_assert(data_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST == INIT_EXPR_TYPE_I32_CONST
@ -1337,8 +1340,10 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
goto fail; goto fail;
} }
bh_memcpy_s(memory_data + base_offset, memory_size - base_offset, if (memory_data) {
data_seg->data, length); bh_memcpy_s(memory_data + base_offset, memory_size - base_offset,
data_seg->data, length);
}
} }
/* Initialize the table data with table segment section */ /* 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))) { if (!(new_memory_data = wasm_runtime_malloc((uint32)total_size))) {
return false; return false;
} }
bh_memcpy_s(new_memory_data, (uint32)total_size, if (memory_data) {
memory_data, total_size_old); bh_memcpy_s(new_memory_data, (uint32)total_size,
wasm_runtime_free(memory_data); memory_data, total_size_old);
wasm_runtime_free(memory_data);
}
} }
memset(new_memory_data + total_size_old, memset(new_memory_data + total_size_old,

View File

@ -1652,7 +1652,8 @@ static __wasi_errno_t path_get_nofollow(
static void path_put( static void path_put(
struct path_access *pa struct path_access *pa
) UNLOCKS(pa->fd_object->refcount) { ) 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) if (fd_number(pa->fd_object) != pa->fd)
close(pa->fd); close(pa->fd);
fd_object_release(pa->fd_object); fd_object_release(pa->fd_object);

View File

@ -51,7 +51,7 @@ bh_log(LogLevel log_level, const char *file, int line, const char *fmt, ...);
#endif #endif
#if BH_DEBUG == 1 #if BH_DEBUG != 0
#define LOG_FATAL(...) bh_log(BH_LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__) #define LOG_FATAL(...) bh_log(BH_LOG_LEVEL_FATAL, __FILE__, __LINE__, __VA_ARGS__)
#else #else
#define LOG_FATAL(...) bh_log(BH_LOG_LEVEL_FATAL, __FUNCTION__, __LINE__, __VA_ARGS__) #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_WARNING(...) bh_log(BH_LOG_LEVEL_WARNING, NULL, 0, __VA_ARGS__)
#define LOG_VERBOSE(...) bh_log(BH_LOG_LEVEL_VERBOSE, 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__) #define LOG_DEBUG(...) bh_log(BH_LOG_LEVEL_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#else #else
#define LOG_DEBUG(...) (void)0 #define LOG_DEBUG(...) (void)0

View File

@ -14,7 +14,7 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
{ {
char *buffer; char *buffer;
int file; int file;
uint32 file_size, read_size; uint32 file_size, buf_size, read_size;
struct stat stat_buf; struct stat stat_buf;
if (!filename || !ret_size) { 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; 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"); printf("Read file to buffer failed: alloc memory failed.\n");
_close(file); _close(file);
return NULL; return NULL;
@ -63,7 +66,7 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
{ {
char *buffer; char *buffer;
int file; int file;
uint32 file_size, read_size; uint32 file_size, buf_size, read_size;
struct stat stat_buf; struct stat stat_buf;
if (!filename || !ret_size) { 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; 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"); printf("Read file to buffer failed: alloc memory failed.\n");
close(file); close(file);
return NULL; return NULL;

View File

@ -74,7 +74,7 @@ endif()
## locate wat2wasm ## locate wat2wasm
find_program(WAT2WASM find_program(WAT2WASM
wat2wasm wat2wasm
PATHS /opt/wabt/bin /opt/wabt-1.0.18/bin PATHS /opt/wabt/bin
REQUIRED REQUIRED
) )

View File

@ -1,5 +1,5 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt
index ffdb4da..536a5c8 100644 index ffdb4da..a397427 100644
--- a/CMakeLists.txt --- a/CMakeLists.txt
+++ b/CMakeLists.txt +++ b/CMakeLists.txt
@@ -127,3 +127,43 @@ install(FILES @@ -127,3 +127,43 @@ install(FILES
@ -24,7 +24,7 @@ index ffdb4da..536a5c8 100644
+ +
+target_link_options(codecbench +target_link_options(codecbench
+ PUBLIC + PUBLIC
+ LINKER:-allow-undefined,--demangle + LINKER:-allow-undefined,--demangle,--export=malloc,--export=free
+) +)
+ +
+find_program(WASM_OPT +find_program(WASM_OPT