Explorar el Código

Implement aux stack overflow/underflow check for AOT/interp (#601)

Wenyong Huang hace 5 años
padre
commit
77c3ddf7d0

+ 8 - 1
core/iwasm/aot/aot_runtime.c

@@ -1393,6 +1393,12 @@ aot_set_exception_with_id(AOTModuleInstance *module_inst,
         case EXCE_UNALIGNED_ATOMIC:
             aot_set_exception(module_inst, "unaligned atomic");
             break;
+        case EXCE_AUX_STACK_OVERFLOW:
+            aot_set_exception(module_inst, "wasm auxiliary stack overflow");
+            break;
+        case EXCE_AUX_STACK_UNDERFLOW:
+            aot_set_exception(module_inst, "wasm auxiliary stack underflow");
+            break;
         default:
             break;
     }
@@ -2208,7 +2214,8 @@ aot_set_aux_stack(WASMExecEnv *exec_env,
 
         /* The aux stack boundary is a constant value,
             set the value to exec_env */
-        exec_env->aux_stack_boundary = start_offset - size;
+        exec_env->aux_stack_boundary.boundary = start_offset - size;
+        exec_env->aux_stack_bottom.bottom = start_offset;
         return true;
     }
 

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

@@ -32,6 +32,8 @@ typedef enum AOTExceptionID {
     EXCE_CALL_UNLINKED_IMPORT_FUNC,
     EXCE_NATIVE_STACK_OVERFLOW,
     EXCE_UNALIGNED_ATOMIC,
+    EXCE_AUX_STACK_OVERFLOW,
+    EXCE_AUX_STACK_UNDERFLOW,
     EXCE_NUM,
 } AOTExceptionID;
 

+ 29 - 6
core/iwasm/common/wasm_exec_env.c

@@ -5,6 +5,12 @@
 
 #include "wasm_exec_env.h"
 #include "wasm_runtime_common.h"
+#if WASM_ENABLE_INTERP != 0
+#include "../interpreter/wasm_runtime.h"
+#endif
+#if WASM_ENABLE_AOT != 0
+#include "../aot/aot_runtime.h"
+#endif
 
 #if WASM_ENABLE_THREAD_MGR != 0
 #include "../libraries/thread-mgr/thread_manager.h"
@@ -88,20 +94,37 @@ WASMExecEnv *
 wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
                      uint32 stack_size)
 {
+#if WASM_ENABLE_THREAD_MGR != 0
+    WASMCluster *cluster;
+#endif
     WASMExecEnv *exec_env =
         wasm_exec_env_create_internal(module_inst, stack_size);
 
     if (!exec_env)
         return NULL;
 
-    /* Set the aux_stack_boundary to 0 */
-    exec_env->aux_stack_boundary = 0;
-#if WASM_ENABLE_THREAD_MGR != 0
-    WASMCluster *cluster;
+    /* Set the aux_stack_boundary and aux_stack_bottom */
+#if WASM_ENABLE_INTERP != 0
+    if (module_inst->module_type == Wasm_Module_Bytecode) {
+        WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
+        exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
+        exec_env->aux_stack_boundary.boundary = module->aux_stack_bottom
+                                                - module->aux_stack_size;
+    }
+#endif
+#if WASM_ENABLE_AOT != 0
+    if (module_inst->module_type == Wasm_Module_AoT) {
+        AOTModule *module =
+            (AOTModule *)(((AOTModuleInstance *)module_inst)->aot_module.ptr);
+        exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
+        exec_env->aux_stack_boundary.boundary = module->aux_stack_bottom
+                                                - module->aux_stack_size;
+    }
+#endif
 
+#if WASM_ENABLE_THREAD_MGR != 0
     /* Create a new cluster for this exec_env */
-    cluster = wasm_cluster_create(exec_env);
-    if (!cluster) {
+    if (!(cluster = wasm_cluster_create(exec_env))) {
         wasm_exec_env_destroy_internal(exec_env);
         return NULL;
     }

+ 25 - 9
core/iwasm/common/wasm_exec_env.h

@@ -37,8 +37,10 @@ typedef struct WASMExecEnv {
     /* Previous thread's exec env of a WASM module instance. */
     struct WASMExecEnv *prev;
 
-    /* Note: field module_inst, argv_buf and native_stack_boundary
-             are used by AOTed code, don't change the places of them */
+    /* Note: field module_inst, argv_buf, native_stack_boundary,
+       suspend_flags, aux_stack_boundary, aux_stack_bottom, and
+       native_symbol are used by AOTed code, don't change the
+       places of them */
 
     /* The WASM module instance of current thread */
     struct WASMModuleInstanceCommon *module_inst;
@@ -52,10 +54,9 @@ typedef struct WASMExecEnv {
        exception. */
     uint8 *native_stack_boundary;
 
-#if WASM_ENABLE_THREAD_MGR != 0
-    /* Used to terminate or suspend the interpreter
-        bit 0: need terminate
-        bit 1: need suspend
+    /* Used to terminate or suspend current thread
+        bit 0: need to terminate
+        bit 1: need to suspend
         bit 2: need to go into breakpoint
         bit 3: return from pthread_exit */
     union {
@@ -63,6 +64,24 @@ typedef struct WASMExecEnv {
         uintptr_t __padding__;
     } suspend_flags;
 
+    /* Auxiliary stack boundary */
+    union {
+        uint32 boundary;
+        uintptr_t __padding__;
+    } aux_stack_boundary;
+
+    /* Auxiliary stack bottom */
+    union {
+        uint32 bottom;
+        uintptr_t __padding__;
+    } aux_stack_bottom;
+
+#if WASM_ENABLE_AOT != 0
+    /* Native symbol list, reserved */
+    void **native_symbol;
+#endif
+
+#if WASM_ENABLE_THREAD_MGR != 0
     /* thread return value */
     void *thread_ret_value;
 
@@ -78,9 +97,6 @@ typedef struct WASMExecEnv {
     korp_cond wait_cond;
 #endif
 
-    /* Aux stack boundary */
-    uint32 aux_stack_boundary;
-
     /* attachment for native function */
     void *attachment;
 

+ 5 - 1
core/iwasm/compilation/aot_compiler.c

@@ -336,8 +336,12 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
         break;
 
       case WASM_OP_SET_GLOBAL:
+      case WASM_OP_SET_GLOBAL_64:
+      case WASM_OP_SET_GLOBAL_AUX_STACK:
         read_leb_uint32(frame_ip, frame_ip_end, global_idx);
-        if (!aot_compile_op_set_global(comp_ctx, func_ctx, global_idx))
+        if (!aot_compile_op_set_global(comp_ctx, func_ctx, global_idx,
+                                       opcode == WASM_OP_SET_GLOBAL_AUX_STACK
+                                       ? true : false))
           return false;
         break;
 

+ 3 - 0
core/iwasm/compilation/aot_compiler.h

@@ -233,6 +233,9 @@ typedef enum FloatArithmetic {
 #define I32_TWO     (comp_ctx->llvm_consts.i32_two)
 #define I32_THREE   (comp_ctx->llvm_consts.i32_three)
 #define I32_FOUR    (comp_ctx->llvm_consts.i32_four)
+#define I32_FIVE    (comp_ctx->llvm_consts.i32_five)
+#define I32_SIX     (comp_ctx->llvm_consts.i32_six)
+#define I32_SEVEN   (comp_ctx->llvm_consts.i32_seven)
 #define I32_EIGHT   (comp_ctx->llvm_consts.i32_eight)
 #define I32_NEG_ONE (comp_ctx->llvm_consts.i32_neg_one)
 #define I64_NEG_ONE (comp_ctx->llvm_consts.i64_neg_one)

+ 1 - 2
core/iwasm/compilation/aot_emit_control.c

@@ -640,8 +640,7 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
     LLVMBasicBlockRef terminate_block;
 
     /* Offset of suspend_flags */
-    offset = I32_CONST(5);
-    CHECK_LLVM_CONST(offset);
+    offset = I32_FIVE;
 
     if (!(terminate_addr =
                 LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,

+ 60 - 4
core/iwasm/compilation/aot_emit_variable.c

@@ -4,6 +4,7 @@
  */
 
 #include "aot_emit_variable.h"
+#include "aot_emit_exception.h"
 #include "../aot/aot_runtime.h"
 
 #define CHECK_LOCAL(idx) do {                               \
@@ -107,7 +108,7 @@ fail:
 
 static bool
 compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
-               uint32 global_idx, bool is_set)
+               uint32 global_idx, bool is_set, bool is_aux_stack)
 {
     AOTCompData *comp_data = comp_ctx->comp_data;
     uint32 import_global_count = comp_data->import_global_count;
@@ -179,6 +180,61 @@ compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
     }
     else {
         POP(global, global_type);
+
+        if (is_aux_stack && comp_ctx->enable_aux_stack_check) {
+            LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
+            LLVMBasicBlockRef check_overflow_succ, check_underflow_succ;
+            LLVMValueRef cmp;
+
+            /* Add basic blocks */
+            if (!(check_overflow_succ =
+                        LLVMAppendBasicBlockInContext(comp_ctx->context,
+                                                      func_ctx->func,
+                                                      "check_overflow_succ"))) {
+                aot_set_last_error("llvm add basic block failed.");
+                return false;
+            }
+            LLVMMoveBasicBlockAfter(check_overflow_succ, block_curr);
+
+            if (!(check_underflow_succ =
+                        LLVMAppendBasicBlockInContext(comp_ctx->context,
+                                                      func_ctx->func,
+                                                      "check_underflow_succ"))) {
+                aot_set_last_error("llvm add basic block failed.");
+                return false;
+            }
+            LLVMMoveBasicBlockAfter(check_underflow_succ, check_overflow_succ);
+
+            /* Check aux stack overflow */
+            if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntULE,
+                                      global, func_ctx->aux_stack_bound,
+                                      "cmp"))) {
+                aot_set_last_error("llvm build icmp failed.");
+                return false;
+            }
+            if (!aot_emit_exception(comp_ctx, func_ctx,
+                                    EXCE_AUX_STACK_OVERFLOW,
+                                    true, cmp, check_overflow_succ)) {
+                return false;
+            }
+
+            /* Check aux stack underflow */
+            LLVMPositionBuilderAtEnd(comp_ctx->builder, check_overflow_succ);
+            if (!(cmp = LLVMBuildICmp(comp_ctx->builder, LLVMIntUGT,
+                                      global, func_ctx->aux_stack_bottom,
+                                      "cmp"))) {
+                aot_set_last_error("llvm build icmp failed.");
+                return false;
+            }
+            if (!aot_emit_exception(comp_ctx, func_ctx,
+                                    EXCE_AUX_STACK_UNDERFLOW,
+                                    true, cmp, check_underflow_succ)) {
+                return false;
+            }
+
+            LLVMPositionBuilderAtEnd(comp_ctx->builder, check_underflow_succ);
+        }
+
         if (!(res = LLVMBuildStore(comp_ctx->builder,
                                    global, global_ptr))) {
             aot_set_last_error("llvm build store failed.");
@@ -197,13 +253,13 @@ bool
 aot_compile_op_get_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
                           uint32 global_idx)
 {
-    return compile_global(comp_ctx, func_ctx, global_idx, false);
+    return compile_global(comp_ctx, func_ctx, global_idx, false, false);
 }
 
 bool
 aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
-                          uint32 global_idx)
+                          uint32 global_idx, bool is_aux_stack)
 {
-    return compile_global(comp_ctx, func_ctx, global_idx, true);
+    return compile_global(comp_ctx, func_ctx, global_idx, true, is_aux_stack);
 }
 

+ 1 - 1
core/iwasm/compilation/aot_emit_variable.h

@@ -30,7 +30,7 @@ aot_compile_op_get_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
 
 bool
 aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
-                          uint32 global_idx);
+                          uint32 global_idx, bool is_aux_stack);
 
 #ifdef __cplusplus
 } /* end of extern "C" */

