Skip to content

Commit f72e848

Browse files
authored
Refine aot memory boundary check, add more llvm passes (#236)
Fix issue of some error info mismatch with spec cases
1 parent f844234 commit f72e848

File tree

7 files changed

+216
-39
lines changed

7 files changed

+216
-39
lines changed

core/iwasm/compilation/aot_emit_control.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ handle_next_reachable_block(AOTCompContext *comp_ctx,
127127
AOTBlock *block_prev;
128128
uint8 *frame_ip;
129129

130+
aot_checked_addr_list_destroy(func_ctx);
131+
130132
if (block->block_type == BLOCK_TYPE_IF
131133
&& block->llvm_else_block
132134
&& !block->skip_wasm_code_else
@@ -233,6 +235,8 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
233235
/* Start to translate the block */
234236
SET_BUILDER_POS(block->llvm_entry_block);
235237
aot_block_stack_push(&func_ctx->block_stack, block);
238+
if (block_type == BLOCK_TYPE_LOOP)
239+
aot_checked_addr_list_destroy(func_ctx);
236240
}
237241
else if (block_type == BLOCK_TYPE_IF) {
238242
POP_COND(value);
@@ -373,6 +377,7 @@ aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
373377
/* Clear value stack and start to translate else branch */
374378
aot_value_stack_destroy(&block->value_stack);
375379
SET_BUILDER_POS(block->llvm_else_block);
380+
aot_checked_addr_list_destroy(func_ctx);
376381
return true;
377382
}
378383

core/iwasm/compilation/aot_emit_memory.c

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
8282
LLVMValueRef mem_base_addr, mem_check_bound, total_mem_size;
8383
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
8484
LLVMBasicBlockRef check_succ, check_mem_space;
85+
AOTValue *aot_value;
8586

8687
CHECK_LLVM_CONST(offset_const);
8788
CHECK_LLVM_CONST(bytes_const);
@@ -100,6 +101,8 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
100101
}
101102
}
102103

104+
aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end;
105+
103106
POP_I32(addr);
104107
/* offset1 = offset + addr; */
105108
BUILD_OP(Add, offset_const, addr, offset1, "offset1");
@@ -152,27 +155,37 @@ check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
152155
SET_BUILD_POS(check_mem_space);
153156
}
154157

