Skip to content

Commit 7cdd02e

Browse files
committed
fix compilation error in JIT and potentially load nullptr
1 parent 7ddc5f8 commit 7cdd02e

2 files changed

Lines changed: 71 additions & 31 deletions

File tree

core/iwasm/compilation/aot_emit_memory.c

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ ffs(int n)
145145
static LLVMValueRef
146146
get_memory_curr_page_count(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
147147

148+
#if WASM_ENABLE_SHARED_HEAP != 0
148149
uint32
149150
get_module_inst_extra_offset(AOTCompContext *comp_ctx);
150151

@@ -192,8 +193,7 @@ get_module_inst_extra_offset(AOTCompContext *comp_ctx);
192193
BUILD_LOAD_PTR(field_p, data_type, res); \
193194
} while (0)
194195

195-
/* Only update last used shared heap info(alloc ptr) in function ctx,
196-
* let runtime API update module inst shared heap info
196+
/* Update last used shared heap info(alloc ptr) in function ctx:
197197
* 1. shared_heap_start_off 2. shared_heap_end_off 3. shared_heap_base_addr_adj
198198
*/
199199
bool
@@ -224,7 +224,6 @@ aot_check_shared_heap_chain(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
224224

225225
/* Call function */
226226
param_values[0] = func_ctx->aot_inst;
227-
/* TODO: all use alloca to optimize the func call to single basic block? */
228227
param_values[1] = start_offset;
229228
param_values[2] = bytes;
230229
/* pass alloc ptr */
@@ -299,26 +298,12 @@ aot_check_shared_heap_memory_overflow_common(
299298
else
300299
LLVMMoveBasicBlockAfter(block_maddr_phi, check_succ);
301300

302-
// BUILD_LOAD_PTR(func_ctx->shared_heap_start_off, offset_type,
303-
// shared_heap_start_off);
304-
// BUILD_ICMP(LLVMIntUGE, start_offset, shared_heap_start_off,
305-
// is_in_shared_heap, "shared_heap_lb_cmp");
306-
BUILD_ICMP(LLVMIntUGE, start_offset, func_ctx->shared_heap_head_start_off,
301+
/* Use >= here for func_ctx->shared_heap_head_start_off =
302+
* shared_heap_head->start - 1 and use UINT32_MAX/UINT64_MAX value to
303+
* indicate invalid value. The shared heap chain oob will be detected in
304+
* app_addr_in_shared_heap block or aot_check_shared_heap_chain function */
305+
BUILD_ICMP(LLVMIntUGT, start_offset, func_ctx->shared_heap_head_start_off,
307306
is_in_shared_heap, "shared_heap_lb_cmp");
308-
/* For bulk memory previously already check whether start_offset + bytes
309-
* overflows, can safely omit the upper boundary check */
310-
if (!bulk_memory) {
311-
shared_heap_check_bound =
312-
is_memory64
313-
? I64_CONST(UINT64_MAX - bytes_u32 + 1)
314-
: (is_target_64bit ? I64_CONST(UINT32_MAX - bytes_u32 + 1)
315-
: I32_CONST(UINT32_MAX - bytes_u32 + 1));
316-
CHECK_LLVM_CONST(shared_heap_check_bound);
317-
BUILD_ICMP(LLVMIntULE, start_offset, shared_heap_check_bound, cmp,
318-
"shared_heap_ub_cmp");
319-
BUILD_OP(And, is_in_shared_heap, cmp, is_in_shared_heap,
320-
"is_in_shared_heap");
321-
}
322307
BUILD_COND_BR(is_in_shared_heap, app_addr_in_shared_heap_chain,
323308
app_addr_in_linear_mem);
324309

@@ -435,6 +420,7 @@ aot_check_bulk_memory_shared_heap_memory_overflow(
435420
start_offset, max_addr, NULL, bytes, 0, is_memory64, is_target_64bit,
436421
true, false);
437422
}
423+
#endif
438424

439425
LLVMValueRef
440426
aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
@@ -443,10 +429,10 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
443429
{
444430
LLVMValueRef offset_const =
445431
MEMORY64_COND_VALUE(I64_CONST(offset), I32_CONST(offset));
446-
LLVMValueRef addr, maddr, maddr_phi = NULL, offset1, cmp1, cmp;
432+
LLVMValueRef addr, maddr, offset1, cmp1, cmp;
447433
LLVMValueRef mem_base_addr, mem_check_bound;
448434
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
449-
LLVMBasicBlockRef check_succ, block_maddr_phi = NULL;
435+
LLVMBasicBlockRef check_succ;
450436
AOTValue *aot_value_top;
451437
uint32 local_idx_of_aot_value = 0;
452438
uint64 const_value;
@@ -461,6 +447,10 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
461447
#else
462448
bool is_memory64 = IS_MEMORY64;
463449
#endif
450+
#if WASM_ENABLE_SHARED_HEAP != 0
451+
LLVMValueRef maddr_phi = NULL;
452+
LLVMBasicBlockRef block_maddr_phi = NULL;
453+
#endif
464454

465455
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
466456

@@ -626,6 +616,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
626616
block_curr = check_integer_overflow_end;
627617
}
628618

619+
#if WASM_ENABLE_SHARED_HEAP != 0
629620
if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) {
630621
ADD_BASIC_BLOCK(block_maddr_phi, "maddr_phi");
631622
SET_BUILD_POS(block_maddr_phi);
@@ -645,6 +636,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
645636
goto fail;
646637
}
647638
}
639+
#endif
648640

