diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 497c034ba..96ea02f8e 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" @@ -106,159 +110,6 @@ check_buf(const uint8 *buf, const uint8 *buf_end, uint32 length, } \ } while (0) -#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 -static bool -check_utf8_str(const uint8 *str, uint32 len) -{ - /* The valid ranges are taken from page 125, below link - https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */ - const uint8 *p = str, *p_end = str + len; - uint8 chr; - - while (p < p_end) { - chr = *p; - if (chr < 0x80) { - p++; - } - else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) { - if (p[1] < 0x80 || p[1] > 0xBF) { - return false; - } - p += 2; - } - else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) { - if (chr == 0xE0) { - if (p[1] < 0xA0 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) { - return false; - } - } - else if (chr == 0xED) { - if (p[1] < 0x80 || p[1] > 0x9F || p[2] < 0x80 || p[2] > 0xBF) { - return false; - } - } - else if (chr >= 0xE1 && chr <= 0xEF) { - if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF) { - return false; - } - } - p += 3; - } - else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) { - if (chr == 0xF0) { - if (p[1] < 0x90 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF - || p[3] < 0x80 || p[3] > 0xBF) { - return false; - } - } - else if (chr >= 0xF1 && chr <= 0xF3) { - if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF - || p[3] < 0x80 || p[3] > 0xBF) { - return false; - } - } - else if (chr == 0xF4) { - if (p[1] < 0x80 || p[1] > 0x8F || p[2] < 0x80 || p[2] > 0xBF - || p[3] < 0x80 || p[3] > 0xBF) { - return false; - } - } - p += 4; - } - else { - return false; - } - } - return (p == p_end); -} - -static bool -read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign, - uint64 *p_result, char *error_buf, uint32 error_buf_size) -{ - const uint8 *buf = *p_buf; - uint64 result = 0; - uint32 shift = 0; - uint32 offset = 0, bcnt = 0; - uint64 byte; - - while (true) { - /* uN or SN must not exceed ceil(N/7) bytes */ - if (bcnt + 1 > (maxbits + 6) / 7) { - set_error_buf(error_buf, error_buf_size, - "integer representation too long"); - return false; - } - - CHECK_BUF(buf, buf_end, offset + 1); - byte = buf[offset]; - offset += 1; - result |= ((byte & 0x7f) << shift); - shift += 7; - bcnt += 1; - if ((byte & 0x80) == 0) { - break; - } - } - - if (!sign && maxbits == 32 && shift >= maxbits) { - /* The top bits set represent values > 32 bits */ - if (((uint8)byte) & 0xf0) - goto fail_integer_too_large; - } - else if (sign && maxbits == 32) { - if (shift < maxbits) { - /* Sign extend, second highest bit is the sign bit */ - if ((uint8)byte & 0x40) - result |= (~((uint64)0)) << shift; - } - else { - /* The top bits should be a sign-extension of the sign bit */ - bool sign_bit_set = ((uint8)byte) & 0x8; - int top_bits = ((uint8)byte) & 0xf0; - if ((sign_bit_set && top_bits != 0x70) - || (!sign_bit_set && top_bits != 0)) - goto fail_integer_too_large; - } - } - else if (sign && maxbits == 64) { - if (shift < maxbits) { - /* Sign extend, second highest bit is the sign bit */ - if ((uint8)byte & 0x40) - result |= (~((uint64)0)) << shift; - } - else { - /* The top bits should be a sign-extension of the sign bit */ - bool sign_bit_set = ((uint8)byte) & 0x1; - int top_bits = ((uint8)byte) & 0xfe; - - if ((sign_bit_set && top_bits != 0x7e) - || (!sign_bit_set && top_bits != 0)) - goto fail_integer_too_large; - } - } - - *p_buf += offset; - *p_result = result; - return true; - -fail_integer_too_large: - set_error_buf(error_buf, error_buf_size, "integer too large"); -fail: - return false; -} - -#define read_leb_uint32(p, p_end, res) \ - do { \ - uint64 res64; \ - if (!read_leb((uint8 **)&p, p_end, 32, false, &res64, error_buf, \ - error_buf_size)) \ - goto fail; \ - res = (uint32)res64; \ - } while (0) - -#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */ - static uint8 * align_ptr(const uint8 *p, uint32 b) { @@ -830,52 +681,47 @@ load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module, #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 case AOT_CUSTOM_SECTION_RAW: { - char section_name[32]; const uint8 *p_orig = p; + char section_name_buf[32]; + const char *section_name; uint32 name_len, buffer_len; - WASMSection *section; + WASMCustomSection *section; if (p >= p_end) { set_error_buf(error_buf, error_buf_size, "unexpected end"); goto fail; } - read_leb_uint32(p, p_end, name_len); + read_string(p, p_end, section_name); - if (name_len == 0 || p + name_len > p_end) { - set_error_buf(error_buf, error_buf_size, "unexpected end"); - goto fail; - } + name_len = p - p_orig; - if (!check_utf8_str(p, name_len)) { - set_error_buf(error_buf, error_buf_size, - "invalid UTF-8 encoding"); - goto fail; - } - - buffer_len = sizeof(section_name); - memset(section_name, 0, buffer_len); + buffer_len = sizeof(section_name_buf); + memset(section_name_buf, 0, buffer_len); if (name_len < buffer_len) { - bh_memcpy_s(section_name, buffer_len, p, name_len); + bh_memcpy_s(section_name_buf, buffer_len, section_name, + name_len); } else { - bh_memcpy_s(section_name, buffer_len, p, buffer_len - 4); - memset(section_name + buffer_len - 4, '.', 3); + bh_memcpy_s(section_name_buf, buffer_len, section_name, + buffer_len - 4); + memset(section_name_buf + buffer_len - 4, '.', 3); } - section = - loader_malloc(sizeof(WASMSection), error_buf, error_buf_size); + section = loader_malloc(sizeof(WASMCustomSection), error_buf, + error_buf_size); if (!section) { goto fail; } - section->section_type = SECTION_TYPE_USER; - section->section_body = (uint8 *)p_orig; - section->section_body_size = p_end - p_orig; + section->name_addr = (char *)section_name; + section->name_len = name_len; + 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); + LOG_VERBOSE("Load custom section [%s] success.", section_name_buf); break; } #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */ @@ -3467,7 +3313,7 @@ aot_unload(AOTModule *module) #endif #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 - destroy_sections(module->custom_section_list, false); + wasm_loader_destroy_custom_sections(module->custom_section_list); #endif wasm_runtime_free(module); @@ -3483,25 +3329,15 @@ aot_get_plt_table_size() const uint8 * aot_get_custom_section(AOTModule *module, const char *name, uint32 *len) { - WASMSection *section = module->custom_section_list; + WASMCustomSection *section = module->custom_section_list; while (section) { - uint64 res64; - uint32 name_len; - uint8 *p = section->section_body; - - if (!read_leb((uint8 **)&p, - section->section_body + section->section_body_size, 32, - false, &res64, NULL, 0)) { - continue; - } - name_len = (uint32)res64; - - if ((name_len == strlen(name)) && (memcmp(p, name, name_len) == 0)) { + if ((section->name_len == strlen(name)) + && (memcmp(section->name_addr, name, section->name_len) == 0)) { if (len) { - *len = section->section_body_size; + *len = section->content_len; } - return section->section_body; + return section->content_addr; } section = section->next; diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 1e166137f..56b556aba 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -270,7 +270,7 @@ typedef struct AOTModule { uint32 aux_func_name_count; #endif #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 - wasm_section_t *custom_section_list; + WASMCustomSection *custom_section_list; #endif } AOTModule; diff --git a/core/iwasm/compilation/aot.c b/core/iwasm/compilation/aot.c index 4ab5f55c8..3232a9874 100644 --- a/core/iwasm/compilation/aot.c +++ b/core/iwasm/compilation/aot.c @@ -4,7 +4,7 @@ */ #include "aot.h" -#include "wasm_loader.h" +#include "../interpreter/wasm_loader.h" static char aot_error[128]; @@ -591,9 +591,5 @@ aot_destroy_comp_data(AOTCompData *comp_data) if (comp_data->aot_name_section_buf) wasm_runtime_free(comp_data->aot_name_section_buf); - if (comp_data->custom_sections_to_emit) { - wasm_loader_destroy_sections(comp_data->custom_sections_to_emit); - } - wasm_runtime_free(comp_data); } diff --git a/core/iwasm/compilation/aot.h b/core/iwasm/compilation/aot.h index 069819dfc..78dc78e20 100644 --- a/core/iwasm/compilation/aot.h +++ b/core/iwasm/compilation/aot.h @@ -246,9 +246,6 @@ typedef struct AOTCompData { uint8 *aot_name_section_buf; uint32 aot_name_section_size; - /* custom sections */ - wasm_section_t *custom_sections_to_emit; - uint32 global_data_size; uint32 start_func_index; diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 0e8e4f373..bdfa5df0e 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -878,7 +878,7 @@ static uint32 get_name_section_size(AOTCompData *comp_data); static uint32 -get_custom_sections_size(AOTCompData *comp_data); +get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data); static uint32 get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data, @@ -942,10 +942,10 @@ get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data, get_name_section_size(comp_data)); } - if (comp_data->custom_sections_to_emit) { + if (comp_ctx->custom_sections_wp) { /* custom sections */ size = align_uint(size, 4); - size += get_custom_sections_size(comp_data); + size += get_custom_sections_size(comp_ctx, comp_data); } return size; @@ -1284,17 +1284,30 @@ fail: } static uint32 -get_custom_sections_size(AOTCompData *comp_data) +get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data) { - uint32 size = 0; - WASMSection *section = comp_data->custom_sections_to_emit; + 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; + } - while (section) { size = align_uint(size, 4); /* section id + section size + sub section id */ size += (uint32)sizeof(uint32) * 3; - size += section->section_body_size; - section = section->next; + /* section name, null terminated string */ + size += get_string_size(comp_ctx, section_name); + /* section content */ + size += length; } return size; @@ -1927,23 +1940,32 @@ static bool aot_emit_custom_sections(uint8 *buf, uint8 *buf_end, uint32 *p_offset, AOTCompData *comp_data, AOTCompContext *comp_ctx) { - WASMSection *section = comp_data->custom_sections_to_emit; - uint32 offset = *p_offset; + uint32 offset = *p_offset, i; *p_offset = offset = align_uint(offset, 4); - while (section) { - offset = align_uint(offset, 4); + 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 + section->section_body_size); + EMIT_U32(sizeof(uint32) * 1 + get_string_size(comp_ctx, section_name) + + length); EMIT_U32(AOT_CUSTOM_SECTION_RAW); - bh_memcpy_s((uint8 *)(buf + offset), (uint32)(buf_end - buf), - section->section_body, (uint32)section->section_body_size); - offset += section->section_body_size; - - section = section->next; + EMIT_STR(section_name); + bh_memcpy_s((uint8 *)(buf + offset), (uint32)(buf_end - buf), content, + length); + offset += length; } *p_offset = offset; diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index 6f4ce5a2f..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; @@ -2068,43 +2071,6 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option) if (comp_ctx->disable_llvm_intrinsics) aot_intrinsic_fill_capability_flags(comp_ctx); -#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 - if (option->custom_sections) { - /* Extract custom sections to emit */ - for (i = 0; i < option->custom_sections_count; i++) { - const uint8 *content = NULL; - uint32 length = 0; - WASMSection *section; - - content = wasm_loader_get_custom_section( - comp_data->wasm_module, option->custom_sections[i], &length); - if (!content) { - LOG_WARNING("Can't find custom section [%s], ignore it", - option->custom_sections[i]); - continue; - } - - if (!(section = wasm_runtime_malloc((uint32)sizeof(WASMSection)))) { - aot_set_last_error("allocate memory failed"); - /* Don't need to destroy the previous sections here, they will - * be destroyed during destroying the comp_data */ - goto fail; - } - memset(section, 0, sizeof(WASMSection)); - - section->section_type = SECTION_TYPE_USER; - section->section_body = (uint8 *)content; - section->section_body_size = length; - - section->next = comp_data->custom_sections_to_emit; - comp_data->custom_sections_to_emit = section; - - LOG_VERBOSE("Found custom section [%s].", - option->custom_sections[i]); - } - } -#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */ - ret = comp_ctx; fail: diff --git a/core/iwasm/compilation/aot_llvm.h b/core/iwasm/compilation/aot_llvm.h index df5a24bcc..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 { diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index d68f62554..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; @@ -455,7 +468,7 @@ struct WASMModule { #endif #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 - struct wasm_section_t *custom_section_list; + WASMCustomSection *custom_section_list; #endif }; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 458db3ca2..335c94695 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2811,7 +2811,6 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf_end; - const uint8 *p_orig = p; char section_name[32]; uint32 name_len, buffer_len; @@ -2856,16 +2855,17 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 { - WASMSection *section = - loader_malloc(sizeof(WASMSection), error_buf, error_buf_size); + WASMCustomSection *section = + loader_malloc(sizeof(WASMCustomSection), error_buf, error_buf_size); if (!section) { return false; } - section->section_type = SECTION_TYPE_USER; - section->section_body = (uint8 *)p_orig; - section->section_body_size = p_end - p; + 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; @@ -2875,7 +2875,6 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, #endif LOG_VERBOSE("Ignore custom section [%s].", section_name); - (void)p_orig; return true; fail: @@ -3789,7 +3788,7 @@ wasm_loader_unload(WASMModule *module) #endif #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 - destroy_sections(module->custom_section_list); + wasm_loader_destroy_custom_sections(module->custom_section_list); #endif wasm_runtime_free(module); @@ -6488,25 +6487,15 @@ const uint8 * wasm_loader_get_custom_section(WASMModule *module, const char *name, uint32 *len) { - WASMSection *section = module->custom_section_list; + WASMCustomSection *section = module->custom_section_list; while (section) { - uint64 res64; - uint32 name_len; - uint8 *p = section->section_body; - - if (!read_leb((uint8 **)&p, - section->section_body + section->section_body_size, 32, - false, &res64, NULL, 0)) { - continue; - } - name_len = (uint32)res64; - - if ((name_len == strlen(name)) && (memcmp(p, name, name_len) == 0)) { + if ((section->name_len == strlen(name)) + && (memcmp(section->name_addr, name, section->name_len) == 0)) { if (len) { - *len = section->section_body_size; + *len = section->content_len; } - return section->section_body; + return section->content_addr; } section = section->next; @@ -6514,13 +6503,18 @@ wasm_loader_get_custom_section(WASMModule *module, const char *name, return false; } -#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */ void -wasm_loader_destroy_sections(WASMSection *section_list) +wasm_loader_destroy_custom_sections(WASMCustomSection *section_list) { - destroy_sections(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, diff --git a/core/iwasm/interpreter/wasm_loader.h b/core/iwasm/interpreter/wasm_loader.h index 867901810..09aa2117a 100644 --- a/core/iwasm/interpreter/wasm_loader.h +++ b/core/iwasm/interpreter/wasm_loader.h @@ -74,7 +74,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, uint8 **p_end_addr); void -wasm_loader_destroy_sections(WASMSection *section_list); +wasm_loader_destroy_custom_sections(WASMCustomSection *section_list); #ifdef __cplusplus } 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/wamr-compiler/main.c b/wamr-compiler/main.c index 882a1ddc9..67e3edbbb 100644 --- a/wamr-compiler/main.c +++ b/wamr-compiler/main.c @@ -84,7 +84,7 @@ print_help() static char ** split_string(char *str, int *count, const char *delimer) { - char **res = NULL; + char **res = NULL, **res1; char *p; int idx = 0; @@ -92,16 +92,18 @@ split_string(char *str, int *count, const char *delimer) do { p = strtok(str, delimer); 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 section name, + * res[0] might contain a '\' to indicate a space * func\name -> func name */ p = strchr(res[0], '\\');