Parcourir la source

Refine aot stack overflow check and enhance wasm loader malformed checks (#248)

And separate global data from wasm memory instance
wenyongh il y a 5 ans
Parent
commit
e8e45aeecd

+ 8 - 6
core/iwasm/aot/aot_loader.c

@@ -1959,12 +1959,14 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
 
     module->start_func_index = comp_data->start_func_index;
     if (comp_data->start_func_index != (uint32)-1) {
-        bh_assert(comp_data->start_func_index >= module->import_func_count
-                  && comp_data->start_func_index < module->import_func_count
-                                                   + module->func_count);
-        module->start_function =
-            module->func_ptrs[comp_data->start_func_index
-                              - module->import_func_count];
+        bh_assert(comp_data->start_func_index < module->import_func_count
+                                                + module->func_count);
+        /* TODO: fix issue that start func cannot be import func */
+        if (comp_data->start_func_index >= module->import_func_count) {
+            module->start_function =
+                module->func_ptrs[comp_data->start_func_index
+                                  - module->import_func_count];
+        }
     }
     else {
         module->start_function = NULL;

+ 9 - 9
core/iwasm/aot/aot_runtime.c

@@ -897,6 +897,15 @@ aot_call_indirect(WASMExecEnv *exec_env,
     void *attachment = NULL;
     char buf[128];
 
+    /* this function is called from native code, so exec_env->handle and
+       exec_env->native_stack_boundary must have been set, we don't set
+       it again */
+
+    if ((uint8*)&module_inst < exec_env->native_stack_boundary) {
+        aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
+        return false;
+    }
+
     if (table_elem_idx >= table_size) {
         aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
         return false;
@@ -941,15 +950,6 @@ aot_call_indirect(WASMExecEnv *exec_env,
         }
     }
 
-    /* this function is called from native code, so exec_env->handle and
-       exec_env->native_stack_boundary must have been set, we don't set
-       it again */
-
-    if ((uint8*)&module_inst < exec_env->native_stack_boundary) {
-        aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
-        return false;
-    }
-
     return wasm_runtime_invoke_native(exec_env, func_ptr,
                                       func_type, signature, attachment,
                                       argv, argc, argv);

+ 2 - 0
core/iwasm/compilation/aot.c

@@ -327,6 +327,8 @@ aot_create_funcs(const WASMModule *module)
     /* Resolve local variable info and code info */
     funcs[i]->local_count = func->local_count;
     funcs[i]->local_types = func->local_types;
+    funcs[i]->param_cell_num = func->param_cell_num;
+    funcs[i]->local_cell_num = func->local_cell_num;
     funcs[i]->code = func->code;
     funcs[i]->code_size = func->code_size;
   }

+ 2 - 0
core/iwasm/compilation/aot.h

@@ -98,6 +98,8 @@ typedef struct AOTFunc {
   uint32 func_type_index;
   uint32 local_count;
   uint8 *local_types;
+  uint16 param_cell_num;
+  uint16 local_cell_num;
   uint32 code_size;
   uint8 *code;
 } AOTFunc;

+ 22 - 4
core/iwasm/compilation/aot_emit_function.c

@@ -256,11 +256,25 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 }
 
 static bool
-check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
+check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
+                     uint32 callee_cell_num)
 {
     LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
     LLVMBasicBlockRef check_stack;
-    LLVMValueRef cmp;
+    LLVMValueRef callee_local_size, stack_bound, cmp;
+
+    if (!(callee_local_size = I32_CONST(callee_cell_num * 4))) {
+        aot_set_last_error("llvm build const failed.");
+        return false;
+    }
+
+    if (!(stack_bound = LLVMBuildInBoundsGEP(comp_ctx->builder,
+                                             func_ctx->native_stack_bound,
+                                             &callee_local_size, 1,
+                                             "stack_bound"))) {
+        aot_set_last_error("llvm build inbound gep failed.");
+        return false;
+    }
 
     if (!(check_stack = LLVMAppendBasicBlockInContext(comp_ctx->context,
                                                       func_ctx->func,
@@ -272,7 +286,7 @@ check_stack_boundary(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
     LLVMMoveBasicBlockAfter(check_stack, block_curr);
 
     if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULT,
-                              func_ctx->last_alloca, func_ctx->native_stack_bound,
+                              func_ctx->last_alloca, stack_bound,
                               "cmp"))) {
         aot_set_last_error("llvm build icmp failed.");
         return false;
@@ -297,11 +311,13 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     uint32 func_count = comp_ctx->func_ctx_count, param_cell_num = 0;
     AOTFuncContext **func_ctxes = comp_ctx->func_ctxes;
     AOTFuncType *func_type;
+    AOTFunc *aot_func;
     LLVMTypeRef *param_types = NULL, ret_type;
     LLVMValueRef *param_values = NULL, value_ret = NULL, func;
     LLVMValueRef import_func_idx, res;
     int32 i, j = 0, param_count;
     uint64 total_size;
+    uint32 callee_cell_num;
     uint8 wasm_ret_type;
     bool ret = false;
 
@@ -379,8 +395,10 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     }
     else {
         func = func_ctxes[func_idx - import_func_count]->func;
+        aot_func = func_ctxes[func_idx - import_func_count]->aot_func;
+        callee_cell_num = aot_func->param_cell_num + aot_func->local_cell_num + 1;
 
-        if (!check_stack_boundary(comp_ctx, func_ctx))
+        if (!check_stack_boundary(comp_ctx, func_ctx, callee_cell_num))
             goto fail;
 
         /* Call the function */

+ 1 - 2
core/iwasm/interpreter/wasm_interp_classic.c

@@ -901,7 +901,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
   uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
   uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count
                                    - heap_base_offset : 0;
-  uint8 *global_data = memory ? memory->global_data : NULL;
+  uint8 *global_data = module->global_data;
   WASMTableInstance *table = module->default_table;
   WASMGlobalInstance *globals = module->globals;
   uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
@@ -1521,7 +1521,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
           memory = module->default_memory;
           total_mem_size = num_bytes_per_page * memory->cur_page_count
                            - heap_base_offset;
-          global_data = memory->global_data;
         }
 
         (void)reserved;

+ 1 - 2
core/iwasm/interpreter/wasm_interp_fast.c

@@ -893,7 +893,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
   uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
   uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count
                                    - heap_base_offset : 0;
-  uint8 *global_data = memory ? memory->global_data : NULL;
+  uint8 *global_data = module->global_data;
   WASMTableInstance *table = module->default_table;
   WASMGlobalInstance *globals = module->globals;
   uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
@@ -1429,7 +1429,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
           memory = module->default_memory;
           total_mem_size = num_bytes_per_page * memory->cur_page_count
                            - heap_base_offset;
-          global_data = memory->global_data;
         }
 
         (void)reserved;

+ 149 - 76
core/iwasm/interpreter/wasm_loader.c

@@ -467,6 +467,18 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
     return true;
 }
 
