Просмотр исходного кода

Fix the error of AOT mode on the "i386-windows-msvc" platform (#4183)

* Fix errors on the "i386-windows-msvc" platform
* Refactor symbol name handling for AOT COFF32 binary format
* Fix preprocessor directive placement for Windows compatibility in aot_reloc_x86_32.c

---------

Co-authored-by: liang.he@intel.com <liang.he@intel.com>
a seven 9 месяцев назад
Родитель
Сommit
fc78d67e15

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

@@ -3285,8 +3285,25 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
             cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
         }
 
+#if WASM_ENABLE_AOT_STACK_FRAME != 0
+        void *prev_frame = get_top_frame(exec_env);
+        if (!is_frame_per_function(exec_env)
+            && !aot_alloc_frame(exec_env, func_idx)) {
+            if (argv1 != argv1_buf)
+                wasm_runtime_free(argv1);
+            return false;
+        }
+#endif
         ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
                                      attachment, argv1, argc, argv);
+#if WASM_ENABLE_AOT_STACK_FRAME != 0
+        /* Free all frames allocated, note that some frames
+           may be allocated in AOT code and haven't been
+           freed if exception occurred */
+        while (get_top_frame(exec_env) != prev_frame)
+            aot_free_frame(exec_env);
+#endif
+
         if (!ret) {
             if (argv1 != argv1_buf)
                 wasm_runtime_free(argv1);
@@ -3327,8 +3344,25 @@ aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
         return true;
     }
     else {
+#if WASM_ENABLE_AOT_STACK_FRAME != 0
+        void *prev_frame = get_top_frame(exec_env);
+        /* Only allocate frame for frame-per-call mode; in the
+           frame-per-function mode the frame is allocated at the
+           beginning of the function. */
+        if (!is_frame_per_function(exec_env)
+            && !aot_alloc_frame(exec_env, func_idx)) {
+            return false;
+        }
+#endif
         ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
                                      attachment, argv, argc, argv);
+#if WASM_ENABLE_AOT_STACK_FRAME != 0
+        /* Free all frames allocated, note that some frames
+           may be allocated in AOT code and haven't been
+           freed if exception occurred */
+        while (get_top_frame(exec_env) != prev_frame)
+            aot_free_frame(exec_env);
+#endif
         if (!ret)
             goto fail;
 

+ 19 - 12
core/iwasm/aot/arch/aot_reloc_x86_32.c

@@ -30,36 +30,39 @@ void __umoddi3();
 #pragma function(floor)
 #pragma function(ceil)
 
-static int64
-__divdi3(int64 a, int64 b)
+static int64 __stdcall __divdi3(int64 a, int64 b)
 {
     return a / b;
 }
 
-static uint64
-__udivdi3(uint64 a, uint64 b)
+static uint64 __stdcall __udivdi3(uint64 a, uint64 b)
 {
     return a / b;
 }
 
-static int64
-__moddi3(int64 a, int64 b)
+static int64 __stdcall __moddi3(int64 a, int64 b)
 {
     return a % b;
 }
 
-static uint64
-__umoddi3(uint64 a, uint64 b)
+static uint64 __stdcall __umoddi3(uint64 a, uint64 b)
 {
     return a % b;
 }
-#endif
 
-static uint64
-__aulldiv(uint64 a, uint64 b)
+static uint64 __stdcall __aulldiv(uint64 a, uint64 b)
+{
+    return a / b;
+}
+static int64 __stdcall __alldiv(int64 a, int64 b)
 {
     return a / b;
 }
