Ver Fonte

Enable emitting custom name section to aot file (#794)

Enable emitting custom name section to aot file when adding
`--enable-dump-call-stack` or `--enable-dump-call-stack` to
wamrc and there is custom name section in wasm file, which
can be generated by wasi-sdk/emcc "-g" option. So aot runtime
can also get the function name from the custom name section
instead of export section,  to which developer should use
`--export-all` for wasi-sdk/emcc to generate export function
names.
Javan há 4 anos atrás
pai
commit
788e14ed6c

+ 2 - 0
.gitignore

@@ -1,6 +1,8 @@
 
 .vs
 .vscode
+/.idea
+**/cmake-build-*/
 **/*build/
 core/deps/**
 core/shared/mem-alloc/tlsf

+ 145 - 4
core/iwasm/aot/aot_loader.c

@@ -434,6 +434,133 @@ fail:
     return false;
 }
 
+static bool
+load_name_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
+                  char *error_buf, uint32 error_buf_size)
+{
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+    const uint8 *p = buf, *p_end = buf_end;
+    uint32 *aux_func_indexes;
+    const char **aux_func_names;
+    uint32 name_type, subsection_size;
+    uint32 previous_name_type = 0;
+    uint32 num_func_name;
+    uint32 func_index;
+    uint32 previous_func_index = ~0U;
+    uint32 name_index;
+    int i = 0;
+    uint32 name_len;
+    uint64 size;
+
+    if (p >= p_end) {
+        set_error_buf(error_buf, error_buf_size, "unexpected end");
+        return false;
+    }
+
+    read_uint32(p, p_end, name_len);
+
+    if (name_len != 4 || p + name_len > p_end) {
+        set_error_buf(error_buf, error_buf_size, "unexpected end");
+        return false;
+    }
+
+    if (memcmp(p, "name", 4) != 0) {
+        set_error_buf(error_buf, error_buf_size, "invalid custom name section");
+        return false;
+    }
+    p += name_len;
+
+    while (p < p_end) {
+        read_uint32(p, p_end, name_type);
+        if (i != 0) {
+            if (name_type == previous_name_type) {
+                set_error_buf(error_buf, error_buf_size,
+                              "duplicate sub-section");
+                return false;
+            }
+            if (name_type < previous_name_type) {
+                set_error_buf(error_buf, error_buf_size,
+                              "out-of-order sub-section");
+                return false;
+            }
+        }
+        previous_name_type = name_type;
+        read_uint32(p, p_end, subsection_size);
+        CHECK_BUF(p, p_end, subsection_size);
+        switch (name_type) {
+            case SUB_SECTION_TYPE_FUNC:
+                if (subsection_size) {
+                    read_uint32(p, p_end, num_func_name);
+                    if (num_func_name
+                        > module->import_func_count + module->func_count) {
+                        set_error_buf(error_buf, error_buf_size,
+                                      "function name count out of bounds");
+                        return false;
+                    }
+                    module->aux_func_name_count = num_func_name;
+
+                    /* Allocate memory */
+                    size = sizeof(uint32) * (uint64)module->aux_func_name_count;
+                    if (!(aux_func_indexes = module->aux_func_indexes =
+                              loader_malloc(size, error_buf, error_buf_size))) {
+                        return false;
+                    }
+                    size =
+                        sizeof(char **) * (uint64)module->aux_func_name_count;
+                    if (!(aux_func_names = module->aux_func_names =
+                              loader_malloc(size, error_buf, error_buf_size))) {
+                        return false;
+                    }
+
+                    for (name_index = 0; name_index < num_func_name;
+                         name_index++) {
+                        read_uint32(p, p_end, func_index);
+                        if (name_index != 0
+                            && func_index == previous_func_index) {
+                            set_error_buf(error_buf, error_buf_size,
+                                          "duplicate function name");
+                            return false;
+                        }
+                        if (name_index != 0
+                            && func_index < previous_func_index) {
+                            set_error_buf(error_buf, error_buf_size,
+                                          "out-of-order function index ");
+                            return false;
+                        }
+                        if (func_index
+                            >= module->import_func_count + module->func_count) {
+                            set_error_buf(error_buf, error_buf_size,
+                                          "function index out of bounds");
+                            return false;
+                        }
+                        previous_func_index = func_index;
+                        *(aux_func_indexes + name_index) = func_index;
+                        read_string(p, p_end, *(aux_func_names + name_index));
+#if 0
+                        LOG_DEBUG("func_index %u -> aux_func_name = %s\n",
+                               func_index, *(aux_func_names + name_index));
+#endif
+                    }
+                }
+                break;
+            case SUB_SECTION_TYPE_MODULE: /* TODO: Parse for module subsection
+                                           */
+            case SUB_SECTION_TYPE_LOCAL:  /* TODO: Parse for local subsection */
+            default:
+                p = p + subsection_size;
+                break;
+        }
+        i++;
+    }
+
+    return true;
+fail:
+    return false;
+#else
+    return true;
+#endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
+}
+
 static bool
 load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
                     char *error_buf, uint32 error_buf_size)
