diff --git a/.github/workflows/compilation_on_android_ubuntu_macos.yml b/.github/workflows/compilation_on_android_ubuntu_macos.yml index d15d0649..becc0881 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 621ed953..f0416838 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/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 432acf58..be5ca9e8 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 49b1f3e2..db281924 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 d7728707..e4fd3e0f 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -12,8 +12,12 @@ #include "../compilation/aot.h" #if WASM_ENABLE_JIT != 0 #include "../compilation/aot_llvm.h" +#endif + +#if (WASM_ENABLE_JIT != 0) || (WASM_ENABLE_LOAD_CUSTOM_SECTION != 0) #include "../interpreter/wasm_loader.h" #endif + #if WASM_ENABLE_DEBUG_AOT != 0 #include "debug/elf_parser.h" #include "debug/jit_debug.h" @@ -674,6 +678,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 +3295,10 @@ aot_unload(AOTModule *module) } #endif +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 + wasm_loader_destroy_custom_sections(module->custom_section_list); +#endif + wasm_runtime_free(module); } @@ -3269,3 +3307,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 1ab325c3..0aa4edea 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 943577b4..efaf842d 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2843,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; diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index bb3e2840..0256b0fe 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); diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index dacb59c6..e6d07054 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 9252fc2a..3d8f2b18 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 1cb8d3b7..ae8b31d6 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 e0ee8966..b6045439 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 3802ce14..9b1481d7 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 55354527..25c19e8e 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_loader.c b/core/iwasm/interpreter/wasm_loader.c index a21dac3a..335c9469 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_loader_destroy_custom_sections(module->custom_section_list); +#endif + wasm_runtime_free(module); } @@ -6440,6 +6482,40 @@ 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; +} + +void +wasm_loader_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 */ + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 cur_func_idx, char *error_buf, diff --git a/core/iwasm/interpreter/wasm_loader.h b/core/iwasm/interpreter/wasm_loader.h index 8b0dc77d..ff6b535b 100644 --- a/core/iwasm/interpreter/wasm_loader.h +++ b/core/iwasm/interpreter/wasm_loader.h @@ -73,6 +73,11 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, uint8 block_type, uint8 **p_else_addr, uint8 **p_end_addr); +#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 +void +wasm_loader_destroy_custom_sections(WASMCustomSection *section_list); +#endif + #ifdef __cplusplus } #endif diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 57c4c1de..ccdf538a 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/doc/build_wamr.md b/doc/build_wamr.md index 2bb3e7f1..f57d6678 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: @@ -546,13 +555,13 @@ 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. +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. diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index c78ef399..6942df8c 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 9baecc1a..0276c1dc 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/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index df32251b..1445abab 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 1587d2ae..67e3edbb 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; }