diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index bef63979..7b85f2cd 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -49,10 +49,17 @@ jobs: with: os: "ubuntu-20.04" arch: "X86" + build_llvm_libraries_on_ubuntu_2204: + uses: ./.github/workflows/build_llvm_libraries.yml + with: + os: "ubuntu-22.04" + arch: "X86" build_wamrc: needs: - [build_llvm_libraries_on_ubuntu_2004] + [ + build_llvm_libraries_on_ubuntu_2004, + ] runs-on: ${{ matrix.os }} strategy: matrix: @@ -90,7 +97,9 @@ jobs: build_iwasm: needs: - [build_llvm_libraries_on_ubuntu_2004] + [ + build_llvm_libraries_on_ubuntu_2004, + ] runs-on: ${{ matrix.os }} strategy: matrix: @@ -497,14 +506,15 @@ jobs: [ build_iwasm, build_llvm_libraries_on_ubuntu_2004, + build_llvm_libraries_on_ubuntu_2204, build_wamrc, ] runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu-20.04] - sanitizer: ["", "ubsan", "asan"] + os: [ubuntu-20.04, ubuntu-22.04] + sanitizer: ["", "ubsan", "asan", "tsan"] running_mode: [ "classic-interp", @@ -530,11 +540,14 @@ jobs: - os: ubuntu-20.04 llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }} ubuntu_version: "20.04" + - os: ubuntu-22.04 + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} + ubuntu_version: "22.04" exclude: # uncompatiable modes and features - os: ubuntu-20.04 - sanitizer: asan + sanitizer: tsan # asan works only for aot now - running_mode: "classic-interp" sanitizer: asan @@ -546,6 +559,14 @@ jobs: sanitizer: asan - running_mode: "multi-tier-jit" sanitizer: asan + - running_mode: "classic-interp" + sanitizer: tsan + - running_mode: "jit" + sanitizer: tsan + - running_mode: "fast-jit" + sanitizer: tsan + - running_mode: "multi-tier-jit" + sanitizer: tsan # classic-interp and fast-interp don't support simd - running_mode: "classic-interp" test_option: $SIMD_TEST_OPTIONS @@ -595,9 +616,10 @@ jobs: || matrix.test_option == '$WASI_TEST_OPTIONS') && matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit' run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV - - - name: set sanitizer - run: echo "WAMR_BUILD_SANITIZER=${{ matrix.sanitizer }}" >> $GITHUB_ENV + + - name: set additional tsan options + run: echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV + working-directory: tests/wamr-test-suites #only download llvm libraries in jit and aot mode - name: Get LLVM libraries @@ -638,7 +660,7 @@ jobs: - name: run tests timeout-minutes: 40 - run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} + run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} -T %{{matrix.sanitizer}} working-directory: ./tests/wamr-test-suites #only install x32 support libraries when to run x86_32 cases diff --git a/CMakeLists.txt b/CMakeLists.txt index fbea2616..1c879949 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,11 +107,6 @@ endif () set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -# Set the strip command based on the system (GNU or Clang) -if (CMAKE_STRIP) - set (CMAKE_STRIP_FLAGS "--strip-all") -endif () - include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -Wshadow -Wno-unused-parameter") @@ -146,15 +141,6 @@ endif () install (TARGETS iwasm_static ARCHIVE DESTINATION lib) -# If it's a Release build, strip the static library -if (CMAKE_STRIP AND CMAKE_BUILD_TYPE STREQUAL "Release") - # Strip static library - message (STATUS "Stripping static library after build!") - add_custom_command (TARGET iwasm_static POST_BUILD - COMMAND ${CMAKE_STRIP} ${CMAKE_STRIP_FLAGS} $ - ) -endif () - # SHARED LIBRARY add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE}) set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm) @@ -176,12 +162,3 @@ install (FILES ${WAMR_ROOT_DIR}/core/iwasm/include/wasm_export.h ${WAMR_ROOT_DIR}/core/iwasm/include/lib_export.h DESTINATION include) - -# If it's a Release build, strip the shared library -if (CMAKE_STRIP AND CMAKE_BUILD_TYPE STREQUAL "Release") - # Strip shared library - message (STATUS "Stripping shared library after build!") - add_custom_command (TARGET iwasm_shared POST_BUILD - COMMAND ${CMAKE_STRIP} ${CMAKE_STRIP_FLAGS} $ - ) -endif () diff --git a/README.md b/README.md index 486ca0fd..dfdae2da 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,10 @@ The current TSC members: - [lum1n0us](https://github.com/lum1n0us) - **Liang He**, - [no1wudi](https://github.com/no1wudi) **Qi Huang**, - [qinxk-inter](https://github.com/qinxk-inter) - **Xiaokang Qin**, +- [ttrenner ](https://github.com/ttrenner) - **Trenner, Thomas**, - [wei-tang](https://github.com/wei-tang) - **Wei Tang**, - [wenyongh](https://github.com/wenyongh) - **Wenyong Huang**, +- [woodsmc](https://github.com/woodsmc) - **Woods, Chris**, - [xujuntwt95329](https://github.com/xujuntwt95329) - **Jun Xu**, - [xwang98](https://github.com/xwang98) - **Xin Wang**, (chair) - [yamt](https://github.com/yamt) - **Takashi Yamamoto**, diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 0799d625..2e63c587 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -7,6 +7,7 @@ #include "bh_log.h" #include "mem_alloc.h" #include "../common/wasm_runtime_common.h" +#include "../common/wasm_memory.h" #include "../interpreter/wasm_runtime.h" #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" @@ -382,7 +383,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, uint32 inc_page_count, aux_heap_base, global_idx; uint32 bytes_of_last_page, bytes_to_page_end; uint32 heap_offset = num_bytes_per_page * init_page_count; - uint64 total_size; + uint64 memory_data_size, max_memory_data_size; uint8 *p = NULL, *global_addr; #ifdef OS_ENABLE_HW_BOUND_CHECK uint8 *mapped_mem; @@ -488,6 +489,12 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, if (max_page_count > DEFAULT_MAX_PAGES) max_page_count = DEFAULT_MAX_PAGES; } + else { /* heap_size == 0 */ + if (init_page_count == DEFAULT_MAX_PAGES) { + num_bytes_per_page = UINT32_MAX; + init_page_count = max_page_count = 1; + } + } LOG_VERBOSE("Memory instantiate:"); LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u", @@ -496,23 +503,34 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, module->aux_stack_size); LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size); - total_size = (uint64)num_bytes_per_page * init_page_count; -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (is_shared_memory) { - /* Allocate max page for shared memory */ - total_size = (uint64)num_bytes_per_page * max_page_count; - } -#endif - bh_assert(total_size <= UINT32_MAX); + memory_data_size = (uint64)num_bytes_per_page * init_page_count; + max_memory_data_size = (uint64)num_bytes_per_page * max_page_count; + bh_assert(memory_data_size <= UINT32_MAX); + bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB); + (void)max_memory_data_size; #ifndef OS_ENABLE_HW_BOUND_CHECK - /* Allocate memory */ - if (total_size > 0 - && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) { - return NULL; +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (is_shared_memory) { + /* Allocate maximum memory size when memory is shared */ + if (max_memory_data_size > 0 + && !(p = runtime_malloc(max_memory_data_size, error_buf, + error_buf_size))) { + return NULL; + } } -#else - total_size = (total_size + page_size - 1) & ~(page_size - 1); + else +#endif + { + /* Allocate initial memory size when memory is not shared */ + if (memory_data_size > 0 + && !(p = runtime_malloc(memory_data_size, error_buf, + error_buf_size))) { + return NULL; + } + } +#else /* else of OS_ENABLE_HW_BOUND_CHECK */ + memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1); /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G: * ea = i + memarg.offset @@ -526,37 +544,39 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, } #ifdef BH_PLATFORM_WINDOWS - if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) { + if (!os_mem_commit(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) { set_error_buf(error_buf, error_buf_size, "commit memory failed"); os_munmap(mapped_mem, map_size); return NULL; } #endif - if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) { + if (os_mprotect(p, memory_data_size, MMAP_PROT_READ | MMAP_PROT_WRITE) + != 0) { set_error_buf(error_buf, error_buf_size, "mprotect memory failed"); #ifdef BH_PLATFORM_WINDOWS - os_mem_decommit(p, total_size); + os_mem_decommit(p, memory_data_size); #endif os_munmap(mapped_mem, map_size); return NULL; } + /* Newly allocated pages are filled with zero by the OS, we don't fill it * again here */ -#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ - if (total_size > UINT32_MAX) - total_size = UINT32_MAX; + if (memory_data_size > UINT32_MAX) + memory_data_size = UINT32_MAX; +#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ memory_inst->module_type = Wasm_Module_AoT; memory_inst->num_bytes_per_page = num_bytes_per_page; memory_inst->cur_page_count = init_page_count; memory_inst->max_page_count = max_page_count; - memory_inst->memory_data_size = (uint32)total_size; + memory_inst->memory_data_size = (uint32)memory_data_size; /* Init memory info */ memory_inst->memory_data = p; - memory_inst->memory_data_end = p + (uint32)total_size; + memory_inst->memory_data_end = p + (uint32)memory_data_size; /* Initialize heap info */ memory_inst->heap_data = p + heap_offset; @@ -579,24 +599,13 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, } } - if (total_size > 0) { -#if UINTPTR_MAX == UINT64_MAX - memory_inst->mem_bound_check_1byte.u64 = total_size - 1; - memory_inst->mem_bound_check_2bytes.u64 = total_size - 2; - memory_inst->mem_bound_check_4bytes.u64 = total_size - 4; - memory_inst->mem_bound_check_8bytes.u64 = total_size - 8; - memory_inst->mem_bound_check_16bytes.u64 = total_size - 16; -#else - memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1; - memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2; - memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4; - memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8; - memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16; -#endif + if (memory_data_size > 0) { + wasm_runtime_set_mem_bound_check_bytes(memory_inst, memory_data_size); } #if WASM_ENABLE_SHARED_MEMORY != 0 if (is_shared_memory) { + memory_inst->is_shared_memory = true; memory_inst->ref_count = 1; } #endif @@ -613,7 +622,7 @@ fail1: #else #ifdef BH_PLATFORM_WINDOWS if (memory_inst->memory_data) - os_mem_decommit(p, total_size); + os_mem_decommit(p, memory_data_size); #endif os_munmap(mapped_mem, map_size); #endif @@ -673,6 +682,10 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent, if (data_seg->is_passive) continue; #endif + if (parent != NULL) + /* Ignore setting memory init data if the memory has been + initialized */ + continue; bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST || data_seg->offset.init_expr_type @@ -1897,6 +1910,13 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, if (ptr) { uint8 *addr = memory_inst->memory_data + ptr; + uint8 *memory_data_end; + + /* memory->memory_data_end may be changed in memory grow */ + SHARED_MEMORY_LOCK(memory_inst); + memory_data_end = memory_inst->memory_data_end; + SHARED_MEMORY_UNLOCK(memory_inst); + if (memory_inst->heap_handle && memory_inst->heap_data < addr && addr < memory_inst->heap_data_end) { mem_allocator_free(memory_inst->heap_handle, addr); @@ -1904,7 +1924,7 @@ aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, else if (module->malloc_func_index != (uint32)-1 && module->free_func_index != (uint32)-1 && memory_inst->memory_data <= addr - && addr < memory_inst->memory_data_end) { + && addr < memory_data_end) { AOTFunctionInstance *free_func; char *free_func_name; @@ -2298,7 +2318,9 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset, maddr = wasm_runtime_addr_app_to_native( (WASMModuleInstanceCommon *)module_inst, dst); + SHARED_MEMORY_LOCK(memory_inst); bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len); + SHARED_MEMORY_UNLOCK(memory_inst); return true; } diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index 4aecf991..bcd0a6d0 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -312,7 +312,6 @@ execute_func(WASMModuleInstanceCommon *module_inst, const char *name, #endif int32 i, p, module_type; uint64 total_size; - const char *exception; char buf[128]; bh_assert(argc >= 0); @@ -647,9 +646,7 @@ fail: if (argv1) wasm_runtime_free(argv1); - exception = wasm_runtime_get_exception(module_inst); - bh_assert(exception); - os_printf("%s\n", exception); + bh_assert(wasm_runtime_get_exception(module_inst)); return false; } diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index 05635ef5..e97f92df 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -298,10 +298,15 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm, goto fail; } + SHARED_MEMORY_LOCK(memory_inst); + if (app_offset + size <= memory_inst->memory_data_size) { + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); + fail: wasm_set_exception(module_inst, "out of bounds memory access"); return false; @@ -364,11 +369,16 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm, goto fail; } + SHARED_MEMORY_LOCK(memory_inst); + if (memory_inst->memory_data <= addr && addr + size <= memory_inst->memory_data_end) { + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); + fail: wasm_set_exception(module_inst, "out of bounds memory access"); return false; @@ -393,20 +403,24 @@ wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm, return NULL; } + SHARED_MEMORY_LOCK(memory_inst); + addr = memory_inst->memory_data + app_offset; if (bounds_checks) { if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end) { - + SHARED_MEMORY_UNLOCK(memory_inst); return addr; } } /* If bounds checks is disabled, return the address directly */ else if (app_offset != 0) { + SHARED_MEMORY_UNLOCK(memory_inst); return addr; } + SHARED_MEMORY_UNLOCK(memory_inst); return NULL; } @@ -418,6 +432,7 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm, WASMMemoryInstance *memory_inst; uint8 *addr = (uint8 *)native_ptr; bool bounds_checks; + uint32 ret; bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode || module_inst_comm->module_type == Wasm_Module_AoT); @@ -429,16 +444,24 @@ wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm, return 0; } + SHARED_MEMORY_LOCK(memory_inst); + if (bounds_checks) { if (memory_inst->memory_data <= addr - && addr < memory_inst->memory_data_end) - return (uint32)(addr - memory_inst->memory_data); + && addr < memory_inst->memory_data_end) { + ret = (uint32)(addr - memory_inst->memory_data); + SHARED_MEMORY_UNLOCK(memory_inst); + return ret; + } } /* If bounds checks is disabled, return the offset directly */ else if (addr != NULL) { - return (uint32)(addr - memory_inst->memory_data); + ret = (uint32)(addr - memory_inst->memory_data); + SHARED_MEMORY_UNLOCK(memory_inst); + return ret; } + SHARED_MEMORY_UNLOCK(memory_inst); return 0; } @@ -459,6 +482,8 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm, return false; } + SHARED_MEMORY_LOCK(memory_inst); + memory_data_size = memory_inst->memory_data_size; if (app_offset < memory_data_size) { @@ -466,9 +491,11 @@ wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm, *p_app_start_offset = 0; if (p_app_end_offset) *p_app_end_offset = memory_data_size; + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); return false; } @@ -490,15 +517,19 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm, return false; } + SHARED_MEMORY_LOCK(memory_inst); + if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end) { if (p_native_start_addr) *p_native_start_addr = memory_inst->memory_data; if (p_native_end_addr) *p_native_end_addr = memory_inst->memory_data_end; + SHARED_MEMORY_UNLOCK(memory_inst); return true; } + SHARED_MEMORY_UNLOCK(memory_inst); return false; } @@ -512,7 +543,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, bool bounds_checks; if (!memory_inst) { - goto fail; + wasm_set_exception(module_inst, "out of bounds memory access"); + return false; } native_addr = memory_inst->memory_data + app_buf_addr; @@ -529,6 +561,8 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, /* No need to check the app_offset and buf_size if memory access boundary check with hardware trap is enabled */ #ifndef OS_ENABLE_HW_BOUND_CHECK + SHARED_MEMORY_LOCK(memory_inst); + if (app_buf_addr >= memory_inst->memory_data_size) { goto fail; } @@ -549,14 +583,20 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str, if (str == str_end) goto fail; } + + SHARED_MEMORY_UNLOCK(memory_inst); #endif success: *p_native_addr = (void *)native_addr; return true; + +#ifndef OS_ENABLE_HW_BOUND_CHECK fail: + SHARED_MEMORY_UNLOCK(memory_inst); wasm_set_exception(module_inst, "out of bounds memory access"); return false; +#endif } WASMMemoryInstance * @@ -568,6 +608,27 @@ wasm_get_default_memory(WASMModuleInstance *module_inst) return NULL; } +void +wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory, + uint64 memory_data_size) +{ +#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0 +#if UINTPTR_MAX == UINT64_MAX + memory->mem_bound_check_1byte.u64 = memory_data_size - 1; + memory->mem_bound_check_2bytes.u64 = memory_data_size - 2; + memory->mem_bound_check_4bytes.u64 = memory_data_size - 4; + memory->mem_bound_check_8bytes.u64 = memory_data_size - 8; + memory->mem_bound_check_16bytes.u64 = memory_data_size - 16; +#else + memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1; + memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2; + memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4; + memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8; + memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16; +#endif +#endif +} + #ifndef OS_ENABLE_HW_BOUND_CHECK bool wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) @@ -625,9 +686,10 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->num_bytes_per_page = num_bytes_per_page; memory->cur_page_count = total_page_count; memory->max_page_count = max_page_count; - /* No need to update memory->memory_data_size as it is - initialized with the maximum memory data size for - shared memory */ + memory->memory_data_size = (uint32)total_size_new; + memory->memory_data_end = memory->memory_data + (uint32)total_size_new; + + wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new); return true; } #endif @@ -679,21 +741,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->memory_data = memory_data_new; memory->memory_data_end = memory_data_new + (uint32)total_size_new; -#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0 -#if UINTPTR_MAX == UINT64_MAX - memory->mem_bound_check_1byte.u64 = total_size_new - 1; - memory->mem_bound_check_2bytes.u64 = total_size_new - 2; - memory->mem_bound_check_4bytes.u64 = total_size_new - 4; - memory->mem_bound_check_8bytes.u64 = total_size_new - 8; - memory->mem_bound_check_16bytes.u64 = total_size_new - 16; -#else - memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1; - memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2; - memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4; - memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8; - memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16; -#endif -#endif + wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new); #if defined(os_writegsbase) /* write base addr of linear memory to GS segment register */ @@ -799,13 +847,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) memory->memory_data_size = (uint32)total_size_new; memory->memory_data_end = memory->memory_data + (uint32)total_size_new; -#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0 - memory->mem_bound_check_1byte.u64 = total_size_new - 1; - memory->mem_bound_check_2bytes.u64 = total_size_new - 2; - memory->mem_bound_check_4bytes.u64 = total_size_new - 4; - memory->mem_bound_check_8bytes.u64 = total_size_new - 8; - memory->mem_bound_check_16bytes.u64 = total_size_new - 16; -#endif + wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new); return_func: if (!ret && enlarge_memory_error_cb) { diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index daca2b71..c46b32ea 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -24,6 +24,10 @@ wasm_runtime_memory_destroy(); unsigned wasm_runtime_memory_pool_size(); +void +wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory, + uint64 memory_data_size); + void wasm_runtime_set_enlarge_mem_error_callback( const enlarge_memory_error_callback_t callback, void *user_data); diff --git a/core/iwasm/common/wasm_native.c b/core/iwasm/common/wasm_native.c index 0a585134..c42bf7b3 100644 --- a/core/iwasm/common/wasm_native.c +++ b/core/iwasm/common/wasm_native.c @@ -542,8 +542,7 @@ void wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm, WASIContext *wasi_ctx) { - return wasm_native_set_context(module_inst_comm, g_wasi_context_key, - wasi_ctx); + wasm_native_set_context(module_inst_comm, g_wasi_context_key, wasi_ctx); } static void diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 59ed016a..a8b3da6d 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -3037,6 +3037,74 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, } } + for (i = 0; i < map_dir_count; i++, wasm_fd++) { + char mapping_copy_buf[256]; + char *mapping_copy = mapping_copy_buf; + char *map_mapped = NULL, *map_host = NULL; + const unsigned long max_len = strlen(map_dir_list[i]) * 2 + 3; + + /* Allocation limit for runtime environments with reduced stack size */ + if (max_len > 256) { + if (!(mapping_copy = wasm_runtime_malloc(max_len))) { + snprintf(error_buf, error_buf_size, + "error while allocating for directory mapping\n"); + goto fail; + } + } + + bh_memcpy_s(mapping_copy, max_len, map_dir_list[i], + (uint32)(strlen(map_dir_list[i]) + 1)); + map_mapped = strtok(mapping_copy, "::"); + map_host = strtok(NULL, "::"); + + if (!map_mapped || !map_host) { + if (error_buf) + snprintf(error_buf, error_buf_size, + "error while pre-opening mapped directory: " + "invalid map\n"); + if (mapping_copy != mapping_copy_buf) + wasm_runtime_free(mapping_copy); + goto fail; + } + + path = os_realpath(map_host, resolved_path); + if (!path) { + if (error_buf) + snprintf(error_buf, error_buf_size, + "error while pre-opening mapped directory %s: %d\n", + map_host, errno); + if (mapping_copy != mapping_copy_buf) + wasm_runtime_free(mapping_copy); + goto fail; + } + + __wasi_errno_t error = os_open_preopendir(path, &file_handle); + if (error != __WASI_ESUCCESS) { + if (error_buf) + snprintf(error_buf, error_buf_size, + "error while pre-opening mapped directory %s: %d\n", + map_host, errno); + if (mapping_copy != mapping_copy_buf) + wasm_runtime_free(mapping_copy); + goto fail; + } + + if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false) + || !fd_prestats_insert(prestats, map_mapped, wasm_fd)) { + if (error_buf) + snprintf(error_buf, error_buf_size, + "error while pre-opening mapped directory %s: " + "insertion failed\n", + dir_list[i]); + if (mapping_copy != mapping_copy_buf) + wasm_runtime_free(mapping_copy); + goto fail; + } + + if (mapping_copy != mapping_copy_buf) + wasm_runtime_free(mapping_copy); + } + /* addr_pool(textual) -> apool */ for (i = 0; i < addr_pool_size; i++) { char *cp, *address, *mask; @@ -4361,10 +4429,12 @@ static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative; || defined(BUILD_TARGET_RISCV64_LP64) */ #endif /* end of defined(_WIN32) || defined(_WIN32_) */ -/* ASAN is not designed to work with custom stack unwind or other low-level \ - things. > Ignore a function that does some low-level magic. (e.g. walking \ - through the thread's stack bypassing the frame boundaries) */ -#if defined(__GNUC__) +/* + * ASAN is not designed to work with custom stack unwind or other low-level + * things. Ignore a function that does some low-level magic. (e.g. walking + * through the thread's stack bypassing the frame boundaries) + */ +#if defined(__GNUC__) || defined(__clang__) __attribute__((no_sanitize_address)) #endif bool diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 4cfef6fa..367ea88f 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -12,6 +12,7 @@ #include "wasm_native.h" #include "../include/wasm_export.h" #include "../interpreter/wasm.h" + #if WASM_ENABLE_LIBC_WASI != 0 #if WASM_ENABLE_UVWASI == 0 #include "posix.h" @@ -43,15 +44,16 @@ extern "C" { /* For STORE opcodes */ #define STORE_I64 PUT_I64_TO_ADDR -#define STORE_U32(addr, value) \ - do { \ - *(uint32 *)(addr) = (uint32)(value); \ - } while (0) -#define STORE_U16(addr, value) \ - do { \ - *(uint16 *)(addr) = (uint16)(value); \ - } while (0) - +static inline void +STORE_U32(void *addr, uint32_t value) +{ + *(uint32_t *)(addr) = (uint32_t)(value); +} +static inline void +STORE_U16(void *addr, uint16_t value) +{ + *(uint16_t *)(addr) = (uint16_t)(value); +} /* For LOAD opcodes */ #define LOAD_I64(addr) (*(int64 *)(addr)) #define LOAD_F64(addr) (*(float64 *)(addr)) @@ -146,42 +148,42 @@ GET_F64_FROM_ADDR(uint32 *addr) } \ } while (0) -#define STORE_U32(addr, value) \ - do { \ - uintptr_t addr_ = (uintptr_t)(addr); \ - union { \ - uint32 val; \ - uint16 u16[2]; \ - uint8 u8[4]; \ - } u; \ - if ((addr_ & (uintptr_t)3) == 0) \ - *(uint32 *)(addr) = (uint32)(value); \ - else { \ - u.val = (uint32)(value); \ - if ((addr_ & (uintptr_t)1) == 0) { \ - ((uint16 *)(addr))[0] = u.u16[0]; \ - ((uint16 *)(addr))[1] = u.u16[1]; \ - } \ - else { \ - ((uint8 *)(addr))[0] = u.u8[0]; \ - ((uint8 *)(addr))[1] = u.u8[1]; \ - ((uint8 *)(addr))[2] = u.u8[2]; \ - ((uint8 *)(addr))[3] = u.u8[3]; \ - } \ - } \ - } while (0) - -#define STORE_U16(addr, value) \ - do { \ - union { \ - uint16 val; \ - uint8 u8[2]; \ - } u; \ - u.val = (uint16)(value); \ - ((uint8 *)(addr))[0] = u.u8[0]; \ - ((uint8 *)(addr))[1] = u.u8[1]; \ - } while (0) - +static inline void +STORE_U32(void *addr, uint32_t value) +{ + uintptr_t addr_ = (uintptr_t)(addr); + union { + uint32_t val; + uint16_t u16[2]; + uint8_t u8[4]; + } u; + if ((addr_ & (uintptr_t)3) == 0) + *(uint32_t *)(addr) = (uint32_t)(value); + else { + u.val = (uint32_t)(value); + if ((addr_ & (uintptr_t)1) == 0) { + ((uint16_t *)(addr))[0] = u.u16[0]; + ((uint16_t *)(addr))[1] = u.u16[1]; + } + else { + ((uint8_t *)(addr))[0] = u.u8[0]; + ((uint8_t *)(addr))[1] = u.u8[1]; + ((uint8_t *)(addr))[2] = u.u8[2]; + ((uint8_t *)(addr))[3] = u.u8[3]; + } + } +} +static inline void +STORE_U16(void *addr, uint16_t value) +{ + union { + uint16_t val; + uint8_t u8[2]; + } u; + u.val = (uint16_t)(value); + ((uint8_t *)(addr))[0] = u.u8[0]; + ((uint8_t *)(addr))[1] = u.u8[1]; +} /* For LOAD opcodes */ static inline int64 LOAD_I64(void *addr) @@ -297,6 +299,14 @@ LOAD_I16(void *addr) #endif /* WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 */ +#if WASM_ENABLE_SHARED_MEMORY != 0 +#define SHARED_MEMORY_LOCK(memory) shared_memory_lock(memory) +#define SHARED_MEMORY_UNLOCK(memory) shared_memory_unlock(memory) +#else +#define SHARED_MEMORY_LOCK(memory) (void)0 +#define SHARED_MEMORY_UNLOCK(memory) (void)0 +#endif + typedef struct WASMModuleCommon { /* Module type, for module loaded from WASM bytecode binary, this field is Wasm_Module_Bytecode, and this structure should diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index c95d4b7e..70e84a37 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -18,7 +18,7 @@ * - If you care performance, it's better to make the interpreters * use atomic ops. */ -static korp_mutex _shared_memory_lock; +korp_mutex g_shared_memory_lock; /* clang-format off */ enum { @@ -55,13 +55,13 @@ destroy_wait_info(void *wait_info); bool wasm_shared_memory_init() { - if (os_mutex_init(&_shared_memory_lock) != 0) + if (os_mutex_init(&g_shared_memory_lock) != 0) return false; /* wait map not exists, create new map */ if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash, (KeyEqualFunc)wait_address_equal, NULL, destroy_wait_info))) { - os_mutex_destroy(&_shared_memory_lock); + os_mutex_destroy(&g_shared_memory_lock); return false; } return true; @@ -71,79 +71,47 @@ void wasm_shared_memory_destroy() { bh_hash_map_destroy(wait_map); - os_mutex_destroy(&_shared_memory_lock); + os_mutex_destroy(&g_shared_memory_lock); } -uint32 +uint16 shared_memory_inc_reference(WASMMemoryInstance *memory) { bh_assert(shared_memory_is_shared(memory)); - uint32 old; -#if BH_ATOMIC_32_IS_ATOMIC == 0 - os_mutex_lock(&_shared_memory_lock); + uint16 old; +#if BH_ATOMIC_16_IS_ATOMIC == 0 + os_mutex_lock(&g_shared_memory_lock); #endif - old = BH_ATOMIC_32_FETCH_ADD(memory->ref_count, 1); -#if BH_ATOMIC_32_IS_ATOMIC == 0 - os_mutex_unlock(&_shared_memory_lock); + old = BH_ATOMIC_16_FETCH_ADD(memory->ref_count, 1); +#if BH_ATOMIC_16_IS_ATOMIC == 0 + os_mutex_unlock(&g_shared_memory_lock); #endif bh_assert(old >= 1); - bh_assert(old < UINT32_MAX); + bh_assert(old < UINT16_MAX); return old + 1; } -uint32 +uint16 shared_memory_dec_reference(WASMMemoryInstance *memory) { bh_assert(shared_memory_is_shared(memory)); - uint32 old; -#if BH_ATOMIC_32_IS_ATOMIC == 0 - os_mutex_lock(&_shared_memory_lock); + uint16 old; +#if BH_ATOMIC_16_IS_ATOMIC == 0 + os_mutex_lock(&g_shared_memory_lock); #endif - old = BH_ATOMIC_32_FETCH_SUB(memory->ref_count, 1); -#if BH_ATOMIC_32_IS_ATOMIC == 0 - os_mutex_unlock(&_shared_memory_lock); + old = BH_ATOMIC_16_FETCH_SUB(memory->ref_count, 1); +#if BH_ATOMIC_16_IS_ATOMIC == 0 + os_mutex_unlock(&g_shared_memory_lock); #endif bh_assert(old > 0); return old - 1; } -bool -shared_memory_is_shared(WASMMemoryInstance *memory) -{ - uint32 old; -#if BH_ATOMIC_32_IS_ATOMIC == 0 - os_mutex_lock(&_shared_memory_lock); -#endif - old = BH_ATOMIC_32_LOAD(memory->ref_count); -#if BH_ATOMIC_32_IS_ATOMIC == 0 - os_mutex_unlock(&_shared_memory_lock); -#endif - return old > 0; -} - static korp_mutex * shared_memory_get_lock_pointer(WASMMemoryInstance *memory) { bh_assert(memory != NULL); - return &_shared_memory_lock; -} - -void -shared_memory_lock(WASMMemoryInstance *memory) -{ - /* - * Note: exception logic is currently abusing this lock. - * cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407 - */ - bh_assert(memory != NULL); - os_mutex_lock(&_shared_memory_lock); -} - -void -shared_memory_unlock(WASMMemoryInstance *memory) -{ - bh_assert(memory != NULL); - os_mutex_unlock(&_shared_memory_lock); + return &g_shared_memory_lock; } /* Atomics wait && notify APIs */ @@ -301,12 +269,15 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, return -1; } + shared_memory_lock(module_inst->memories[0]); if ((uint8 *)address < module_inst->memories[0]->memory_data || (uint8 *)address + (wait64 ? 8 : 4) > module_inst->memories[0]->memory_data_end) { + shared_memory_unlock(module_inst->memories[0]); wasm_runtime_set_exception(module, "out of bounds memory access"); return -1; } + shared_memory_unlock(module_inst->memories[0]); #if WASM_ENABLE_THREAD_MGR != 0 exec_env = @@ -423,9 +394,11 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, bh_assert(module->module_type == Wasm_Module_Bytecode || module->module_type == Wasm_Module_AoT); + shared_memory_lock(module_inst->memories[0]); out_of_bounds = ((uint8 *)address < module_inst->memories[0]->memory_data || (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end); + shared_memory_unlock(module_inst->memories[0]); if (out_of_bounds) { wasm_runtime_set_exception(module, "out of bounds memory access"); diff --git a/core/iwasm/common/wasm_shared_memory.h b/core/iwasm/common/wasm_shared_memory.h index 6a6538d2..8bbc4a80 100644 --- a/core/iwasm/common/wasm_shared_memory.h +++ b/core/iwasm/common/wasm_shared_memory.h @@ -14,26 +14,39 @@ extern "C" { #endif +extern korp_mutex g_shared_memory_lock; + bool wasm_shared_memory_init(); void wasm_shared_memory_destroy(); -uint32 +uint16 shared_memory_inc_reference(WASMMemoryInstance *memory); -uint32 +uint16 shared_memory_dec_reference(WASMMemoryInstance *memory); -bool -shared_memory_is_shared(WASMMemoryInstance *memory); +#define shared_memory_is_shared(memory) memory->is_shared_memory -void -shared_memory_lock(WASMMemoryInstance *memory); +#define shared_memory_lock(memory) \ + do { \ + /* \ + * Note: exception logic is currently abusing this lock. \ + * cf. \ + * https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407 \ + */ \ + bh_assert(memory != NULL); \ + if (memory->is_shared_memory) \ + os_mutex_lock(&g_shared_memory_lock); \ + } while (0) -void -shared_memory_unlock(WASMMemoryInstance *memory); +#define shared_memory_unlock(memory) \ + do { \ + if (memory->is_shared_memory) \ + os_mutex_unlock(&g_shared_memory_lock); \ + } while (0) uint32 wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 446ca5ea..895bf7e3 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -344,7 +344,9 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx, for (i = 0; i < block->param_count; i++) { param_index = block->param_count - 1 - i; POP(value, block->param_types[param_index]); - ADD_TO_PARAM_PHIS(block, value, param_index); + if (block->llvm_entry_block) + /* Only add incoming phis if the entry block was created */ + ADD_TO_PARAM_PHIS(block, value, param_index); if (block->label_type == LABEL_TYPE_IF && !block->skip_wasm_code_else) { if (block->llvm_else_block) { @@ -366,7 +368,17 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx, /* Push param phis to the new block */ for (i = 0; i < block->param_count; i++) { - PUSH(block->param_phis[i], block->param_types[i]); + if (block->llvm_entry_block) + /* Push param phis if the entry basic block was created */ + PUSH(block->param_phis[i], block->param_types[i]); + else { + bh_assert(block->label_type == LABEL_TYPE_IF + && block->llvm_else_block && block->else_param_phis + && !block->skip_wasm_code_else); + /* Push else param phis if we start to translate the + else branch */ + PUSH(block->else_param_phis[i], block->param_types[i]); + } } return true; diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index 7484d4b5..8c35c3fe 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -157,7 +157,10 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, if (mem_offset + bytes <= mem_data_size) { /* inside memory space */ - offset1 = I32_CONST((uint32)mem_offset); + if (comp_ctx->pointer_size == sizeof(uint64)) + offset1 = I64_CONST((uint32)mem_offset); + else + offset1 = I32_CONST((uint32)mem_offset); CHECK_LLVM_CONST(offset1); if (!enable_segue) { if (!(maddr = LLVMBuildInBoundsGEP2(comp_ctx->builder, diff --git a/core/iwasm/compilation/aot_emit_numberic.c b/core/iwasm/compilation/aot_emit_numberic.c index bda64f83..8b6ec02d 100644 --- a/core/iwasm/compilation/aot_emit_numberic.c +++ b/core/iwasm/compilation/aot_emit_numberic.c @@ -171,15 +171,6 @@ right = shift_count_mask; \ } while (0) -static bool -is_shift_count_mask_needed(AOTCompContext *comp_ctx, LLVMValueRef left, - LLVMValueRef right) -{ - return (strcmp(comp_ctx->target_arch, "x86_64") != 0 - && strcmp(comp_ctx->target_arch, "i386") != 0) - || (LLVMIsEfficientConstInt(left) && LLVMIsEfficientConstInt(right)); -} - /* Call llvm constrained floating-point intrinsic */ static LLVMValueRef call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx, @@ -737,8 +728,7 @@ compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right, { LLVMValueRef res; - if (is_shift_count_mask_needed(comp_ctx, left, right)) - SHIFT_COUNT_MASK; + SHIFT_COUNT_MASK; /* Build shl */ LLVM_BUILD_OP(Shl, left, right, res, "shl", NULL); @@ -752,8 +742,7 @@ compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left, { LLVMValueRef res; - if (is_shift_count_mask_needed(comp_ctx, left, right)) - SHIFT_COUNT_MASK; + SHIFT_COUNT_MASK; /* Build shl */ LLVM_BUILD_OP(AShr, left, right, res, "shr_s", NULL); @@ -767,8 +756,7 @@ compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left, { LLVMValueRef res; - if (is_shift_count_mask_needed(comp_ctx, left, right)) - SHIFT_COUNT_MASK; + SHIFT_COUNT_MASK; /* Build shl */ LLVM_BUILD_OP(LShr, left, right, res, "shr_u", NULL); @@ -789,17 +777,25 @@ compile_int_rot(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right, if (IS_CONST_ZERO(right)) return left; - /* Calculate (bits - shif_count) */ + /* Calculate (bits - shift_count) */ LLVM_BUILD_OP(Sub, is_i32 ? I32_32 : I64_64, right, bits_minus_shift_count, "bits_minus_shift_count", NULL); + /* Calculate (bits - shift_count) & mask */ + bits_minus_shift_count = + LLVMBuildAnd(comp_ctx->builder, bits_minus_shift_count, + is_i32 ? I32_31 : I64_63, "bits_minus_shift_count_and"); + if (!bits_minus_shift_count) { + aot_set_last_error("llvm build and failed."); + return NULL; + } if (is_rotl) { - /* left<>(BITS-count) */ + /* (left << count) | (left >> ((BITS - count) & mask)) */ LLVM_BUILD_OP(Shl, left, right, tmp_l, "tmp_l", NULL); LLVM_BUILD_OP(LShr, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL); } else { - /* left>>count | left<<(BITS-count) */ + /* (left >> count) | (left << ((BITS - count) & mask)) */ LLVM_BUILD_OP(LShr, left, right, tmp_l, "tmp_l", NULL); LLVM_BUILD_OP(Shl, left, bits_minus_shift_count, tmp_r, "tmp_r", NULL); } diff --git a/core/iwasm/compilation/aot_llvm_extra.cpp b/core/iwasm/compilation/aot_llvm_extra.cpp index ab6c621a..72e163fa 100644 --- a/core/iwasm/compilation/aot_llvm_extra.cpp +++ b/core/iwasm/compilation/aot_llvm_extra.cpp @@ -343,18 +343,23 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module) ExitOnErr(PB.parsePassPipeline(MPM, comp_ctx->llvm_passes)); } - if (!disable_llvm_lto) { - /* Apply LTO for AOT mode */ - if (comp_ctx->comp_data->func_count >= 10 - || comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file) - /* Add the pre-link optimizations if the func count - is large enough or PGO is enabled */ - MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(OL)); - else - MPM.addPass(PB.buildLTODefaultPipeline(OL, NULL)); + if (OptimizationLevel::O0 == OL) { + MPM.addPass(PB.buildO0DefaultPipeline(OL)); } else { - MPM.addPass(PB.buildPerModuleDefaultPipeline(OL)); + if (!disable_llvm_lto) { + /* Apply LTO for AOT mode */ + if (comp_ctx->comp_data->func_count >= 10 + || comp_ctx->enable_llvm_pgo || comp_ctx->use_prof_file) + /* Add the pre-link optimizations if the func count + is large enough or PGO is enabled */ + MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(OL)); + else + MPM.addPass(PB.buildLTODefaultPipeline(OL, NULL)); + } + else { + MPM.addPass(PB.buildPerModuleDefaultPipeline(OL)); + } } /* Run specific passes for AOT indirect mode in last since general diff --git a/core/iwasm/compilation/simd/simd_bit_shifts.c b/core/iwasm/compilation/simd/simd_bit_shifts.c index 675ffbcf..1d645ed7 100644 --- a/core/iwasm/compilation/simd/simd_bit_shifts.c +++ b/core/iwasm/compilation/simd/simd_bit_shifts.c @@ -30,11 +30,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, LLVM_CONST(i16x8_vec_zero), LLVM_CONST(i32x4_vec_zero), LLVM_CONST(i64x2_vec_zero) }; - LLVMValueRef lane_bits[] = { - LLVM_CONST(i32_eight), - LLVMConstInt(I32_TYPE, 16, true), - LLVMConstInt(I32_TYPE, 32, true), - LLVMConstInt(I32_TYPE, 64, true), + LLVMValueRef lane_shift_masks[] = { + LLVMConstInt(I32_TYPE, 7, true), + LLVMConstInt(I32_TYPE, 15, true), + LLVMConstInt(I32_TYPE, 31, true), + LLVMConstInt(I32_TYPE, 63, true), }; POP_I32(offset); @@ -44,11 +44,11 @@ simd_shift(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, return false; } - /* offset mod LaneBits */ - if (!lane_bits[itype] - || !(offset = LLVMBuildSRem(comp_ctx->builder, offset, lane_bits[itype], - "offset_fix"))) { - HANDLE_FAILURE("LLVMBuildSRem"); + /* offset = offset & shift_mask */ + if (!lane_shift_masks[itype] + || !(offset = LLVMBuildAnd(comp_ctx->builder, offset, + lane_shift_masks[itype], "offset_fix"))) { + HANDLE_FAILURE("LLVMBuildAnd"); return false; } diff --git a/core/iwasm/fast-jit/fe/jit_emit_compare.c b/core/iwasm/fast-jit/fe/jit_emit_compare.c index d4124934..8fe48f14 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_compare.c +++ b/core/iwasm/fast-jit/fe/jit_emit_compare.c @@ -227,7 +227,7 @@ jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond) POP_F32(rhs); POP_F32(lhs); - if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) { + if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) { float32 lvalue = jit_cc_get_const_F32(cc, lhs); float32 rvalue = jit_cc_get_const_F32(cc, rhs); @@ -290,7 +290,7 @@ jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond) POP_F64(rhs); POP_F64(lhs); - if (jit_reg_is_const_val(lhs) && jit_reg_is_const_val(rhs)) { + if (jit_reg_is_const(lhs) && jit_reg_is_const(rhs)) { float64 lvalue = jit_cc_get_const_F64(cc, lhs); float64 rvalue = jit_cc_get_const_F64(cc, rhs); diff --git a/core/iwasm/fast-jit/fe/jit_emit_control.c b/core/iwasm/fast-jit/fe/jit_emit_control.c index f7536c73..5438bc62 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_control.c +++ b/core/iwasm/fast-jit/fe/jit_emit_control.c @@ -808,7 +808,7 @@ jit_compile_op_block(JitCompContext *cc, uint8 **p_frame_ip, else if (label_type == LABEL_TYPE_IF) { POP_I32(value); - if (!jit_reg_is_const_val(value)) { + if (!jit_reg_is_const(value)) { /* Compare value is not constant, create condition br IR */ /* Create entry block */ diff --git a/core/iwasm/fast-jit/fe/jit_emit_conversion.c b/core/iwasm/fast-jit/fe/jit_emit_conversion.c index 8308a3ca..89d84f14 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_conversion.c +++ b/core/iwasm/fast-jit/fe/jit_emit_conversion.c @@ -192,6 +192,55 @@ jit_compile_check_value_range(JitCompContext *cc, JitReg value, JitReg min_fp, bh_assert(JIT_REG_KIND_F32 == kind || JIT_REG_KIND_F64 == kind); + if (JIT_REG_KIND_F32 == kind && jit_reg_is_const(value)) { + /* value is an f32 const */ + float value_f32_const = jit_cc_get_const_F32(cc, value); + float min_fp_f32_const = jit_cc_get_const_F32(cc, min_fp); + float max_fp_f32_const = jit_cc_get_const_F32(cc, max_fp); + + if (isnan(value_f32_const)) { + /* throw exception if value is nan */ + if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER, + JIT_OP_JMP, 0, NULL)) + goto fail; + } + + if (value_f32_const <= min_fp_f32_const + || value_f32_const >= max_fp_f32_const) { + /* throw exception if value is out of range */ + if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_JMP, 0, + NULL)) + goto fail; + } + + /* value is in range, do nothing */ + return true; + } + else if (JIT_REG_KIND_F64 == kind && jit_reg_is_const(value)) { + /* value is an f64 const */ + double value_f64_const = jit_cc_get_const_F64(cc, value); + double min_fp_f64_const = jit_cc_get_const_F64(cc, min_fp); + double max_fp_f64_const = jit_cc_get_const_F64(cc, max_fp); + + if (isnan(value_f64_const)) { + /* throw exception if value is nan */ + if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER, + JIT_OP_JMP, 0, NULL)) + goto fail; + } + + if (value_f64_const <= min_fp_f64_const + || value_f64_const >= max_fp_f64_const) { + /* throw exception if value is out of range */ + if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_JMP, 0, + NULL)) + goto fail; + } + + /* value is in range, do nothing */ + return true; + } + /* If value is NaN, throw exception */ if (JIT_REG_KIND_F32 == kind) emit_ret = jit_emit_callnative(cc, local_isnanf, nan_ret, &value, 1); diff --git a/core/iwasm/fast-jit/jit_frontend.c b/core/iwasm/fast-jit/jit_frontend.c index ec68ad91..b2465724 100644 --- a/core/iwasm/fast-jit/jit_frontend.c +++ b/core/iwasm/fast-jit/jit_frontend.c @@ -2311,77 +2311,3 @@ jit_frontend_get_jitted_return_addr_offset() { return (uint32)offsetof(WASMInterpFrame, jitted_return_addr); } - -#if 0 -#if WASM_ENABLE_THREAD_MGR != 0 -bool -check_suspend_flags(JitCompContext *cc, JITFuncContext *func_ctx) -{ - LLVMValueRef terminate_addr, terminate_flags, flag, offset, res; - JitBasicBlock *terminate_check_block, non_terminate_block; - JITFuncType *jit_func_type = func_ctx->jit_func->func_type; - JitBasicBlock *terminate_block; - - /* Offset of suspend_flags */ - offset = I32_FIVE; - - if (!(terminate_addr = LLVMBuildInBoundsGEP( - cc->builder, func_ctx->exec_env, &offset, 1, "terminate_addr"))) { - jit_set_last_error("llvm build in bounds gep failed"); - return false; - } - if (!(terminate_addr = - LLVMBuildBitCast(cc->builder, terminate_addr, INT32_PTR_TYPE, - "terminate_addr_ptr"))) { - jit_set_last_error("llvm build bit cast failed"); - return false; - } - - if (!(terminate_flags = - LLVMBuildLoad(cc->builder, terminate_addr, "terminate_flags"))) { - jit_set_last_error("llvm build bit cast failed"); - return false; - } - /* Set terminate_flags memory accecc to volatile, so that the value - will always be loaded from memory rather than register */ - LLVMSetVolatile(terminate_flags, true); - - CREATE_BASIC_BLOCK(terminate_check_block, "terminate_check"); - MOVE_BASIC_BLOCK_AFTER_CURR(terminate_check_block); - - CREATE_BASIC_BLOCK(non_terminate_block, "non_terminate"); - MOVE_BASIC_BLOCK_AFTER_CURR(non_terminate_block); - - BUILD_ICMP(LLVMIntSGT, terminate_flags, I32_ZERO, res, "need_terminate"); - BUILD_COND_BR(res, terminate_check_block, non_terminate_block); - - /* Move builder to terminate check block */ - SET_BUILDER_POS(terminate_check_block); - - CREATE_BASIC_BLOCK(terminate_block, "terminate"); - MOVE_BASIC_BLOCK_AFTER_CURR(terminate_block); - - if (!(flag = LLVMBuildAnd(cc->builder, terminate_flags, I32_ONE, - "termination_flag"))) { - jit_set_last_error("llvm build AND failed"); - return false; - } - - BUILD_ICMP(LLVMIntSGT, flag, I32_ZERO, res, "need_terminate"); - BUILD_COND_BR(res, terminate_block, non_terminate_block); - - /* Move builder to terminate block */ - SET_BUILDER_POS(terminate_block); - if (!jit_build_zero_function_ret(cc, func_ctx, jit_func_type)) { - goto fail; - } - - /* Move builder to terminate block */ - SET_BUILDER_POS(non_terminate_block); - return true; - -fail: - return false; -} -#endif /* End of WASM_ENABLE_THREAD_MGR */ -#endif diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index c554e200..86f4573c 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -423,6 +423,7 @@ wasm_runtime_get_module_hash(wasm_module_t module); * @param dir_list The list of directories to preopen. (real path) * @param dir_count The number of elements in dir_list. * @param map_dir_list The list of directories to preopen. (mapped path) + * Format for each map entry: :: * @param map_dir_count The number of elements in map_dir_list. * If map_dir_count is smaller than dir_count, * mapped path is assumed to be same as the diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 50860d3a..71b8644d 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -4009,10 +4009,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } #if WASM_ENABLE_FAST_JIT != 0 -/* ASAN is not designed to work with custom stack unwind or other low-level \ - things. > Ignore a function that does some low-level magic. (e.g. walking \ - through the thread's stack bypassing the frame boundaries) */ -#if defined(__GNUC__) +/* + * ASAN is not designed to work with custom stack unwind or other low-level + * things. Ignore a function that does some low-level magic. (e.g. walking + * through the thread's stack bypassing the frame boundaries) + */ +#if defined(__GNUC__) || defined(__clang__) __attribute__((no_sanitize_address)) #endif static void diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index e565c2c8..701886d6 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1128,12 +1128,27 @@ wasm_interp_dump_op_count() goto *p_label_addr; \ } while (0) #else -#define FETCH_OPCODE_AND_DISPATCH() \ - do { \ - const void *p_label_addr = label_base + *(int16 *)frame_ip; \ - frame_ip += sizeof(int16); \ - goto *p_label_addr; \ +#if UINTPTR_MAX == UINT64_MAX +#define FETCH_OPCODE_AND_DISPATCH() \ + do { \ + const void *p_label_addr; \ + bh_assert(((uintptr_t)frame_ip & 1) == 0); \ + /* int32 relative offset was emitted in 64-bit target */ \ + p_label_addr = label_base + (int32)LOAD_U32_WITH_2U16S(frame_ip); \ + frame_ip += sizeof(int32); \ + goto *p_label_addr; \ } while (0) +#else +#define FETCH_OPCODE_AND_DISPATCH() \ + do { \ + const void *p_label_addr; \ + bh_assert(((uintptr_t)frame_ip & 1) == 0); \ + /* uint32 label address was emitted in 32-bit target */ \ + p_label_addr = (void *)(uintptr_t)LOAD_U32_WITH_2U16S(frame_ip); \ + frame_ip += sizeof(int32); \ + goto *p_label_addr; \ + } while (0) +#endif #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ #define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH() @@ -1183,7 +1198,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */ register uint32 *frame_lp = NULL; /* cache of frame->lp */ #if WASM_ENABLE_LABELS_AS_VALUES != 0 -#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 +#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 && UINTPTR_MAX == UINT64_MAX /* cache of label base addr */ register uint8 *label_base = &&HANDLE_WASM_OP_UNREACHABLE; #endif diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index cf8b7719..9e88e205 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -173,7 +173,6 @@ fail: #define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p) #define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p) -#define read_bool(p) TEMPLATE_READ_VALUE(bool, p) #define read_leb_int64(p, p_end, res) \ do { \ @@ -490,6 +489,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, if (type != VALUE_TYPE_V128) goto fail_type_mismatch; + CHECK_BUF(p, p_end, 1); flag = read_uint8(p); (void)flag; @@ -1375,7 +1375,15 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory, return false; } if (memory->flags > 1) { - set_error_buf(error_buf, error_buf_size, "integer too large"); + if (memory->flags & 2) { + set_error_buf(error_buf, error_buf_size, + "shared memory flag was found, " + "please enable shared memory, lib-pthread " + "or lib-wasi-threads"); + } + else { + set_error_buf(error_buf, error_buf_size, "invalid memory flags"); + } return false; } #else @@ -5389,21 +5397,27 @@ fail: LOG_OP("\ndelete last op\n"); \ } while (0) #else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ +#if UINTPTR_MAX == UINT64_MAX #define emit_label(opcode) \ do { \ int32 offset = \ (int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \ - if (!(offset >= INT16_MIN && offset < INT16_MAX)) { \ - set_error_buf(error_buf, error_buf_size, \ - "pre-compiled label offset out of range"); \ - goto fail; \ - } \ - wasm_loader_emit_int16(loader_ctx, offset); \ + /* emit int32 relative offset in 64-bit target */ \ + wasm_loader_emit_uint32(loader_ctx, offset); \ LOG_OP("\nemit_op [%02x]\t", opcode); \ } while (0) +#else +#define emit_label(opcode) \ + do { \ + uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \ + /* emit uint32 label address in 32-bit target */ \ + wasm_loader_emit_uint32(loader_ctx, label_addr); \ + LOG_OP("\nemit_op [%02x]\t", opcode); \ + } while (0) +#endif #define skip_label() \ do { \ - wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \ + wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \ LOG_OP("\ndelete last op\n"); \ } while (0) #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ @@ -5733,12 +5747,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode, (void)error_buf; (void)error_buf_size; return true; -#if WASM_ENABLE_LABELS_AS_VALUES != 0 -#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 -fail: - return false; -#endif -#endif } static bool @@ -7130,6 +7138,7 @@ re_scan: BlockType block_type; p_org = p - 1; + CHECK_BUF(p, p_end, 1); value_type = read_uint8(p); if (is_byte_a_type(value_type)) { /* If the first byte is one of these special values: @@ -7793,6 +7802,9 @@ re_scan: uint8 ref_type; BranchBlock *cur_block = loader_ctx->frame_csp - 1; int32 available_stack_cell; +#if WASM_ENABLE_FAST_INTERP != 0 + uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled; +#endif POP_I32(); @@ -7821,26 +7833,26 @@ re_scan: #if WASM_ENABLE_FAST_INTERP != 0 if (loader_ctx->p_code_compiled) { uint8 opcode_tmp = WASM_OP_SELECT_64; - uint8 *p_code_compiled_tmp = - loader_ctx->p_code_compiled - 2; #if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 *(void **)(p_code_compiled_tmp - sizeof(void *)) = handle_table[opcode_tmp]; #else +#if UINTPTR_MAX == UINT64_MAX + /* emit int32 relative offset in 64-bit target + */ int32 offset = (int32)((uint8 *)handle_table[opcode_tmp] - (uint8 *)handle_table[0]); - if (!(offset >= INT16_MIN - && offset < INT16_MAX)) { - set_error_buf(error_buf, error_buf_size, - "pre-compiled label offset " - "out of range"); - goto fail; - } - *(int16 *)(p_code_compiled_tmp - - sizeof(int16)) = (int16)offset; + *(int32 *)(p_code_compiled_tmp + - sizeof(int32)) = offset; +#else + /* emit uint32 label address in 32-bit target */ + *(uint32 *)(p_code_compiled_tmp + - sizeof(uint32)) = + (uint32)(uintptr_t)handle_table[opcode_tmp]; +#endif #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ #else /* else of WASM_ENABLE_LABELS_AS_VALUES */ #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 @@ -7934,16 +7946,17 @@ re_scan: *(void **)(p_code_compiled_tmp - sizeof(void *)) = handle_table[opcode_tmp]; #else +#if UINTPTR_MAX == UINT64_MAX + /* emit int32 relative offset in 64-bit target */ int32 offset = (int32)((uint8 *)handle_table[opcode_tmp] - (uint8 *)handle_table[0]); - if (!(offset >= INT16_MIN && offset < INT16_MAX)) { - set_error_buf( - error_buf, error_buf_size, - "pre-compiled label offset out of range"); - goto fail; - } - *(int16 *)(p_code_compiled_tmp - sizeof(int16)) = - (int16)offset; + *(int32 *)(p_code_compiled_tmp - sizeof(int32)) = + offset; +#else + /* emit uint32 label address in 32-bit target */ + *(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) = + (uint32)(uintptr_t)handle_table[opcode_tmp]; +#endif #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ #else /* else of WASM_ENABLE_LABELS_AS_VALUES */ #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 @@ -9087,6 +9100,7 @@ re_scan: { uint32 opcode1; + CHECK_BUF(p, p_end, 1); opcode1 = read_uint8(p); /* follow the order of enum WASMSimdEXTOpcode in wasm_opcode.h */ @@ -9748,6 +9762,7 @@ re_scan: { uint32 opcode1; + CHECK_BUF(p, p_end, 1); opcode1 = read_uint8(p); #if WASM_ENABLE_FAST_INTERP != 0 emit_byte(loader_ctx, opcode1); diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index d16bc1a2..44aab265 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -4009,21 +4009,27 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf, LOG_OP("\ndelete last op\n"); \ } while (0) #else /* else of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ +#if UINTPTR_MAX == UINT64_MAX #define emit_label(opcode) \ do { \ int32 offset = \ (int32)((uint8 *)handle_table[opcode] - (uint8 *)handle_table[0]); \ - if (!(offset >= INT16_MIN && offset < INT16_MAX)) { \ - set_error_buf(error_buf, error_buf_size, \ - "pre-compiled label offset out of range"); \ - goto fail; \ - } \ - wasm_loader_emit_int16(loader_ctx, offset); \ + /* emit int32 relative offset in 64-bit target */ \ + wasm_loader_emit_uint32(loader_ctx, offset); \ LOG_OP("\nemit_op [%02x]\t", opcode); \ } while (0) +#else +#define emit_label(opcode) \ + do { \ + uint32 label_addr = (uint32)(uintptr_t)handle_table[opcode]; \ + /* emit uint32 label address in 32-bit target */ \ + wasm_loader_emit_uint32(loader_ctx, label_addr); \ + LOG_OP("\nemit_op [%02x]\t", opcode); \ + } while (0) +#endif #define skip_label() \ do { \ - wasm_loader_emit_backspace(loader_ctx, sizeof(int16)); \ + wasm_loader_emit_backspace(loader_ctx, sizeof(int32)); \ LOG_OP("\ndelete last op\n"); \ } while (0) #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ @@ -4351,13 +4357,6 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode, } return true; - -#if WASM_ENABLE_LABELS_AS_VALUES != 0 -#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 -fail: - return false; -#endif -#endif } static bool @@ -6146,6 +6145,9 @@ re_scan: uint8 ref_type; BranchBlock *cur_block = loader_ctx->frame_csp - 1; int32 available_stack_cell; +#if WASM_ENABLE_FAST_INTERP != 0 + uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled; +#endif POP_I32(); @@ -6168,26 +6170,26 @@ re_scan: #if WASM_ENABLE_FAST_INTERP != 0 if (loader_ctx->p_code_compiled) { uint8 opcode_tmp = WASM_OP_SELECT_64; - uint8 *p_code_compiled_tmp = - loader_ctx->p_code_compiled - 2; #if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 *(void **)(p_code_compiled_tmp - sizeof(void *)) = handle_table[opcode_tmp]; #else +#if UINTPTR_MAX == UINT64_MAX + /* emit int32 relative offset in 64-bit target + */ int32 offset = (int32)((uint8 *)handle_table[opcode_tmp] - (uint8 *)handle_table[0]); - if (!(offset >= INT16_MIN - && offset < INT16_MAX)) { - set_error_buf(error_buf, error_buf_size, - "pre-compiled label offset " - "out of range"); - goto fail; - } - *(int16 *)(p_code_compiled_tmp - - sizeof(int16)) = (int16)offset; + *(int32 *)(p_code_compiled_tmp + - sizeof(int32)) = offset; +#else + /* emit uint32 label address in 32-bit target */ + *(uint32 *)(p_code_compiled_tmp + - sizeof(uint32)) = + (uint32)(uintptr_t)handle_table[opcode_tmp]; +#endif #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ #else /* else of WASM_ENABLE_LABELS_AS_VALUES */ #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 @@ -6263,15 +6265,16 @@ re_scan: *(void **)(p_code_compiled_tmp - sizeof(void *)) = handle_table[opcode_tmp]; #else +#if UINTPTR_MAX == UINT64_MAX + /* emit int32 relative offset in 64-bit target */ int32 offset = (int32)((uint8 *)handle_table[opcode_tmp] - (uint8 *)handle_table[0]); - if (!(offset >= INT16_MIN && offset < INT16_MAX)) { - set_error_buf(error_buf, error_buf_size, - "pre-compiled label offset out of range"); - goto fail; - } - *(int16 *)(p_code_compiled_tmp - sizeof(int16)) = - (int16)offset; + *(int32 *)(p_code_compiled_tmp - sizeof(int32)) = offset; +#else + /* emit uint32 label address in 32-bit target */ + *(uint32 *)(p_code_compiled_tmp - sizeof(uint32)) = + (uint32)(uintptr_t)handle_table[opcode_tmp]; +#endif #endif /* end of WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS */ #else /* else of WASM_ENABLE_LABELS_AS_VALUES */ #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 81675563..af00b1c0 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -10,6 +10,7 @@ #include "bh_log.h" #include "mem_alloc.h" #include "../common/wasm_runtime_common.h" +#include "../common/wasm_memory.h" #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif @@ -167,7 +168,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, char *error_buf, uint32 error_buf_size) { WASMModule *module = module_inst->module; - uint64 memory_data_size; + uint64 memory_data_size, max_memory_data_size; uint32 heap_offset = num_bytes_per_page * init_page_count; uint32 inc_page_count, aux_heap_base, global_idx; uint32 bytes_of_last_page, bytes_to_page_end; @@ -275,6 +276,12 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, if (max_page_count > DEFAULT_MAX_PAGES) max_page_count = DEFAULT_MAX_PAGES; } + else { /* heap_size == 0 */ + if (init_page_count == DEFAULT_MAX_PAGES) { + num_bytes_per_page = UINT32_MAX; + init_page_count = max_page_count = 1; + } + } LOG_VERBOSE("Memory instantiate:"); LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u", @@ -282,22 +289,33 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size); memory_data_size = (uint64)num_bytes_per_page * init_page_count; -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (is_shared_memory) { - /* Allocate max page for shared memory */ - memory_data_size = (uint64)num_bytes_per_page * max_page_count; - } -#endif - bh_assert(memory_data_size <= 4 * (uint64)BH_GB); + max_memory_data_size = (uint64)num_bytes_per_page * max_page_count; + bh_assert(memory_data_size <= UINT32_MAX); + bh_assert(max_memory_data_size <= 4 * (uint64)BH_GB); + (void)max_memory_data_size; bh_assert(memory != NULL); #ifndef OS_ENABLE_HW_BOUND_CHECK - if (memory_data_size > 0 - && !(memory->memory_data = - runtime_malloc(memory_data_size, error_buf, error_buf_size))) { - goto fail1; +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (is_shared_memory) { + /* Allocate maximum memory size when memory is shared */ + if (max_memory_data_size > 0 + && !(memory->memory_data = runtime_malloc( + max_memory_data_size, error_buf, error_buf_size))) { + goto fail1; + } } -#else + else +#endif + { + /* Allocate initial memory size when memory is not shared */ + if (memory_data_size > 0 + && !(memory->memory_data = runtime_malloc( + memory_data_size, error_buf, error_buf_size))) { + goto fail1; + } + } +#else /* else of OS_ENABLE_HW_BOUND_CHECK */ memory_data_size = (memory_data_size + page_size - 1) & ~(page_size - 1); /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G: @@ -327,12 +345,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, set_error_buf(error_buf, error_buf_size, "mprotect memory failed"); goto fail2; } + /* Newly allocated pages are filled with zero by the OS, we don't fill it * again here */ -#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ if (memory_data_size > UINT32_MAX) - memory_data_size = (uint32)memory_data_size; + memory_data_size = UINT32_MAX; +#endif /* end of OS_ENABLE_HW_BOUND_CHECK */ memory->module_type = Wasm_Module_Bytecode; memory->num_bytes_per_page = num_bytes_per_page; @@ -360,26 +379,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent, } } -#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 if (memory_data_size > 0) { -#if UINTPTR_MAX == UINT64_MAX - memory->mem_bound_check_1byte.u64 = memory_data_size - 1; - memory->mem_bound_check_2bytes.u64 = memory_data_size - 2; - memory->mem_bound_check_4bytes.u64 = memory_data_size - 4; - memory->mem_bound_check_8bytes.u64 = memory_data_size - 8; - memory->mem_bound_check_16bytes.u64 = memory_data_size - 16; -#else - memory->mem_bound_check_1byte.u32[0] = (uint32)memory_data_size - 1; - memory->mem_bound_check_2bytes.u32[0] = (uint32)memory_data_size - 2; - memory->mem_bound_check_4bytes.u32[0] = (uint32)memory_data_size - 4; - memory->mem_bound_check_8bytes.u32[0] = (uint32)memory_data_size - 8; - memory->mem_bound_check_16bytes.u32[0] = (uint32)memory_data_size - 16; -#endif + wasm_runtime_set_mem_bound_check_bytes(memory, memory_data_size); } -#endif #if WASM_ENABLE_SHARED_MEMORY != 0 if (is_shared_memory) { + memory->is_shared_memory = true; memory->ref_count = 1; } #endif @@ -1780,6 +1786,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent, if (data_seg->is_passive) continue; #endif + if (is_sub_inst) + /* Ignore setting memory init data if the memory has been + initialized */ + continue; /* has check it in loader */ memory = module_inst->memories[data_seg->memory_index]; @@ -2473,15 +2483,20 @@ void wasm_module_free_internal(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, uint32 ptr) { + WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); + + if (!memory) { + return; + } + if (ptr) { - WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); - uint8 *addr; + uint8 *addr = memory->memory_data + ptr; + uint8 *memory_data_end; - if (!memory) { - return; - } - - addr = memory->memory_data + ptr; + /* memory->memory_data_end may be changed in memory grow */ + SHARED_MEMORY_LOCK(memory); + memory_data_end = memory->memory_data_end; + SHARED_MEMORY_UNLOCK(memory); if (memory->heap_handle && memory->heap_data <= addr && addr < memory->heap_data_end) { @@ -2489,7 +2504,7 @@ wasm_module_free_internal(WASMModuleInstance *module_inst, } else if (module_inst->e->malloc_function && module_inst->e->free_function && memory->memory_data <= addr - && addr < memory->memory_data_end) { + && addr < memory_data_end) { execute_free_function(module_inst, exec_env, module_inst->e->free_function, ptr); } @@ -3151,7 +3166,9 @@ llvm_jit_memory_init(WASMModuleInstance *module_inst, uint32 seg_index, maddr = wasm_runtime_addr_app_to_native( (WASMModuleInstanceCommon *)module_inst, dst); + SHARED_MEMORY_LOCK(memory_inst); bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len); + SHARED_MEMORY_UNLOCK(memory_inst); return true; } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index d6661fa0..7d78df14 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -79,8 +79,11 @@ typedef union { struct WASMMemoryInstance { /* Module type */ uint32 module_type; + + bool is_shared_memory; + /* Shared memory flag */ - bh_atomic_32_t ref_count; /* 0: non-shared, > 0: reference count */ + bh_atomic_16_t ref_count; /* 0: non-shared, > 0: reference count */ /* Number bytes per page */ uint32 num_bytes_per_page; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 03b262ca..9801a4c5 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -2644,8 +2644,8 @@ wasi_ssp_sock_open(wasm_exec_env_t exec_env, struct fd_table *curfds, bool is_tcp = SOCKET_DGRAM == socktype ? false : true; bool is_ipv4 = INET6 == af ? false : true; int ret; - __wasi_filetype_t wasi_type; - __wasi_rights_t max_base, max_inheriting; + __wasi_filetype_t wasi_type = __WASI_FILETYPE_UNKNOWN; + __wasi_rights_t max_base = 0, max_inheriting = 0; __wasi_errno_t error; (void)poolfd; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index 274979c3..bcc750c2 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -26,8 +26,8 @@ // On Linux, prefer to use getrandom, though it isn't available in // GLIBC before 2.25. -#if (defined(__linux__) || defined(ESP_PLATFORM)) \ - && (!defined(__GLIBC__) || __GLIBC__ > 2 \ +#if (defined(__linux__) || defined(ESP_PLATFORM) || defined(__COSMOPOLITAN__)) \ + && (!defined(__GLIBC__) || __GLIBC__ > 2 \ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)) #define CONFIG_HAS_GETRANDOM 1 #else diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index 98ccef80..157490a7 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -496,8 +496,14 @@ static os_thread_local_attribute bool thread_signal_inited = false; /* The signal alternate stack base addr */ static os_thread_local_attribute uint8 *sigalt_stack_base_addr; +/* + * ASAN is not designed to work with custom stack unwind or other low-level + * things. Ignore a function that does some low-level magic. (e.g. walking + * through the thread's stack bypassing the frame boundaries) + */ #if defined(__clang__) #pragma clang optimize off +__attribute__((no_sanitize_address)) #elif defined(__GNUC__) #pragma GCC push_options #pragma GCC optimize("O0") @@ -558,10 +564,12 @@ destroy_stack_guard_pages() } #endif /* end of WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 */ -/* ASAN is not designed to work with custom stack unwind or other low-level \ - things. > Ignore a function that does some low-level magic. (e.g. walking \ - through the thread's stack bypassing the frame boundaries) */ -#if defined(__GNUC__) +/* + * ASAN is not designed to work with custom stack unwind or other low-level + * things. Ignore a function that does some low-level magic. (e.g. walking + * through the thread's stack bypassing the frame boundaries) + */ +#if defined(__GNUC__) || defined(__clang__) __attribute__((no_sanitize_address)) #endif static void @@ -578,10 +586,12 @@ mask_signals(int how) static struct sigaction prev_sig_act_SIGSEGV; static struct sigaction prev_sig_act_SIGBUS; -/* ASAN is not designed to work with custom stack unwind or other low-level \ - things. > Ignore a function that does some low-level magic. (e.g. walking \ - through the thread's stack bypassing the frame boundaries) */ -#if defined(__GNUC__) +/* + * ASAN is not designed to work with custom stack unwind or other low-level + * things. Ignore a function that does some low-level magic. (e.g. walking + * through the thread's stack bypassing the frame boundaries) + */ +#if defined(__GNUC__) || defined(__clang__) __attribute__((no_sanitize_address)) #endif static void diff --git a/core/shared/utils/bh_atomic.h b/core/shared/utils/bh_atomic.h index 64dfee1b..ac3417c3 100644 --- a/core/shared/utils/bh_atomic.h +++ b/core/shared/utils/bh_atomic.h @@ -45,6 +45,7 @@ extern "C" { */ typedef uint32 bh_atomic_32_t; +typedef uint16 bh_atomic_16_t; #if defined(__GNUC_PREREQ) #if __GNUC_PREREQ(4, 7) @@ -59,6 +60,7 @@ typedef uint32 bh_atomic_32_t; #if defined(CLANG_GCC_HAS_ATOMIC_BUILTIN) #define BH_ATOMIC_32_IS_ATOMIC 1 #define BH_ATOMIC_32_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_32_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST) #define BH_ATOMIC_32_FETCH_OR(v, val) \ __atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST) #define BH_ATOMIC_32_FETCH_AND(v, val) \ @@ -67,13 +69,33 @@ typedef uint32 bh_atomic_32_t; __atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST) #define BH_ATOMIC_32_FETCH_SUB(v, val) \ __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST) + +#define BH_ATOMIC_16_IS_ATOMIC 1 +#define BH_ATOMIC_16_LOAD(v) __atomic_load_n(&(v), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_STORE(v, val) __atomic_store_n(&(v), val, __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_OR(v, val) \ + __atomic_fetch_or(&(v), (val), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_AND(v, val) \ + __atomic_fetch_and(&(v), (val), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_ADD(v, val) \ + __atomic_fetch_add(&(v), (val), __ATOMIC_SEQ_CST) +#define BH_ATOMIC_16_FETCH_SUB(v, val) \ + __atomic_fetch_sub(&(v), (val), __ATOMIC_SEQ_CST) #else /* else of defined(CLANG_GCC_HAS_ATOMIC_BUILTIN) */ #define BH_ATOMIC_32_LOAD(v) (v) +#define BH_ATOMIC_32_STORE(v, val) (v) = val #define BH_ATOMIC_32_FETCH_OR(v, val) nonatomic_32_fetch_or(&(v), val) #define BH_ATOMIC_32_FETCH_AND(v, val) nonatomic_32_fetch_and(&(v), val) #define BH_ATOMIC_32_FETCH_ADD(v, val) nonatomic_32_fetch_add(&(v), val) #define BH_ATOMIC_32_FETCH_SUB(v, val) nonatomic_32_fetch_sub(&(v), val) +#define BH_ATOMIC_16_LOAD(v) (v) +#define BH_ATOMIC_16_STORE(v) (v) = val +#define BH_ATOMIC_16_FETCH_OR(v, val) nonatomic_16_fetch_or(&(v), val) +#define BH_ATOMIC_16_FETCH_AND(v, val) nonatomic_16_fetch_and(&(v), val) +#define BH_ATOMIC_16_FETCH_ADD(v, val) nonatomic_16_fetch_add(&(v), val) +#define BH_ATOMIC_16_FETCH_SUB(v, val) nonatomic_16_fetch_sub(&(v), val) + static inline uint32 nonatomic_32_fetch_or(bh_atomic_32_t *p, uint32 val) { @@ -106,6 +128,38 @@ nonatomic_32_fetch_sub(bh_atomic_32_t *p, uint32 val) return old; } +static inline uint16 +nonatomic_16_fetch_or(bh_atomic_16_t *p, uint16 val) +{ + uint16 old = *p; + *p |= val; + return old; +} + +static inline uint16 +nonatomic_16_fetch_and(bh_atomic_16_t *p, uint16 val) +{ + uint16 old = *p; + *p &= val; + return old; +} + +static inline uint16 +nonatomic_16_fetch_add(bh_atomic_16_t *p, uint16 val) +{ + uint16 old = *p; + *p += val; + return old; +} + +static inline uint16 +nonatomic_16_fetch_sub(bh_atomic_16_t *p, uint16 val) +{ + uint16 old = *p; + *p -= val; + return old; +} + /* The flag can be defined by the user if the platform supports atomic access to uint32 aligned memory. */ #ifdef WASM_UINT32_IS_ATOMIC @@ -114,6 +168,12 @@ nonatomic_32_fetch_sub(bh_atomic_32_t *p, uint32 val) #define BH_ATOMIC_32_IS_ATOMIC 0 #endif /* WASM_UINT32_IS_ATOMIC */ +#ifdef WASM_UINT16_IS_ATOMIC +#define BH_ATOMIC_16_IS_ATOMIC 1 +#else /* else of WASM_UINT16_IS_ATOMIC */ +#define BH_ATOMIC_16_IS_ATOMIC 0 +#endif /* WASM_UINT16_IS_ATOMIC */ + #endif #ifdef __cplusplus diff --git a/language-bindings/go/go.mod b/language-bindings/go/go.mod index 60afebbf..b7e42865 100644 --- a/language-bindings/go/go.mod +++ b/language-bindings/go/go.mod @@ -1,4 +1,4 @@ -module gitlab.alipay-inc.com/TNT_Runtime/ant-runtime/bindings/go +module github.com/bytecodealliance/wasm-micro-runtime/language-bindings/go go 1.15 diff --git a/language-bindings/go/samples/build.sh b/language-bindings/go/samples/build.sh index 1b0a8071..0799fe5a 100755 --- a/language-bindings/go/samples/build.sh +++ b/language-bindings/go/samples/build.sh @@ -3,19 +3,11 @@ # Copyright (C) 2019 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -PLATFORM=$(uname -s | tr A-Z a-z) CUR_DIR=$PWD -WAMR_DIR=$PWD/../../.. -WAMR_GO_DIR=$PWD/../wamr -cp -a ${WAMR_DIR}/core/iwasm/include/*.h ${WAMR_GO_DIR}/packaged/include - -mkdir -p build && cd build -cmake ${WAMR_DIR}/product-mini/platforms/${PLATFORM} \ - -DWAMR_BUILD_LIB_PTHREAD=1 -DWAMR_BUILD_DUMP_CALL_STACK=1 \ - -DWAMR_BUILD_MEMORY_PROFILING=1 -make -j ${nproc} -cp -a libvmlib.a ${WAMR_GO_DIR}/packaged/lib/${PLATFORM}-amd64 +pushd ${CUR_DIR}/.. > /dev/null 2>&1 +./build.sh +popd > /dev/null 2>& 1 cd ${CUR_DIR} rm -f test diff --git a/language-bindings/go/samples/test.go b/language-bindings/go/samples/test.go index aacb4a95..d0fc7d8b 100644 --- a/language-bindings/go/samples/test.go +++ b/language-bindings/go/samples/test.go @@ -6,7 +6,7 @@ package main import ( - "gitlab.alipay-inc.com/TNT_Runtime/ant-runtime/bindings/go/wamr" + "github.com/bytecodealliance/wasm-micro-runtime/language-bindings/go/wamr" "fmt" ) diff --git a/language-bindings/go/wamr/instance.go b/language-bindings/go/wamr/instance.go index 08757f4d..7c761ee9 100644 --- a/language-bindings/go/wamr/instance.go +++ b/language-bindings/go/wamr/instance.go @@ -272,7 +272,9 @@ func (self *Instance) CallFuncV(funcName string, for i = 0; i < result_count; i++ { switch result_types[i] { case C.WASM_I32: + fallthrough case C.WASM_FUNCREF: + fallthrough case C.WASM_ANYREF: i32 := (int32)(argv[argc]) results[i] = i32 diff --git a/product-mini/platforms/common/libc_wasi.c b/product-mini/platforms/common/libc_wasi.c index 0fd2443c..4bcb1d27 100644 --- a/product-mini/platforms/common/libc_wasi.c +++ b/product-mini/platforms/common/libc_wasi.c @@ -11,6 +11,8 @@ typedef struct { const char *dir_list[8]; uint32 dir_list_size; + const char *map_dir_list[8]; + uint32 map_dir_list_size; const char *env_list[8]; uint32 env_list_size; const char *addr_pool[8]; @@ -37,6 +39,12 @@ libc_wasi_print_help() "directories\n"); printf(" to the program, for example:\n"); printf(" --dir= --dir=\n"); + printf(" --map-dir= Grant wasi access to the given host " + "directories\n"); + printf(" to the program at a specific guest " + "path, for example:\n"); + printf(" --map-dir= " + "--map-dir=\n"); printf(" --addr-pool= Grant wasi access to the given network " "addresses in\n"); printf(" CIRD notation to the program, seperated " @@ -84,6 +92,17 @@ libc_wasi_parse(char *arg, libc_wasi_parse_context_t *ctx) } ctx->dir_list[ctx->dir_list_size++] = arg + 6; } + else if (!strncmp(arg, "--map-dir=", 10)) { + if (arg[10] == '\0') + return LIBC_WASI_PARSE_RESULT_NEED_HELP; + if (ctx->map_dir_list_size + >= sizeof(ctx->map_dir_list) / sizeof(char *)) { + printf("Only allow max map dir number %d\n", + (int)(sizeof(ctx->map_dir_list) / sizeof(char *))); + return 1; + } + ctx->map_dir_list[ctx->map_dir_list_size++] = arg + 10; + } else if (!strncmp(arg, "--env=", 6)) { char *tmp_env; @@ -145,8 +164,8 @@ libc_wasi_init(wasm_module_t wasm_module, int argc, char **argv, libc_wasi_parse_context_t *ctx) { wasm_runtime_set_wasi_args(wasm_module, ctx->dir_list, ctx->dir_list_size, - NULL, 0, ctx->env_list, ctx->env_list_size, argv, - argc); + ctx->map_dir_list, ctx->map_dir_list_size, + ctx->env_list, ctx->env_list_size, argv, argc); wasm_runtime_set_wasi_addr_pool(wasm_module, ctx->addr_pool, ctx->addr_pool_size); diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index fc8f791c..d8076ead 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -194,8 +194,11 @@ app_instance_repl(wasm_module_inst_t module_inst) break; } if (app_argc != 0) { + const char *exception; wasm_application_execute_func(module_inst, app_argv[0], app_argc - 1, app_argv + 1); + if ((exception = wasm_runtime_get_exception(module_inst))) + printf("%s\n", exception); } free(app_argv); } @@ -406,7 +409,7 @@ module_reader_callback(package_type_t module_type, const char *module_name, const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) + strlen(file_format) + 1; - char *wasm_file_name = BH_MALLOC(sz); + char *wasm_file_name = wasm_runtime_malloc(sz); if (!wasm_file_name) { return false; } @@ -432,7 +435,37 @@ moudle_destroyer(uint8 *buffer, uint32 size) #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0 static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 }; +#else +static void * +malloc_func( +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + void *user_data, #endif + unsigned int size) +{ + return malloc(size); +} + +static void * +realloc_func( +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + void *user_data, +#endif + void *ptr, unsigned int size) +{ + return realloc(ptr, size); +} + +static void +free_func( +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + void *user_data, +#endif + void *ptr) +{ + free(ptr); +} +#endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */ #if WASM_ENABLE_STATIC_PGO != 0 static void @@ -764,9 +797,13 @@ main(int argc, char *argv[]) init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); #else init_args.mem_alloc_type = Alloc_With_Allocator; - init_args.mem_alloc_option.allocator.malloc_func = malloc; - init_args.mem_alloc_option.allocator.realloc_func = realloc; - init_args.mem_alloc_option.allocator.free_func = free; +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + /* Set user data for the allocator is needed */ + /* init_args.mem_alloc_option.allocator.user_data = user_data; */ +#endif + init_args.mem_alloc_option.allocator.malloc_func = malloc_func; + init_args.mem_alloc_option.allocator.realloc_func = realloc_func; + init_args.mem_alloc_option.allocator.free_func = free_func; #endif #if WASM_ENABLE_FAST_JIT != 0 diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 2be3e36f..98b33ffb 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -161,8 +161,11 @@ app_instance_repl(wasm_module_inst_t module_inst) break; } if (app_argc != 0) { + const char *exception; wasm_application_execute_func(module_inst, app_argv[0], app_argc - 1, app_argv + 1); + if ((exception = wasm_runtime_get_exception(module_inst))) + printf("%s\n", exception); } free(app_argv); } @@ -172,7 +175,37 @@ app_instance_repl(wasm_module_inst_t module_inst) #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0 static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 }; +#else +static void * +malloc_func( +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + void *user_data, #endif + unsigned int size) +{ + return malloc(size); +} + +static void * +realloc_func( +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + void *user_data, +#endif + void *ptr, unsigned int size) +{ + return realloc(ptr, size); +} + +static void +free_func( +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + void *user_data, +#endif + void *ptr) +{ + free(ptr); +} +#endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */ #if WASM_ENABLE_MULTI_MODULE != 0 static char * @@ -200,7 +233,7 @@ module_reader_callback(package_type_t module_type, const char *module_name, const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) + strlen(file_format) + 1; - char *wasm_file_name = BH_MALLOC(sz); + char *wasm_file_name = wasm_runtime_malloc(sz); if (!wasm_file_name) { return false; } @@ -414,9 +447,13 @@ main(int argc, char *argv[]) init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf); #else init_args.mem_alloc_type = Alloc_With_Allocator; - init_args.mem_alloc_option.allocator.malloc_func = malloc; - init_args.mem_alloc_option.allocator.realloc_func = realloc; - init_args.mem_alloc_option.allocator.free_func = free; +#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 + /* Set user data for the allocator is needed */ + /* init_args.mem_alloc_option.allocator.user_data = user_data; */ +#endif + init_args.mem_alloc_option.allocator.malloc_func = malloc_func; + init_args.mem_alloc_option.allocator.realloc_func = realloc_func; + init_args.mem_alloc_option.allocator.free_func = free_func; #endif #if WASM_ENABLE_JIT != 0 diff --git a/product-mini/platforms/zephyr/simple/src/main.c b/product-mini/platforms/zephyr/simple/src/main.c index 8799e737..f7ae7b0a 100644 --- a/product-mini/platforms/zephyr/simple/src/main.c +++ b/product-mini/platforms/zephyr/simple/src/main.c @@ -248,7 +248,7 @@ fail1: end = k_uptime_get_32(); - printf("elpase: %d\n", (end - start)); + printf("elapsed: %d\n", (end - start)); } #define MAIN_THREAD_STACK_SIZE (CONFIG_MAIN_THREAD_STACK_SIZE) diff --git a/samples/gui/wasm-apps/decrease/src/main.c b/samples/gui/wasm-apps/decrease/src/main.c index a6c30aa1..9635ebea 100644 --- a/samples/gui/wasm-apps/decrease/src/main.c +++ b/samples/gui/wasm-apps/decrease/src/main.c @@ -46,14 +46,14 @@ on_init() count_label = lv_label_create(NULL, NULL); lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); - btn1 = lv_btn_create( - NULL, NULL); /*Create a button on the currently loaded screen*/ - lv_obj_set_event_cb( - btn1, - btn_event_cb); /*Set function to be called when the button is released*/ - lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align below the label*/ + /* Create a button on the currently loaded screen */ + btn1 = lv_btn_create(NULL, NULL); + /* Set function to be called when the button is released */ + lv_obj_set_event_cb(btn1, (lv_event_cb_t)btn_event_cb); + /* Align below the label */ + lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); - /*Create a label on the button*/ + /* Create a label on the button */ lv_obj_t *btn_label = lv_label_create(btn1, NULL); lv_label_set_text(btn_label, "Click --"); @@ -61,7 +61,7 @@ on_init() lv_label_set_text(label_count1, "100"); lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - /* set up a timer */ + /* Set up a timer */ user_timer_t timer; timer = api_timer_create(10, true, false, timer1_update); if (timer) diff --git a/samples/gui/wasm-apps/increase/src/main.c b/samples/gui/wasm-apps/increase/src/main.c index b5271830..31118f7b 100644 --- a/samples/gui/wasm-apps/increase/src/main.c +++ b/samples/gui/wasm-apps/increase/src/main.c @@ -46,14 +46,14 @@ on_init() count_label = lv_label_create(NULL, NULL); lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); - btn1 = lv_btn_create( - NULL, NULL); /*Create a button on the currently loaded screen*/ - lv_obj_set_event_cb( - btn1, - btn_event_cb); /*Set function to be called when the button is released*/ - lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align below the label*/ + /* Create a button on the current loaded screen */ + btn1 = lv_btn_create(NULL, NULL); + /* Set function to be called when the button is released */ + lv_obj_set_event_cb(btn1, (lv_event_cb_t)btn_event_cb); + /* Align below the label */ + lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); - /*Create a label on the button*/ + /* Create a label on the button */ lv_obj_t *btn_label = lv_label_create(btn1, NULL); lv_label_set_text(btn_label, "Click ++"); @@ -61,7 +61,7 @@ on_init() lv_label_set_text(label_count1, "1"); lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); - /* set up a timer */ + /* Set up a timer */ user_timer_t timer; timer = api_timer_create(10, true, false, timer1_update); if (timer) diff --git a/samples/multi-module/src/main.c b/samples/multi-module/src/main.c index 36185613..c63cf6b8 100644 --- a/samples/multi-module/src/main.c +++ b/samples/multi-module/src/main.c @@ -11,7 +11,7 @@ static bool module_reader_callback(package_type_t module_type, const char *module_name, uint8 **p_buffer, uint32 *p_size) { - char *file_format; + char *file_format = NULL; #if WASM_ENABLE_INTERP != 0 if (module_type == Wasm_Module_Bytecode) file_format = ".wasm"; @@ -21,10 +21,11 @@ module_reader_callback(package_type_t module_type, const char *module_name, file_format = ".aot"; #endif + bh_assert(file_format != NULL); const char *format = "%s/%s%s"; int sz = strlen(module_search_path) + strlen("/") + strlen(module_name) + strlen(file_format) + 1; - char *wasm_file_name = BH_MALLOC(sz); + char *wasm_file_name = wasm_runtime_malloc(sz); if (!wasm_file_name) { return false; } diff --git a/tests/wamr-compiler/test_shift_negative_constants.wat b/tests/wamr-compiler/test_shift_negative_constants.wat index 030cc898..83bc3c44 100644 --- a/tests/wamr-compiler/test_shift_negative_constants.wat +++ b/tests/wamr-compiler/test_shift_negative_constants.wat @@ -7,6 +7,7 @@ ;; any problems. See: https://github.com/bytecodealliance/wasm-micro-runtime/pull/2619 (module (memory (export "memory") 1 1) + (func $assert_eq (param i32 i32) (i32.ne (local.get 0) (local.get 1)) if @@ -23,7 +24,7 @@ (func $i32_shr_s (call $assert_eq - (i32.shr_u (i32.const 32) (i32.const -30)) + (i32.shr_s (i32.const 32) (i32.const -30)) (i32.const 8) ) ) @@ -35,9 +36,43 @@ ) ) + (func $const_ret (result i32) + i32.const -5 + ) + + ;; *_func_call tests validate the potential LLVM optimizations + ;; where the right parameter of the shift operation is an + ;; indirect constant value. + (func $i32_shr_u_func_call + (call $assert_eq + (i32.shr_u (i32.const -1) (call $const_ret)) + (i32.const 31) + ) + ) + + (func $i32_shr_s_func_call + (call $assert_eq + (i32.shr_s + (i32.const 1073741824) ;; 2^30 + (call $const_ret) + ) + (i32.const 8) + ) + ) + + (func $i32_shl_func_call + (call $assert_eq + (i32.shl (i32.const -1) (call $const_ret)) + (i32.const -134217728) + ) + ) + (func (export "_start") call $i32_shr_u call $i32_shr_s call $i32_shl + call $i32_shr_u_func_call + call $i32_shr_s_func_call + call $i32_shl_func_call ) ) diff --git a/tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch b/tests/wamr-test-suites/spec-test-script/multi_module_aot_ignore_cases.patch similarity index 100% rename from tests/wamr-test-suites/spec-test-script/muti_module_aot_ignore_cases.patch rename to tests/wamr-test-suites/spec-test-script/multi_module_aot_ignore_cases.patch diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index e23f7e68..d7991ddf 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -32,6 +32,7 @@ function help() echo "-F set the firmware path used by qemu" echo "-C enable code coverage collect" echo "-j set the platform to test" + echo "-T set sanitizer to use in tests(ubsan|tsan|asan)" } OPT_PARSED="" @@ -65,7 +66,7 @@ QEMU_FIRMWARE="" # prod/testsuite-all branch WASI_TESTSUITE_COMMIT="ee807fc551978490bf1c277059aabfa1e589a6c2" -while getopts ":s:cabgvt:m:MCpSXxwPGQF:j:" opt +while getopts ":s:cabgvt:m:MCpSXxwPGQF:j:T:" opt do OPT_PARSED="TRUE" case $opt in @@ -171,9 +172,14 @@ do echo "test platform " ${OPTARG} PLATFORM=${OPTARG} ;; + T) + echo "sanitizer is " ${OPTARG} + WAMR_BUILD_SANITIZER=${OPTARG} + ;; ?) help - exit 1;; + exit 1 + ;; esac done @@ -395,7 +401,7 @@ function spec_test() git apply ../../spec-test-script/simd_ignore_cases.patch fi if [[ ${ENABLE_MULTI_MODULE} == 1 && $1 == 'aot' ]]; then - git apply ../../spec-test-script/muti_module_aot_ignore_cases.patch + git apply ../../spec-test-script/multi_module_aot_ignore_cases.patch fi # udpate thread cases @@ -566,7 +572,7 @@ function wasi_certification_test() cd wasi-testsuite git reset --hard ${WASI_TESTSUITE_COMMIT} - bash ../../wasi-test-script/run_wasi_tests.sh $1 $TARGET $WASI_TEST_FILTER \ + TSAN_OPTIONS=${TSAN_OPTIONS} bash ../../wasi-test-script/run_wasi_tests.sh $1 $TARGET $WASI_TEST_FILTER \ | tee -a ${REPORT_DIR}/wasi_test_report.txt ret=${PIPESTATUS[0]} diff --git a/tests/wamr-test-suites/tsan_suppressions.txt b/tests/wamr-test-suites/tsan_suppressions.txt new file mode 100644 index 00000000..079fcd05 --- /dev/null +++ b/tests/wamr-test-suites/tsan_suppressions.txt @@ -0,0 +1,11 @@ +# Proposing to accept this risk for now. It might be wasi-libc related. +# https://github.com/bytecodealliance/wasm-micro-runtime/pull/1963#issuecomment-1455342931 +race:STORE_U32 + + +# https://github.com/bytecodealliance/wasm-micro-runtime/issues/2680 +race:execute_post_instantiate_functions + +# Suppressing signal-unsafe inside of a signal for AOT mode +# see https://github.com/bytecodealliance/wasm-micro-runtime/issues/2248#issuecomment-1630189656 +signal:* \ No newline at end of file diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index 56d0a06b..4cfe6c29 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -108,11 +108,11 @@ if [[ $MODE != "aot" ]];then TEST_OPTIONS="${TEST_OPTIONS} --exclude-filter ${TEST_FILTER}" fi - $PYTHON_EXE ${THIS_DIR}/pipe.py | $PYTHON_EXE test-runner/wasi_test_runner.py $TEST_OPTIONS + $PYTHON_EXE ${THIS_DIR}/pipe.py | TSAN_OPTIONS=${TSAN_OPTIONS} $PYTHON_EXE test-runner/wasi_test_runner.py $TEST_OPTIONS ret=${PIPESTATUS[1]} - TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" $PYTHON_EXE test-runner/wasi_test_runner.py \ + TEST_RUNTIME_EXE="${IWASM_CMD_STRESS}" TSAN_OPTIONS=${TSAN_OPTIONS} $PYTHON_EXE test-runner/wasi_test_runner.py \ -r adapters/wasm-micro-runtime.py \ -t \ ${THREAD_STRESS_TESTS} @@ -120,9 +120,9 @@ if [[ $MODE != "aot" ]];then if [ "${ret}" -eq 0 ]; then ret=${PIPESTATUS[0]} fi - + exit_code=${ret} - + deactivate else target_option=""