+ 58 - 0
core/iwasm/compilation/aot_llvm.c

@@ -628,6 +628,8 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
     LLVMValueRef aot_inst_offset = I32_TWO, aot_inst_addr;
     LLVMValueRef argv_buf_offset = I32_THREE, argv_buf_addr;
     LLVMValueRef stack_bound_offset = I32_FOUR, stack_bound_addr;
+    LLVMValueRef aux_stack_bound_offset = I32_SIX, aux_stack_bound_addr;
+    LLVMValueRef aux_stack_bottom_offset = I32_SEVEN, aux_stack_bottom_addr;
     char local_name[32];
     uint64 size;
     uint32 i, j = 0;
@@ -718,6 +720,53 @@ aot_create_func_context(AOTCompData *comp_data, AOTCompContext *comp_ctx,
         goto fail;
     }
 
+    /* Get aux stack boundary address */
+    if (!(aux_stack_bound_addr =
+            LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
+                                 &aux_stack_bound_offset, 1,
+                                 "aux_stack_bound_addr"))) {
+        aot_set_last_error("llvm build in bounds gep failed");
+        goto fail;
+    }
+
+    if (!(aux_stack_bound_addr =
+            LLVMBuildBitCast(comp_ctx->builder,
+                             aux_stack_bound_addr,
+                             INT32_PTR_TYPE, "aux_stack_bound_ptr"))) {
+        aot_set_last_error("llvm build bit cast failed");
+        goto fail;
+    }
+
+    if (!(func_ctx->aux_stack_bound =
+            LLVMBuildLoad(comp_ctx->builder,
+                          aux_stack_bound_addr, "aux_stack_bound"))) {
+        aot_set_last_error("llvm build load failed");
+        goto fail;
+    }
+
+    /* Get aux stack bottom address */
+    if (!(aux_stack_bottom_addr =
+            LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->exec_env,
+                                 &aux_stack_bottom_offset, 1,
+                                 "aux_stack_bottom_addr"))) {
+        aot_set_last_error("llvm build in bounds gep failed");
+        goto fail;
+    }
+
+    if (!(aux_stack_bottom_addr =
+            LLVMBuildBitCast(comp_ctx->builder,
+                             aux_stack_bottom_addr,
+                             INT32_PTR_TYPE, "aux_stack_bottom_ptr"))) {
+        aot_set_last_error("llvm build bit cast failed");
+        goto fail;
+    }
+    if (!(func_ctx->aux_stack_bottom =
+            LLVMBuildLoad(comp_ctx->builder,
+                          aux_stack_bottom_addr, "aux_stack_bottom"))) {
+        aot_set_last_error("llvm build load failed");
+        goto fail;
+    }
+
     for (i = 0; i < aot_func_type->param_count; i++, j++) {
         snprintf(local_name, sizeof(local_name), "l%d", i);
         func_ctx->locals[i] =
@@ -953,6 +1002,9 @@ aot_create_llvm_consts(AOTLLVMConsts *consts, AOTCompContext *comp_ctx)
     consts->i32_two = I32_CONST(2);
     consts->i32_three = I32_CONST(3);
     consts->i32_four = I32_CONST(4);
+    consts->i32_five = I32_CONST(5);
+    consts->i32_six = I32_CONST(6);
+    consts->i32_seven = I32_CONST(7);
     consts->i32_eight = I32_CONST(8);
     consts->i32_neg_one = I32_CONST((uint32)-1);
     consts->i64_neg_one = I64_CONST((uint64)-1);
@@ -978,6 +1030,9 @@ aot_create_llvm_consts(AOTLLVMConsts *consts, AOTCompContext *comp_ctx)
             && consts->i32_two
             && consts->i32_three
             && consts->i32_four
+            && consts->i32_five
+            && consts->i32_six
+            && consts->i32_seven
             && consts->i32_eight
             && consts->i32_neg_one
             && consts->i64_neg_one
@@ -1192,6 +1247,9 @@ aot_create_comp_context(AOTCompData *comp_data,
     if (option->enable_aux_stack_frame)
         comp_ctx->enable_aux_stack_frame = true;
 
+    if (option->enable_aux_stack_check)
+        comp_ctx->enable_aux_stack_check = true;
+
     if (option->is_jit_mode) {
         char *triple_jit = NULL;
 

+ 10 - 1
core/iwasm/compilation/aot_llvm.h

@@ -122,6 +122,8 @@ typedef struct AOTFuncContext {
   LLVMValueRef table_base;
   LLVMValueRef argv_buf;
   LLVMValueRef native_stack_bound;
+  LLVMValueRef aux_stack_bound;
+  LLVMValueRef aux_stack_bottom;
   LLVMValueRef last_alloca;
   LLVMValueRef func_ptrs;
 
@@ -185,6 +187,9 @@ typedef struct AOTLLVMConsts {
     LLVMValueRef i32_two;
     LLVMValueRef i32_three;
     LLVMValueRef i32_four;
+    LLVMValueRef i32_five;
+    LLVMValueRef i32_six;
+    LLVMValueRef i32_seven;
     LLVMValueRef i32_eight;
     LLVMValueRef i32_neg_one;
     LLVMValueRef i64_neg_one;
@@ -224,7 +229,10 @@ typedef struct AOTCompContext {
   /* 128-bit SIMD */
   bool enable_simd;
 
-  /* generate auxiliary stack frame */
+  /* Auxiliary stack overflow/underflow check */
+  bool enable_aux_stack_check;
+
+  /* Generate auxiliary stack frame */
   bool enable_aux_stack_frame;
 
   /* Thread Manager */
@@ -275,6 +283,7 @@ typedef struct AOTCompOption{
     bool enable_thread_mgr;
     bool enable_tail_call;
     bool enable_simd;
+    bool enable_aux_stack_check;
     bool enable_aux_stack_frame;
     bool is_sgx_platform;
     uint32 opt_level;

+ 1 - 0
core/iwasm/include/aot_export.h

@@ -43,6 +43,7 @@ typedef struct AOTCompOption{
     bool enable_thread_mgr;
     bool enable_tail_call;
     bool enable_simd;
+    bool enable_aux_stack_check;
     bool enable_aux_stack_frame;
     bool is_sgx_platform;
     uint32_t opt_level;

+ 15 - 5
core/iwasm/interpreter/wasm_interp_classic.c

@@ -702,7 +702,7 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
     }
     else {
         wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
-                           "stack overflow");
+                           "wasm operand stack overflow");
     }
 
     return frame;
@@ -1350,6 +1350,8 @@ label_pop_csp_n:
 
       HANDLE_OP (WASM_OP_SET_GLOBAL_AUX_STACK):
         {
+          uint32 aux_stack_top;
+
           read_leb_uint32(frame_ip, frame_ip_end, global_idx);
           bh_assert(global_idx < module->global_count);
           global = globals + global_idx;
@@ -1361,9 +1363,17 @@ label_pop_csp_n:
                           + global->import_global_inst->data_offset
                         : global_data + global->data_offset;
 #endif
-          if (*(uint32*)(frame_sp - 1) < exec_env->aux_stack_boundary)
-            goto out_of_bounds;
-          *(int32*)global_addr = POP_I32();
+          aux_stack_top = *(uint32*)(frame_sp - 1);
+          if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
+            wasm_set_exception(module, "wasm auxiliary stack overflow");
+            goto got_exception;
+          }
+          if (aux_stack_top > exec_env->aux_stack_bottom.bottom) {
+            wasm_set_exception(module, "wasm auxiliary stack underflow");
+            goto got_exception;
+          }
+          *(int32*)global_addr = aux_stack_top;
+          frame_sp--;
 #if WASM_ENABLE_MEMORY_PROFILING != 0
           if (module->module->aux_stack_top_global_index != (uint32)-1) {
               uint32 aux_stack_used =
@@ -3021,7 +3031,7 @@ label_pop_csp_n:
                        + (uint64)cur_wasm_func->max_stack_cell_num
                        + ((uint64)cur_wasm_func->max_block_num) * sizeof(WASMBranchBlock) / 4;
         if (all_cell_num >= UINT32_MAX) {
-            wasm_set_exception(module, "stack overflow");
+            wasm_set_exception(module, "wasm operand stack overflow");
             goto got_exception;
         }
 

+ 14 - 6
core/iwasm/interpreter/wasm_interp_fast.c

@@ -775,7 +775,7 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
     }
     else {
         wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
-                           "stack overflow");
+                           "wasm operand stack overflow");
     }
 
     return frame;
@@ -1339,6 +1339,8 @@ recover_br_info:
 
       HANDLE_OP (WASM_OP_SET_GLOBAL_AUX_STACK):
         {
+          uint32 aux_stack_top;
+
           global_idx = read_uint32(frame_ip);
           bh_assert(global_idx < module->global_count);
           global = globals + global_idx;
@@ -1350,10 +1352,16 @@ recover_br_info:
                           + global->import_global_inst->data_offset
                         : global_data + global->data_offset;
 #endif
-          addr1 = GET_OFFSET();
-          if (frame_lp[addr1] < exec_env->aux_stack_boundary)
-              goto out_of_bounds;
-          *(int32*)global_addr = frame_lp[addr1];
+          aux_stack_top = frame_lp[GET_OFFSET()];
+          if (aux_stack_top <= exec_env->aux_stack_boundary.boundary) {
+            wasm_set_exception(module, "wasm auxiliary stack overflow");
+            goto got_exception;
+          }
+          if (aux_stack_top > exec_env->aux_stack_bottom.bottom) {
+            wasm_set_exception(module, "wasm auxiliary stack underflow");
+            goto got_exception;
+          }
+          *(int32*)global_addr = aux_stack_top;
 #if WASM_ENABLE_MEMORY_PROFILING != 0
           if (module->module->aux_stack_top_global_index != (uint32)-1) {
               uint32 aux_stack_used =
@@ -3130,7 +3138,7 @@ recover_br_info:
                        + (uint64)cur_func->const_cell_num
                        + (uint64)cur_wasm_func->max_stack_cell_num;
         if (all_cell_num >= UINT32_MAX) {
-            wasm_set_exception(module, "stack overflow");
+            wasm_set_exception(module, "wasm operand stack overflow");
             goto got_exception;
         }
 

+ 0 - 2
core/iwasm/interpreter/wasm_loader.c

@@ -6705,7 +6705,6 @@ handle_op_block_and_loop:
                 POP_TYPE(global_type);
 
 #if WASM_ENABLE_FAST_INTERP == 0
-#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
                 if (global_type == VALUE_TYPE_I64
                     || global_type == VALUE_TYPE_F64) {
                     *p_org = WASM_OP_SET_GLOBAL_64;
@@ -6714,7 +6713,6 @@ handle_op_block_and_loop:
                          && global_idx == module->aux_stack_top_global_index) {
                     *p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
                 }
-#endif
 #else /* else of WASM_ENABLE_FAST_INTERP */
                 if (global_type == VALUE_TYPE_I64
                     || global_type == VALUE_TYPE_F64) {

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

@@ -2071,7 +2071,8 @@ wasm_set_aux_stack(WASMExecEnv *exec_env,
         *(int32*)global_addr = start_offset;
         /* The aux stack boundary is a constant value,
             set the value to exec_env */
-        exec_env->aux_stack_boundary = start_offset - size;
+        exec_env->aux_stack_boundary.boundary = start_offset - size;
+        exec_env->aux_stack_bottom.bottom = start_offset;
         return true;
     }
 

+ 3 - 6
core/iwasm/libraries/thread-mgr/thread_manager.c

@@ -384,8 +384,7 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env)
     bh_assert(cluster != NULL);
 
     /* Free aux stack space */
-    free_aux_stack(cluster,
-                   exec_env->aux_stack_boundary + cluster->stack_size);
+    free_aux_stack(cluster, exec_env->aux_stack_bottom.bottom);
     wasm_cluster_del_exec_env(cluster, exec_env);
     wasm_exec_env_destroy_internal(exec_env);
 
@@ -411,8 +410,7 @@ thread_manager_start_routine(void *arg)
 
     /* Routine exit */
     /* Free aux stack space */
-    free_aux_stack(cluster,
-                   exec_env->aux_stack_boundary + cluster->stack_size);
+    free_aux_stack(cluster, exec_env->aux_stack_bottom.bottom);
     /* Detach the native thread here to ensure the resources are freed */
     wasm_cluster_detach_thread(exec_env);
     /* Remove and destroy exec_env */
@@ -519,8 +517,7 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval)
 
     /* App exit the thread, free the resources before exit native thread */
     /* Free aux stack space */
-    free_aux_stack(cluster,
-                   exec_env->aux_stack_boundary + cluster->stack_size);
+    free_aux_stack(cluster, exec_env->aux_stack_bottom.bottom);
     /* Detach the native thread here to ensure the resources are freed */
     wasm_cluster_detach_thread(exec_env);
     /* Remove and destroy exec_env */

+ 5 - 0
wamr-compiler/main.c

@@ -47,6 +47,7 @@ print_help()
   printf("                              currently 128-bit SIMD is only supported for x86-64 target,\n");
   printf("                              and by default it is enabled in x86-64 target and disabled\n");
   printf("                              in other targets\n");
+  printf("  --disable-aux-stack-check Disable auxiliary stack overflow/underflow check\n");
   printf("  --enable-dump-call-stack  Enable stack trace feature\n");
   printf("  --enable-perf-profiling   Enable function performance profiling\n");
   printf("  -v=n                      Set log verbose level (0 to 5, default is 2), larger with more log\n");
@@ -77,6 +78,7 @@ main(int argc, char *argv[])
   /* default value, enable or disable depends on the platform */
   option.bounds_checks = 2;
   option.enable_simd = true;
+  option.enable_aux_stack_check = true;
 
   /* Process options.  */
   for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@@ -164,6 +166,9 @@ main(int argc, char *argv[])
     else if (!strcmp(argv[0], "--disable-simd")) {
         option.enable_simd = false;
     }
+    else if (!strcmp(argv[0], "--disable-aux-stack-check")) {
+        option.enable_aux_stack_check = false;
+    }
     else if (!strcmp(argv[0], "--enable-dump-call-stack")) {
         option.enable_aux_stack_frame = true;
     }