Skip to content

Commit

Permalink
do aot bounds check by calling native
Browse files Browse the repository at this point in the history
Signed-off-by: wenlingyun1 <wenlingyun1@xiaomi.com>
  • Loading branch information
WenLY1 committed Jun 26, 2024
1 parent 74dbafc commit 1da0f59
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 41 deletions.
1 change: 1 addition & 0 deletions core/iwasm/aot/aot_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ typedef struct {
#define REG_COMMON_SYMBOLS \
REG_SYM(aot_set_exception_with_id), \
REG_SYM(aot_invoke_native), \
REG_SYM(aot_bounds_check), \
REG_SYM(aot_call_indirect), \
REG_SYM(aot_enlarge_memory), \
REG_SYM(aot_set_exception), \
Expand Down
15 changes: 15 additions & 0 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -3109,6 +3109,21 @@ aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
return ret;
}

uint64
aot_bounds_check(AOTModuleInstance *module_inst, uint64 offset,
uint32 bytes)
{
WASMMemoryInstance *memory = aot_get_default_memory(module_inst);
uint64 linear_memory_size = memory->memory_data_size;

if (offset + bytes <= linear_memory_size)
{
return memory->memory_data + offset;
}
// execption
return NULL;
}

void *
aot_memmove(void *dest, const void *src, size_t n)
{
Expand Down
7 changes: 7 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,13 @@ aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
uint64 app_buf_addr, uint64 app_buf_size,
void **p_native_addr);

/**
* Check whether the memory offset is inside the linear memory
*/
uint64
aot_bounds_check(AOTModuleInstance *module_inst, uint64 offset,
uint32 bytes);

uint32
aot_get_plt_table_size();

Expand Down
125 changes: 84 additions & 41 deletions core/iwasm/compilation/aot_emit_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,37 @@ get_memory_check_bound(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
static LLVMValueRef
get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);

static LLVMValueRef
aot_call_runtime_bounds_check(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, LLVMValueRef offset,
uint32 bytes)
{
LLVMValueRef param_values[3], value, maddr, func;
LLVMTypeRef param_types[3], ret_type = 0, func_type = 0, func_ptr_type = 0;
;
uint32 argc = 3;

param_types[0] = INT8_PTR_TYPE;
param_types[1] = I64_TYPE;
param_types[2] = I32_TYPE;
ret_type = INT8_PTR_TYPE;

param_values[0] = func_ctx->aot_inst;
param_values[1] = offset;
param_values[2] = I32_CONST(bytes);

GET_AOT_FUNCTION(aot_bounds_check, argc);

if (!(maddr = LLVMBuildCall2(comp_ctx->builder, func_type, func,
param_values, argc, "maddr"))) {
aot_set_last_error("llvm build call failed.");
goto fail;
}
return maddr;
fail:
return NULL;
}

LLVMValueRef
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
mem_offset_t offset, uint32 bytes, bool enable_segue,
Expand Down Expand Up @@ -257,59 +288,70 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
&& !(is_local_of_aot_value
&& aot_checked_addr_list_find(func_ctx, local_idx_of_aot_value,
offset, bytes))) {
uint32 init_page_count =
comp_ctx->comp_data->memories[0].init_page_count;
if (init_page_count == 0) {
LLVMValueRef mem_size;
if (comp_ctx->enable_runtime_bound_check) {

if (!(maddr = aot_call_runtime_bounds_check(comp_ctx, func_ctx, offset1, bytes)))
{
goto fail;
}
}
else {
uint32 init_page_count =
comp_ctx->comp_data->memories[0].init_page_count;
if (init_page_count == 0) {
LLVMValueRef mem_size;

if (!(mem_size =
get_memory_curr_page_count(comp_ctx, func_ctx))) {
goto fail;
}
BUILD_ICMP(LLVMIntEQ, mem_size,
MEMORY64_COND_VALUE(I64_ZERO, I32_ZERO), cmp,
"is_zero");
ADD_BASIC_BLOCK(check_succ, "check_mem_size_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr);
if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true,
cmp, check_succ)) {
goto fail;
}

if (!(mem_size = get_memory_curr_page_count(comp_ctx, func_ctx))) {
SET_BUILD_POS(check_succ);
block_curr = check_succ;
}

if (!(mem_check_bound =
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
goto fail;
}
BUILD_ICMP(LLVMIntEQ, mem_size,
MEMORY64_COND_VALUE(I64_ZERO, I32_ZERO), cmp, "is_zero");
ADD_BASIC_BLOCK(check_succ, "check_mem_size_succ");

if (is_target_64bit) {
BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp, "cmp");
}
else {
/* Check integer overflow */
BUILD_ICMP(LLVMIntULT, offset1, addr, cmp1, "cmp1");
BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp2, "cmp2");
BUILD_OP(Or, cmp1, cmp2, cmp, "cmp");
}

/* Add basic blocks */
ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr);

if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
check_succ)) {
goto fail;
}

