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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 103 additions and 7 deletions

View File

@ -92,6 +92,7 @@ else:
if GetDepend(['WAMR_DISABLE_HW_BOUND_CHECK']): if GetDepend(['WAMR_DISABLE_HW_BOUND_CHECK']):
CPPDEFINES += ['WASM_DISABLE_HW_BOUND_CHECK=1'] CPPDEFINES += ['WASM_DISABLE_HW_BOUND_CHECK=1']
CPPDEFINES += ['WASM_DISABLE_STACK_HW_BOUND_CHECK=1']
print("[WAMR] Hardware boundary check disabled") print("[WAMR] Hardware boundary check disabled")
if GetDepend(['WAMR_BUILD_SIMD']): if GetDepend(['WAMR_BUILD_SIMD']):

View File

@ -205,9 +205,16 @@ else ()
endif () endif ()
if (WAMR_DISABLE_HW_BOUND_CHECK EQUAL 1) if (WAMR_DISABLE_HW_BOUND_CHECK EQUAL 1)
add_definitions (-DWASM_DISABLE_HW_BOUND_CHECK=1) add_definitions (-DWASM_DISABLE_HW_BOUND_CHECK=1)
add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=1)
message (" Hardware boundary check disabled") message (" Hardware boundary check disabled")
else () else ()
add_definitions (-DWASM_DISABLE_HW_BOUND_CHECK=0) add_definitions (-DWASM_DISABLE_HW_BOUND_CHECK=0)
if (WAMR_DISABLE_STACK_HW_BOUND_CHECK EQUAL 1)
add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=1)
message (" Hardware boundary check for native stack disabled")
else ()
add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0)
endif ()
endif () endif ()
if (WAMR_BUILD_SIMD EQUAL 1) if (WAMR_BUILD_SIMD EQUAL 1)
if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*") if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")

View File

@ -260,6 +260,12 @@
#define WASM_DISABLE_HW_BOUND_CHECK 0 #define WASM_DISABLE_HW_BOUND_CHECK 0
#endif #endif
/* Disable native stack access boundary check with hardware
* trap or not, enable it by default if it is supported */
#ifndef WASM_DISABLE_STACK_HW_BOUND_CHECK
#define WASM_DISABLE_STACK_HW_BOUND_CHECK 0
#endif
/* Disable SIMD unless it is manualy enabled somewhere */ /* Disable SIMD unless it is manualy enabled somewhere */
#ifndef WASM_ENABLE_SIMD #ifndef WASM_ENABLE_SIMD
#define WASM_ENABLE_SIMD 0 #define WASM_ENABLE_SIMD 0

View File

@ -143,9 +143,11 @@ runtime_signal_handler(void *sig_addr)
WASMJmpBuf *jmpbuf_node; WASMJmpBuf *jmpbuf_node;
uint8 *mapped_mem_start_addr = NULL; uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL; uint8 *mapped_mem_end_addr = NULL;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
uint8 *stack_min_addr; uint8 *stack_min_addr;
uint32 page_size; uint32 page_size;
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT; uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
#endif
/* Check whether current thread is running wasm function */ /* Check whether current thread is running wasm function */
if (exec_env_tls && exec_env_tls->handle == os_self_thread() 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; 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 */ /* Get stack info of current thread */
page_size = os_getpagesize(); page_size = os_getpagesize();
stack_min_addr = os_thread_get_stack_boundary(); stack_min_addr = os_thread_get_stack_boundary();
#endif
if (memory_inst if (memory_inst
&& (mapped_mem_start_addr <= (uint8 *)sig_addr && (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"); wasm_set_exception(module_inst, "out of bounds memory access");
os_longjmp(jmpbuf_node->jmpbuf, 1); os_longjmp(jmpbuf_node->jmpbuf, 1);
} }
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
else if (stack_min_addr - page_size <= (uint8 *)sig_addr else if (stack_min_addr - page_size <= (uint8 *)sig_addr
&& (uint8 *)sig_addr && (uint8 *)sig_addr
< stack_min_addr + page_size * guard_page_count) { < 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"); wasm_set_exception(module_inst, "native stack overflow");
os_longjmp(jmpbuf_node->jmpbuf, 1); os_longjmp(jmpbuf_node->jmpbuf, 1);
} }
#endif
} }
} }
#else #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) { else if (ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
/* Set stack overflow exception and let the wasm func continue /* Set stack overflow exception and let the wasm func continue
to run, when the wasm func returns, the caller will check 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; return EXCEPTION_CONTINUE_EXECUTION;
} }
} }
#endif
} }
os_printf("Unhandled exception thrown: exception code: 0x%lx, " 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 = callee_cell_num =
aot_func->param_cell_num + aot_func->local_cell_num + 1; 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)) && !check_stack_boundary(comp_ctx, func_ctx, callee_cell_num))
goto fail; goto fail;
@ -1411,7 +1411,7 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Translate call non-import block */ /* Translate call non-import block */
LLVMPositionBuilderAtEnd(comp_ctx->builder, block_call_non_import); 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, && !check_stack_boundary(comp_ctx, func_ctx,
param_cell_num + ext_cell_num param_cell_num + ext_cell_num
+ 1 + 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 #ifndef OS_ENABLE_HW_BOUND_CHECK
comp_ctx->enable_bound_check = true; comp_ctx->enable_bound_check = true;
/* Always enable stack boundary check if `bounds-checks`
is enabled */
comp_ctx->enable_stack_bound_check = true;
#else #else
comp_ctx->enable_bound_check = false; 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 #endif
} }
else { 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("Create AoT compiler with:\n");
os_printf(" target: %s\n", comp_ctx->target_arch); os_printf(" target: %s\n", comp_ctx->target_arch);
os_printf(" target cpu: %s\n", cpu); os_printf(" target cpu: %s\n", cpu);

View File

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

View File

@ -59,6 +59,7 @@ typedef struct AOTCompOption {
uint32_t size_level; uint32_t size_level;
uint32_t output_format; uint32_t output_format;
uint32_t bounds_checks; uint32_t bounds_checks;
uint32_t stack_bounds_checks;
char **custom_sections; char **custom_sections;
uint32_t custom_sections_count; uint32_t custom_sections_count;
} AOTCompOption, *aot_comp_option_t; } 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; 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) { if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
wasm_set_exception((WASMModuleInstance *)exec_env->module_inst, wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
"native stack overflow"); "native stack overflow");

