mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
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.
This commit is contained in:
parent
1a987ae59b
commit
788e14ed6c
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
.vs
|
.vs
|
||||||
.vscode
|
.vscode
|
||||||
|
/.idea
|
||||||
|
**/cmake-build-*/
|
||||||
**/*build/
|
**/*build/
|
||||||
core/deps/**
|
core/deps/**
|
||||||
core/shared/mem-alloc/tlsf
|
core/shared/mem-alloc/tlsf
|
||||||
|
|
|
@ -434,6 +434,133 @@ fail:
|
||||||
return false;
|
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
|
static bool
|
||||||
load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
|
load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
|
||||||
char *error_buf, uint32 error_buf_size)
|
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))
|
error_buf_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
case AOT_CUSTOM_SECTION_NAME:
|
||||||
|
if (!load_name_section(buf, buf_end, module, error_buf,
|
||||||
|
error_buf_size))
|
||||||
|
goto fail;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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) */
|
/* The layout is: literal size + literal + code (with plt table) */
|
||||||
read_uint32(buf, buf_end, module->literal_size);
|
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->literal = (uint8 *)buf;
|
||||||
module->code = (void *)(buf + module->literal_size);
|
module->code = (void *)(buf + module->literal_size);
|
||||||
module->code_size = (uint32)(buf_end - (uint8 *)module->code);
|
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;
|
AOTSection *section_list = NULL, *section_list_end = NULL, *section;
|
||||||
const uint8 *p = buf, *p_end = buf + size;
|
const uint8 *p = buf, *p_end = buf + size;
|
||||||
bool destory_aot_text = false;
|
bool destroy_aot_text = false;
|
||||||
uint32 native_symbol_count = 0;
|
uint32 native_symbol_count = 0;
|
||||||
uint32 section_type;
|
uint32 section_type;
|
||||||
uint32 section_size;
|
uint32 section_size;
|
||||||
|
@ -2403,7 +2535,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
|
||||||
bh_memcpy_s(aot_text, (uint32)total_size,
|
bh_memcpy_s(aot_text, (uint32)total_size,
|
||||||
section->section_body, (uint32)section_size);
|
section->section_body, (uint32)section_size);
|
||||||
section->section_body = aot_text;
|
section->section_body = aot_text;
|
||||||
destory_aot_text = true;
|
destroy_aot_text = true;
|
||||||
|
|
||||||
if ((uint32)total_size > section->section_body_size) {
|
if ((uint32)total_size > section->section_body_size) {
|
||||||
memset(aot_text + (uint32)section_size, 0,
|
memset(aot_text + (uint32)section_size, 0,
|
||||||
|
@ -2437,7 +2569,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
|
||||||
return true;
|
return true;
|
||||||
fail:
|
fail:
|
||||||
if (section_list)
|
if (section_list)
|
||||||
destroy_sections(section_list, destory_aot_text);
|
destroy_sections(section_list, destroy_aot_text);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2868,6 +3000,15 @@ aot_unload(AOTModule *module)
|
||||||
jit_code_entry_destroy(module->elf_hdr);
|
jit_code_entry_destroy(module->elf_hdr);
|
||||||
#endif
|
#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);
|
wasm_runtime_free(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2815,6 +2815,27 @@ aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
||||||
#endif /* WASM_ENABLE_REF_TYPES != 0 */
|
#endif /* WASM_ENABLE_REF_TYPES != 0 */
|
||||||
|
|
||||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 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 *
|
static const char *
|
||||||
get_func_name_from_index(const AOTModuleInstance *module_inst,
|
get_func_name_from_index(const AOTModuleInstance *module_inst,
|
||||||
uint32 func_index)
|
uint32 func_index)
|
||||||
|
@ -2822,6 +2843,14 @@ get_func_name_from_index(const AOTModuleInstance *module_inst,
|
||||||
const char *func_name = NULL;
|
const char *func_name = NULL;
|
||||||
AOTModule *module = module_inst->aot_module.ptr;
|
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) {
|
if (func_index < module->import_func_count) {
|
||||||
func_name = module->import_funcs[func_index].func_name;
|
func_name = module->import_funcs[func_index].func_name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ typedef enum AOTSectionType {
|
||||||
typedef enum AOTCustomSectionType {
|
typedef enum AOTCustomSectionType {
|
||||||
AOT_CUSTOM_SECTION_NATIVE_SYMBOL = 1,
|
AOT_CUSTOM_SECTION_NATIVE_SYMBOL = 1,
|
||||||
AOT_CUSTOM_SECTION_ACCESS_CONTROL = 2,
|
AOT_CUSTOM_SECTION_ACCESS_CONTROL = 2,
|
||||||
|
AOT_CUSTOM_SECTION_NAME = 3,
|
||||||
} AOTCustomSectionType;
|
} AOTCustomSectionType;
|
||||||
|
|
||||||
typedef struct AOTObjectDataSection {
|
typedef struct AOTObjectDataSection {
|
||||||
|
@ -133,7 +134,7 @@ typedef struct AOTModule {
|
||||||
uint32 mem_init_data_count;
|
uint32 mem_init_data_count;
|
||||||
AOTMemInitData **mem_init_data_list;
|
AOTMemInitData **mem_init_data_list;
|
||||||
|
|
||||||
/* native symobl */
|
/* native symbol */
|
||||||
uint32 native_symbol_count;
|
uint32 native_symbol_count;
|
||||||
void **native_symbol_list;
|
void **native_symbol_list;
|
||||||
|
|
||||||
|
@ -153,7 +154,7 @@ typedef struct AOTModule {
|
||||||
uint32 func_type_count;
|
uint32 func_type_count;
|
||||||
AOTFuncType **func_types;
|
AOTFuncType **func_types;
|
||||||
|
|
||||||
/* import global varaible info */
|
/* import global variable info */
|
||||||
uint32 import_global_count;
|
uint32 import_global_count;
|
||||||
AOTImportGlobal *import_globals;
|
AOTImportGlobal *import_globals;
|
||||||
|
|
||||||
|
@ -260,6 +261,11 @@ typedef struct AOTModule {
|
||||||
void *elf_hdr;
|
void *elf_hdr;
|
||||||
uint32 elf_size;
|
uint32 elf_size;
|
||||||
#endif
|
#endif
|
||||||
|
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||||
|
const char **aux_func_names;
|
||||||
|
uint32 *aux_func_indexes;
|
||||||
|
uint32 aux_func_name_count;
|
||||||
|
#endif
|
||||||
} AOTModule;
|
} AOTModule;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
@ -335,7 +341,7 @@ typedef struct AOTModuleInstance {
|
||||||
/* points to AOTTableInstance[] */
|
/* points to AOTTableInstance[] */
|
||||||
AOTPointer tables;
|
AOTPointer tables;
|
||||||
|
|
||||||
/* funciton pointer array */
|
/* function pointer array */
|
||||||
AOTPointer func_ptrs;
|
AOTPointer func_ptrs;
|
||||||
/* function type indexes */
|
/* function type indexes */
|
||||||
AOTPointer func_type_indexes;
|
AOTPointer func_type_indexes;
|
||||||
|
|
|
@ -224,7 +224,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
/* S + A */
|
/* S + A */
|
||||||
X = (int64)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) {
|
switch (reloc_type) {
|
||||||
case R_AARCH64_MOVW_UABS_G0:
|
case R_AARCH64_MOVW_UABS_G0:
|
||||||
if (X < 0 || X >= (1LL << 16))
|
if (X < 0 || X >= (1LL << 16))
|
||||||
|
@ -324,7 +324,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
/* S + A */
|
/* S + A */
|
||||||
X = (int64)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 */
|
/* write the imm12 back to instruction */
|
||||||
*(int32 *)P = (insn & 0xFFC003FF) | ((int32)((X & 0xFFF) << 10));
|
*(int32 *)P = (insn & 0xFFC003FF) | ((int32)((X & 0xFFF) << 10));
|
||||||
|
@ -354,7 +354,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
|
||||||
/* S + A */
|
/* S + A */
|
||||||
X = (int64)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 */
|
/* write the imm12 back to instruction */
|
||||||
switch (reloc_type) {
|
switch (reloc_type) {
|
||||||
|
|
|
@ -515,6 +515,12 @@ aot_create_comp_data(WASMModule *module)
|
||||||
if (comp_data->func_count && !(comp_data->funcs = aot_create_funcs(module)))
|
if (comp_data->func_count && !(comp_data->funcs = aot_create_funcs(module)))
|
||||||
goto fail;
|
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 */
|
/* Create aux data/heap/stack information */
|
||||||
comp_data->aux_data_end_global_index = module->aux_data_end_global_index;
|
comp_data->aux_data_end_global_index = module->aux_data_end_global_index;
|
||||||
comp_data->aux_data_end = module->aux_data_end;
|
comp_data->aux_data_end = module->aux_data_end;
|
||||||
|
@ -581,5 +587,8 @@ aot_destroy_comp_data(AOTCompData *comp_data)
|
||||||
if (comp_data->funcs)
|
if (comp_data->funcs)
|
||||||
aot_destroy_funcs(comp_data->funcs, comp_data->func_count);
|
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);
|
wasm_runtime_free(comp_data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,12 @@ typedef struct AOTCompData {
|
||||||
uint32 func_count;
|
uint32 func_count;
|
||||||
AOTFunc **funcs;
|
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 global_data_size;
|
||||||
|
|
||||||
uint32 start_func_index;
|
uint32 start_func_index;
|
||||||
|
|
|
@ -25,6 +25,71 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} 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 */
|
/* Internal function in object file */
|
||||||
typedef struct AOTObjectFunc {
|
typedef struct AOTObjectFunc {
|
||||||
char *func_name;
|
char *func_name;
|
||||||
|
@ -794,6 +859,9 @@ get_native_symbol_list_size(AOTCompContext *comp_ctx)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32
|
||||||
|
get_name_section_size(AOTCompData *comp_data);
|
||||||
|
|
||||||
static uint32
|
static uint32
|
||||||
get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|
||||||
AOTObjectData *obj_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);
|
size += get_relocation_section_size(obj_data);
|
||||||
|
|
||||||
if (get_native_symbol_list_size(comp_ctx) > 0) {
|
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);
|
size = align_uint(size, 4);
|
||||||
/* section id + section size + sub section id + symbol count */
|
/* section id + section size + sub section id + symbol count */
|
||||||
size += (uint32)sizeof(uint32) * 4;
|
size += (uint32)sizeof(uint32) * 4;
|
||||||
size += get_native_symbol_list_size(comp_ctx);
|
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;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,6 +1052,205 @@ static union {
|
||||||
EMIT_BUF(s, str_len); \
|
EMIT_BUF(s, str_len); \
|
||||||
} while (0)
|
} 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
|
static bool
|
||||||
aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
|
||||||
AOTCompData *comp_data, AOTObjectData *obj_data)
|
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;
|
AOTNativeSymbol *sym = NULL;
|
||||||
|
|
||||||
if (bh_list_length(&comp_ctx->native_symbols) == 0)
|
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;
|
return true;
|
||||||
|
|
||||||
*p_offset = offset = align_uint(offset, 4);
|
*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;
|
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 uint32 U32;
|
||||||
typedef int32 I32;
|
typedef int32 I32;
|
||||||
typedef uint16 U16;
|
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");
|
bool has_addend = str_starts_with(group->section_name, ".rela");
|
||||||
uint8 *rela_content = NULL;
|
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))
|
if (!get_relocations_count(rel_sec, &group->relocation_count))
|
||||||
return false;
|
return false;
|
||||||
if (group->relocation_count == 0) {
|
if (group->relocation_count == 0) {
|
||||||
|
@ -2146,7 +2446,7 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data)
|
||||||
char *name;
|
char *name;
|
||||||
uint32 size;
|
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))
|
if (!get_relocation_groups_count(obj_data, &group_count))
|
||||||
return false;
|
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_export_section(buf, buf_end, &offset, comp_data, obj_data)
|
||||||
|| !aot_emit_relocation_section(buf, buf_end, &offset, comp_data,
|
|| !aot_emit_relocation_section(buf, buf_end, &offset, comp_data,
|
||||||
obj_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;
|
goto fail2;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -418,6 +418,11 @@ struct WASMModule {
|
||||||
uint64 load_size;
|
uint64 load_size;
|
||||||
uint64 buf_code_size;
|
uint64 buf_code_size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||||
|
const uint8 *name_section_buf;
|
||||||
|
const uint8 *name_section_buf_end;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct BlockType {
|
typedef struct BlockType {
|
||||||
|
|
|
@ -3643,7 +3643,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
frame->csp_boundary =
|
frame->csp_boundary =
|
||||||
frame->csp_bottom + cur_wasm_func->max_block_num;
|
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,
|
memset(frame_lp + cur_func->param_cell_num, 0,
|
||||||
(uint32)(cur_func->local_cell_num * 4));
|
(uint32)(cur_func->local_cell_num * 4));
|
||||||
|
|
||||||
|
|
|
@ -3658,7 +3658,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
word_copy(frame->operand, (uint32 *)cur_wasm_func->consts,
|
word_copy(frame->operand, (uint32 *)cur_wasm_func->consts,
|
||||||
cur_wasm_func->const_cell_num);
|
cur_wasm_func->const_cell_num);
|
||||||
|
|
||||||
/* Initialize the local varialbes */
|
/* Initialize the local variables */
|
||||||
memset(frame_lp + cur_func->param_cell_num, 0,
|
memset(frame_lp + cur_func->param_cell_num, 0,
|
||||||
(uint32)(cur_func->local_cell_num * 4));
|
(uint32)(cur_func->local_cell_num * 4));
|
||||||
|
|
||||||
|
|
|
@ -2838,6 +2838,8 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
|
|
||||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||||
if (memcmp(p, "name", 4) == 0) {
|
if (memcmp(p, "name", 4) == 0) {
|
||||||
|
module->name_section_buf = buf;
|
||||||
|
module->name_section_buf_end = buf_end;
|
||||||
p += name_len;
|
p += name_len;
|
||||||
handle_name_section(p, p_end, module, error_buf, error_buf_size);
|
handle_name_section(p, p_end, module, error_buf, error_buf_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,7 @@ void on_destroy()
|
||||||
|
|
||||||
## GUI API
|
## 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
|
``` C
|
||||||
static void btn_event_cb(wgl_obj_t btn, wgl_event_t event);
|
static void btn_event_cb(wgl_obj_t btn, wgl_event_t event);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user