+static bool
+check_table_max_size(uint32 init_size, uint32 max_size,
+                     char *error_buf, uint32 error_buf_size)
+{
+    if (max_size < init_size) {
+        set_error_buf(error_buf, error_buf_size,
+                      "size minimum must not be greater than maximum");
+        return false;
+    }
+    return true;
+}
+
 static bool
 load_table_import(const uint8 **p_buf, const uint8 *buf_end,
                   WASMTableImport *table,
@@ -480,8 +492,12 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
     bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC);
     read_leb_uint32(p, p_end, table->flags);
     read_leb_uint32(p, p_end, table->init_size);
-    if (table->flags & 1)
+    if (table->flags & 1) {
         read_leb_uint32(p, p_end, table->max_size);
+        if (!check_table_max_size(table->init_size, table->max_size,
+                                  error_buf, error_buf_size))
+            return false;
+    }
     else
         table->max_size = 0x10000;
 
@@ -573,8 +589,12 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table,
     bh_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC);
     read_leb_uint32(p, p_end, table->flags);
     read_leb_uint32(p, p_end, table->init_size);
-    if (table->flags & 1)
+    if (table->flags & 1) {
         read_leb_uint32(p, p_end, table->max_size);
+        if (!check_table_max_size(table->init_size, table->max_size,
+                                  error_buf, error_buf_size))
+            return false;
+    }
     else
         table->max_size = 0x10000;
 
@@ -1065,7 +1085,6 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
     WASMTable *table;
 
     read_leb_uint32(p, p_end, table_count);
