mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 06:55:07 +00:00
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:
parent
efd648959c
commit
a5188f5574
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__); \
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user