diff --git a/core/iwasm/aot/aot_intrinsic.c b/core/iwasm/aot/aot_intrinsic.c index 2b4a350b9..b11edd7b0 100644 --- a/core/iwasm/aot/aot_intrinsic.c +++ b/core/iwasm/aot/aot_intrinsic.c @@ -53,6 +53,8 @@ static const aot_intrinsic g_intrinsic_mapping[] = { { "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 }, { "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 }, { "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 }, + { "i32_trunc_f32_u", "aot_intrinsic_f32_to_u32", AOT_INTRINSIC_FLAG_F32_TO_U32 }, + { "i32_trunc_f32_s", "aot_intrinsic_f32_to_i32", AOT_INTRINSIC_FLAG_F32_TO_I32 }, { "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 }, { "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 }, { "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 }, @@ -423,6 +425,9 @@ int32 aot_intrinsic_f32_cmp(AOTFloatCond cond, float32 lhs, float32 rhs) { switch (cond) { + case FLOAT_EQ: + return (float32)fabs(lhs - rhs) <= WA_FLT_EPSILON ? 1 : 0; + case FLOAT_LT: return lhs < rhs ? 1 : 0; @@ -451,6 +456,9 @@ int32 aot_intrinsic_f64_cmp(AOTFloatCond cond, float64 lhs, float64 rhs) { switch (cond) { + case FLOAT_EQ: + return fabs(lhs - rhs) <= WA_DBL_EPSILON ? 1 : 0; + case FLOAT_LT: return lhs < rhs ? 1 : 0; diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 7631be23f..a786a5032 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -174,6 +174,7 @@ GET_U64_FROM_ADDR(uint32 *addr) #define E_TYPE_REL 1 /* Relocatable file */ #define E_TYPE_EXEC 2 /* Executable file */ #define E_TYPE_DYN 3 /* Shared object file */ +#define E_TYPE_XIP 4 /* eXecute In Place file */ /* Legal values for e_machine (architecture). */ #define E_MACHINE_386 3 /* Intel 80386 */ @@ -422,10 +423,10 @@ load_target_info_section(const uint8 *buf, const uint8 *buf_end, } /* Check target elf file type */ - if (target_info.e_type != E_TYPE_REL) { + if (target_info.e_type != E_TYPE_REL && target_info.e_type != E_TYPE_XIP) { set_error_buf(error_buf, error_buf_size, "invalid object file type, " - "expected relocatable file type but got others"); + "expected relocatable or XIP file type but got others"); return false; } @@ -476,8 +477,6 @@ load_native_symbol_section(const uint8 *buf, const uint8 *buf_end, read_uint32(p, p_end, cnt); - module->native_symbol_count = cnt; - if (cnt > 0) { module->native_symbol_list = wasm_runtime_malloc(cnt * sizeof(void *)); if (module->native_symbol_list == NULL) { @@ -1467,7 +1466,7 @@ load_text_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module, } #endif - if ((module->code_size > 0) && (module->native_symbol_count == 0)) { + if ((module->code_size > 0) && !module->is_indirect_mode) { plt_base = (uint8 *)buf_end - get_plt_table_size(); init_plt_table(plt_base); } @@ -2192,7 +2191,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, ) { #if !defined(BH_PLATFORM_LINUX) && !defined(BH_PLATFORM_LINUX_SGX) \ && !defined(BH_PLATFORM_DARWIN) - if (module->native_symbol_count > 0) { + if (module->is_indirect_mode) { set_error_buf(error_buf, error_buf_size, "cannot apply relocation to text section " "for aot file generated with " @@ -2492,33 +2491,36 @@ destroy_sections(AOTSection *section_list, bool destroy_aot_text) } static bool -resolve_native_symbols(const uint8 *buf, uint32 size, uint32 *p_count, - char *error_buf, uint32 error_buf_size) +resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode, + char *error_buf, uint32 error_buf_size) { const uint8 *p = buf, *p_end = buf + size; uint32 section_type; uint32 section_size = 0; + uint16 e_type = 0; p += 8; while (p < p_end) { read_uint32(p, p_end, section_type); if (section_type <= AOT_SECTION_TYPE_SIGANATURE - || section_type == AOT_SECTION_TYPE_CUSTOM) { + || section_type == AOT_SECTION_TYPE_TARGET_INFO) { read_uint32(p, p_end, section_size); CHECK_BUF(p, p_end, section_size); - if (section_type == AOT_SECTION_TYPE_CUSTOM) { - read_uint32(p, p_end, section_type); - if (section_type == AOT_CUSTOM_SECTION_NATIVE_SYMBOL) { - /* Read the count of native symbol */ - read_uint32(p, p_end, *p_count); - return true; + if (section_type == AOT_SECTION_TYPE_TARGET_INFO) { + p += 4; + read_uint16(p, p_end, e_type); + if (e_type == E_TYPE_XIP) { + *p_mode = true; } - p -= sizeof(uint32); + else { + *p_mode = false; + } + break; } } else if (section_type > AOT_SECTION_TYPE_SIGANATURE) { set_error_buf(error_buf, error_buf_size, - "resolve native symbol failed"); + "resolve execute mode failed"); break; } p += section_size; @@ -2536,18 +2538,18 @@ 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 destroy_aot_text = false; - uint32 native_symbol_count = 0; + bool is_indirect_mode = false; uint32 section_type; uint32 section_size; uint64 total_size; uint8 *aot_text; - if (!resolve_native_symbols(buf, size, &native_symbol_count, error_buf, - error_buf_size)) { + if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf, + error_buf_size)) { goto fail; } - module->native_symbol_count = native_symbol_count; + module->is_indirect_mode = is_indirect_mode; p += 8; while (p < p_end) { @@ -2568,7 +2570,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size, section->section_body_size = section_size; if (section_type == AOT_SECTION_TYPE_TEXT) { - if ((section_size > 0) && (native_symbol_count == 0)) { + if ((section_size > 0) && !module->is_indirect_mode) { int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC; #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \ @@ -2671,8 +2673,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf, if (!ret) { /* If load_from_sections() fails, then aot text is destroyed in destroy_sections() */ - destroy_sections(section_list, - module->native_symbol_count == 0 ? true : false); + destroy_sections(section_list, module->is_indirect_mode ? false : true); /* aot_unload() won't destroy aot text again */ module->code = NULL; } @@ -3039,7 +3040,7 @@ aot_unload(AOTModule *module) if (module->const_str_set) bh_hash_map_destroy(module->const_str_set); - if (module->code && (module->native_symbol_count == 0)) { + if (module->code && !module->is_indirect_mode) { /* The layout is: literal size + literal + code (with plt table) */ uint8 *mmap_addr = module->literal - sizeof(uint32); uint32 total_size = diff --git a/core/iwasm/aot/aot_reloc.h b/core/iwasm/aot/aot_reloc.h index 65fccedeb..c0ca507ed 100644 --- a/core/iwasm/aot/aot_reloc.h +++ b/core/iwasm/aot/aot_reloc.h @@ -99,6 +99,8 @@ typedef struct { REG_SYM(aot_intrinsic_i64_to_f64), \ REG_SYM(aot_intrinsic_u64_to_f64), \ REG_SYM(aot_intrinsic_f64_to_f32), \ + REG_SYM(aot_intrinsic_f32_to_i32), \ + REG_SYM(aot_intrinsic_f32_to_u32), \ REG_SYM(aot_intrinsic_f64_to_i32), \ REG_SYM(aot_intrinsic_f64_to_u32), \ REG_SYM(aot_intrinsic_f32_to_f64), \ diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 22d585892..08a7a9089 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -135,7 +135,6 @@ typedef struct AOTModule { AOTMemInitData **mem_init_data_list; /* native symbol */ - uint32 native_symbol_count; void **native_symbol_list; /* import tables */ @@ -246,6 +245,9 @@ typedef struct AOTModule { /* is jit mode or not */ bool is_jit_mode; + /* is indirect mode or not */ + bool is_indirect_mode; + #if WASM_ENABLE_JIT != 0 WASMModule *wasm_module; AOTCompContext *comp_ctx; diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 075e422c9..e97b81a86 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -56,6 +56,8 @@ static void wasm_runtime_destroy_registered_module_list(); #endif /* WASM_ENABLE_MULTI_MODULE */ +#define E_TYPE_XIP 4 + #if WASM_ENABLE_REF_TYPES != 0 /* Initialize externref hashmap */ static bool @@ -309,6 +311,14 @@ align_ptr(const uint8 *p, uint32 b) return false; \ } while (0) +#define read_uint16(p, p_end, res) \ + do { \ + p = (uint8 *)align_ptr(p, sizeof(uint16)); \ + CHECK_BUF(p, p_end, sizeof(uint16)); \ + res = *(uint16 *)p; \ + p += sizeof(uint16); \ + } while (0) + #define read_uint32(p, p_end, res) \ do { \ p = (uint8 *)align_ptr(p, sizeof(uint32)); \ @@ -321,7 +331,8 @@ bool wasm_runtime_is_xip_file(const uint8 *buf, uint32 size) { const uint8 *p = buf, *p_end = buf + size; - uint32 section_type, sub_section_type, section_size; + uint32 section_type, section_size; + uint16 e_type; if (get_package_type(buf, size) != Wasm_Module_AoT) return false; @@ -333,14 +344,12 @@ wasm_runtime_is_xip_file(const uint8 *buf, uint32 size) read_uint32(p, p_end, section_size); CHECK_BUF(p, p_end, section_size); - if (section_type == AOT_SECTION_TYPE_CUSTOM) { - read_uint32(p, p_end, sub_section_type); - if (sub_section_type == AOT_CUSTOM_SECTION_NATIVE_SYMBOL) { + if (section_type == AOT_SECTION_TYPE_TARGET_INFO) { + p += 4; + read_uint16(p, p_end, e_type); + if (e_type == E_TYPE_XIP) { return true; } - else { - p -= sizeof(uint32); - } } else if (section_type >= AOT_SECTION_TYPE_SIGANATURE) { return false; diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index aac8fee95..be8310585 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -1909,6 +1909,9 @@ struct coff_hdr { U16 u16Characs; }; +#define E_TYPE_REL 1 +#define E_TYPE_XIP 4 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_IA64 0x0200 @@ -2025,7 +2028,13 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) return false; } coff_header = (struct coff_hdr *)elf_buf; - obj_data->target_info.e_type = 1; + + /* Emit eXecute In Place file type while in indirect mode */ + if (comp_ctx->is_indirect_mode) + obj_data->target_info.e_type = E_TYPE_XIP; + else + obj_data->target_info.e_type = E_TYPE_REL; + obj_data->target_info.e_machine = coff_header->u16Machine; obj_data->target_info.e_version = 1; obj_data->target_info.e_flags = 0; @@ -2047,6 +2056,11 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) } elf_header = (struct elf32_ehdr *)elf_buf; + + /* Emit eXecute In Place file type while in indirect mode */ + if (comp_ctx->is_indirect_mode) + elf_header->e_type = E_TYPE_XIP; + SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin); SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin); SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin); @@ -2063,6 +2077,11 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) } elf_header = (struct elf64_ehdr *)elf_buf; + + /* Emit eXecute In Place file type while in indirect mode */ + if (comp_ctx->is_indirect_mode) + elf_header->e_type = E_TYPE_XIP; + SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin); SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin); SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin); diff --git a/core/shared/utils/bh_platform.h b/core/shared/utils/bh_platform.h index 86aef839d..3bbd0c82b 100644 --- a/core/shared/utils/bh_platform.h +++ b/core/shared/utils/bh_platform.h @@ -35,4 +35,9 @@ #define WA_FREE wasm_runtime_free #endif +/* The epsilon value is from https://www.cplusplus.com/reference/cfloat/ */ + +#define WA_FLT_EPSILON 1e-5f +#define WA_DBL_EPSILON 1e-9 + #endif /* #ifndef _BH_PLATFORM_H */