Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/iwasm/compilation/aot_emit_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
AOTBlock *block_prev;
uint8 *frame_ip;

aot_checked_addr_list_destroy(func_ctx);

if (block->block_type == BLOCK_TYPE_IF
&& block->llvm_else_block
&& !block->skip_wasm_code_else
Expand Down Expand Up @@ -233,6 +235,8 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Start to translate the block */
SET_BUILDER_POS(block->llvm_entry_block);
aot_block_stack_push(&func_ctx->block_stack, block);
if (block_type == BLOCK_TYPE_LOOP)
aot_checked_addr_list_destroy(func_ctx);
}
else if (block_type == BLOCK_TYPE_IF) {
POP_COND(value);
Expand Down Expand Up @@ -373,6 +377,7 @@ aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
/* Clear value stack and start to translate else branch */
aot_value_stack_destroy(&block->value_stack);
SET_BUILDER_POS(block->llvm_else_block);
aot_checked_addr_list_destroy(func_ctx);
return true;
}

Expand Down
47 changes: 30 additions & 17 deletions core/iwasm/compilation/aot_emit_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMValueRef mem_base_addr, mem_check_bound, total_mem_size;
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
LLVMBasicBlockRef check_succ, check_mem_space;
AOTValue *aot_value;

CHECK_LLVM_CONST(offset_const);
CHECK_LLVM_CONST(bytes_const);
Expand All @@ -100,6 +101,8 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}
}

aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end;

POP_I32(addr);
/* offset1 = offset + addr; */
BUILD_OP(Add, offset_const, addr, offset1, "offset1");
Expand Down Expand Up @@ -152,27 +155,37 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
SET_BUILD_POS(check_mem_space);
}

/* offset2 = offset1 - heap_base_offset; */
BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");
if (!(aot_value->is_local
&& aot_checked_addr_list_find(func_ctx, aot_value->local_idx,
offset, bytes))) {
/* offset2 = offset1 - heap_base_offset; */
BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");

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

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

/* offset2 > bound ? */
BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
if (!aot_emit_exception(comp_ctx, func_ctx,
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
true, cmp, check_succ)) {
goto fail;
}
/* offset2 > bound ? */
BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
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);

SET_BUILD_POS(check_succ);
if (aot_value->is_local) {
if (!aot_checked_addr_list_add(func_ctx, aot_value->local_idx,
offset, bytes))
goto fail;
}
}

/* maddr = mem_base_addr + offset1 */
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,
Expand Down
7 changes: 7 additions & 0 deletions core/iwasm/compilation/aot_emit_variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
{
char name[32];
LLVMValueRef value;
AOTValue *aot_value;

CHECK_LOCAL(local_idx);

Expand All @@ -42,6 +43,10 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}

PUSH(value, get_local_type(func_ctx, local_idx));

aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end;
aot_value->is_local = true;
aot_value->local_idx = local_idx;
return true;

fail:
Expand All @@ -65,6 +70,7 @@ aot_compile_op_set_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}

aot_checked_addr_list_del(func_ctx, local_idx);
return true;

fail:
Expand Down Expand Up @@ -92,6 +98,7 @@ aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
}

PUSH(value, type);
aot_checked_addr_list_del(func_ctx, local_idx);
return true;

fail:
Expand Down
84 changes: 83 additions & 1 deletion core/iwasm/compilation/aot_llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ aot_destroy_func_contexts(AOTFuncContext **func_ctxes, uint32 count)
if (func_ctxes[i]->exception_blocks)
wasm_runtime_free(func_ctxes[i]->exception_blocks);
aot_block_stack_destroy(&func_ctxes[i]->block_stack);
aot_checked_addr_list_destroy(func_ctxes[i]);
wasm_runtime_free(func_ctxes[i]);
}
wasm_runtime_free(func_ctxes);
Expand Down Expand Up @@ -1119,11 +1120,15 @@ aot_create_comp_context(AOTCompData *comp_data,
aot_set_last_error("create LLVM pass manager failed.");
goto fail;
}