+static int64 __stdcall __allrem(int64 a, int64 b)
+{
+    return a % b;
+}
+#endif /* !defined(_WIN32) && !defined(_WIN32_) */
 
 /* clang-format off */
 static SymbolMap target_sym_map[] = {
@@ -69,7 +72,11 @@ static SymbolMap target_sym_map[] = {
     REG_SYM(__udivdi3),
     REG_SYM(__moddi3),
     REG_SYM(__umoddi3),
-    REG_SYM(__aulldiv)
+#if defined(_WIN32) || defined(_WIN32_)
+    REG_SYM(__aulldiv),
+    REG_SYM(__alldiv),
+    REG_SYM(__allrem)
+#endif /* defined(_WIN32) || defined(_WIN32_) */
 };
 /* clang-format on */
 

+ 36 - 22
core/iwasm/compilation/aot_emit_aot_file.c

@@ -920,9 +920,11 @@ get_relocations_size(AOTObjectData *obj_data,
         /* ignore the relocations to aot_func_internal#n in text section
            for windows platform since they will be applied in
            aot_emit_text_section */
+
+        const char *name = relocation->symbol_name;
         if ((!strcmp(relocation_group->section_name, ".text")
              || !strcmp(relocation_group->section_name, ".ltext"))
-            && !strncmp(relocation->symbol_name, AOT_FUNC_INTERNAL_PREFIX,
+            && !strncmp(name, AOT_FUNC_INTERNAL_PREFIX,
                         strlen(AOT_FUNC_INTERNAL_PREFIX))
             && ((!strncmp(obj_data->comp_ctx->target_arch, "x86_64", 6)
                  /* Windows AOT_COFF64_BIN_TYPE */
@@ -2489,8 +2491,8 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
                 relocation_count = relocation_group->relocation_count;
                 for (j = 0; j < relocation_count; j++) {
                     /* relocation to aot_func_internal#n */
-                    if (str_starts_with(relocation->symbol_name,
-                                        AOT_FUNC_INTERNAL_PREFIX)
+                    const char *name = relocation->symbol_name;
+                    if (str_starts_with(name, AOT_FUNC_INTERNAL_PREFIX)
                         && ((obj_data->target_info.bin_type
                                  == 6 /* AOT_COFF64_BIN_TYPE */
                              && relocation->relocation_type
@@ -2500,8 +2502,7 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
                                 && relocation->relocation_type
                                        == 20 /* IMAGE_REL_I386_REL32 */))) {
                         uint32 func_idx =
-                            atoi(relocation->symbol_name
-                                 + strlen(AOT_FUNC_INTERNAL_PREFIX));
+                            atoi(name + strlen(AOT_FUNC_INTERNAL_PREFIX));
                         uint64 text_offset, reloc_offset, reloc_addend;
 
                         bh_assert(func_idx < obj_data->func_count);
@@ -3052,6 +3053,27 @@ typedef struct elf64_rela {
 #define SET_TARGET_INFO_FIELD(f, v, type, little) \
     SET_TARGET_INFO_VALUE(f, elf_header->v, type, little)
 
+/* in windows 32, the symbol name may start with '_' */
+static char *
+LLVMGetSymbolNameAndUnDecorate(LLVMSymbolIteratorRef si,
+                               AOTTargetInfo target_info)
+{
+    char *original_name = (char *)LLVMGetSymbolName(si);
+    if (!original_name) {
+        return NULL;
+    }
+
+    if (target_info.bin_type != AOT_COFF32_BIN_TYPE) {
+        return original_name;
+    }
+
+    if (*original_name == '_') {
+        return ++original_name;
+    }
+
+    return original_name;
+}
+
 static bool
 aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
 {
@@ -3526,12 +3548,9 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
     }
 
     while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) {
-        if ((name = LLVMGetSymbolName(sym_itr))
-            && (!strcmp(name, aot_stack_sizes_alias_name)
-                /* symbol of COFF32 starts with "_" */
-                || (obj_data->target_info.bin_type == AOT_COFF32_BIN_TYPE
-                    && !strncmp(name, "_", 1)
-                    && !strcmp(name + 1, aot_stack_sizes_alias_name)))) {
+        if ((name =
+                 LLVMGetSymbolNameAndUnDecorate(sym_itr, obj_data->target_info))
+            && (!strcmp(name, aot_stack_sizes_alias_name))) {
 #if 0 /* cf. https://github.com/llvm/llvm-project/issues/67765 */
             uint64 sz = LLVMGetSymbolSize(sym_itr);
             if (sz != sizeof(uint32) * obj_data->func_count
@@ -3695,8 +3714,8 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
     }
 
     while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) {
-        if ((name = (char *)LLVMGetSymbolName(sym_itr))
-            && str_starts_with(name, prefix)) {
+        name = LLVMGetSymbolNameAndUnDecorate(sym_itr, obj_data->target_info);
+        if (name && str_starts_with(name, prefix)) {
             /* symbol aot_func#n */
             func_index = (uint32)atoi(name + strlen(prefix));
             if (func_index < obj_data->func_count) {
@@ -3734,8 +3753,7 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
                 }
             }
         }
-        else if ((name = (char *)LLVMGetSymbolName(sym_itr))
-                 && str_starts_with(name, AOT_FUNC_INTERNAL_PREFIX)) {
+        else if (name && str_starts_with(name, AOT_FUNC_INTERNAL_PREFIX)) {
             /* symbol aot_func_internal#n */
             func_index = (uint32)atoi(name + strlen(AOT_FUNC_INTERNAL_PREFIX));
             if (func_index < obj_data->func_count) {
@@ -3883,7 +3901,8 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
 
         /* set relocation fields */
         relocation->relocation_type = (uint32)type;
-        relocation->symbol_name = (char *)LLVMGetSymbolName(rel_sym);
+        relocation->symbol_name =
+            LLVMGetSymbolNameAndUnDecorate(rel_sym, obj_data->target_info);
         relocation->relocation_offset = offset;
         if (!strcmp(group->section_name, ".rela.text.unlikely.")
             || !strcmp(group->section_name, ".rel.text.unlikely.")) {
@@ -3910,12 +3929,7 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data,
          * Note: aot_stack_sizes_section_name section only contains
          * stack_sizes table.
          */
-        if (!strcmp(relocation->symbol_name, aot_stack_sizes_name)
-            /* in windows 32, the symbol name may start with '_' */
-            || (strlen(relocation->symbol_name) > 0
-                && relocation->symbol_name[0] == '_'
-                && !strcmp(relocation->symbol_name + 1,
-                           aot_stack_sizes_name))) {
+        if (!strcmp(relocation->symbol_name, aot_stack_sizes_name)) {
             /* discard const */
             relocation->symbol_name = (char *)aot_stack_sizes_section_name;
         }