@@ -450,6 +577,11 @@ load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
                                             error_buf_size))
                 goto fail;
             break;
+        case AOT_CUSTOM_SECTION_NAME:
+            if (!load_name_section(buf, buf_end, module, error_buf,
+                                   error_buf_size))
+                goto fail;
+            break;
         default:
             break;
     }
@@ -1233,7 +1365,7 @@ load_text_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
     /* The layout is: literal size + literal + code (with plt table) */
     read_uint32(buf, buf_end, module->literal_size);
 
-    /* literal data is at begining of the text section */
+    /* literal data is at beginning of the text section */
     module->literal = (uint8 *)buf;
     module->code = (void *)(buf + module->literal_size);
     module->code_size = (uint32)(buf_end - (uint8 *)module->code);
@@ -2336,7 +2468,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
 {
     AOTSection *section_list = NULL, *section_list_end = NULL, *section;
     const uint8 *p = buf, *p_end = buf + size;
-    bool destory_aot_text = false;
+    bool destroy_aot_text = false;
     uint32 native_symbol_count = 0;
     uint32 section_type;
     uint32 section_size;
@@ -2403,7 +2535,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
                     bh_memcpy_s(aot_text, (uint32)total_size,
                                 section->section_body, (uint32)section_size);
                     section->section_body = aot_text;
-                    destory_aot_text = true;
+                    destroy_aot_text = true;
 
                     if ((uint32)total_size > section->section_body_size) {
                         memset(aot_text + (uint32)section_size, 0,
@@ -2437,7 +2569,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
     return true;
 fail:
     if (section_list)
-        destroy_sections(section_list, destory_aot_text);
+        destroy_sections(section_list, destroy_aot_text);
     return false;
 }
 
@@ -2868,6 +3000,15 @@ aot_unload(AOTModule *module)
     jit_code_entry_destroy(module->elf_hdr);
 #endif
 
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+    if (module->aux_func_indexes) {
+        wasm_runtime_free(module->aux_func_indexes);
+    }
+    if (module->aux_func_names) {
+        wasm_runtime_free(module->aux_func_names);
+    }
+#endif
+
     wasm_runtime_free(module);
 }
 

+ 29 - 0
core/iwasm/aot/aot_runtime.c

@@ -2815,6 +2815,27 @@ aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
 #endif /* WASM_ENABLE_REF_TYPES != 0 */
 
 #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
+static const char *
+lookup_func_name(const char **func_names, uint32 *func_indexes,
+                 uint32 func_index_count, uint32 func_index)
+{
+    int64 low = 0, mid;
+    int64 high = func_index_count - 1;
+
+    while (low <= high) {
+        mid = (low + high) / 2;
+        if (func_index == func_indexes[mid]) {
+            return func_names[mid];
+        }
+        else if (func_index < func_indexes[mid])
+            high = mid - 1;
+        else
+            low = mid + 1;
+    }
+
+    return NULL;
+}
+
 static const char *
 get_func_name_from_index(const AOTModuleInstance *module_inst,
                          uint32 func_index)
@@ -2822,6 +2843,14 @@ get_func_name_from_index(const AOTModuleInstance *module_inst,
     const char *func_name = NULL;
     AOTModule *module = module_inst->aot_module.ptr;
 
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+    if ((func_name =
+             lookup_func_name(module->aux_func_names, module->aux_func_indexes,
+                              module->aux_func_name_count, func_index))) {
+        return func_name;
+    }
+#endif
+
     if (func_index < module->import_func_count) {
         func_name = module->import_funcs[func_index].func_name;
     }

+ 9 - 3
core/iwasm/aot/aot_runtime.h

@@ -52,6 +52,7 @@ typedef enum AOTSectionType {
 typedef enum AOTCustomSectionType {
     AOT_CUSTOM_SECTION_NATIVE_SYMBOL = 1,
     AOT_CUSTOM_SECTION_ACCESS_CONTROL = 2,
+    AOT_CUSTOM_SECTION_NAME = 3,
 } AOTCustomSectionType;
 
 typedef struct AOTObjectDataSection {
@@ -133,7 +134,7 @@ typedef struct AOTModule {
     uint32 mem_init_data_count;
     AOTMemInitData **mem_init_data_list;
 
-    /* native symobl */
+    /* native symbol */
     uint32 native_symbol_count;
     void **native_symbol_list;
 
@@ -153,7 +154,7 @@ typedef struct AOTModule {
     uint32 func_type_count;
     AOTFuncType **func_types;
 
-    /* import global varaible info */
+    /* import global variable info */
     uint32 import_global_count;
     AOTImportGlobal *import_globals;
 
@@ -260,6 +261,11 @@ typedef struct AOTModule {
     void *elf_hdr;
     uint32 elf_size;
 #endif
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+    const char **aux_func_names;
+    uint32 *aux_func_indexes;
+    uint32 aux_func_name_count;
+#endif
 } AOTModule;
 
 typedef union {
@@ -335,7 +341,7 @@ typedef struct AOTModuleInstance {
     /* points to AOTTableInstance[] */
     AOTPointer tables;
 
-    /* funciton pointer array */
+    /* function pointer array */
     AOTPointer func_ptrs;
     /* function type indexes */
     AOTPointer func_type_indexes;

+ 3 - 3
core/iwasm/aot/arch/aot_reloc_aarch64.c

@@ -224,7 +224,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
             /* S + A */
             X = (int64)S + A;
 
-            /* No need to check overflow for this reloction type */
+            /* No need to check overflow for this relocation type */
             switch (reloc_type) {
                 case R_AARCH64_MOVW_UABS_G0:
                     if (X < 0 || X >= (1LL << 16))
@@ -324,7 +324,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
             /* S + A */
             X = (int64)S + A;
 
-            /* No need to check overflow for this reloction type */
+            /* No need to check overflow for this relocation type */
 
             /* write the imm12 back to instruction */
             *(int32 *)P = (insn & 0xFFC003FF) | ((int32)((X & 0xFFF) << 10));
@@ -354,7 +354,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
             /* S + A */
             X = (int64)S + A;
 
-            /* No need to check overflow for this reloction type */
+            /* No need to check overflow for this relocation type */
 
             /* write the imm12 back to instruction */
             switch (reloc_type) {

+ 9 - 0
core/iwasm/compilation/aot.c

@@ -515,6 +515,12 @@ aot_create_comp_data(WASMModule *module)
     if (comp_data->func_count && !(comp_data->funcs = aot_create_funcs(module)))
         goto fail;
 
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+    /* Create custom name section */
+    comp_data->name_section_buf = module->name_section_buf;
+    comp_data->name_section_buf_end = module->name_section_buf_end;
+#endif
+
     /* Create aux data/heap/stack information */
     comp_data->aux_data_end_global_index = module->aux_data_end_global_index;
     comp_data->aux_data_end = module->aux_data_end;
@@ -581,5 +587,8 @@ aot_destroy_comp_data(AOTCompData *comp_data)
     if (comp_data->funcs)
         aot_destroy_funcs(comp_data->funcs, comp_data->func_count);
 
+    if (comp_data->aot_name_section_buf)
+        wasm_runtime_free(comp_data->aot_name_section_buf);
+
     wasm_runtime_free(comp_data);
 }

+ 6 - 0
core/iwasm/compilation/aot.h

@@ -239,6 +239,12 @@ typedef struct AOTCompData {
     uint32 func_count;
     AOTFunc **funcs;
 
+    /* Custom name sections */
+    const uint8 *name_section_buf;
+    const uint8 *name_section_buf_end;
+    uint8 *aot_name_section_buf;
+    uint32 aot_name_section_size;
+
     uint32 global_data_size;
 
     uint32 start_func_index;

+ 306 - 5
core/iwasm/compilation/aot_emit_aot_file.c

@@ -25,6 +25,71 @@
         }                                                  \
     } while (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);
+}
+
 /* Internal function in object file */
 typedef struct AOTObjectFunc {
     char *func_name;
@@ -794,6 +859,9 @@ get_native_symbol_list_size(AOTCompContext *comp_ctx)
     return len;
 }
 
+static uint32
+get_name_section_size(AOTCompData *comp_data);
+
 static uint32
 get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
                   AOTObjectData *obj_data)
@@ -840,13 +908,22 @@ get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
     size += get_relocation_section_size(obj_data);
 
     if (get_native_symbol_list_size(comp_ctx) > 0) {
-        /* emit only when threre are native symbols */
+        /* emit only when there are native symbols */
         size = align_uint(size, 4);
         /* section id + section size + sub section id + symbol count */
         size += (uint32)sizeof(uint32) * 4;
         size += get_native_symbol_list_size(comp_ctx);
     }
 
+    if (comp_ctx->enable_aux_stack_frame) {
+        /* custom name section */
+        size = align_uint(size, 4);
+        /* section id + section size + sub section id */
+        size += (uint32)sizeof(uint32) * 3;
+        size += (comp_data->aot_name_section_size =
+                     get_name_section_size(comp_data));
+    }
+
     return size;
 }
 
@@ -975,6 +1052,205 @@ static union {
         EMIT_BUF(s, str_len);               \
     } while (0)
 
+static bool
+read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
+         uint64 *p_result)
+{
+    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) {
+            aot_set_last_error("integer representation too long");
+            return false;
+        }
+
+        if (buf + offset + 1 > buf_end) {
+            aot_set_last_error("unexpected end of section or function");
+            return false;
+        }
+        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:
+    aot_set_last_error("integer too large");
+    return false;
+}
+
+#define read_leb_uint32(p, p_end, res)                         \
+    do {                                                       \
+        uint64 res64;                                          \
+        if (!read_leb((uint8 **)&p, p_end, 32, false, &res64)) \
+            goto fail;                                         \
+        res = (uint32)res64;                                   \
+    } while (0)
+
+static uint32
+get_name_section_size(AOTCompData *comp_data)
+{
+    const uint8 *p = comp_data->name_section_buf,
+                *p_end = comp_data->name_section_buf_end;
+    uint8 *buf, *buf_end;
+    uint32 name_type, subsection_size;
+    uint32 previous_name_type = 0;
+    uint32 num_func_name;
+    uint32 func_index;
+    uint32 previous_func_index = ~0U;
+    uint32 func_name_len;
+    uint32 name_index;
+    int i = 0;
+    uint32 name_len;
+    uint32 offset = 0;
+    uint32 max_aot_buf_size = 0;
+
+    if (p >= p_end) {
+        aot_set_last_error("unexpected end");
+        return 0;
+    }
+
+    max_aot_buf_size = 4 * (p_end - p);
+    if (!(buf = comp_data->aot_name_section_buf =
+              wasm_runtime_malloc(max_aot_buf_size))) {
+        aot_set_last_error("allocate memory for custom name section failed.");
+        return 0;
+    }
+    buf_end = buf + max_aot_buf_size;
+
+    read_leb_uint32(p, p_end, name_len);
+    offset = align_uint(offset, 4);
+    EMIT_U32(name_len);
+
+    if (name_len == 0 || p + name_len > p_end) {
+        aot_set_last_error("unexpected end");
+        return 0;
+    }
+
+    if (!check_utf8_str(p, name_len)) {
+        aot_set_last_error("invalid UTF-8 encoding");
+        return 0;
+    }
+
+    if (memcmp(p, "name", 4) != 0) {
+        aot_set_last_error("invalid custom name section");
+        return 0;
+    }
+    EMIT_BUF(p, name_len);
+    p += name_len;
+
+    while (p < p_end) {
+        read_leb_uint32(p, p_end, name_type);
+        if (i != 0) {
+            if (name_type == previous_name_type) {
+                aot_set_last_error("duplicate sub-section");
+                return 0;
+            }
+            if (name_type < previous_name_type) {
+                aot_set_last_error("out-of-order sub-section");
+                return 0;
+            }
+        }
+        previous_name_type = name_type;
+        read_leb_uint32(p, p_end, subsection_size);
+        switch (name_type) {
+            case SUB_SECTION_TYPE_FUNC:
+                if (subsection_size) {
+                    offset = align_uint(offset, 4);
+                    EMIT_U32(name_type);
+                    EMIT_U32(subsection_size);
+
+                    read_leb_uint32(p, p_end, num_func_name);
+                    EMIT_U32(num_func_name);
+
+                    for (name_index = 0; name_index < num_func_name;
+                         name_index++) {
+                        read_leb_uint32(p, p_end, func_index);
+                        offset = align_uint(offset, 4);
+                        EMIT_U32(func_index);
+                        if (func_index == previous_func_index) {
+                            aot_set_last_error("duplicate function name");
+                            return 0;
+                        }
+                        if (func_index < previous_func_index
+                            && previous_func_index != ~0U) {
+                            aot_set_last_error("out-of-order function index ");
+                            return 0;
+                        }
+                        previous_func_index = func_index;
+                        read_leb_uint32(p, p_end, func_name_len);
+                        offset = align_uint(offset, 2);
+                        EMIT_U16(func_name_len);
+                        EMIT_BUF(p, func_name_len);
+                        p += func_name_len;
+                    }
+                }
+                break;
+            case SUB_SECTION_TYPE_MODULE: /* TODO: Parse for module subsection
+                                           */
+            case SUB_SECTION_TYPE_LOCAL:  /* TODO: Parse for local subsection */
+            default:
+                p = p + subsection_size;
+                break;
+        }
+        i++;
+    }
+
+    return offset;
+fail:
+    return 0;
+}
+
 static bool
 aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
                      AOTCompData *comp_data, AOTObjectData *obj_data)
@@ -1537,7 +1813,7 @@ aot_emit_native_symbol(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
     AOTNativeSymbol *sym = NULL;
 
     if (bh_list_length(&comp_ctx->native_symbols) == 0)
-        /* emit only when threre are native symbols */
+        /* emit only when there are native symbols */
         return true;
 
     *p_offset = offset = align_uint(offset, 4);
@@ -1561,6 +1837,30 @@ aot_emit_native_symbol(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
     return true;
 }
 
+static bool
+aot_emit_name_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
+                      AOTCompData *comp_data, AOTCompContext *comp_ctx)
+{
+    if (comp_ctx->enable_aux_stack_frame) {
+        uint32 offset = *p_offset;
+
+        *p_offset = offset = align_uint(offset, 4);
+
+        EMIT_U32(AOT_SECTION_TYPE_CUSTOM);
+        /* sub section id + name section size */
+        EMIT_U32(sizeof(uint32) * 1 + comp_data->aot_name_section_size);
+        EMIT_U32(AOT_CUSTOM_SECTION_NAME);
+        bh_memcpy_s((uint8 *)(buf + offset), buf_end - buf,
+                    comp_data->aot_name_section_buf,
+                    comp_data->aot_name_section_size);
+        offset += comp_data->aot_name_section_size;
+
+        *p_offset = offset;
+    }
+
+    return true;
+}
+
 typedef uint32 U32;
 typedef int32 I32;
 typedef uint16 U16;
@@ -1970,7 +2270,7 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
     bool has_addend = str_starts_with(group->section_name, ".rela");
     uint8 *rela_content = NULL;
 
-    /* calculate relocations count and allcate memory */
+    /* calculate relocations count and allocate memory */
     if (!get_relocations_count(rel_sec, &group->relocation_count))
         return false;
     if (group->relocation_count == 0) {
@@ -2146,7 +2446,7 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
     char *name;
     uint32 size;
 
-    /* calculate relocation groups count and allcate memory */
+    /* calculate relocation groups count and allocate memory */
     if (!get_relocation_groups_count(obj_data, &group_count))
         return false;
 
@@ -2384,7 +2684,8 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
         || !aot_emit_export_section(buf, buf_end, &offset, comp_data, obj_data)
         || !aot_emit_relocation_section(buf, buf_end, &offset, comp_data,
                                         obj_data)
-        || !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx))
+        || !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx)
+        || !aot_emit_name_section(buf, buf_end, &offset, comp_data, comp_ctx))
         goto fail2;
 
 #if 0