155-
/* offset2 = offset1 - heap_base_offset; */
156-
BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");
158+
if (!(aot_value->is_local
159+
&& aot_checked_addr_list_find(func_ctx, aot_value->local_idx,
160+
offset, bytes))) {
161+
/* offset2 = offset1 - heap_base_offset; */
162+
BUILD_OP(Sub, offset1, heap_base_offset, offset2, "offset2");
157163

158-
if (!(mem_check_bound =
159-
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
160-
goto fail;
161-
}
164+
if (!(mem_check_bound =
165+
get_memory_check_bound(comp_ctx, func_ctx, bytes))) {
166+
goto fail;
167+
}
162168

163-
/* Add basic blocks */
164-
ADD_BASIC_BLOCK(check_succ, "check_succ");
165-
LLVMMoveBasicBlockAfter(check_succ, block_curr);
169+
/* Add basic blocks */
170+
ADD_BASIC_BLOCK(check_succ, "check_succ");
171+
LLVMMoveBasicBlockAfter(check_succ, block_curr);
166172

167-
/* offset2 > bound ? */
168-
BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
169-
if (!aot_emit_exception(comp_ctx, func_ctx,
170-
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
171-
true, cmp, check_succ)) {
172-
goto fail;
173-
}
173+
/* offset2 > bound ? */
174+
BUILD_ICMP(LLVMIntUGT, offset2, mem_check_bound, cmp, "cmp");
175+
if (!aot_emit_exception(comp_ctx, func_ctx,
176+
EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS,
177+
true, cmp, check_succ)) {
178+
goto fail;
179+
}
180+
181+
SET_BUILD_POS(check_succ);
174182

175-
SET_BUILD_POS(check_succ);
183+
if (aot_value->is_local) {
184+
if (!aot_checked_addr_list_add(func_ctx, aot_value->local_idx,
185+
offset, bytes))
186+
goto fail;
187+
}
188+
}
176189

177190
/* maddr = mem_base_addr + offset1 */
178191
if (!(maddr = LLVMBuildInBoundsGEP(comp_ctx->builder, mem_base_addr,

core/iwasm/compilation/aot_emit_variable.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
3030
{
3131
char name[32];
3232
LLVMValueRef value;
33+
AOTValue *aot_value;
3334

3435
CHECK_LOCAL(local_idx);
3536

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

4445
PUSH(value, get_local_type(func_ctx, local_idx));
46+
47+
aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end;
48+
aot_value->is_local = true;
49+
aot_value->local_idx = local_idx;
4550
return true;
4651

4752
fail:
@@ -65,6 +70,7 @@ aot_compile_op_set_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
6570
return false;
6671
}
6772

73+
aot_checked_addr_list_del(func_ctx, local_idx);
6874
return true;
6975

7076
fail:
@@ -92,6 +98,7 @@ aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
9298
}
9399

94100
PUSH(value, type);
101+
aot_checked_addr_list_del(func_ctx, local_idx);
95102
return true;
96103

97104
fail:

core/iwasm/compilation/aot_llvm.c

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ aot_destroy_func_contexts(AOTFuncContext **func_ctxes, uint32 count)
629629
if (func_ctxes[i]->exception_blocks)
630630
wasm_runtime_free(func_ctxes[i]->exception_blocks);
631631
aot_block_stack_destroy(&func_ctxes[i]->block_stack);
632+
aot_checked_addr_list_destroy(func_ctxes[i]);
632633
wasm_runtime_free(func_ctxes[i]);
633634
}
634635
wasm_runtime_free(func_ctxes);
@@ -1119,11 +1120,15 @@ aot_create_comp_context(AOTCompData *comp_data,
11191120
aot_set_last_error("create LLVM pass manager failed.");
11201121
goto fail;
11211122
}
1123+
1124+
LLVMAddBasicAliasAnalysisPass(comp_ctx->pass_mgr);
11221125
LLVMAddPromoteMemoryToRegisterPass(comp_ctx->pass_mgr);
11231126
LLVMAddInstructionCombiningPass(comp_ctx->pass_mgr);
1124-
LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
11251127
LLVMAddJumpThreadingPass(comp_ctx->pass_mgr);
11261128
LLVMAddConstantPropagationPass(comp_ctx->pass_mgr);
1129+
LLVMAddReassociatePass(comp_ctx->pass_mgr);
1130+
LLVMAddGVNPass(comp_ctx->pass_mgr);
1131+
LLVMAddCFGSimplificationPass(comp_ctx->pass_mgr);
11271132

11281133
/* Create metadata for llvm float experimental constrained intrinsics */
11291134
if (!(comp_ctx->fp_rounding_mode =
@@ -1298,3 +1303,80 @@ aot_block_destroy(AOTBlock *block)
12981303
aot_value_stack_destroy(&block->value_stack);
12991304
wasm_runtime_free(block);
13001305
}
1306+
1307+
bool
1308+
aot_checked_addr_list_add(AOTFuncContext *func_ctx,
1309+
uint32 local_idx, uint32 offset, uint32 bytes)
1310+
{
1311+
AOTCheckedAddr *node = func_ctx->checked_addr_list;
1312+
1313+
if (!(node = wasm_runtime_malloc(sizeof(AOTCheckedAddr)))) {
1314+
aot_set_last_error("allocate memory failed.");
1315+
return false;
1316+
}
1317+
1318+
node->local_idx = local_idx;
1319+
node->offset = offset;
1320+
node->bytes = bytes;
1321+
1322+
node->next = func_ctx->checked_addr_list;
1323+
func_ctx->checked_addr_list = node;
1324+
return true;
1325+
}
1326+
1327+
void
1328+
aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx)
1329+
{
1330+
AOTCheckedAddr *node = func_ctx->checked_addr_list;
1331+
AOTCheckedAddr *node_prev = NULL, *node_next;
1332+
1333+
while (node) {
1334+
node_next = node->next;
1335+
1336+
if (node->local_idx == local_idx) {
1337+
if (!node_prev)
1338+
func_ctx->checked_addr_list = node_next;
1339+
else
1340+
node_prev->next = node_next;
1341+
wasm_runtime_free(node);
1342+
}
1343+
else {
1344+
node_prev = node;
1345+
}
1346+
1347+
node = node_next;
1348+
}
1349+
}
1350+
1351+
bool
1352+
aot_checked_addr_list_find(AOTFuncContext *func_ctx,
1353+
uint32 local_idx, uint32 offset, uint32 bytes)
1354+
{
1355+
AOTCheckedAddr *node = func_ctx->checked_addr_list;
1356+
1357+
while (node) {
1358+
if (node->local_idx == local_idx
1359+
&& node->offset == offset
1360+
&& node->bytes >= bytes) {
1361+
return true;
1362+
}
1363+
node = node->next;
1364+
}
1365+
1366+
return false;
1367+
}
1368+
1369+
void
1370+
aot_checked_addr_list_destroy(AOTFuncContext *func_ctx)
1371+
{
1372+
AOTCheckedAddr *node = func_ctx->checked_addr_list, *node_next;
1373+
1374+
while (node) {
1375+
node_next = node->next;
1376+
wasm_runtime_free(node);
1377+
node = node_next;
1378+
}
1379+
1380+
func_ctx->checked_addr_list = NULL;
1381+
}
1382+

core/iwasm/compilation/aot_llvm.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ typedef struct AOTValue {
3030
LLVMValueRef value;
3131
/* VALUE_TYPE_I32/I64/F32/F64/VOID */
3232
uint8 type;
33+
bool is_local;
34+
uint32 local_idx;
3335
} AOTValue;
3436

3537
/**
@@ -84,6 +86,13 @@ typedef struct AOTBlockStack {
8486
uint32 block_index[3];
8587
} AOTBlockStack;
8688

89+
typedef struct AOTCheckedAddr {
90+
struct AOTCheckedAddr *next;
91+
uint32 local_idx;
92+
uint32 offset;
93+
uint32 bytes;
94+
} AOTCheckedAddr, *AOTCheckedAddrList;
95+
8796
typedef struct AOTFuncContext {
8897
AOTFunc *aot_func;
8998
LLVMValueRef func;
@@ -105,6 +114,7 @@ typedef struct AOTFuncContext {
105114
LLVMValueRef cur_exception;
106115

107116
bool mem_space_unchanged;
117+
AOTCheckedAddrList checked_addr_list;
108118

109119
LLVMBasicBlockRef *exception_blocks;
110120
LLVMBasicBlockRef got_exception_block;
@@ -258,6 +268,20 @@ aot_block_destroy(AOTBlock *block);
258268
LLVMTypeRef
259269
wasm_type_to_llvm_type(AOTLLVMTypes *llvm_types, uint8 wasm_type);
260270

271+
bool
272+
aot_checked_addr_list_add(AOTFuncContext *func_ctx,
273+
uint32 local_idx, uint32 offset, uint32 bytes);
274+
275+
void
276+
aot_checked_addr_list_del(AOTFuncContext *func_ctx, uint32 local_idx);
277+
278+
bool
279+
aot_checked_addr_list_find(AOTFuncContext *func_ctx,
280+
uint32 local_idx, uint32 offset, uint32 bytes);
281+
282+
void
283+
aot_checked_addr_list_destroy(AOTFuncContext *func_ctx);
284+
261285
#ifdef __cplusplus
262286
} /* end of extern "C" */
263287
#endif

0 commit comments

Comments
 (0)