649641
if (comp_ctx->enable_bound_check
650642
&& !(is_local_of_aot_value
@@ -723,6 +715,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
723715
}
724716
}
725717

718+
#if WASM_ENABLE_SHARED_HEAP != 0
726719
if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) {
727720
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
728721
LLVMAddIncoming(maddr_phi, &maddr, &block_curr, 1);
@@ -734,6 +727,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
734727
return maddr_phi;
735728
}
736729
else
730+
#endif
737731
return maddr;
738732
fail:
739733
return NULL;
@@ -1356,16 +1350,20 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
13561350
LLVMValueRef offset, LLVMValueRef bytes)
13571351
{
13581352
LLVMValueRef maddr, max_addr, cmp, cmp1;
1359-
LLVMValueRef mem_base_addr, maddr_phi = NULL;
1353+
LLVMValueRef mem_base_addr;
13601354
LLVMBasicBlockRef block_curr = LLVMGetInsertBlock(comp_ctx->builder);
1361-
LLVMBasicBlockRef check_succ, block_maddr_phi = NULL;
1355+
LLVMBasicBlockRef check_succ;
13621356
LLVMValueRef mem_size;
13631357
bool is_target_64bit;
13641358
#if WASM_ENABLE_MEMORY64 == 0
13651359
bool is_memory64 = false;
13661360
#else
13671361
bool is_memory64 = IS_MEMORY64;
13681362
#endif
1363+
#if WASM_ENABLE_SHARED_HEAP != 0
1364+
LLVMValueRef maddr_phi = NULL;
1365+
LLVMBasicBlockRef block_maddr_phi = NULL;
1366+
#endif
13691367

13701368
is_target_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
13711369

@@ -1466,6 +1464,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
14661464
block_curr = check_integer_overflow_end;
14671465
}
14681466

1467+
#if WASM_ENABLE_SHARED_HEAP != 0
14691468
if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) {
14701469
ADD_BASIC_BLOCK(block_maddr_phi, "maddr_phi");
14711470
SET_BUILD_POS(block_maddr_phi);
@@ -1483,6 +1482,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
14831482
goto fail;
14841483
}
14851484
}
1485+
#endif
14861486

14871487
/* mem_size is always 64-bit, extend max_addr on 32 bits platform */
14881488
if (!is_target_64bit
@@ -1506,6 +1506,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
15061506
goto fail;
15071507
}
15081508

1509+
#if WASM_ENABLE_SHARED_HEAP != 0
15091510
if (comp_ctx->enable_shared_heap /* TODO: && mem_idx == 0 */) {
15101511
block_curr = LLVMGetInsertBlock(comp_ctx->builder);
15111512
LLVMAddIncoming(maddr_phi, &maddr, &block_curr, 1);
@@ -1517,6 +1518,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
15171518
return maddr_phi;
15181519
}
15191520
else
1521+
#endif
15201522
return maddr;
15211523
fail:
15221524
return NULL;

core/iwasm/compilation/aot_llvm.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,14 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
15171517
return true;
15181518
}
15191519

