瀏覽代碼

Add new E_TYPE_XIP to indicate XIP mode (#874)

Emit e_type = E_TYPE_XIP in target info section to indicate that it is
an XIP file, and replace related checks in aot loader.
Huang Qi 4 年之前
父節點
當前提交
208cafc776

+ 8 - 0
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;
 

+ 26 - 25
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;
+                }
+                else {
+                    *p_mode = false;
                 }
-                p -= sizeof(uint32);
+                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 =

+ 2 - 0
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),    \

+ 3 - 1
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;

+ 16 - 7
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;

+ 20 - 1
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);

+ 5 - 0
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 */