SET_BUILD_POS(check_succ);
block_curr = check_succ;
}

if (!(mem_check_bound =
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
goto fail;
}

if (is_target_64bit) {
BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp, "cmp");
}
else {
/* Check integer overflow */
BUILD_ICMP(LLVMIntULT, offset1, addr, cmp1, "cmp1");
BUILD_ICMP(LLVMIntUGT, offset1, mem_check_bound, cmp2, "cmp2");
BUILD_OP(Or, cmp1, cmp2, cmp, "cmp");
}

/* Add basic blocks */
ADD_BASIC_BLOCK(check_succ, "check_succ");
LLVMMoveBasicBlockAfter(check_succ, block_curr);

if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS, true, cmp,
check_succ)) {
goto fail;
}

SET_BUILD_POS(check_succ);

if (is_local_of_aot_value) {
if (!aot_checked_addr_list_add(func_ctx, local_idx_of_aot_value,
offset, bytes))
goto fail;
if (is_local_of_aot_value) {
if (!aot_checked_addr_list_add(func_ctx, local_idx_of_aot_value,
offset, bytes))
goto fail;
}
}
}

Expand All @@ -321,6 +363,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
aot_set_last_error("llvm build add failed.");
goto fail;
}

}
else {
LLVMValueRef maddr_base;
Expand Down
3 changes: 3 additions & 0 deletions core/iwasm/compilation/aot_llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2621,6 +2621,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)

#ifndef OS_ENABLE_HW_BOUND_CHECK
comp_ctx->enable_bound_check = true;
comp_ctx->enable_runtime_bound_check = option->enable_runtime_bound_check;
/* Always enable stack boundary check if `bounds-checks`
is enabled */
comp_ctx->enable_stack_bound_check = true;
Expand Down Expand Up @@ -2954,6 +2955,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
/* Set by user */
comp_ctx->enable_bound_check =
(option->bounds_checks == 1) ? true : false;
comp_ctx->enable_runtime_bound_check = option->enable_runtime_bound_check;
}
else {
/* Unset by user, use default value */
Expand All @@ -2963,6 +2965,7 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
}
else {
comp_ctx->enable_bound_check = true;
comp_ctx->enable_runtime_bound_check = option->enable_runtime_bound_check;
}
}

Expand Down
3 changes: 3 additions & 0 deletions core/iwasm/compilation/aot_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ typedef struct AOTCompContext {
/* Boundary Check */
bool enable_bound_check;

/* Boundary Check by calling runtime function*/
bool enable_runtime_bound_check;

/* Native stack boundary Check */
bool enable_stack_bound_check;

Expand Down
1 change: 1 addition & 0 deletions core/iwasm/include/aot_comp_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct AOTCompOption {
bool enable_llvm_pgo;
bool enable_stack_estimation;
bool quick_invoke_c_api_import;
bool enable_runtime_bound_check;
char *use_prof_file;
uint32_t opt_level;
uint32_t size_level;
Expand Down
4 changes: 4 additions & 0 deletions wamr-compiler/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ print_help()
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(" --runtime-bounds-checks Enable bounds check by call runtime function:\n");
printf(" --stack-usage=<file> Generate a stack-usage file.\n");
printf(" Similarly to `clang -fstack-usage`.\n");
printf(" --format=<format> Specifies the format of the output file\n");
Expand Down Expand Up @@ -545,6 +546,9 @@ main(int argc, char *argv[])
else if (!strcmp(argv[0], "--invoke-c-api-import")) {
option.quick_invoke_c_api_import = true;
}
else if (!strcmp(argv[0], "--runtime-bounds-checks")) {
option.enable_runtime_bound_check = true;
}
#if WASM_ENABLE_LINUX_PERF != 0
else if (!strcmp(argv[0], "--enable-linux-perf")) {
enable_linux_perf = true;
Expand Down

0 comments on commit 1da0f59

Please sign in to comment.