فهرست منبع

Fix some issues for Arm platform. (#457)

Motivation:
we found some issues during enable the WAMR on arm devices, such as relocation issues, stack alignment issues.

Proposed change:
We optimized the relocation process for arm platform, for relocation jump table, the SP should be aligned to 16 bytes. And we also make "getentropy" worked for other non-supported platform.
sophy228 5 سال پیش
والد
کامیت
c8b0a1cee1

+ 154 - 14
core/iwasm/aot/arch/aot_reloc_aarch64.c

@@ -1,12 +1,36 @@
 /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * Copyright (C) 2020 Intel Corporation. All rights reserved.
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
 #include "aot_reloc.h"
 
+#define R_AARCH64_MOVW_UABS_G0          263
+#define R_AARCH64_MOVW_UABS_G0_NC       264
+#define R_AARCH64_MOVW_UABS_G1          265
+#define R_AARCH64_MOVW_UABS_G1_NC       266
+#define R_AARCH64_MOVW_UABS_G2          267
+#define R_AARCH64_MOVW_UABS_G2_NC       268
+#define R_AARCH64_MOVW_UABS_G3          269
+
+#define R_AARCH64_MOVW_SABS_G0          270
+#define R_AARCH64_MOVW_SABS_G1          271
+#define R_AARCH64_MOVW_SABS_G2          272
+
+#define R_AARCH64_ADR_PREL_LO19         273
+#define R_AARCH64_ADR_PREL_LO21         274
 #define R_AARCH64_ADR_PREL_PG_HI21      275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC   276
+
 #define R_AARCH64_ADD_ABS_LO12_NC       277
+
+#define R_AARCH64_LDST8_ABS_LO12_NC     278
+#define R_AARCH64_LDST16_ABS_LO12_NC    284
+#define R_AARCH64_LDST32_ABS_LO12_NC    285
+#define R_AARCH64_LDST64_ABS_LO12_NC    286
+#define R_AARCH64_LDST128_ABS_LO12_NC   299
+
+#define R_AARCH64_JUMP26                282
 #define R_AARCH64_CALL26                283
 
 static SymbolMap target_sym_map[] = {
@@ -57,8 +81,8 @@ get_current_target(char *target_buf, uint32 target_buf_size)
 static uint32
 get_plt_item_size()
 {
-    /* 8*4 bytes instructions and 8 bytes symbol address */
-    return 40;
+    /* 6*4 bytes instructions and 8 bytes symbol address */
+    return 32;
 }
 
 void
@@ -67,13 +91,11 @@ init_plt_table(uint8 *plt)
     uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
     for (i = 0; i < num; i++) {
         uint32 *p = (uint32*)plt;
-        *p++ = 0xd10023ff; /* sub  sp, sp, #0x8 */
-        *p++ = 0xf90003fe; /* str  x30, [sp]    */
-        *p++ = 0x100000de; /* adr  x30, #24     */
+        *p++ = 0xf81f0ffe; /* str  x30, [sp, #-16]! */
+        *p++ = 0x100000be; /* adr  x30, #20  ;symbol addr is PC + 5 instructions below */
         *p++ = 0xf94003de; /* ldr  x30, [x30]   */
         *p++ = 0xd63f03c0; /* blr  x30          */
-        *p++ = 0xf94003fe; /* ldr  x30, [sp]    */
-        *p++ = 0x910023ff; /* add  sp, sp, #0x8 */
+        *p++ = 0xf84107fe; /* ldr  x30, [sp], #16  */
         *p++ = 0xd61f03c0; /* br   x30          */
         /* symbol addr */
         *(uint64*)p = (uint64)(uintptr_t)target_sym_map[i].symbol_addr;
@@ -173,7 +195,74 @@ apply_relocation(AOTModule *module,
             break;
         }
 
+        case R_AARCH64_MOVW_UABS_G0:
+        case R_AARCH64_MOVW_UABS_G0_NC:
+        case R_AARCH64_MOVW_UABS_G1:
+        case R_AARCH64_MOVW_UABS_G1_NC:
+        case R_AARCH64_MOVW_UABS_G2:
+        case R_AARCH64_MOVW_UABS_G2_NC:
+        case R_AARCH64_MOVW_UABS_G3:
+        {
+            void *S = symbol_addr, *P = (void*)(target_section_addr + reloc_offset);
+            int64 X, A, initial_addend;
+            int32 insn, imm16;
+
+            CHECK_RELOC_OFFSET(sizeof(int32));
+
+            insn = *(int32*)P;
+            imm16 = (insn >> 5) & 0xFFFF;
+
+            SIGN_EXTEND_TO_INT64(imm16, 16, initial_addend);
+            A = initial_addend;
+            A += (int64)reloc_addend;
+
+            /* S + A */
+            X = (int64)S + A;
+
+            /* No need to check overflow for this reloction type */
+            switch (reloc_type) {
+                case R_AARCH64_MOVW_UABS_G0:
+                    if (X < 0 || X >= (1LL << 16))
+                        goto overflow_check_fail;
+                    break;
+                case R_AARCH64_MOVW_UABS_G1:
+                    if (X < 0 || X >= (1LL << 32))
+                        goto overflow_check_fail;
+                    break;
+                case R_AARCH64_MOVW_UABS_G2:
+                    if (X < 0 || X >= (1LL << 48))
+                        goto overflow_check_fail;
+                    break;
+                default:
+                    break;
+            }
+
+            /* write the imm16 back to bits[5:20] of instruction */
+            switch (reloc_type) {
+                case R_AARCH64_MOVW_UABS_G0:
+                case R_AARCH64_MOVW_UABS_G0_NC:
+                    *(int32*)P = (insn & 0xFFE0001F) | ((int32)((X & 0xFFFF) << 5));
+                    break;
+                case R_AARCH64_MOVW_UABS_G1:
+                case R_AARCH64_MOVW_UABS_G1_NC:
+                    *(int32*)P = (insn & 0xFFE0001F) | ((int32)(((X >> 16) & 0xFFFF) << 5));
+                    break;
+                case R_AARCH64_MOVW_UABS_G2:
+                case R_AARCH64_MOVW_UABS_G2_NC:
+                    *(int32*)P = (insn & 0xFFE0001F) | ((int32)(((X >> 32) & 0xFFFF) << 5));
+                    break;
+                case R_AARCH64_MOVW_UABS_G3:
+                    *(int32*)P = (insn & 0xFFE0001F) | ((int32)(((X >> 48) & 0xFFFF) << 5));
+                    break;
+                default:
+                    bh_assert(0);
+                    break;
+            }
+            break;
+        }
+
         case R_AARCH64_ADR_PREL_PG_HI21:
+        case R_AARCH64_ADR_PREL_PG_HI21_NC:
         {
             void *S = symbol_addr, *P = (void*)(target_section_addr + reloc_offset);
             int64 X, A, initial_addend;
@@ -194,12 +283,9 @@ apply_relocation(AOTModule *module,
             X = Page((int64)S + A) - Page((int64)P);
 
             /* Check overflow: +-4GB */
-            if (X > ((int64)4 * BH_GB) || X < ((int64)-4 * BH_GB)) {
-                set_error_buf(error_buf, error_buf_size,
-                              "AOT module load failed: "
-                              "target address out of range.");
-                return false;
-            }
+            if (reloc_type == R_AARCH64_ADR_PREL_PG_HI21
+                && (X > ((int64)4 * BH_GB) || X < ((int64)-4 * BH_GB)))
+                goto overflow_check_fail;
 
             /* write the imm21 back to instruction */
             immhi19 = (int32)(((X >> 12) >> 2) & 0x7FFFF);
@@ -234,6 +320,54 @@ apply_relocation(AOTModule *module,
             break;
         }
 
+        case R_AARCH64_LDST8_ABS_LO12_NC:
+        case R_AARCH64_LDST16_ABS_LO12_NC:
+        case R_AARCH64_LDST32_ABS_LO12_NC:
+        case R_AARCH64_LDST64_ABS_LO12_NC:
+        case R_AARCH64_LDST128_ABS_LO12_NC:
+        {
+            void *S = symbol_addr, *P = (void*)(target_section_addr + reloc_offset);
+            int64 X, A, initial_addend;
+            int32 insn, imm12;
+
+            CHECK_RELOC_OFFSET(sizeof(int32));
+
+            insn = *(int32*)P;
+            imm12 = (insn >> 10) & 0xFFF;
+
+            SIGN_EXTEND_TO_INT64(imm12, 12, initial_addend);
+            A = initial_addend;
+            A += (int64)reloc_addend;
+
+            /* S + A */
+            X = (int64)S + A;
+
+            /* No need to check overflow for this reloction type */
+
+            /* write the imm12 back to instruction */
+            switch (reloc_type) {
+                case R_AARCH64_LDST8_ABS_LO12_NC:
+                    *(int32*)P = (insn & 0xFFC003FF) | ((int32)((X & 0xFFF) << 10));
+                    break;
+                case R_AARCH64_LDST16_ABS_LO12_NC:
+                    *(int32*)P = (insn & 0xFFC003FF) | ((int32)(((X & 0xFFF) >> 1) << 10));
+                    break;
+                case R_AARCH64_LDST32_ABS_LO12_NC:
+                    *(int32*)P = (insn & 0xFFC003FF) | ((int32)(((X & 0xFFF) >> 2) << 10));
+                    break;
+                case R_AARCH64_LDST64_ABS_LO12_NC:
+                    *(int32*)P = (insn & 0xFFC003FF) | ((int32)(((X & 0xFFF) >> 3) << 10));
+                    break;
+                case R_AARCH64_LDST128_ABS_LO12_NC:
+                    *(int32*)P = (insn & 0xFFC003FF) | ((int32)(((X & 0xFFF) >> 4) << 10));
+                    break;
+                default:
+                    bh_assert(0);
+                    break;
+            }
+            break;
+        }
+
         default:
             if (error_buf != NULL)
                 snprintf(error_buf, error_buf_size,
@@ -244,5 +378,11 @@ apply_relocation(AOTModule *module,
     }
 
     return true;
+
+overflow_check_fail:
+    set_error_buf(error_buf, error_buf_size,
+                  "AOT module load failed: "
+                  "target address out of range.");
+    return false;
 }
 

+ 2 - 1
core/iwasm/compilation/aot_emit_numberic.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * Copyright (C) 2020 Intel Corporation. All rights reserved.
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
@@ -744,6 +744,7 @@ static bool
 is_target_arm(AOTCompContext *comp_ctx)
 {
     return !strncmp(comp_ctx->target_arch, "arm", 3) ||
+           !strncmp(comp_ctx->target_arch, "aarch64", 7) ||
            !strncmp(comp_ctx->target_arch, "thumb", 5);
 }
 

+ 8 - 1
core/iwasm/libraries/libc-emcc/libc_emcc_wrapper.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ * Copyright (C) 2020 Intel Corporation.  All rights reserved.
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
@@ -7,6 +7,9 @@
 #include "bh_log.h"
 #include "wasm_export.h"
 #include "../interpreter/wasm.h"
+#ifndef _DEFAULT_SOURCE
+#include "sys/syscall.h"
+#endif
 
 #define get_module_inst(exec_env) \
     wasm_runtime_get_module_inst(exec_env)
@@ -264,7 +267,11 @@ getentropy_wrapper(wasm_exec_env_t exec_env, void *buffer, uint32 length)
 {
     if (buffer == NULL)
         return -1;
+#ifdef _DEFAULT_SOURCE
     return getentropy(buffer, length);
+#else
+    return syscall(SYS_getrandom, buffer, length, 0);
+#endif
 }
 
 static int

+ 1 - 1
product-mini/platforms/windows/CMakeLists.txt

@@ -3,7 +3,7 @@
 
 cmake_minimum_required (VERSION 2.8)
 
-project (iwasm C ASM)
+project (iwasm C ASM CXX)
 enable_language(ASM_MASM)
 # set (CMAKE_VERBOSE_MAKEFILE 1)
 

+ 1 - 1
wamr-compiler/CMakeLists.txt

@@ -6,7 +6,7 @@ cmake_minimum_required (VERSION 2.8)
 if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
   project (aot-compiler)
 else()
-  project (aot-compiler C ASM)
+  project (aot-compiler C ASM CXX)
   enable_language (ASM_MASM)
 endif()