diff --git a/.github/workflows/compilation_on_android_ubuntu_macos.yml b/.github/workflows/compilation_on_android_ubuntu_macos.yml index d15d0649e..becc0881c 100644 --- a/.github/workflows/compilation_on_android_ubuntu_macos.yml +++ b/.github/workflows/compilation_on_android_ubuntu_macos.yml @@ -214,6 +214,7 @@ jobs: "-DWAMR_BUILD_SIMD=1", "-DWAMR_BUILD_TAIL_CALL=1", "-DWAMR_DISABLE_HW_BOUND_CHECK=1", + "-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1", ] os: [ubuntu-18.04, ubuntu-20.04, macos-latest] platform: [android, linux, darwin] diff --git a/.github/workflows/compilation_on_sgx.yml b/.github/workflows/compilation_on_sgx.yml index 621ed953d..f04168389 100644 --- a/.github/workflows/compilation_on_sgx.yml +++ b/.github/workflows/compilation_on_sgx.yml @@ -139,6 +139,7 @@ jobs: # "-DWAMR_BUILD_SIMD=1", "-DWAMR_BUILD_TAIL_CALL=1", "-DWAMR_DISABLE_HW_BOUND_CHECK=1", + "-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1", ] os: [ubuntu-20.04] platform: [linux-sgx] @@ -160,7 +161,7 @@ jobs: - name: install SGX SDK and necessary libraries if: ${{ matrix.light == 'green' }} run: | - mkdir -p /opt/intel + mkdir -p /opt/intel cd /opt/intel wget https://download.01.org/intel-sgx/sgx-linux/2.15/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.15.100.3.bin chmod +x sgx_linux_x64_sdk_2.15.100.3.bin @@ -256,7 +257,7 @@ jobs: - name: install SGX SDK and necessary libraries if: ${{ matrix.light == 'green' }} run: | - mkdir -p /opt/intel + mkdir -p /opt/intel cd /opt/intel wget https://download.01.org/intel-sgx/sgx-linux/2.15/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.15.100.3.bin chmod +x sgx_linux_x64_sdk_2.15.100.3.bin @@ -347,7 +348,7 @@ jobs: - name: install SGX SDK and necessary libraries if: ${{ matrix.light == 'green' }} run: | - mkdir -p /opt/intel + mkdir -p /opt/intel cd /opt/intel wget https://download.01.org/intel-sgx/sgx-linux/2.15/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.15.100.3.bin chmod +x sgx_linux_x64_sdk_2.15.100.3.bin @@ -444,7 +445,7 @@ jobs: - name: install SGX SDK and necessary libraries if: ${{ matrix.light == 'green' }} run: | - mkdir -p /opt/intel + mkdir -p /opt/intel cd /opt/intel wget https://download.01.org/intel-sgx/sgx-linux/2.15/distro/ubuntu20.04-server/sgx_linux_x64_sdk_2.15.100.3.bin chmod +x sgx_linux_x64_sdk_2.15.100.3.bin diff --git a/README.md b/README.md index 4645bc4f7..dac63583a 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Getting started ================== - [Build iwasm VM core](./doc/build_wamr.md) on [Linux](./doc/build_wamr.md#linux), [SGX](./doc/linux_sgx.md), [MacOS](./doc/build_wamr.md#macos) and [Windows](./doc/build_wamr.md#windows), and [Build wamrc AOT compiler](./README.md#build-wamrc-aot-compiler) - [Embed WAMR into host applications](./doc/embed_wamr.md) + - [Embed into C/C++](./doc/embed_wamr.md), [Embed into Python](./language-bindings/python), [Embed into Go](./language-bindings/go) + - [Register native APIs for WASM applications](./doc/export_native_api.md) - [Build WASM applications](./doc/build_wasm_app.md) - [Port WAMR to a new platform](./doc/port_wamr.md) diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 432acf581..be5ca9e81 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -257,3 +257,7 @@ endif () if (WAMR_BUILD_DEBUG_AOT EQUAL 1) message (" Debug AOT enabled") endif () +if (WAMR_BUILD_LOAD_CUSTOM_SECTION EQUAL 1) + add_definitions (-DWASM_ENABLE_LOAD_CUSTOM_SECTION=1) + message (" Load custom section enabled") +endif () diff --git a/core/config.h b/core/config.h index 49b1f3e2d..db2819241 100644 --- a/core/config.h +++ b/core/config.h @@ -168,6 +168,11 @@ #define WASM_ENABLE_DEBUG_AOT 0 #endif +/* Custom sections */ +#ifndef WASM_ENABLE_LOAD_CUSTOM_SECTION +#define WASM_ENABLE_LOAD_CUSTOM_SECTION 0 +#endif + /* WASM log system */ #ifndef WASM_ENABLE_LOG #define WASM_ENABLE_LOG 1 diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index d7728707f..b1dbe7940 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -14,6 +14,7 @@ #include "../compilation/aot_llvm.h" #include "../interpreter/wasm_loader.h" #endif + #if WASM_ENABLE_DEBUG_AOT != 0 #include "debug/elf_parser.h" #include "debug/jit_debug.h" @@ -674,6 +675,36 @@ load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module, error_buf, error_buf_size)) goto fail; break; +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + case AOT_CUSTOM_SECTION_RAW: + { + const char *section_name; + WASMCustomSection *section; + + if (p >= p_end) { + set_error_buf(error_buf, error_buf_size, "unexpected end"); + goto fail; + } + + read_string(p, p_end, section_name); + + section = loader_malloc(sizeof(WASMCustomSection), error_buf, + error_buf_size); + if (!section) { + goto fail; + } + + section->name_addr = (char *)section_name; + section->name_len = strlen(section_name); + section->content_addr = (uint8 *)p; + section->content_len = p_end - p; + + section->next = module->custom_section_list; + module->custom_section_list = section; + LOG_VERBOSE("Load custom section [%s] success.", section_name); + break; + } +#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */ default: break; } @@ -3261,6 +3292,10 @@ aot_unload(AOTModule *module) } #endif +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + wasm_runtime_destroy_custom_sections(module->custom_section_list); +#endif + wasm_runtime_free(module); } @@ -3269,3 +3304,24 @@ aot_get_plt_table_size() { return get_plt_table_size(); } + +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +const uint8 * +aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len) +{ + WASMCustomSection *section = module->custom_section_list; + + while (section) { + if (strcmp(section->name_addr, name) == 0) { + if (len) { + *len = section->content_len; + } + return section->content_addr; + } + + section = section->next; + } + + return NULL; +} +#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */ diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 1ab325c3d..0aa4edeae 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -50,6 +50,7 @@ typedef enum AOTSectionType { } AOTSectionType; typedef enum AOTCustomSectionType { + AOT_CUSTOM_SECTION_RAW = 0, AOT_CUSTOM_SECTION_NATIVE_SYMBOL = 1, AOT_CUSTOM_SECTION_ACCESS_CONTROL = 2, AOT_CUSTOM_SECTION_NAME = 3, @@ -268,6 +269,9 @@ typedef struct AOTModule { uint32 *aux_func_indexes; uint32 aux_func_name_count; #endif +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + WASMCustomSection *custom_section_list; +#endif } AOTModule; typedef union { @@ -733,6 +737,9 @@ aot_dump_call_stack(WASMExecEnv *exec_env); void aot_dump_perf_profiling(const AOTModuleInstance *module_inst); +const uint8 * +aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len); + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 2f7b471e1..35584319a 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1274,10 +1274,6 @@ val_type_to_val_kind(uint8 value_type) case VALUE_TYPE_EXTERNREF: return WASM_ANYREF; default: -#if WASM_ENABLE_GC != 0 - if (wasm_is_type_reftype(value_type)) - return WASM_ANYREF; -#endif bh_assert(0); return 0; } @@ -2847,6 +2843,24 @@ wasm_exec_env_get_module(WASMExecEnv *exec_env) return NULL; } +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +const uint8 * +wasm_runtime_get_custom_section(WASMModuleCommon *const module_comm, + const char *name, uint32 *len) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_comm->module_type == Wasm_Module_Bytecode) + return wasm_loader_get_custom_section((WASMModule *)module_comm, name, + len); +#endif +#if WASM_ENABLE_AOT != 0 + if (module_comm->module_type == Wasm_Module_AoT) + return aot_get_custom_section((AOTModule *)module_comm, name, len); +#endif + return NULL; +} +#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */ + static union { int a; char b; @@ -4891,3 +4905,16 @@ wasm_runtime_show_app_heap_corrupted_prompt() "compiled by asc, please add --exportRuntime to " "export the runtime helpers."); } + +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +void +wasm_runtime_destroy_custom_sections(WASMCustomSection *section_list) +{ + WASMCustomSection *section = section_list, *next; + while (section) { + next = section->next; + wasm_runtime_free(section); + section = next; + } +} +#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */ diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index bb3e28405..7ef8f69c1 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -658,6 +658,11 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst, uint8 **p_native_start_addr, uint8 **p_native_end_addr); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN const uint8 * +wasm_runtime_get_custom_section(WASMModuleCommon *const module_comm, + const char *name, uint32 *len); + uint32 wasm_runtime_get_temp_ret(WASMModuleInstanceCommon *module_inst); @@ -879,6 +884,11 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst, void wasm_runtime_show_app_heap_corrupted_prompt(); +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +void +wasm_runtime_destroy_custom_sections(WASMCustomSection *section_list); +#endif + #ifdef __cplusplus } #endif diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index dacb59c69..e6d070545 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -877,11 +877,15 @@ get_native_symbol_list_size(AOTCompContext *comp_ctx) static uint32 get_name_section_size(AOTCompData *comp_data); +static uint32 +get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data); + static uint32 get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data, AOTObjectData *obj_data) { uint32 size = 0; + uint32 size_custom_section = 0; /* aot file header */ size += get_file_header_size(); @@ -939,6 +943,12 @@ get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data, get_name_section_size(comp_data)); } + size_custom_section = get_custom_sections_size(comp_ctx, comp_data); + if (size_custom_section > 0) { + size = align_uint(size, 4); + size += size_custom_section; + } + return size; } @@ -1274,6 +1284,36 @@ fail: return 0; } +static uint32 +get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data) +{ + uint32 size = 0, i; + + for (i = 0; i < comp_ctx->custom_sections_count; i++) { + const char *section_name = comp_ctx->custom_sections_wp[i]; + const uint8 *content = NULL; + uint32 length = 0; + + content = wasm_loader_get_custom_section(comp_data->wasm_module, + section_name, &length); + if (!content) { + LOG_WARNING("Can't find custom section [%s], ignore it", + section_name); + continue; + } + + size = align_uint(size, 4); + /* section id + section size + sub section id */ + size += (uint32)sizeof(uint32) * 3; + /* section name and len */ + size += get_string_size(comp_ctx, section_name); + /* section content */ + size += length; + } + + return size; +} + static bool aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset, AOTCompData *comp_data, AOTObjectData *obj_data) @@ -1897,6 +1937,41 @@ aot_emit_name_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset, return true; } +static bool +aot_emit_custom_sections(uint8 *buf, uint8 *buf_end, uint32 *p_offset, + AOTCompData *comp_data, AOTCompContext *comp_ctx) +{ + uint32 offset = *p_offset, i; + + for (i = 0; i < comp_ctx->custom_sections_count; i++) { + const char *section_name = comp_ctx->custom_sections_wp[i]; + const uint8 *content = NULL; + uint32 length = 0; + + content = wasm_loader_get_custom_section(comp_data->wasm_module, + section_name, &length); + if (!content) { + /* Warning has been reported during calculating size */ + continue; + } + + offset = align_uint(offset, 4); + EMIT_U32(AOT_SECTION_TYPE_CUSTOM); + /* sub section id + content */ + EMIT_U32(sizeof(uint32) * 1 + get_string_size(comp_ctx, section_name) + + length); + EMIT_U32(AOT_CUSTOM_SECTION_RAW); + EMIT_STR(section_name); + bh_memcpy_s((uint8 *)(buf + offset), (uint32)(buf_end - buf), content, + length); + offset += length; + } + + *p_offset = offset; + + return true; +} + typedef uint32 U32; typedef int32 I32; typedef uint16 U16; @@ -2751,7 +2826,9 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data, || !aot_emit_relocation_section(buf, buf_end, &offset, comp_ctx, comp_data, obj_data) || !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx) - || !aot_emit_name_section(buf, buf_end, &offset, comp_data, comp_ctx)) + || !aot_emit_name_section(buf, buf_end, &offset, comp_data, comp_ctx) + || !aot_emit_custom_sections(buf, buf_end, &offset, comp_data, + comp_ctx)) goto fail2; #if 0 diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 9252fc2ab..3d8f2b18d 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -1587,6 +1587,9 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option) comp_ctx->opt_level = option->opt_level; comp_ctx->size_level = option->size_level; + comp_ctx->custom_sections_wp = option->custom_sections; + comp_ctx->custom_sections_count = option->custom_sections_count; + if (option->is_jit_mode) { char *triple_jit = NULL; diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index 1cb8d3b75..ae8b31d6f 100644 --- a/core/iwasm/compilation/aot_llvm.h +++ b/core/iwasm/compilation/aot_llvm.h @@ -348,6 +348,8 @@ typedef struct AOTCompContext { /* Function contexts */ AOTFuncContext **func_ctxes; uint32 func_ctx_count; + char **custom_sections_wp; + uint32 custom_sections_count; } AOTCompContext; enum { @@ -378,6 +380,8 @@ typedef struct AOTCompOption { uint32 size_level; uint32 output_format; uint32 bounds_checks; + char **custom_sections; + uint32 custom_sections_count; } AOTCompOption, *aot_comp_option_t; AOTCompContext * diff --git a/core/iwasm/include/aot_export.h b/core/iwasm/include/aot_export.h index e0ee89668..b60454398 100644 --- a/core/iwasm/include/aot_export.h +++ b/core/iwasm/include/aot_export.h @@ -59,6 +59,8 @@ typedef struct AOTCompOption { uint32_t size_level; uint32_t output_format; uint32_t bounds_checks; + char **custom_sections; + uint32_t custom_sections_count; } AOTCompOption, *aot_comp_option_t; aot_comp_context_t diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 3802ce14b..9b1481d72 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -1053,6 +1053,20 @@ wasm_externref_retain(uint32_t externref_idx); WASM_RUNTIME_API_EXTERN void wasm_runtime_dump_call_stack(wasm_exec_env_t exec_env); +/** + * Get a custom section by name + * + * @param module_comm the module to find + * @param name name of the custom section + * @param len return the length of the content if found + * + * @return Custom section content (not including the name length + * and name string) if found, NULL otherwise + */ +WASM_RUNTIME_API_EXTERN const uint8_t * +wasm_runtime_get_custom_section(wasm_module_t const module_comm, + const char *name, uint32_t *len); + /* clang-format on */ #ifdef __cplusplus diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 553545276..25c19e8ee 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -335,6 +335,19 @@ typedef struct WASMFastOPCodeNode { } WASMFastOPCodeNode; #endif +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +typedef struct WASMCustomSection { + struct WASMCustomSection *next; + /* Start address of the section name */ + char *name_addr; + /* Length of the section name decoded from leb */ + uint32 name_len; + /* Start address of the content (name len and name skipped) */ + uint8 *content_addr; + uint32 content_len; +} WASMCustomSection; +#endif + struct WASMModule { /* Module type, for module loaded from WASM bytecode binary, this field is Wasm_Module_Bytecode; @@ -453,6 +466,10 @@ struct WASMModule { const uint8 *name_section_buf; const uint8 *name_section_buf_end; #endif + +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + WASMCustomSection *custom_section_list; +#endif }; typedef struct BlockType { diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 150d55626..0c97df44d 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -14,6 +14,7 @@ #endif #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0 #include "../libraries/thread-mgr/thread_manager.h" +#include "../libraries/debug-engine/debug_engine.h" #endif typedef int32 CellType_I32; @@ -930,6 +931,9 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0 #define HANDLE_OP_END() \ do { \ + /* Record the current frame_ip, so when exception occurs, \ + debugger can know the exact opcode who caused the exception */ \ + frame_ip_orig = frame_ip; \ while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \ && exec_env->current_status->step_count++ == 1) { \ exec_env->current_status->step_count = 0; \ @@ -1007,6 +1011,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint32 cache_index, type_index, param_cell_num, cell_num; uint8 value_type; +#if WASM_ENABLE_DEBUG_INTERP != 0 + uint8 *frame_ip_orig = NULL; +#endif + #if WASM_ENABLE_LABELS_AS_VALUES != 0 #define HANDLE_OPCODE(op) &&HANDLE_##op DEFINE_GOTO_TABLE(const void *, handle_table); @@ -3734,6 +3742,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, wasm_set_exception(module, "out of bounds memory access"); got_exception: +#if WASM_ENABLE_DEBUG_INTERP != 0 + if (wasm_exec_env_get_instance(exec_env) != NULL) { + uint8 *frame_ip_temp = frame_ip; + frame_ip = frame_ip_orig; + wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP); + CHECK_SUSPEND_FLAGS(); + frame_ip = frame_ip_temp; + } +#endif SYNC_ALL_TO_FRAME(); return; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index a21dac3a3..fecf75773 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2811,7 +2811,8 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; - uint32 name_len; + char section_name[32]; + uint32 name_len, buffer_len; if (p >= p_end) { set_error_buf(error_buf, error_buf_size, "unexpected end"); @@ -2830,6 +2831,16 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return false; } + buffer_len = sizeof(section_name); + memset(section_name, 0, buffer_len); + if (name_len < buffer_len) { + bh_memcpy_s(section_name, buffer_len, p, name_len); + } + else { + bh_memcpy_s(section_name, buffer_len, p, buffer_len - 4); + memset(section_name + buffer_len - 4, '.', 3); + } + #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0 if (memcmp(p, "name", 4) == 0) { module->name_section_buf = buf; @@ -2837,9 +2848,34 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, p += name_len; handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf, error_buf_size); + LOG_VERBOSE("Load custom name section success."); + return true; } #endif - LOG_VERBOSE("Load custom section success.\n"); + +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + { + WASMCustomSection *section = + loader_malloc(sizeof(WASMCustomSection), error_buf, error_buf_size); + + if (!section) { + return false; + } + + section->name_addr = (char *)p; + section->name_len = name_len; + section->content_addr = (uint8 *)(p + name_len); + section->content_len = p_end - p - name_len; + + section->next = module->custom_section_list; + module->custom_section_list = section; + LOG_VERBOSE("Load custom section [%s] success.", section_name); + return true; + } +#endif + + LOG_VERBOSE("Ignore custom section [%s].", section_name); + return true; fail: return false; @@ -3739,6 +3775,7 @@ wasm_loader_unload(WASMModule *module) } } #endif + #if WASM_ENABLE_DEBUG_INTERP != 0 WASMFastOPCodeNode *fast_opcode = bh_list_first_elem(&module->fast_opcode_list); @@ -3749,6 +3786,11 @@ wasm_loader_unload(WASMModule *module) } os_mutex_destroy(&module->ref_count_lock); #endif + +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + wasm_runtime_destroy_custom_sections(module->custom_section_list); +#endif + wasm_runtime_free(module); } @@ -6440,6 +6482,29 @@ get_table_seg_elem_type(const WASMModule *module, uint32 table_seg_idx, } #endif +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +const uint8 * +wasm_loader_get_custom_section(WASMModule *module, const char *name, + uint32 *len) +{ + WASMCustomSection *section = module->custom_section_list; + + while (section) { + if ((section->name_len == strlen(name)) + && (memcmp(section->name_addr, name, section->name_len) == 0)) { + if (len) { + *len = section->content_len; + } + return section->content_addr; + } + + section = section->next; + } + + return false; +} +#endif + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 cur_func_idx, char *error_buf, diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 57c4c1de3..ccdf538aa 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -436,6 +436,10 @@ void wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env); #endif +const uint8 * +wasm_loader_get_custom_section(WASMModule *module, const char *name, + uint32 *len); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index a20d19669..31f45a1f8 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -456,7 +456,7 @@ wasm_debug_instance_destroy(WASMCluster *cluster) } } -static WASMExecEnv * +WASMExecEnv * wasm_debug_instance_get_current_env(WASMDebugInstance *instance) { WASMExecEnv *exec_env = NULL; @@ -829,7 +829,10 @@ WASMDebugInstance * wasm_exec_env_get_instance(WASMExecEnv *exec_env) { WASMDebugInstance *instance = NULL; - bh_assert(g_debug_engine); + + if (!g_debug_engine) { + return NULL; + } os_mutex_lock(&g_debug_engine->instance_list_lock); instance = bh_list_first_elem(&g_debug_engine->debug_instance_list); diff --git a/core/iwasm/libraries/debug-engine/debug_engine.h b/core/iwasm/libraries/debug-engine/debug_engine.h index 6057b0ce3..015f20d7b 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.h +++ b/core/iwasm/libraries/debug-engine/debug_engine.h @@ -128,6 +128,9 @@ wasm_debug_set_engine_active(bool active); bool wasm_debug_get_engine_active(void); +WASMExecEnv * +wasm_debug_instance_get_current_env(WASMDebugInstance *instance); + uint64 wasm_debug_instance_get_pid(WASMDebugInstance *instance); diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index 1b9bd8de4..4761bd99f 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -334,6 +334,8 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid) char pc_string[17]; uint32 tids_count, i = 0; uint32 gdb_status = status; + WASMExecEnv *exec_env; + const char *exception; if (status == 0) { os_mutex_lock(&tmpbuf_lock); @@ -370,20 +372,41 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid) mem2hex((void *)&pc, pc_string, 8); pc_string[8 * 2] = '\0'; - if (status == WAMR_SIG_TRAP) { - len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, - "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc, - pc_string, "breakpoint"); + exec_env = wasm_debug_instance_get_current_env( + (WASMDebugInstance *)server->thread->debug_instance); + exception = + wasm_runtime_get_exception(wasm_runtime_get_module_inst(exec_env)); + if (exception) { + /* When exception occurs, use reason:exception so the description can be + * correctly processed by LLDB */ + uint32 exception_len = strlen(exception); + len += + snprintf(tmpbuf + len, sizeof(tmpbuf) - len, + "thread-pcs:%" PRIx64 ";00:%s;reason:%s;description:", pc, + pc_string, "exception"); + /* The description should be encoded as HEX */ + for (i = 0; i < exception_len; i++) { + len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%02x", + exception[i]); + } + len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, ";"); } - else if (status == WAMR_SIG_SINGSTEP) { - len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, - "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc, - pc_string, "trace"); - } - else if (status > 0) { - len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, - "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc, - pc_string, "signal"); + else { + if (status == WAMR_SIG_TRAP) { + len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, + "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc, + pc_string, "breakpoint"); + } + else if (status == WAMR_SIG_SINGSTEP) { + len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, + "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc, + pc_string, "trace"); + } + else if (status > 0) { + len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, + "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc, + pc_string, "signal"); + } } write_packet(server, tmpbuf); os_mutex_unlock(&tmpbuf_lock); diff --git a/doc/build_wamr.md b/doc/build_wamr.md index d3fe5a683..f57d6678d 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -148,6 +148,15 @@ Currently we only profile the memory consumption of module, module_instance and - **WAMR_BUILD_DEBUG_INTERP**=1/0, default to 0 if not set > Note: There are some other setup required by source debugging, please refer to [source_debugging.md](./source_debugging.md) for more details. +#### **Enable load wasm custom sections** +- **WAMR_BUILD_LOAD_CUSTOM_SECTION**=1/0, default to disable if not set + +> Note: By default, the custom sections are ignored. If the embedder wants to get custom sections from `wasm_module_t`, then `WAMR_BUILD_LOAD_CUSTOM_SECTION` should be enabled, and then `wasm_runtime_get_custom_section` can be used to get a custom section by name. + +> Note: If `WAMR_BUILD_CUSTOM_NAME_SECTION` is enabled, then the `custom name section` will be treated as a special section and consumed by the runtime, not available to the embedder. + +> For AoT file, must use `--emit-custom-sections` to specify which sections need to be emitted into AoT file, otherwise all custom sections (except custom name section) will be ignored. + **Combination of configurations:** We can combine the configurations. For example, if we want to disable interpreter, enable AOT and WASI, we can run command: @@ -216,7 +225,7 @@ To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../README wamrc -o iwasm ``` - + To enable the `JIT` mode, firstly we should build LLVM: ``` Bash @@ -246,7 +255,7 @@ cd build cmake .. -DWAMR_BUILD_FAST_INTERP=0 make ``` - + Linux SGX (Intel Software Guard Extension) ------------------------- @@ -546,14 +555,14 @@ WAMR is intergrated with NuttX, just enable the WAMR in Kconfig option (Applicat ESP-IDF ------------------------- -WAMR integrates with ESP-IDF both for the XTENSA and RISC-V chips (esp32x and esp32c3 respectively). +WAMR integrates with ESP-IDF both for the XTENSA and RISC-V chips (esp32x and esp32c3 respectively). In order to use this, you need at least version 4.3.1 of ESP-IDF. If you don't have it installed, follow the instructions [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/#get-started-get-prerequisites). ESP-IDF also installs the toolchains needed for compiling WAMR and ESP-IDF. A small demonstration of how to use WAMR and ESP-IDF can be found under [product_mini](/product-mini/platforms/esp-idf). -The demo builds WAMR for ESP-IDF and runs a small wasm program. -In order to run it for your specific Espressif chip, edit the ['build.sh'](/product-mini/platforms/esp-idf/build.sh) file and put the correct toolchain file (see #Cross-compilation) and `IDF_TARGET`. +The demo builds WAMR for ESP-IDF and runs a small wasm program. +In order to run it for your specific Espressif chip, edit the ['build_and_run.sh'](/product-mini/platforms/esp-idf/build_and_run.sh) file and put the correct toolchain file (see #Cross-compilation) and `IDF_TARGET`. Before compiling it is also necessary to call ESP-IDF's `export.sh` script to bring all compile time relevant information in scope. Docker diff --git a/doc/embed_wamr.md b/doc/embed_wamr.md index b78a0be64..ae3fe4181 100644 --- a/doc/embed_wamr.md +++ b/doc/embed_wamr.md @@ -1,7 +1,9 @@ Embedding WAMR guideline ===================================== -**Note**: All the embedding APIs supported by the runtime are defined under folder [core/iwasm/include](../core/iwasm/include). The API details are available in the header files. +**Note**: This document is about how to embed WAMR into C/C++ host applications, for other languages, please refer to: [Embed WAMR into Python](../language-bindings/go), [Embed WAMR into Go](../language-bindings/go). + +All the embedding APIs supported by the runtime are defined under folder [core/iwasm/include](../core/iwasm/include). The API details are available in the header files. ## Embed WAMR into developer's project @@ -109,7 +111,7 @@ There are several ways to call WASM function: 1. Function call with parameters in an array of 32 bits elements and size: ```c - unit32 argv[2]; + uint32 argv[2]; /* arguments are always transferred in 32-bit element */ argv[0] = 8; @@ -128,11 +130,11 @@ There are several ways to call WASM function: The parameters are transferred in an array of 32 bits elements. For parameters that occupy 4 or fewer bytes, each parameter can be a single array element. For parameters in types like double or int64, each parameter will take two array elements. The function return value will be sent back in the first one or two elements of the array according to the value type. See the sample code below: ```c - unit32 argv[6]; + uint32 argv[6]; char arg1 = 'a'; int arg2 = 10; double arg3 = 1.0; - int 64 arg4 = 100; + int64 arg4 = 100; double ret; argv[0] = arg1; @@ -160,7 +162,7 @@ The parameters are transferred in an array of 32 bits elements. For parameters t 2. Function call with results and arguments both in `wasm_val_t` struct and size: ```c - unit32 num_args = 1, num_results = 1; + uint32 num_args = 1, num_results = 1; wasm_val_t args[1], results[1]; /* set the argument type and value */ @@ -181,7 +183,7 @@ The parameters are transferred in an array of 32 bits elements. For parameters t 3. Function call with variant argument support: ```c - unit32 num_args = 1, num_results = 1; + uint32 num_args = 1, num_results = 1; wasm_val_t results[1]; /* call the WASM function */ @@ -238,7 +240,7 @@ uint32_t buffer_for_wasm; buffer_for_wasm = wasm_runtime_module_malloc(module_inst, 100, &buffer); if (buffer_for_wasm != 0) { - unit32 argv[2]; + uint32 argv[2]; strncpy(buffer, "hello", 100); /* use native address for accessing in runtime */ argv[0] = buffer_for_wasm; /* pass the buffer address for WASM space */ argv[1] = 100; /* the size of buffer */ diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index c78ef399e..6942df8c0 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -98,7 +98,7 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name) static char ** split_string(char *str, int *count) { - char **res = NULL; + char **res = NULL, **res1; char *p; int idx = 0; @@ -106,16 +106,18 @@ split_string(char *str, int *count) do { p = strtok(str, " "); str = NULL; - res = (char **)realloc(res, sizeof(char *) * (uint32)(idx + 1)); + res1 = res; + res = (char **)realloc(res1, sizeof(char *) * (uint32)(idx + 1)); if (res == NULL) { + free(res1); return NULL; } res[idx++] = p; } while (p); /** - * since the function name, - * res[0] might be contains a '\' to indicate a space + * Due to the function name, + * res[0] might contain a '\' to indicate a space * func\name -> func name */ p = strchr(res[0], '\\'); diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 9baecc1a4..0276c1dc7 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -84,7 +84,7 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name) static char ** split_string(char *str, int *count) { - char **res = NULL; + char **res = NULL, **res1; char *p, *next_token; int idx = 0; @@ -92,16 +92,18 @@ split_string(char *str, int *count) do { p = strtok_s(str, " ", &next_token); str = NULL; - res = (char **)realloc(res, sizeof(char *) * (uint32)(idx + 1)); + res1 = res; + res = (char **)realloc(res1, sizeof(char *) * (uint32)(idx + 1)); if (res == NULL) { + free(res1); return NULL; } res[idx++] = p; } while (p); /** - * since the function name, - * res[0] might be contains a '\' to indicate a space + * Due to the function name, + * res[0] might contain a '\' to indicate a space * func\name -> func name */ p = strchr(res[0], '\\'); diff --git a/tests/wamr-test-suites/spec-test-script/LICENSE b/tests/wamr-test-suites/spec-test-script/LICENSE deleted file mode 100644 index 49b2aa2cf..000000000 --- a/tests/wamr-test-suites/spec-test-script/LICENSE +++ /dev/null @@ -1,387 +0,0 @@ -Copyright (C) Joel Martin - -The wac project is licensed under the MPL 2.0 (Mozilla Public License -2.0). The text of the MPL 2.0 license is included below and can be -found at https://www.mozilla.org/MPL/2.0/ - -By default, wac and wace link with the BSD licensed editline library -(http://www.thrysoee.dk/editline/). The wac/wace build process can be -switched to link with the GPL license GNU readline library with the -USE_READLINE=1 flag. - - -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. - - diff --git a/tests/wamr-test-suites/spec-test-script/runtest.py b/tests/wamr-test-suites/spec-test-script/runtest.py index 920b0d0f3..9053a720c 100755 --- a/tests/wamr-test-suites/spec-test-script/runtest.py +++ b/tests/wamr-test-suites/spec-test-script/runtest.py @@ -57,26 +57,25 @@ rundir = None class Runner(): def __init__(self, args, no_pty=False): - #print "args: %s" % repr(args) self.no_pty = no_pty # Cleanup child process on exit atexit.register(self.cleanup) - self.p = None + self.process = None env = os.environ env['TERM'] = 'dumb' env['INPUTRC'] = '/dev/null' env['PERL_RL'] = 'false' if no_pty: - self.p = Popen(args, bufsize=0, + self.process = Popen(args, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=STDOUT, preexec_fn=os.setsid, env=env) - self.stdin = self.p.stdin - self.stdout = self.p.stdout + self.stdin = self.process.stdin + self.stdout = self.process.stdout else: - # provide tty to get 'interactive' readline to work + # Use tty to setup an interactive environment master, slave = pty.openpty() # Set terminal size large so that readline will not send @@ -84,7 +83,7 @@ class Runner(): buf = array.array('h', [100, 200, 0, 0]) fcntl.ioctl(master, termios.TIOCSWINSZ, buf, True) - self.p = Popen(args, bufsize=0, + self.process = Popen(args, bufsize=0, stdin=slave, stdout=slave, stderr=STDOUT, preexec_fn=os.setsid, env=env) @@ -95,55 +94,55 @@ class Runner(): self.stdin = os.fdopen(master, 'r+b', 0) self.stdout = self.stdin - #print "started" self.buf = "" - self.last_prompt = "" def read_to_prompt(self, prompts, timeout): - end_time = time.time() + timeout - while time.time() < end_time: + wait_until = time.time() + timeout + while time.time() < wait_until: [outs,_,_] = select([self.stdout], [], [], 1) if self.stdout in outs: - new_data = self.stdout.read(1) - if not new_data: + read_byte = self.stdout.read(1) + if not read_byte: # EOF on macOS ends up here. break - new_data = new_data.decode("utf-8") if IS_PY_3 else new_data - #print("new_data: '%s'" % new_data) - debug(new_data) + read_byte = read_byte.decode('utf-8') if IS_PY_3 else read_byte + + debug(read_byte) if self.no_pty: - self.buf += new_data.replace("\n", "\r\n") + self.buf += read_byte.replace('\n', '\r\n') else: - self.buf += new_data - self.buf = self.buf.replace("\r\r", "\r") + self.buf += read_byte + self.buf = self.buf.replace('\r\r', '\r') + + # filter the prompts for prompt in prompts: - regexp = re.compile(prompt) - match = regexp.search(self.buf) + pattern = re.compile(prompt) + match = pattern.search(self.buf) if match: end = match.end() buf = self.buf[0:end-len(prompt)] self.buf = self.buf[end:] - self.last_prompt = prompt return buf return None def writeline(self, str): - def _to_bytes(s): - return bytes(s, "utf-8") if IS_PY_3 else s + str_to_write = str + '\n' + str_to_write = bytes( + str_to_write, 'utf-8') if IS_PY_3 else str_to_write - self.stdin.write(_to_bytes(str + "\n")) + self.stdin.write(str_to_write) def cleanup(self): - if self.p: + if self.process: try: self.writeline("__exit__") time.sleep(.020) - os.killpg(self.p.pid, signal.SIGTERM) + self.process.kill() except OSError: pass except IOError: pass - self.p = None + self.process = None self.stdin.close() if self.stdin != self.stdout: self.stdout.close() diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index df32251b3..1445abab2 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -35,6 +35,7 @@ add_definitions(-DWASM_ENABLE_REF_TYPES=1) add_definitions(-DWASM_ENABLE_CUSTOM_NAME_SECTION=1) add_definitions(-DWASM_ENABLE_DUMP_CALL_STACK=1) add_definitions(-DWASM_ENABLE_PERF_PROFILING=1) +add_definitions(-DWASM_ENABLE_LOAD_CUSTOM_SECTION=1) if (WAMR_BUILD_LLVM_LEGACY_PM EQUAL 1) add_definitions(-DWASM_ENABLE_LLVM_LEGACY_PM=1) diff --git a/wamr-compiler/main.c b/wamr-compiler/main.c index 1587d2ae1..67e3edbbb 100644 --- a/wamr-compiler/main.c +++ b/wamr-compiler/main.c @@ -10,7 +10,7 @@ #include "aot_export.h" /* clang-format off */ -static int +static void print_help() { printf("Usage: wamrc [options] -o output_file wasm_file\n"); @@ -58,14 +58,66 @@ print_help() printf(" --enable-indirect-mode Enalbe call function through symbol table but not direct call\n"); printf(" --disable-llvm-intrinsics Disable the LLVM built-in intrinsics\n"); printf(" --disable-llvm-lto Disable the LLVM link time optimization\n"); + printf(" --emit-custom-sections=
\n"); + printf(" Emit the specified custom sections to AoT file, using comma to separate\n"); + printf(" multiple names, e.g.\n"); + printf(" --emit-custom-sections=section1,section2,sectionN\n"); printf(" -v=n Set log verbose level (0 to 5, default is 2), larger with more log\n"); printf("Examples: wamrc -o test.aot test.wasm\n"); printf(" wamrc --target=i386 -o test.aot test.wasm\n"); printf(" wamrc --target=i386 --format=object -o test.o test.wasm\n"); - return 1; } /* clang-format on */ +#define PRINT_HELP_AND_EXIT() \ + do { \ + print_help(); \ + goto fail0; \ + } while (0) + +/** + * Split a strings into an array of strings + * Returns NULL on failure + * Memory must be freed by caller + * Based on: http://stackoverflow.com/a/11198630/471795 + */ +static char ** +split_string(char *str, int *count, const char *delimer) +{ + char **res = NULL, **res1; + char *p; + int idx = 0; + + /* split string and append tokens to 'res' */ + do { + p = strtok(str, delimer); + str = NULL; + res1 = res; + res = (char **)realloc(res1, sizeof(char *) * (uint32)(idx + 1)); + if (res == NULL) { + free(res1); + return NULL; + } + res[idx++] = p; + } while (p); + + /** + * Due to the section name, + * res[0] might contain a '\' to indicate a space + * func\name -> func name + */ + p = strchr(res[0], '\\'); + while (p) { + *p = ' '; + p = strchr(p, '\\'); + } + + if (count) { + *count = idx - 1; + } + return res; +} + int main(int argc, char *argv[]) { @@ -97,39 +149,39 @@ main(int argc, char *argv[]) if (!strcmp(argv[0], "-o")) { argc--, argv++; if (argc < 2) - return print_help(); + PRINT_HELP_AND_EXIT(); out_file_name = argv[0]; } else if (!strncmp(argv[0], "--target=", 9)) { if (argv[0][9] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); option.target_arch = argv[0] + 9; } else if (!strncmp(argv[0], "--target-abi=", 13)) { if (argv[0][13] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); option.target_abi = argv[0] + 13; } else if (!strncmp(argv[0], "--cpu=", 6)) { if (argv[0][6] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); option.target_cpu = argv[0] + 6; } else if (!strncmp(argv[0], "--cpu-features=", 15)) { if (argv[0][15] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); option.cpu_features = argv[0] + 15; } else if (!strncmp(argv[0], "--opt-level=", 12)) { if (argv[0][12] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); option.opt_level = (uint32)atoi(argv[0] + 12); if (option.opt_level > 3) option.opt_level = 3; } else if (!strncmp(argv[0], "--size-level=", 13)) { if (argv[0][13] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); option.size_level = (uint32)atoi(argv[0] + 13); if (option.size_level > 3) option.size_level = 3; @@ -143,7 +195,7 @@ main(int argc, char *argv[]) } else if (!strncmp(argv[0], "--format=", 9)) { if (argv[0][9] == '\0') - return print_help(); + PRINT_HELP_AND_EXIT(); if (!strcmp(argv[0] + 9, "aot")) option.output_format = AOT_FORMAT_FILE; else if (!strcmp(argv[0] + 9, "object")) @@ -154,13 +206,13 @@ main(int argc, char *argv[]) option.output_format = AOT_LLVMIR_OPT_FILE; else { printf("Invalid format %s.\n", argv[0] + 9); - return print_help(); + PRINT_HELP_AND_EXIT(); } } else if (!strncmp(argv[0], "-v=", 3)) { log_verbose_level = atoi(argv[0] + 3); if (log_verbose_level < 0 || log_verbose_level > 5) - return print_help(); + PRINT_HELP_AND_EXIT(); } else if (!strcmp(argv[0], "--disable-bulk-memory")) { option.enable_bulk_memory = false; @@ -201,12 +253,27 @@ main(int argc, char *argv[]) else if (!strcmp(argv[0], "--disable-llvm-lto")) { option.disable_llvm_lto = true; } + else if (!strncmp(argv[0], "--emit-custom-sections=", 23)) { + int len = 0; + if (option.custom_sections) { + free(option.custom_sections); + } + + option.custom_sections = split_string(argv[0] + 23, &len, ","); + if (!option.custom_sections) { + printf("Failed to process emit-custom-sections: alloc " + "memory failed\n"); + PRINT_HELP_AND_EXIT(); + } + + option.custom_sections_count = len; + } else - return print_help(); + PRINT_HELP_AND_EXIT(); } if (argc == 0 || !out_file_name) - return print_help(); + PRINT_HELP_AND_EXIT(); if (!size_level_set) { /** @@ -348,6 +415,12 @@ fail1: /* Destroy runtime environment */ wasm_runtime_destroy(); +fail0: + /* free option.custom_sections */ + if (option.custom_sections) { + free(option.custom_sections); + } + bh_print_time("wamrc return"); return exit_status; }