-    bh_assert(table_count == 1);
 
     if (table_count) {
         if (table_count > 1) {
@@ -2419,6 +2438,7 @@ typedef struct BranchBlock {
     uint8 block_type;
     uint8 return_type;
     bool is_block_reachable;
+    bool skip_else_branch;
     uint8 *start_addr;
     uint8 *else_addr;
     uint8 *end_addr;
@@ -2590,10 +2610,13 @@ check_stack_pop(WASMLoaderContext *ctx, uint8 type,
                 char *error_buf, uint32 error_buf_size,
                 const char *type_str)
 {
+    uint32 block_stack_cell_num = ctx->stack_cell_num
+                                  - (ctx->frame_csp - 1)->stack_cell_num;
+
     if (((type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32)
-         && ctx->stack_cell_num < 1)
+         && block_stack_cell_num < 1)
         || ((type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)
-            && ctx->stack_cell_num < 2)) {
+            && block_stack_cell_num < 2)) {
         set_error_buf(error_buf, error_buf_size,
                       "WASM module load failed: "
                       "type mismatch: expect data but stack was empty");
@@ -2766,7 +2789,17 @@ static bool
 wasm_loader_pop_frame_csp(WASMLoaderContext *ctx,
                           char *error_buf, uint32 error_buf_size)
 {
+    uint8 block_return_type;
+
     CHECK_CSP_POP();
+
+    block_return_type = (ctx->frame_csp - 1)->return_type;
+    if (!wasm_loader_pop_frame_ref(ctx, block_return_type,
+                                   error_buf, error_buf_size)
+        || !wasm_loader_push_frame_ref(ctx, block_return_type,
+                                       error_buf, error_buf_size))
+        goto fail;
+
     ctx->frame_csp--;
     ctx->csp_num--;
     return true;
@@ -3476,7 +3509,6 @@ fail:
         goto fail;                                              \
   } while (0)
 
-
 #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() do {      \
     read_leb_uint32(p, p_end, local_idx);           \
     if (local_idx >= param_count + local_count) {   \
@@ -3515,11 +3547,6 @@ check_memory(WASMModule *module,
       goto fail;                                                    \
   } while (0)
 
-#if WASM_ENABLE_FAST_INTERP != 0
-
-
-#endif /* WASM_ENABLE_FAST_INTERP */
-
 static bool
 is_block_type_valid(uint8 type)
 {
@@ -3538,6 +3565,44 @@ is_block_type_valid(uint8 type)
         }                                                                   \
     } while (0)
 
+static BranchBlock *
+check_branch_block(WASMLoaderContext *loader_ctx,
+                   uint8 **p_buf, uint8 *buf_end,
+                   char *error_buf, uint32 error_buf_size)
+{
+    uint8 *p = *p_buf, *p_end = buf_end;
+    BranchBlock *frame_csp_tmp;
+    uint32 depth;
+
+    read_leb_uint32(p, p_end, depth);
+    CHECK_BR(depth);
+    frame_csp_tmp = loader_ctx->frame_csp - depth - 1;
+#if WASM_ENABLE_FAST_INTERP != 0
+    emit_br_info(frame_csp_tmp);
+#endif
+
+    *p_buf = p;
+    return frame_csp_tmp;
+fail:
+    return NULL;
+}
+
+static bool
+check_branch_block_ret(WASMLoaderContext *loader_ctx,
+                       BranchBlock *frame_csp_tmp,
+                       char *error_buf, uint32 error_buf_size)
+{
+    frame_csp_tmp->is_block_reachable = true;
+    if (frame_csp_tmp->block_type != BLOCK_TYPE_LOOP) {
+        uint8 block_return_type = frame_csp_tmp->return_type;
+        POP_TYPE(block_return_type);
+        PUSH_TYPE(block_return_type);
+    }
+    return true;
+fail:
+    return false;
+}
+
 static bool
 wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
                              BlockAddr *block_addr_cache,
@@ -3547,7 +3612,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
     uint32 param_count, local_count, global_count;
     uint8 *param_types, ret_type, *local_types, local_type, global_type;
     uint16 *local_offsets, local_offset;
-    uint32 count, i, local_idx, global_idx, depth, u32, align, mem_offset;
+    uint32 count, i, local_idx, global_idx, u32, align, mem_offset;
     uint32 cache_index, item_index;
     int32 i32, i32_const = 0;
     int64 i64;
@@ -3555,6 +3620,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
     bool return_value = false, is_i32_const = false;
     BlockAddr *cache_items;
     WASMLoaderContext *loader_ctx;
+    BranchBlock *frame_csp_tmp;
 #if WASM_ENABLE_FAST_INTERP != 0
     uint8 *func_const_end, *func_const;
     int16 operand_offset;
@@ -3657,32 +3723,32 @@ re_scan:
                 if (!is_i32_const)
                     (loader_ctx->frame_csp - 1)->is_block_reachable = true;
                 else {
-                    if (!i32_const) {
-                        cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr)
-                                      & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
-                        cache_items = block_addr_cache +
-                                      BLOCK_ADDR_CONFLICT_SIZE * cache_index;
-                        for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE;
-                             item_index++) {
-                            if (cache_items[item_index].start_addr ==
-                                                (loader_ctx->frame_csp - 1)->start_addr) {
-                                (loader_ctx->frame_csp - 1)->else_addr =
-                                            cache_items[item_index].else_addr;
-                                (loader_ctx->frame_csp - 1)->end_addr =
-                                            cache_items[item_index].end_addr;
-                                break;
-                            }
+                    cache_index = ((uintptr_t)(loader_ctx->frame_csp - 1)->start_addr)
+                                   & (uintptr_t)(BLOCK_ADDR_CACHE_SIZE - 1);
+                    cache_items = block_addr_cache
+                                  + BLOCK_ADDR_CONFLICT_SIZE * cache_index;
+                    for (item_index = 0; item_index < BLOCK_ADDR_CONFLICT_SIZE;
+                         item_index++) {
+                        if (cache_items[item_index].start_addr ==
+                                (loader_ctx->frame_csp - 1)->start_addr) {
+                            (loader_ctx->frame_csp - 1)->else_addr =
+                                cache_items[item_index].else_addr;
+                            (loader_ctx->frame_csp - 1)->end_addr =
+                                cache_items[item_index].end_addr;
+                            break;
                         }
-                        if (item_index == BLOCK_ADDR_CONFLICT_SIZE
-                            && !wasm_loader_find_block_addr(block_addr_cache,
-                                                           (loader_ctx->frame_csp - 1)->start_addr,
-                                                           p_end,
-                                                           (loader_ctx->frame_csp - 1)->block_type,
-                                                           &(loader_ctx->frame_csp - 1)->else_addr,
-                                                           &(loader_ctx->frame_csp - 1)->end_addr,
-                                                           error_buf, error_buf_size))
-                            goto fail;
+                    }
+                    if (item_index == BLOCK_ADDR_CONFLICT_SIZE
+                        && !wasm_loader_find_block_addr(block_addr_cache,
+                                        (loader_ctx->frame_csp - 1)->start_addr,
+                                        p_end,
+                                        (loader_ctx->frame_csp - 1)->block_type,
+                                        &(loader_ctx->frame_csp - 1)->else_addr,
+                                        &(loader_ctx->frame_csp - 1)->end_addr,
+                                        error_buf, error_buf_size))
+                        goto fail;
 
+                    if (!i32_const) {
                         if ((loader_ctx->frame_csp - 1)->else_addr) {
 #if WASM_ENABLE_FAST_INTERP != 0
                             loader_ctx->frame_offset = loader_ctx->frame_offset_bottom +
@@ -3698,6 +3764,10 @@ re_scan:
                         is_i32_const = false;
                         continue;
                     }
+                    else {
+                        /* The else branch cannot be reached, ignored it. */
+                        (loader_ctx->frame_csp - 1)->skip_else_branch = true;
+                    }
                 }
                 break;
 
@@ -3710,6 +3780,16 @@ re_scan:
                     goto fail;
                 }
 
+                if ((loader_ctx->frame_csp - 1)->skip_else_branch) {
+                    /* The else branch is ignored. */
+                    is_i32_const = false;
+                    p = (loader_ctx->frame_csp - 1)->end_addr;
+#if WASM_ENABLE_FAST_INTERP != 0
+                    skip_label();
+#endif
+                    continue;
+                }
+
                 (loader_ctx->frame_csp - 1)->else_addr = p - 1;
                 loader_ctx->stack_cell_num = (loader_ctx->frame_csp - 1)->stack_cell_num;
                 loader_ctx->frame_ref = loader_ctx->frame_ref_bottom +
@@ -3748,9 +3828,6 @@ re_scan:
             {
                 POP_CSP();
 
-                POP_TYPE(loader_ctx->frame_csp->return_type);
-                PUSH_TYPE(loader_ctx->frame_csp->return_type);
-
 #if WASM_ENABLE_FAST_INTERP != 0
                 skip_label();
                 // copy the result to the block return address
@@ -3800,16 +3877,13 @@ re_scan:
 
             case WASM_OP_BR:
             {
-#if WASM_ENABLE_FAST_INTERP != 0
-                BranchBlock *frame_csp_tmp;
-#endif
-                read_leb_uint32(p, p_end, depth);
-                CHECK_BR(depth);
+                if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end,
+                                                         error_buf, error_buf_size)))
+                    goto fail;
 
-#if WASM_ENABLE_FAST_INTERP != 0
-                frame_csp_tmp = loader_ctx->frame_csp - depth - 1;
-                emit_br_info(frame_csp_tmp);
-#endif
+                if (!check_branch_block_ret(loader_ctx, frame_csp_tmp,
+                                            error_buf, error_buf_size))
+                    goto fail;
 
 handle_next_reachable_block:
                 for (i = 1; i <= loader_ctx->csp_num; i++)
@@ -3870,31 +3944,25 @@ handle_next_reachable_block:
 
             case WASM_OP_BR_IF:
             {
-#if WASM_ENABLE_FAST_INTERP != 0
-                BranchBlock *frame_csp_tmp;
-#endif
-                read_leb_uint32(p, p_end, depth);
                 POP_I32();
-                CHECK_BR(depth);
-#if WASM_ENABLE_FAST_INTERP != 0
-                frame_csp_tmp = loader_ctx->frame_csp - depth - 1;
-                emit_br_info(frame_csp_tmp);
-#endif
-                if (!is_i32_const)
-                    (loader_ctx->frame_csp - (depth + 1))->is_block_reachable = true;
-                else {
-                    if (i32_const)
-                        goto handle_next_reachable_block;
+
+                if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end,
+                                                         error_buf, error_buf_size)))
+                    goto fail;
+
+                if (!is_i32_const || i32_const) {
+                    /* The branch can be reached */
+                    if (!check_branch_block_ret(loader_ctx, frame_csp_tmp,
+                                                error_buf, error_buf_size))
+                        goto fail;
                 }
+                if (is_i32_const && i32_const)
+                    goto handle_next_reachable_block;
                 break;
             }
 
             case WASM_OP_BR_TABLE:
             {
-#if WASM_ENABLE_FAST_INTERP != 0
-                BranchBlock *frame_csp_tmp;
-#endif
-
                 read_leb_uint32(p, p_end, count);
 #if WASM_ENABLE_FAST_INTERP != 0
                 emit_const(count);
@@ -3903,12 +3971,13 @@ handle_next_reachable_block:
 
                 /* TODO: check the const */
                 for (i = 0; i <= count; i++) {
-                    read_leb_uint32(p, p_end, depth);
-                    CHECK_BR(depth);
-#if WASM_ENABLE_FAST_INTERP != 0
-                    frame_csp_tmp = loader_ctx->frame_csp - depth - 1;
-                    emit_br_info(frame_csp_tmp);
-#endif
+                    if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end,
+                                                        error_buf, error_buf_size)))
+                        goto fail;
+
+                    if (!check_branch_block_ret(loader_ctx, frame_csp_tmp,
+                                                error_buf, error_buf_size))
+                        goto fail;
                 }
 
                 goto handle_next_reachable_block;