LLVMAddBasicAliasAnalysisPass(comp_ctx->pass_mgr);
LLVMAddPromoteMemoryToRegisterPass(comp_ctx->pass_mgr);
LLVMAddInstructionCombiningPass(comp_ctx->pass_mgr);
LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
LLVMAddJumpThreadingPass(comp_ctx->pass_mgr);
LLVMAddConstantPropagationPass(comp_ctx->pass_mgr);
LLVMAddReassociatePass(comp_ctx->pass_mgr);
LLVMAddGVNPass(comp_ctx->pass_mgr);
LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);

/* Create metadata for llvm float experimental constrained intrinsics */
if (!(comp_ctx->fp_rounding_mode =
Expand Down Expand Up @@ -1298,3 +1303,80 @@ aot_block_destroy(AOTBlock *block)
aot_value_stack_destroy(&block->value_stack);
wasm_runtime_free(block);
}

bool
aot_checked_addr_list_add(AOTFuncContext *func_ctx,
uint32 local_idx, uint32 offset, uint32 bytes)
{
AOTCheckedAddr *node = func_ctx->checked_addr_list;

if (!(node = wasm_runtime_malloc(sizeof(AOTCheckedAddr)))) {
aot_set_last_error("allocate memory failed.");
return false;
}

node->local_idx = local_idx;
node->offset = offset;
node->bytes = bytes;

node->next = func_ctx->checked_addr_list;
func_ctx->checked_addr_list = node;
return true;
}

void
aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx)
{
AOTCheckedAddr *node = func_ctx->checked_addr_list;
AOTCheckedAddr *node_prev = NULL, *node_next;

while (node) {
node_next = node->next;

if (node->local_idx == local_idx) {
if (!node_prev)
func_ctx->checked_addr_list = node_next;
else
node_prev->next = node_next;
wasm_runtime_free(node);
}
else {
node_prev = node;
}

node = node_next;
}
}

bool
aot_checked_addr_list_find(AOTFuncContext *func_ctx,
uint32 local_idx, uint32 offset, uint32 bytes)
{
AOTCheckedAddr *node = func_ctx->checked_addr_list;

while (node) {
if (node->local_idx == local_idx
&& node->offset == offset
&& node->bytes >= bytes) {
return true;
}
node = node->next;
}

return false;
}

void
aot_checked_addr_list_destroy(AOTFuncContext *func_ctx)
{
AOTCheckedAddr *node = func_ctx->checked_addr_list, *node_next;

while (node) {
node_next = node->next;
wasm_runtime_free(node);
node = node_next;
}

func_ctx->checked_addr_list = NULL;
}

24 changes: 24 additions & 0 deletions core/iwasm/compilation/aot_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ typedef struct AOTValue {
LLVMValueRef value;
/* VALUE_TYPE_I32/I64/F32/F64/VOID */
uint8 type;
bool is_local;
uint32 local_idx;
} AOTValue;

/**
Expand Down Expand Up @@ -84,6 +86,13 @@ typedef struct AOTBlockStack {
uint32 block_index[3];
} AOTBlockStack;

typedef struct AOTCheckedAddr {
struct AOTCheckedAddr *next;
uint32 local_idx;
uint32 offset;
uint32 bytes;
} AOTCheckedAddr, *AOTCheckedAddrList;

typedef struct AOTFuncContext {
AOTFunc *aot_func;
LLVMValueRef func;
Expand All @@ -105,6 +114,7 @@ typedef struct AOTFuncContext {
LLVMValueRef cur_exception;

bool mem_space_unchanged;
AOTCheckedAddrList checked_addr_list;

LLVMBasicBlockRef *exception_blocks;
LLVMBasicBlockRef got_exception_block;
Expand Down Expand Up @@ -258,6 +268,20 @@ aot_block_destroy(AOTBlock *block);
LLVMTypeRef
wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);

bool
aot_checked_addr_list_add(AOTFuncContext *func_ctx,
uint32 local_idx, uint32 offset, uint32 bytes);

void
aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);

bool
aot_checked_addr_list_find(AOTFuncContext *func_ctx,
uint32 local_idx, uint32 offset, uint32 bytes);

void
aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);

#ifdef __cplusplus
} /* end of extern "C" */
#endif
Expand Down
Loading