View File

@ -3911,7 +3911,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
} }
argc = function->param_cell_num; 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) { if ((uint8 *)&prev_frame < exec_env->native_stack_boundary) {
wasm_set_exception((WASMModuleInstance *)exec_env->module_inst, wasm_set_exception((WASMModuleInstance *)exec_env->module_inst,
"native stack overflow"); "native stack overflow");

View File

@ -425,6 +425,7 @@ os_thread_get_stack_boundary()
*/ */
static os_thread_local_attribute bool thread_signal_inited = false; static os_thread_local_attribute bool thread_signal_inited = false;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
/* The signal alternate stack base addr */ /* The signal alternate stack base addr */
static os_thread_local_attribute uint8 *sigalt_stack_base_addr; static os_thread_local_attribute uint8 *sigalt_stack_base_addr;
@ -488,6 +489,7 @@ destroy_stack_guard_pages()
os_mprotect(stack_min_addr, page_size * guard_page_count, os_mprotect(stack_min_addr, page_size * guard_page_count,
MMAP_PROT_READ | MMAP_PROT_WRITE); MMAP_PROT_READ | MMAP_PROT_WRITE);
} }
#endif /* end of WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 */
static void static void
mask_signals(int how) mask_signals(int how)
@ -553,13 +555,16 @@ int
os_thread_signal_init(os_signal_handler handler) os_thread_signal_init(os_signal_handler handler)
{ {
struct sigaction sig_act; struct sigaction sig_act;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
stack_t sigalt_stack_info; stack_t sigalt_stack_info;
uint32 map_size = SIG_ALT_STACK_SIZE; uint32 map_size = SIG_ALT_STACK_SIZE;
uint8 *map_addr; uint8 *map_addr;
#endif
if (thread_signal_inited) if (thread_signal_inited)
return 0; return 0;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
if (!init_stack_guard_pages()) { if (!init_stack_guard_pages()) {
os_printf("Failed to init stack guard pages\n"); os_printf("Failed to init stack guard pages\n");
return -1; return -1;
@ -581,13 +586,17 @@ os_thread_signal_init(os_signal_handler handler)
os_printf("Failed to init signal alternate stack\n"); os_printf("Failed to init signal alternate stack\n");
goto fail2; goto fail2;
} }
#endif
memset(&prev_sig_act_SIGSEGV, 0, sizeof(struct sigaction)); memset(&prev_sig_act_SIGSEGV, 0, sizeof(struct sigaction));
memset(&prev_sig_act_SIGBUS, 0, sizeof(struct sigaction)); memset(&prev_sig_act_SIGBUS, 0, sizeof(struct sigaction));
/* Install signal hanlder */ /* Install signal hanlder */
sig_act.sa_sigaction = signal_callback; sig_act.sa_sigaction = signal_callback;
sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER; sig_act.sa_flags = SA_SIGINFO | SA_NODEFER;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
sig_act.sa_flags |= SA_ONSTACK;
#endif
sigemptyset(&sig_act.sa_mask); sigemptyset(&sig_act.sa_mask);
if (sigaction(SIGSEGV, &sig_act, &prev_sig_act_SIGSEGV) != 0 if (sigaction(SIGSEGV, &sig_act, &prev_sig_act_SIGSEGV) != 0
|| sigaction(SIGBUS, &sig_act, &prev_sig_act_SIGBUS) != 0) { || sigaction(SIGBUS, &sig_act, &prev_sig_act_SIGBUS) != 0) {
@ -595,12 +604,15 @@ os_thread_signal_init(os_signal_handler handler)
goto fail3; goto fail3;
} }
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
sigalt_stack_base_addr = map_addr; sigalt_stack_base_addr = map_addr;
#endif
signal_handler = handler; signal_handler = handler;
thread_signal_inited = true; thread_signal_inited = true;
return 0; return 0;
fail3: fail3:
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
memset(&sigalt_stack_info, 0, sizeof(stack_t)); memset(&sigalt_stack_info, 0, sizeof(stack_t));
sigalt_stack_info.ss_flags = SS_DISABLE; sigalt_stack_info.ss_flags = SS_DISABLE;
sigalt_stack_info.ss_size = map_size; sigalt_stack_info.ss_size = map_size;
@ -609,17 +621,21 @@ fail2:
os_munmap(map_addr, map_size); os_munmap(map_addr, map_size);
fail1: fail1:
destroy_stack_guard_pages(); destroy_stack_guard_pages();
#endif
return -1; return -1;
} }
void void
os_thread_signal_destroy() os_thread_signal_destroy()
{ {
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
stack_t sigalt_stack_info; stack_t sigalt_stack_info;
#endif
if (!thread_signal_inited) if (!thread_signal_inited)
return; return;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
/* Disable signal alternate stack */ /* Disable signal alternate stack */
memset(&sigalt_stack_info, 0, sizeof(stack_t)); memset(&sigalt_stack_info, 0, sizeof(stack_t));
sigalt_stack_info.ss_flags = SS_DISABLE; sigalt_stack_info.ss_flags = SS_DISABLE;
@ -629,6 +645,7 @@ os_thread_signal_destroy()
os_munmap(sigalt_stack_base_addr, SIG_ALT_STACK_SIZE); os_munmap(sigalt_stack_base_addr, SIG_ALT_STACK_SIZE);
destroy_stack_guard_pages(); destroy_stack_guard_pages();
#endif
thread_signal_inited = false; thread_signal_inited = false;
} }
@ -648,6 +665,7 @@ os_signal_unmask()
void void
os_sigreturn() os_sigreturn()
{ {
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
#if defined(__APPLE__) #if defined(__APPLE__)
#define UC_RESET_ALT_STACK 0x80000000 #define UC_RESET_ALT_STACK 0x80000000
extern int __sigreturn(void *, int); extern int __sigreturn(void *, int);
@ -656,5 +674,6 @@ os_sigreturn()
after exiting the signal handler. */ after exiting the signal handler. */
__sigreturn(NULL, UC_RESET_ALT_STACK); __sigreturn(NULL, UC_RESET_ALT_STACK);
#endif #endif
#endif
} }
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ #endif /* end of OS_ENABLE_HW_BOUND_CHECK */