@@ -4037,10 +4106,12 @@ handle_next_reachable_block:
             case WASM_OP_DROP:
             case WASM_OP_DROP_64:
             {
-                if (loader_ctx->stack_cell_num <= 0) {
+                if (loader_ctx->stack_cell_num
+                     - (loader_ctx->frame_csp - 1)->stack_cell_num <= 0) {
                     set_error_buf(error_buf, error_buf_size,
                                   "WASM loader prepare bytecode failed: "
-                                  "opcode drop was found but stack was empty");
+                                  "type mismatch, opcode drop was found "
+                                  "but stack was empty");
                     goto fail;
                 }
 
@@ -4057,10 +4128,12 @@ handle_next_reachable_block:
 #endif
                 }
                 else {
-                    if (loader_ctx->stack_cell_num <= 1) {
+                    if (loader_ctx->stack_cell_num
+                        - (loader_ctx->frame_csp - 1)->stack_cell_num <= 0) {
                         set_error_buf(error_buf, error_buf_size,
                                       "WASM loader prepare bytecode failed: "
-                                      "opcode drop was found but stack was empty");
+                                      "type mismatch, opcode drop was found "
+                                      "but stack was empty");
                         goto fail;
                     }
                     loader_ctx->frame_ref -= 2;

+ 37 - 43
core/iwasm/interpreter/wasm_runtime.c

@@ -60,15 +60,13 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
 static WASMMemoryInstance*
 memory_instantiate(uint32 num_bytes_per_page,
                    uint32 init_page_count, uint32 max_page_count,
-                   uint32 global_data_size,
                    uint32 heap_size,
                    char *error_buf, uint32 error_buf_size)
 {
     WASMMemoryInstance *memory;
     uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
                         (uint64)heap_size +
-                        num_bytes_per_page * (uint64)init_page_count +
-                        global_data_size;
+                        num_bytes_per_page * (uint64)init_page_count;
 
     /* Allocate memory space, addr data and global data */
     if (total_size >= UINT32_MAX
@@ -85,10 +83,8 @@ memory_instantiate(uint32 num_bytes_per_page,
 
     memory->heap_data = memory->base_addr;
     memory->memory_data = memory->heap_data + heap_size;
-    memory->global_data = memory->memory_data +
+    memory->end_addr = memory->memory_data +
                           num_bytes_per_page * memory->cur_page_count;
-    memory->global_data_size = global_data_size;
-    memory->end_addr = memory->global_data + global_data_size;
 
     bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size);
 
@@ -112,7 +108,7 @@ memory_instantiate(uint32 num_bytes_per_page,
  */
 static WASMMemoryInstance**
 memories_instantiate(const WASMModule *module,
-                     uint32 global_data_size, uint32 heap_size,
+                     uint32 heap_size,
                      char *error_buf, uint32 error_buf_size)
 {
     WASMImport *import;
@@ -121,9 +117,6 @@ memories_instantiate(const WASMModule *module,
     uint64 total_size;
     WASMMemoryInstance **memories, *memory;
 
-    if (memory_count == 0 && global_data_size > 0)
-        memory_count = 1;
-
     total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count;
 
     if (total_size >= UINT32_MAX
@@ -143,7 +136,6 @@ memories_instantiate(const WASMModule *module,
                     memory_instantiate(import->u.memory.num_bytes_per_page,
                                        import->u.memory.init_page_count,
                                        import->u.memory. max_page_count,
-                                       global_data_size,
                                        heap_size, error_buf, error_buf_size))) {
             set_error_buf(error_buf, error_buf_size,
                          "Instantiate memory failed: "
@@ -159,7 +151,6 @@ memories_instantiate(const WASMModule *module,
                     memory_instantiate(module->memories[i].num_bytes_per_page,
                                        module->memories[i].init_page_count,
                                        module->memories[i].max_page_count,
-                                       global_data_size,
                                        heap_size, error_buf, error_buf_size))) {
             set_error_buf(error_buf, error_buf_size,
                           "Instantiate memory failed: "
@@ -172,8 +163,8 @@ memories_instantiate(const WASMModule *module,
     if (mem_index == 0) {
         /* no import memory and define memory, but has global variables */
         if (!(memory = memories[mem_index++] =
-                    memory_instantiate(0, 0, 0, global_data_size,
-                                       heap_size, error_buf, error_buf_size))) {
+                    memory_instantiate(0, 0, 0, heap_size,
+                                       error_buf, error_buf_size))) {
             set_error_buf(error_buf, error_buf_size,
                           "Instantiate memory failed: "
                           "allocate memory failed.\n");
@@ -608,11 +599,20 @@ wasm_instantiate(WASMModule *module,
         module->import_function_count + module->function_count;
     module_inst->export_func_count = get_export_function_count(module);
 
+    if (global_count > 0) {
+        if (!(module_inst->global_data =
+                    wasm_runtime_malloc(global_data_size))) {
+            wasm_deinstantiate(module_inst);
+            return NULL;
+        }
+        memset(module_inst->global_data, 0, global_data_size);
+    }
+
     /* Instantiate memories/tables/functions */
-    if (((module_inst->memory_count > 0 || global_count > 0)
+    if ((module_inst->memory_count > 0
          && !(module_inst->memories =
-             memories_instantiate(module, global_data_size,
-                                  heap_size, error_buf, error_buf_size)))
+                memories_instantiate(module, heap_size,
+                                     error_buf, error_buf_size)))
         || (module_inst->table_count > 0
             && !(module_inst->tables = tables_instantiate(module,
                                                           error_buf,
@@ -629,13 +629,8 @@ wasm_instantiate(WASMModule *module,
         return NULL;
     }
 
-    if (module_inst->memory_count || global_count > 0) {
-        WASMMemoryInstance *memory;
-
-        memory = module_inst->default_memory = module_inst->memories[0];
-        memory_data = module_inst->default_memory->memory_data;
-
-        /* fix import memoryBase */
+    if (global_count > 0) {
+        /* fix globals */
         if (!globals_instantiate_fix(globals, module, module_inst,
                                      error_buf, error_buf_size)) {
             wasm_deinstantiate(module_inst);
@@ -643,7 +638,7 @@ wasm_instantiate(WASMModule *module,
         }
 
         /* Initialize the global data */
-        global_data = memory->global_data;
+        global_data = module_inst->global_data;
         global_data_end = global_data + global_data_size;
         global = globals;
         for (i = 0; i < global_count; i++, global++) {
@@ -665,8 +660,16 @@ wasm_instantiate(WASMModule *module,
         }
         bh_assert(global_data == global_data_end);
 
+    }
+
+    if (module_inst->memory_count) {
+        WASMMemoryInstance *memory;
+
+        memory = module_inst->default_memory = module_inst->memories[0];
+        memory_data = module_inst->default_memory->memory_data;
+
         /* Initialize the memory data with data segment section */
-        if (module_inst->default_memory->cur_page_count > 0) {
+        if (memory->cur_page_count > 0) {
             for (i = 0; i < module->data_seg_count; i++) {
                 data_seg = module->data_segments[i];
                 bh_assert(data_seg->memory_index == 0);
@@ -685,8 +688,8 @@ wasm_instantiate(WASMModule *module,
 
                 base_offset = (uint32)data_seg->base_offset.u.i32;
                 length = data_seg->data_length;
-                memory_size = module_inst->default_memory->num_bytes_per_page
-                              * module_inst->default_memory->cur_page_count;
+                memory_size = memory->num_bytes_per_page
+                              * memory->cur_page_count;
 
                 if (length > 0
                     && (base_offset >= memory_size
@@ -825,6 +828,9 @@ wasm_deinstantiate(WASMModuleInstance *module_inst)
     globals_deinstantiate(module_inst->globals);
     export_functions_deinstantiate(module_inst->export_functions);
 
+    if (module_inst->global_data)
+        wasm_runtime_free(module_inst->global_data);
+
     wasm_runtime_free(module_inst);
 }
 
@@ -1057,14 +1063,11 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
 {
     WASMMemoryInstance *memory = module->default_memory, *new_memory;
     uint32 heap_size = memory->memory_data - memory->heap_data;
-    uint32 old_page_count = memory->cur_page_count;
     uint32 total_size_old = memory->end_addr - (uint8*)memory;
     uint32 total_page_count = inc_page_count + memory->cur_page_count;
     uint64 total_size = offsetof(WASMMemoryInstance, base_addr)
                         + (uint64)heap_size
-                        + memory->num_bytes_per_page * (uint64)total_page_count
-                        + memory->global_data_size;
-    uint8 *global_data_old;
+                        + memory->num_bytes_per_page * (uint64)total_page_count;
     void *heap_handle_old = memory->heap_handle;
 
     if (inc_page_count <= 0)
@@ -1111,17 +1114,8 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
     new_memory->cur_page_count = total_page_count;
     new_memory->heap_data = new_memory->base_addr;
     new_memory->memory_data = new_memory->base_addr + heap_size;
-    new_memory->global_data = new_memory->memory_data +
-                              new_memory->num_bytes_per_page * total_page_count;
-    new_memory->end_addr = new_memory->global_data + new_memory->global_data_size;
-
-    global_data_old = new_memory->memory_data +
-                              new_memory->num_bytes_per_page * old_page_count;
-
-    /* Copy global data */
-    bh_memcpy_s(new_memory->global_data, new_memory->global_data_size,
-                global_data_old, new_memory->global_data_size);
-    memset(global_data_old, 0, new_memory->global_data_size);
+    new_memory->end_addr = new_memory->memory_data +
+                            new_memory->num_bytes_per_page * total_page_count;
 
     module->memories[0] = module->default_memory = new_memory;
     return true;

+ 3 - 6
core/iwasm/interpreter/wasm_runtime.h

@@ -33,17 +33,12 @@ typedef struct WASMMemoryInstance {
     /* Memory data */
     uint8 *memory_data;
 
-    /* Global data of global instances */
-    uint8 *global_data;
-    uint32 global_data_size;
-
     /* End address of memory */
     uint8 *end_addr;
 
     /* Base address, the layout is:
-       heap_data + memory data + global data
+       heap_data + memory data
        memory data init size is: num_bytes_per_page * cur_page_count
-       global data size is calculated in module instantiating
        Note: when memory is re-allocated, the heap data and memory data
              must be copied to new memory also.
      */
@@ -127,6 +122,8 @@ typedef struct WASMModuleInstance {
 
     WASMMemoryInstance *default_memory;
     WASMTableInstance *default_table;
+    /* Global data of global instances */
+    uint8 *global_data;
 
     WASMFunctionInstance *start_function;
 

+ 1 - 3
core/shared/platform/android/platform_internal.h

@@ -37,10 +37,8 @@ extern "C" {
 #define BH_PLATFORM_ANDROID
 #endif
 
-#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
-
 /* Stack size of applet threads's native part.  */
-#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT)
+#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
 
 /* Default thread priority */
 #define BH_THREAD_DEFAULT_PRIORITY 0

+ 2 - 1
core/shared/platform/common/posix/posix_thread.c

@@ -233,7 +233,8 @@ uint8 *os_thread_get_stack_boundary()
     }
 
     if (addr)
-        return (uint8*)addr + _STACK_SIZE_ADJUSTMENT;
+        /* Reserved 4 KB for safety */
+        return (uint8*)addr + 4 * 1024;
     else
         return NULL;
 }

+ 1 - 3
core/shared/platform/darwin/platform_internal.h

@@ -37,10 +37,8 @@ extern "C" {
 #define BH_PLATFORM_DARWIN
 #endif
 
-#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
-
 /* Stack size of applet threads's native part.  */
-#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT)
+#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
 
 /* Default thread priority */
 #define BH_THREAD_DEFAULT_PRIORITY 0

+ 1 - 3
core/shared/platform/linux/platform_internal.h

@@ -37,10 +37,8 @@ extern "C" {
 #define BH_PLATFORM_LINUX
 #endif
 
-#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
-
 /* Stack size of applet threads's native part.  */
-#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT)
+#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
 
 /* Default thread priority */
 #define BH_THREAD_DEFAULT_PRIORITY 0

+ 1 - 3
core/shared/platform/vxworks/platform_internal.h

@@ -36,10 +36,8 @@ extern "C" {
 #define BH_PLATFORM_VXWORKS
 #endif
 
-#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
-
 /* Stack size of applet threads's native part.  */
-#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024 + _STACK_SIZE_ADJUSTMENT)
+#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
 
 /* Default thread priority */
 #define BH_THREAD_DEFAULT_PRIORITY 0

+ 1 - 1
samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c

@@ -74,7 +74,7 @@ host_interface interface = {
 
 timer_ctx_t timer_ctx;
 
-static char global_heap_buf[370 * 1024] = { 0 };
+static char global_heap_buf[368 * 1024] = { 0 };
 
 static NativeSymbol native_symbols[] = {
     EXPORT_WASM_API_WITH_SIG(display_input_read, "(*)i"),