+ 5 - 0
core/iwasm/interpreter/wasm.h

@@ -418,6 +418,11 @@ struct WASMModule {
     uint64 load_size;
     uint64 buf_code_size;
 #endif
+
+#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
+    const uint8 *name_section_buf;
+    const uint8 *name_section_buf_end;
+#endif
 };
 
 typedef struct BlockType {

+ 1 - 1
core/iwasm/interpreter/wasm_interp_classic.c

@@ -3643,7 +3643,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             frame->csp_boundary =
                 frame->csp_bottom + cur_wasm_func->max_block_num;
 
-            /* Initialize the local varialbes */
+            /* Initialize the local variables */
             memset(frame_lp + cur_func->param_cell_num, 0,
                    (uint32)(cur_func->local_cell_num * 4));
 

+ 1 - 1
core/iwasm/interpreter/wasm_interp_fast.c

@@ -3658,7 +3658,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             word_copy(frame->operand, (uint32 *)cur_wasm_func->consts,
                       cur_wasm_func->const_cell_num);
 
-            /* Initialize the local varialbes */
+            /* Initialize the local variables */
             memset(frame_lp + cur_func->param_cell_num, 0,
                    (uint32)(cur_func->local_cell_num * 4));
 

+ 2 - 0
core/iwasm/interpreter/wasm_loader.c

@@ -2838,6 +2838,8 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
 
 #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
     if (memcmp(p, "name", 4) == 0) {
+        module->name_section_buf = buf;
+        module->name_section_buf_end = buf_end;
         p += name_len;
         handle_name_section(p, p_end, module, error_buf, error_buf_size);
     }

+ 1 - 1
doc/wamr_api.md

@@ -283,7 +283,7 @@ void on_destroy()
 
 ## GUI API
 
-The API's is listed in header file ```core/app-framework/wgl/app/wa-inc/wgl.h``` which is implemented based on open soure 2D graphic library [LittlevGL](https://docs.littlevgl.com/en/html/index.html).
+The API's is listed in header file ```core/app-framework/wgl/app/wa-inc/wgl.h``` which is implemented based on open source 2D graphic library [LittlevGL](https://docs.littlevgl.com/en/html/index.html).
 
 ``` C
 static void btn_event_cb(wgl_obj_t btn, wgl_event_t event);