View File

@ -706,13 +706,19 @@ static os_thread_local_attribute bool thread_signal_inited = false;
int int
os_thread_signal_init() os_thread_signal_init()
{ {
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
ULONG StackSizeInBytes = 16 * 1024; ULONG StackSizeInBytes = 16 * 1024;
#endif
bool ret; bool ret;
if (thread_signal_inited) if (thread_signal_inited)
return 0; return 0;
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
ret = SetThreadStackGuarantee(&StackSizeInBytes); ret = SetThreadStackGuarantee(&StackSizeInBytes);
#else
ret = true;
#endif
if (ret) if (ret)
thread_signal_inited = true; thread_signal_inited = true;
return ret ? 0 : -1; return ret ? 0 : -1;

View File

@ -80,9 +80,13 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM
- **WAMR_BUILD_LIB_PTHREAD_SEMAPHORE**=1/0, default to disable if not set - **WAMR_BUILD_LIB_PTHREAD_SEMAPHORE**=1/0, default to disable if not set
> Note: This feature depends on `lib-pthread`, it will be enabled automatically if this feature is enabled. > Note: This feature depends on `lib-pthread`, it will be enabled automatically if this feature is enabled.
#### **Disable boundary check with hardware trap in AOT or JIT mode** #### **Disable boundary check with hardware trap**
- **WAMR_DISABLE_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform - **WAMR_DISABLE_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform
> Note: by default only platform linux/darwin/android/vxworks 64-bit will enable boundary check with hardware trap in AOT or JIT mode, and the wamrc tool will generate AOT code without boundary check instructions in all 64-bit targets except SGX to improve performance. > Note: by default only platform linux/darwin/android/windows/vxworks 64-bit will enable the boundary check with hardware trap feature, and the wamrc tool will generate AOT code without boundary check instructions in all 64-bit targets except SGX to improve performance. The boundary check includes linear memory access boundary and native stack access boundary, if `WAMR_DISABLE_STACK_HW_BOUND_CHECK` below isn't set.
#### **Disable native stack boundary check with hardware trap**
- **WAMR_DISABLE_STACK_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform, same as `WAMR_DISABLE_HW_BOUND_CHECK`.
> Note: When boundary check with hardware trap is disabled, or `WAMR_DISABLE_HW_BOUND_CHECK` is set to 1, the native stack boundary check with hardware trap will be disabled too, no matter what value is set to `WAMR_DISABLE_STACK_HW_BOUND_CHECK`. And when boundary check with hardware trap is enabled, the status of this feature is set according to the value of `WAMR_DISABLE_STACK_HW_BOUND_CHECK`.
#### **Enable tail call feature** #### **Enable tail call feature**
- **WAMR_BUILD_TAIL_CALL**=1/0, default to disable if not set - **WAMR_BUILD_TAIL_CALL**=1/0, default to disable if not set

View File

@ -268,8 +268,10 @@ endif
ifeq ($(CONFIG_INTERPRETERS_WAMR_DISABLE_HW_BOUND_CHECK),y) ifeq ($(CONFIG_INTERPRETERS_WAMR_DISABLE_HW_BOUND_CHECK),y)
CFLAGS += -DWASM_DISABLE_HW_BOUND_CHECK=1 CFLAGS += -DWASM_DISABLE_HW_BOUND_CHECK=1
CFLAGS += -DWASM_DISABLE_STACK_HW_BOUND_CHECK=1
else else
CFLAGS += -DWASM_DISABLE_HW_BOUND_CHECK=0 CFLAGS += -DWASM_DISABLE_HW_BOUND_CHECK=0
CFLAGS += -DWASM_DISABLE_STACK_HW_BOUND_CHECK=0
endif endif
ifeq ($(CONFIG_INTERPRETERS_WAMR_CUSTOM_NAME_SECTIONS),y) ifeq ($(CONFIG_INTERPRETERS_WAMR_CUSTOM_NAME_SECTIONS),y)

View File

@ -37,6 +37,11 @@ print_help()
printf(" by default it is disabled in all 64-bit platforms except SGX and\n"); printf(" by default it is disabled in all 64-bit platforms except SGX and\n");
printf(" in these platforms runtime does bounds checks with hardware trap,\n"); printf(" in these platforms runtime does bounds checks with hardware trap,\n");
printf(" and by default it is enabled in all 32-bit platforms\n"); printf(" and by default it is enabled in all 32-bit platforms\n");
printf(" --stack-bounds-checks=1/0 Enable or disable the bounds checks for native stack:\n");
printf(" if the option isn't set, the status is same as `--bounds-check`,\n");
printf(" if the option is set:\n");
printf(" (1) it is always enabled when `--bounds-checks` is enabled,\n");
printf(" (2) else it is enabled/disabled according to the option value\n");
printf(" --format=<format> Specifies the format of the output file\n"); printf(" --format=<format> Specifies the format of the output file\n");
printf(" The format supported:\n"); printf(" The format supported:\n");
printf(" aot (default) AoT file\n"); printf(" aot (default) AoT file\n");
@ -139,6 +144,8 @@ main(int argc, char *argv[])
option.output_format = AOT_FORMAT_FILE; option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */ /* default value, enable or disable depends on the platform */
option.bounds_checks = 2; option.bounds_checks = 2;
/* default value, enable or disable depends on the platform */
option.stack_bounds_checks = 2;
option.enable_simd = true; option.enable_simd = true;
option.enable_aux_stack_check = true; option.enable_aux_stack_check = true;
option.enable_bulk_memory = true; option.enable_bulk_memory = true;
@ -193,6 +200,9 @@ main(int argc, char *argv[])
else if (!strncmp(argv[0], "--bounds-checks=", 16)) { else if (!strncmp(argv[0], "--bounds-checks=", 16)) {
option.bounds_checks = (atoi(argv[0] + 16) == 1) ? 1 : 0; option.bounds_checks = (atoi(argv[0] + 16) == 1) ? 1 : 0;
} }
else if (!strncmp(argv[0], "--stack-bounds-checks=", 22)) {
option.stack_bounds_checks = (atoi(argv[0] + 22) == 1) ? 1 : 0;
}
else if (!strncmp(argv[0], "--format=", 9)) { else if (!strncmp(argv[0], "--format=", 9)) {
if (argv[0][9] == '\0') if (argv[0][9] == '\0')
PRINT_HELP_AND_EXIT(); PRINT_HELP_AND_EXIT();