Add control for the native stack check with hardware trap (#1682)

Add a new options to control the native stack hw bound check feature:
- Besides the original option `cmake -DWAMR_DISABLE_HW_BOUND_CHECK=1/0`,
  add a new option `cmake -DWAMR_DISABLE_STACK_HW_BOUND_CHECK=1/0`
- When the linear memory hw bound check is disabled, the stack hw bound check
   will be disabled automatically, no matter what the input option is
- When the linear memory hw bound check is enabled, the stack hw bound check
  is enabled/disabled according to the value of input option
- Besides the original option `--bounds-checks=1/0`, add a new option
  `--stack-bounds-checks=1/0` for wamrc

Refer to: https://github.com/bytecodealliance/wasm-micro-runtime/issues/1677
This commit is contained in:
Wenyong Huang
2022-11-07 18:26:33 +08:00
committed by GitHub
parent 810007857b
commit 7fd37190e8
15 changed files with 103 additions and 7 deletions

View File

@ -143,9 +143,11 @@ runtime_signal_handler(void *sig_addr)
WASMJmpBuf *jmpbuf_node;
uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
uint8 *stack_min_addr;
uint32 page_size;
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
#endif
/* Check whether current thread is running wasm function */
if (exec_env_tls && exec_env_tls->handle == os_self_thread()
@ -159,9 +161,11 @@ runtime_signal_handler(void *sig_addr)
mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
}
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
/* Get stack info of current thread */
page_size = os_getpagesize();
stack_min_addr = os_thread_get_stack_boundary();
#endif
if (memory_inst
&& (mapped_mem_start_addr <= (uint8 *)sig_addr
@ -171,6 +175,7 @@ runtime_signal_handler(void *sig_addr)
wasm_set_exception(module_inst, "out of bounds memory access");
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
else if (stack_min_addr - page_size <= (uint8 *)sig_addr
&& (uint8 *)sig_addr
< stack_min_addr + page_size * guard_page_count) {
@ -179,6 +184,7 @@ runtime_signal_handler(void *sig_addr)
wasm_set_exception(module_inst, "native stack overflow");
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
#endif
}
}
#else
@ -230,6 +236,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
}
}
}
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
else if (ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
/* Set stack overflow exception and let the wasm func continue
to run, when the wasm func returns, the caller will check
@ -243,6 +250,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
return EXCEPTION_CONTINUE_EXECUTION;
}
}
#endif
}
os_printf("Unhandled exception thrown: exception code: 0x%lx, "

View File

@ -797,7 +797,7 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
callee_cell_num =
aot_func->param_cell_num + aot_func->local_cell_num + 1;
if (comp_ctx->enable_bound_check
if (comp_ctx->enable_stack_bound_check
&& !check_stack_boundary(comp_ctx, func_ctx, callee_cell_num))
goto fail;
@ -1411,7 +1411,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Translate call non-import block */
LLVMPositionBuilderAtEnd(comp_ctx->builder, block_call_non_import);
if (comp_ctx->enable_bound_check
if (comp_ctx->enable_stack_bound_check
&& !check_stack_boundary(comp_ctx, func_ctx,
param_cell_num + ext_cell_num
+ 1

View File

@ -1555,8 +1555,22 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
#ifndef OS_ENABLE_HW_BOUND_CHECK
comp_ctx->enable_bound_check = true;
/* Always enable stack boundary check if `bounds-checks`
is enabled */
comp_ctx->enable_stack_bound_check = true;
#else
comp_ctx->enable_bound_check = false;
/* When `bounds-checks` is disabled, we set stack boundary
check status according to the compilation option */
#if WASM_DISABLE_STACK_HW_BOUND_CHECK != 0
/* Native stack overflow check with hardware trap is disabled,
we need to enable the check by LLVM JITed/AOTed code */
comp_ctx->enable_stack_bound_check = true;
#else
/* Native stack overflow check with hardware trap is enabled,
no need to enable the check by LLVM JITed/AOTed code */
comp_ctx->enable_stack_bound_check = false;
#endif
#endif
}
else {
@ -1868,6 +1882,18 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
}
}
if (comp_ctx->enable_bound_check) {
/* Always enable stack boundary check if `bounds-checks`
is enabled */
comp_ctx->enable_stack_bound_check = true;
}
else {
/* When `bounds-checks` is disabled, we set stack boundary
check status according to the input option */
comp_ctx->enable_stack_bound_check =
(option->stack_bounds_checks == 1) ? true : false;
}
os_printf("Create AoT compiler with:\n");
os_printf(" target: %s\n", comp_ctx->target_arch);
os_printf(" target cpu: %s\n", cpu);

View File

@ -310,6 +310,9 @@ typedef struct AOTCompContext {
/* Bounday Check */
bool enable_bound_check;
/* Native stack bounday Check */
bool enable_stack_bound_check;
/* 128-bit SIMD */
bool enable_simd;
@ -404,6 +407,7 @@ typedef struct AOTCompOption {
uint32 size_level;
uint32 output_format;
uint32 bounds_checks;
uint32 stack_bounds_checks;
char **custom_sections;
uint32 custom_sections_count;
} AOTCompOption, *aot_comp_option_t;

View File

@ -59,6 +59,7 @@ typedef struct AOTCompOption {
uint32_t size_level;
uint32_t output_format;
uint32_t bounds_checks;
uint32_t stack_bounds_checks;
char **custom_sections;
uint32_t custom_sections_count;
} AOTCompOption, *aot_comp_option_t;

View File

@ -4115,7 +4115,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
}
argc = function->param_cell_num;
#ifndef OS_ENABLE_HW_BOUND_CHECK
#if !(defined(OS_ENABLE_HW_BOUND_CHECK) \
&& WASM_DISABLE_STACK_HW_BOUND_CHECK == 0)
if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
"native stack overflow");

View File

@ -3911,7 +3911,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
}
argc = function->param_cell_num;
#ifndef OS_ENABLE_HW_BOUND_CHECK
#if !(defined(OS_ENABLE_HW_BOUND_CHECK) \
&& WASM_DISABLE_STACK_HW_BOUND_CHECK == 0)
if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
"native stack overflow");