mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
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.
This commit is contained in:
parent
591e4ce536
commit
c8b0a1cee1
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user