1520+
#define BUILD_IS_NOT_NULL(value, res, name) \
1521+
do { \
1522+
if (!(res = LLVMBuildIsNotNull(comp_ctx->builder, value, name))) { \
1523+
aot_set_last_error("llvm build is not null failed."); \
1524+
goto fail; \
1525+
} \
1526+
} while (0)
1527+
15201528
#define LOAD_MODULE_EXTRA_FIELD_AND_ALLOCA(field, type) \
15211529
do { \
15221530
get_module_extra_field_offset(field); \
@@ -1547,8 +1555,10 @@ create_memory_info(const AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
15471555
static bool
15481556
create_shared_heap_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
15491557
{
1558+
#if WASM_ENABLE_SHARED_HEAP != 0
15501559
LLVMValueRef offset, field_p, load_val, shared_heap_head_p,
1551-
shared_heap_head;
1560+
shared_heap_head, cmp, field_p_or_default, shared_heap_head_start_off,
1561+
shared_heap_head_start_off_minus_one;
15521562
LLVMTypeRef shared_heap_offset_type;
15531563
uint32 offset_u32;
15541564
#if WASM_ENABLE_MEMORY64 == 0
@@ -1586,6 +1596,7 @@ create_shared_heap_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
15861596
aot_set_last_error("llvm build load failed");
15871597
goto fail;
15881598
}
1599+
BUILD_IS_NOT_NULL(shared_heap_head, cmp, "has_shared_heap");
15891600

15901601
if (is_memory64) {
15911602
offset_u32 = offsetof(WASMSharedHeap, start_off_mem64);
@@ -1601,16 +1612,43 @@ create_shared_heap_info(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
16011612
aot_set_last_error("llvm build inbounds gep failed");
16021613
goto fail;
16031614
}
1604-
if (!(func_ctx->shared_heap_head_start_off =
1605-
LLVMBuildLoad2(comp_ctx->builder, shared_heap_offset_type,
1606-
field_p, "shared_heap_head_start_off"))) {
1615+
1616+
/* Select shared heap head ptr or safe alloca
1617+
* shared_heap_start_off(UINT32_MAX/UINT64_MAX) based on the condition */
1618+
if (!(field_p_or_default = LLVMBuildSelect(comp_ctx->builder, cmp, field_p,
1619+
func_ctx->shared_heap_start_off,
1620+
"ptr_or_default"))) {
1621+
aot_set_last_error("llvm build select failed");
1622+
goto fail;
1623+
}
1624+
1625+
if (!(shared_heap_head_start_off = LLVMBuildLoad2(
1626+
comp_ctx->builder, shared_heap_offset_type, field_p_or_default,
1627+
"shared_heap_head_start_off"))) {
1628+
aot_set_last_error("llvm build load failed");
1629+
goto fail;
1630+
}
1631+
if (!(shared_heap_head_start_off_minus_one = LLVMBuildAdd(
1632+
comp_ctx->builder, shared_heap_head_start_off,
1633+
comp_ctx->pointer_size == sizeof(uint64) ? I64_NEG_ONE
1634+
: I32_NEG_ONE,
1635+
"head_start_off_minus_one"))) {
16071636
aot_set_last_error("llvm build load failed");
16081637
goto fail;
16091638
}
16101639

1640+
if (!(func_ctx->shared_heap_head_start_off = LLVMBuildSelect(
1641+
comp_ctx->builder, cmp, shared_heap_head_start_off_minus_one,
1642+
shared_heap_head_start_off, "head_start_off"))) {
1643+
aot_set_last_error("llvm build select failed");
1644+
goto fail;
1645+
}
16111646
return true;
16121647
fail:
16131648
return false;
1649+
#else
1650+
return true;
1651+
#endif
16141652
}
16151653

16161654
static bool
@@ -2465,7 +2503,7 @@ jit_stack_size_callback(void *user_data, const char *name, size_t namelen,
24652503
stack_consumption_to_call_wrapped_func =
24662504
musttail ? 0
24672505
: aot_estimate_stack_usage_for_function_call(
2468-
comp_ctx, func_ctx->aot_func->func_type);
2506+
comp_ctx, func_ctx->aot_func->func_type);
24692507
LOG_VERBOSE("func %.*s stack %u + %zu + %u", (int)namelen, name,
24702508
stack_consumption_to_call_wrapped_func, stack_size, call_size);
24712509

0 commit comments

Comments
 (0)