Enable ARM and THUMB AOT support, enable Android platform support (#182)

* Sync with internal/feature: enable arm aot and android platform
This commit is contained in:
wenyongh
2020-02-27 16:38:44 +08:00
committed by GitHub
parent 4dbe7c44d0
commit 9a961c4843
52 changed files with 2466 additions and 466 deletions

View File

@ -274,7 +274,10 @@ static void* lv_task_handler_thread_routine (void *arg)
{
korp_sem sem;
vm_sem_init(&sem, 0);
if (vm_sem_init(&sem, 1) != 0) {
printf("Init semaphore for lvgl task handler thread fail!\n");
return NULL;
}
while (lv_task_handler_thread_run) {
vm_sem_reltimedwait(&sem, 100);

View File

@ -658,7 +658,6 @@ wasm_app_module_install(request_t * msg)
destroy_all_aot_sections(aot_file->sections);
return false;
}
/* Destroy useless sections from list after load */
destroy_part_aot_sections(&aot_file->sections,
sections1,

View File

@ -7,6 +7,7 @@
#include "bh_common.h"
#include "bh_memory.h"
#include "bh_log.h"
#include "aot_reloc.h"
#include "../common/wasm_runtime_common.h"
#include "../common/wasm_native.h"
#include "../compilation/aot.h"
@ -182,38 +183,6 @@ const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
return c_str;
}
static void
get_current_target(char *target_buf, uint32 target_buf_size)
{
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
snprintf(target_buf, target_buf_size, "x86_64");
#elif defined(BUILD_TARGET_X86_32)
snprintf(target_buf, target_buf_size, "i386");
#elif defined(BUILD_TARGET_ARM) \
|| defined(BUILD_TARGET_ARM_VFP) \
|| defined(BUILD_TARGET_THUMB) \
|| defined(BUILD_TARGET_THUMB_VFP)
char *build_target = BUILD_TARGET;
char *p = target_buf, *p_end;
snprintf(target_buf, target_buf_size, "%s", build_target);
p_end = p + strlen(target_buf);
while (p < p_end) {
if (*p >= 'A' && *p <= 'Z')
*p++ += 'a' - 'A';
else
p++;
}
if (!strcmp(target_buf, "arm"))
snprintf(target_buf, target_buf_size, "armv4");
else if (!strcmp(target_buf, "thumb"))
snprintf(target_buf, target_buf_size, "thumbv4t");
#elif defined(BUILD_TARGET_MIPS)
snprintf(target_buf, target_buf_size, "mips");
#elif defined(BUILD_TARGET_XTENSA)
snprintf(target_buf, target_buf_size, "xtensa");
#endif
}
static bool
get_aot_file_target(AOTTargetInfo *target_info,
char *target_buf, uint32 target_buf_size,
@ -1025,15 +994,6 @@ fail:
return false;
}
static uint32
get_plt_item_size();
static uint32
get_plt_table_size();
static void
init_plt_table(uint8 *plt);
static bool
load_text_section(const uint8 *buf, const uint8 *buf_end,
AOTModule *module,
@ -1211,197 +1171,6 @@ fail:
return false;
}
#define R_386_32 1 /* Direct 32 bit */
#define R_386_PC32 2 /* PC relative 32 bit */
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */
#define R_ARM_JMP24 29 /* PC relative 24 bit (B/BL<cond>). */
#define R_ARM_ABS32 2 /* Direct 32 bit */
#define R_ARM_THM_CALL 10 /* PC relative (Thumb BL and ARMv5 Thumb BLX). */
#define R_ARM_THM_JMP24 30 /* B.W */
#define R_MIPS_32 2 /* Direct 32 bit */
#define R_MIPS_26 4 /* Direct 26 bit shifted */
#ifndef BH_MB
#define BH_MB 1024 * 1024
#endif
static bool
check_reloc_offset(uint32 target_section_size,
uint64 reloc_offset, uint32 reloc_data_size,
char *error_buf, uint32 error_buf_size)
{
if (!(reloc_offset < (uint64)target_section_size
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: invalid relocation offset.");
return false;
}
return true;
}
#define CHECK_RELOC_OFFSET(data_size) do { \
if (!check_reloc_offset(target_section_size, reloc_offset, data_size, \
error_buf, error_buf_size)) \
return false; \
} while (0)
static bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
case R_X86_64_64:
{
intptr_t value;
CHECK_RELOC_OFFSET(sizeof(void*));
value = *(intptr_t*)(target_section_addr + (uint32)reloc_offset);
*(uint8**)(target_section_addr + reloc_offset)
= (uint8*)symbol_addr + reloc_addend + value; /* S + A */
break;
}
case R_X86_64_PC32:
{
intptr_t target_addr = (intptr_t) /* S + A - P */
((uint8*)symbol_addr + reloc_addend
- (target_section_addr + reloc_offset));
CHECK_RELOC_OFFSET(sizeof(int32));
if ((int32)target_addr != target_addr) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"relocation truncated to fit R_X86_64_PC32 failed. "
"Try using wamrc with --size-level=1 option.");
return false;
}
*(int32*)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
case R_X86_64_32:
case R_X86_64_32S:
{
char buf[128];
uintptr_t target_addr = (uintptr_t) /* S + A */
((uint8*)symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(int32));
if ((reloc_type == R_X86_64_32
&& (uint32)target_addr != (uint64)target_addr)
|| (reloc_type == R_X86_64_32S
&& (int32)target_addr != (int64)target_addr)) {
snprintf(buf, sizeof(buf),
"AOT module load failed: "
"relocation truncated to fit %s failed. "
"Try using wamrc with --size-level=1 option.",
reloc_type == R_X86_64_32
? "R_X86_64_32" : "R_X86_64_32S");
set_error_buf(error_buf, error_buf_size, buf);
return false;
}
*(int32*)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
case R_X86_64_PLT32:
{
uint8 *plt = module->code + module->code_size - get_plt_table_size()
+ get_plt_item_size() * symbol_index;
intptr_t target_addr = (intptr_t) /* L + A - P */
(plt + reloc_addend
- (target_section_addr + reloc_offset));
CHECK_RELOC_OFFSET(sizeof(int32));
if (symbol_index < 0) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"invalid symbol index for relocation");
return false;
}
if ((int32)target_addr != target_addr) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"relocation truncated to fit R_X86_64_PC32 failed. "
"Try using wamrc with --size-level=1 option.");
return false;
}
*(int32*)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
#endif /* end of BUILD_TARGET_X86_64 || BUILD_TARGET_AMD_64 */
#if defined(BUILD_TARGET_X86_32)
case R_386_32:
{
intptr_t value;
CHECK_RELOC_OFFSET(sizeof(void*));
value = *(intptr_t*)(target_section_addr + (uint32)reloc_offset);
*(uint8**)(target_section_addr + reloc_offset)
= (uint8*)symbol_addr + reloc_addend + value; /* S + A */
break;
}
case R_386_PC32:
{
int32 value;
CHECK_RELOC_OFFSET(sizeof(void*));
value = *(int32*)(target_section_addr + (uint32)reloc_offset);
*(uint32*)(target_section_addr + (uint32)reloc_offset) = (uint32)
((uint8*)symbol_addr + (uint32)reloc_addend
- (uint8*)(target_section_addr + (uint32)reloc_offset)
+ value); /* S + A - P */
break;
}
#endif /* end of BUILD_TARGET_X86_32 */
#if defined(BUILD_TARGET_ARM) || defined(BUILD_TARGET_ARM_VFP)
/* TODO: implement ARM relocation */
case R_ARM_CALL:
case R_ARM_JMP24:
case R_ARM_ABS32:
#endif
#if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
/* TODO: implement THUMB relocation */
case R_ARM_THM_CALL:
case R_ARM_THM_JMP24:
#endif
#if defined(BUILD_TARGET_MIPS_32)
case R_MIPS_26:
case R_MIPS_32:
/* TODO: implement relocation for mips */
#endif
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load import section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}
static void *
get_data_section_addr(AOTModule *module, const char *section_name,
@ -1420,123 +1189,15 @@ get_data_section_addr(AOTModule *module, const char *section_name,
return NULL;
}
typedef struct {
const char *symbol_name;
void *symbol_addr;
} SymbolMap;
#define REG_SYM(symbol) { #symbol, (void*)symbol }
#if defined(BUILD_TARGET_X86_32)
void __divdi3();
void __udivdi3();
void __moddi3();
void __umoddi3();
#endif
#if defined(BUILD_TARGET_ARM) \
|| defined(BUILD_TARGET_ARM_VFP) \
|| defined(BUILD_TARGET_THUMB) \
|| defined(BUILD_TARGET_THUMB_VFP)
void __divdi3();
void __udivdi3();
void __moddi3();
void __umoddi3();
void __divsi3();
void __udivsi3();
void __modsi3();
void __udivmoddi4();
void __clzsi2();
void __fixsfdi();
void __fixunssfdi();
void __fixdfdi();
void __fixunsdfdi();
void __floatdisf();
void __floatundisf();
void __floatdidf();
void __floatundidf();
void __aeabi_l2f();
void __aeabi_f2lz();
void __aeabi_ul2f();
void __aeabi_d2lz();
void __aeabi_l2d();
void __aeabi_f2ulz();
void __aeabi_ul2d();
void __aeabi_d2ulz();
void __aeabi_idiv();
void __aeabi_uidiv();
void __aeabi_idivmod();
void __aeabi_uidivmod();
void __aeabi_ldivmod();
void __aeabi_uldivmod();
#endif
static SymbolMap target_sym_map[] = {
REG_SYM(aot_set_exception_with_id),
REG_SYM(aot_get_exception),
REG_SYM(aot_is_wasm_type_equal),
REG_SYM(wasm_runtime_enlarge_memory),
REG_SYM(wasm_runtime_set_exception),
REG_SYM(fmin),
REG_SYM(fminf),
REG_SYM(fmax),
REG_SYM(fmaxf),
REG_SYM(ceil),
REG_SYM(ceilf),
REG_SYM(floor),
REG_SYM(floorf),
REG_SYM(trunc),
REG_SYM(truncf),
REG_SYM(rint),
REG_SYM(rintf),
/* compiler-rt symbols that come from compiler(e.g. gcc) */
#if defined(BUILD_TARGET_X86_32)
REG_SYM(__divdi3),
REG_SYM(__udivdi3),
REG_SYM(__moddi3),
REG_SYM(__umoddi3)
#elif defined(BUILD_TARGET_ARM) \
|| defined(BUILD_TARGET_ARM_VFP) \
|| defined(BUILD_TARGET_THUMB) \
|| defined(BUILD_TARGET_THUMB_VFP)
REG_SYM(__divdi3),
REG_SYM(__udivdi3),
REG_SYM(__umoddi3),
REG_SYM(__divsi3),
REG_SYM(__udivsi3),
REG_SYM(__modsi3),
REG_SYM(__udivmoddi4),
REG_SYM(__clzsi2),
REG_SYM(__fixsfdi),
REG_SYM(__fixunssfdi),
REG_SYM(__fixdfdi),
REG_SYM(__fixunsdfdi),
REG_SYM(__floatdisf),
REG_SYM(__floatundisf),
REG_SYM(__floatdidf),
REG_SYM(__floatundidf),
REG_SYM(__aeabi_l2f),
REG_SYM(__aeabi_f2lz),
REG_SYM(__aeabi_ul2f),
REG_SYM(__aeabi_d2lz),
REG_SYM(__aeabi_l2d),
REG_SYM(__aeabi_f2ulz),
REG_SYM(__aeabi_ul2d),
REG_SYM(__aeabi_d2ulz),
REG_SYM(__aeabi_idiv),
REG_SYM(__aeabi_uidiv),
REG_SYM(__aeabi_idivmod),
REG_SYM(__aeabi_uidivmod),
REG_SYM(__aeabi_ldivmod),
REG_SYM(__aeabi_uldivmod),
#endif /* end of BUILD_TARGET_X86_32 */
};
static void *
resolve_target_sym(const char *symbol, int32 *p_index)
{
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
uint32 i, num = 0;
SymbolMap *target_sym_map;
if (!(target_sym_map = get_target_symbol_map(&num)))
return NULL;
for (i = 0; i < num; i++)
if (!strcmp(target_sym_map[i].symbol_name, symbol)) {
*p_index = (int32)i;
@ -1545,94 +1206,6 @@ resolve_target_sym(const char *symbol, int32 *p_index)
return NULL;
}
static inline uint32
get_plt_item_size()
{
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
/* size of mov instruction and jmp instruction */
return 12;
#elif defined(BUILD_TARGET_ARM) || defined(BUILD_TARGET_ARM_VFP)
/* 20 bytes instructions and 4 bytes symbol address */
return 24;
#elif defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
/* 16 bytes instructions and 4 bytes symbol address */
return 20;
#endif
return 0;
}
static uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
static void
init_plt_table(uint8 *plt)
{
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
for (i = 0; i < num; i++) {
uint8 *p = plt;
/* mov symbol_addr, rax */
*p++ = 0x48;
*p++ = 0xB8;
*(uint64*)p = (uint64)(uintptr_t)target_sym_map[i].symbol_addr;
p += sizeof(uint64);
/* jmp rax */
*p++ = 0xFF;
*p++ = 0xE0;
plt += get_plt_item_size();
}
#endif
#if defined(BUILD_TARGET_ARM) || defined(BUILD_TARGET_ARM_VFP)
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
for (i = 0; i < num; i++) {
uint32 *p = (uint32*)plt;
/* push {lr} */
*p++ = 0xe52de004;
/* ldr lr, [pc, #8] */
*p++ = 0xe59fe008;
/* blx lr */
*p++ = 0xe12fff3e;
/* pop {lr} */
*p++ = 0xe49de004;
/* bx lr */
*p++ = 0xe12fff1e;
/* symbol addr */
*p++ = (uint32)(uintptr_t)target_sym_map[i].symbol_addr;;
plt += get_plt_item_size();
}
#endif
#if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
for (i = 0; i < num; i++) {
uint16 *p = (uint16*)plt;
/* push {lr} */
*p++ = 0xb500;
/* push {r4, r5} */
*p++ = 0xb430;
/* add r4, pc, #8 */
*p++ = 0xa402;
/* ldr r5, [r4, #0] */
*p++ = 0x6825;
/* blx r5 */
*p++ = 0x47a8;
/* pop {r4, r5} */
*p++ = 0xbc30;
/* pop {pc} */
*p++ = 0xbd00;
p++;
/* symbol addr */
*(uint32*)p = (uint32)(uintptr_t)target_sym_map[i].symbol_addr;;
plt += get_plt_item_size();
}
#endif
}
static bool
do_text_relocation(AOTModule *module,
AOTRelocationGroup *group,
@ -2046,6 +1619,10 @@ load_from_sections(AOTModule *module, AOTSection *sections,
return false;
}
/* Flush data cache before executing AOT code,
* otherwise unpredictable behavior can occur. */
bh_dcache_flush();
return true;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_runtime.h"
typedef struct {
const char *symbol_name;
void *symbol_addr;
} SymbolMap;
#define REG_SYM(symbol) { #symbol, (void*)symbol }
#define REG_COMMON_SYMBOLS \
REG_SYM(aot_set_exception_with_id), \
REG_SYM(aot_get_exception), \
REG_SYM(aot_is_wasm_type_equal), \
REG_SYM(wasm_runtime_enlarge_memory), \
REG_SYM(wasm_runtime_set_exception), \
REG_SYM(fmin), \
REG_SYM(fminf), \
REG_SYM(fmax), \
REG_SYM(fmaxf), \
REG_SYM(ceil), \
REG_SYM(ceilf), \
REG_SYM(floor), \
REG_SYM(floorf), \
REG_SYM(trunc), \
REG_SYM(truncf), \
REG_SYM(rint), \
REG_SYM(rintf)
#define CHECK_RELOC_OFFSET(data_size) do { \
if (!check_reloc_offset(target_section_size, reloc_offset, data_size, \
error_buf, error_buf_size)) \
return false; \
} while (0)
SymbolMap *
get_target_symbol_map(uint32 *sym_num);
uint32
get_plt_table_size();
void
init_plt_table(uint8 *plt);
void
get_current_target(char *target_buf, uint32 target_buf_size);
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size);

View File

@ -0,0 +1,247 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */
#define R_ARM_JMP24 29 /* PC relative 24 bit (B/BL<cond>). */
#define R_ARM_ABS32 2 /* Direct 32 bit */
#ifndef BH_MB
#define BH_MB 1024 * 1024
#endif
void __divdi3();
void __udivdi3();
void __moddi3();
void __umoddi3();
void __divsi3();
void __udivsi3();
void __modsi3();
void __udivmoddi4();
void __clzsi2();
void __fixsfdi();
void __fixunssfdi();
void __fixdfdi();
void __fixunsdfdi();
void __floatdisf();
void __floatundisf();
void __floatdidf();
void __floatundidf();
void __aeabi_l2f();
void __aeabi_f2lz();
void __aeabi_ul2f();
void __aeabi_d2lz();
void __aeabi_l2d();
void __aeabi_f2ulz();
void __aeabi_ul2d();
void __aeabi_d2ulz();
void __aeabi_idiv();
void __aeabi_uidiv();
void __aeabi_idivmod();
void __aeabi_uidivmod();
void __aeabi_ldivmod();
void __aeabi_uldivmod();
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS,
/* compiler-rt symbols that come from compiler(e.g. gcc) */
REG_SYM(__divdi3),
REG_SYM(__udivdi3),
REG_SYM(__umoddi3),
REG_SYM(__divsi3),
REG_SYM(__udivsi3),
REG_SYM(__modsi3),
REG_SYM(__udivmoddi4),
REG_SYM(__clzsi2),
REG_SYM(__fixsfdi),
REG_SYM(__fixunssfdi),
REG_SYM(__fixdfdi),
REG_SYM(__fixunsdfdi),
REG_SYM(__floatdisf),
REG_SYM(__floatundisf),
REG_SYM(__floatdidf),
REG_SYM(__floatundidf),
REG_SYM(__aeabi_l2f),
REG_SYM(__aeabi_f2lz),
REG_SYM(__aeabi_ul2f),
REG_SYM(__aeabi_d2lz),
REG_SYM(__aeabi_l2d),
REG_SYM(__aeabi_f2ulz),
REG_SYM(__aeabi_ul2d),
REG_SYM(__aeabi_d2ulz),
REG_SYM(__aeabi_idiv),
REG_SYM(__aeabi_uidiv),
REG_SYM(__aeabi_idivmod),
REG_SYM(__aeabi_uidivmod),
REG_SYM(__aeabi_ldivmod),
REG_SYM(__aeabi_uldivmod)
};
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
if (error_buf != NULL)
snprintf(error_buf, error_buf_size, "%s", string);
}
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
char *build_target = BUILD_TARGET;
char *p = target_buf, *p_end;
snprintf(target_buf, target_buf_size, "%s", build_target);
p_end = p + strlen(target_buf);
while (p < p_end) {
if (*p >= 'A' && *p <= 'Z')
*p++ += 'a' - 'A';
else
p++;
}
if (!strcmp(target_buf, "arm"))
snprintf(target_buf, target_buf_size, "armv4");
}
uint32
get_plt_item_size()
{
/* 8 bytes instructions and 4 bytes symbol address */
return 12;
}
uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
void
init_plt_table(uint8 *plt)
{
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
for (i = 0; i < num; i++) {
uint32 *p = (uint32*)plt;
/* ldr pc, [pc] */
*p++ = 0xe59ff000;
/* nop */
*p++ = 0xe1a00000;
/* symbol addr */
*p++ = (uint32)(uintptr_t)target_sym_map[i].symbol_addr;;
plt += get_plt_item_size();
}
}
static bool
check_reloc_offset(uint32 target_section_size,
uint64 reloc_offset, uint32 reloc_data_size,
char *error_buf, uint32 error_buf_size)
{
if (!(reloc_offset < (uint64)target_section_size
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: invalid relocation offset.");
return false;
}
return true;
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
case R_ARM_CALL:
case R_ARM_JMP24:
{
intptr_t result;
int32 RESULT_MASK = 0x03FFFFFE;
int32 insn = *(int32*)(target_section_addr + reloc_offset);
/* Initial addend: sign_extend(insn[23:0] << 2) */
int32 initial_addend = ((insn & 0xFFFFFF) << 2)
| ((insn & 0x800000) ? 0xFC000000 : 0);
CHECK_RELOC_OFFSET(sizeof(int32));
if (symbol_index < 0) {
/* Symbol address itself is an AOT function.
* Apply relocation with the symbol directly.
* Suppose the symbol address is in +-32MB relative
* to the relocation address.
*/
/* operation: ((S + A) | T) - P where S is symbol address and T is 0 */
result = (intptr_t)
((uint8*)symbol_addr + reloc_addend
- (target_section_addr + reloc_offset));
}
else {
if (reloc_addend > 0) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: relocate to plt table "
"with reloc addend larger than 0 is unsupported.");
return false;
}
/* Symbol address is not an AOT function,
* but a function of runtime or native. Its address is
* beyond of the +-32MB space. Apply relocation with
* the PLT which branch to the target symbol address.
*/
/* operation: ((S + A) | T) - P where S is PLT address and T is 0 */
uint8 *plt = (uint8*)module->code + module->code_size - get_plt_table_size()
+ get_plt_item_size() * symbol_index;
result = (intptr_t)
(plt + reloc_addend
- (target_section_addr + reloc_offset));
}
result += initial_addend;
/* Check overflow: +-32MB */
if (result > (32 * BH_MB) || result < (-32 * BH_MB)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"target address out of range.");
return false;
}
*(int32*)(target_section_addr + reloc_offset) =
(int32)
((insn & 0xff000000)
| (((int32)result & RESULT_MASK) >> 2));
break;
}
case R_ARM_ABS32:
{
intptr_t initial_addend;
/* (S + A) | T where T is 0 */
CHECK_RELOC_OFFSET(sizeof(void*));
initial_addend = *(intptr_t*)(target_section_addr + (uint32)reloc_offset);
*(uint8**)(target_section_addr + reloc_offset)
= (uint8*)symbol_addr + initial_addend + reloc_addend;
break;
}
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
#define R_MIPS_32 2 /* Direct 32 bit */
#define R_MIPS_26 4 /* Direct 26 bit shifted */
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS
};
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
snprintf(target_buf, target_buf_size, "mips");
}
static uint32
get_plt_item_size()
{
return 0;
}
void
init_plt_table(uint8 *plt)
{
(void)plt;
}
uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
/* TODO: implement relocation for mips */
case R_MIPS_26:
case R_MIPS_32:
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}

View File

@ -0,0 +1,253 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
#define R_ARM_THM_CALL 10 /* PC relative (Thumb BL and ARMv5 Thumb BLX). */
#define R_ARM_THM_JMP24 30 /* B.W */
#ifndef BH_MB
#define BH_MB 1024 * 1024
#endif
void __divdi3();
void __udivdi3();
void __moddi3();
void __umoddi3();
void __divsi3();
void __udivsi3();
void __modsi3();
void __udivmoddi4();
void __clzsi2();
void __fixsfdi();
void __fixunssfdi();
void __fixdfdi();
void __fixunsdfdi();
void __floatdisf();
void __floatundisf();
void __floatdidf();
void __floatundidf();
void __aeabi_l2f();
void __aeabi_f2lz();
void __aeabi_ul2f();
void __aeabi_d2lz();
void __aeabi_l2d();
void __aeabi_f2ulz();
void __aeabi_ul2d();
void __aeabi_d2ulz();
void __aeabi_idiv();
void __aeabi_uidiv();
void __aeabi_idivmod();
void __aeabi_uidivmod();
void __aeabi_ldivmod();
void __aeabi_uldivmod();
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS,
/* compiler-rt symbols that come from compiler(e.g. gcc) */
REG_SYM(__divdi3),
REG_SYM(__udivdi3),
REG_SYM(__umoddi3),
REG_SYM(__divsi3),
REG_SYM(__udivsi3),
REG_SYM(__modsi3),
REG_SYM(__udivmoddi4),
REG_SYM(__clzsi2),
REG_SYM(__fixsfdi),
REG_SYM(__fixunssfdi),
REG_SYM(__fixdfdi),
REG_SYM(__fixunsdfdi),
REG_SYM(__floatdisf),
REG_SYM(__floatundisf),
REG_SYM(__floatdidf),
REG_SYM(__floatundidf),
REG_SYM(__aeabi_l2f),
REG_SYM(__aeabi_f2lz),
REG_SYM(__aeabi_ul2f),
REG_SYM(__aeabi_d2lz),
REG_SYM(__aeabi_l2d),
REG_SYM(__aeabi_f2ulz),
REG_SYM(__aeabi_ul2d),
REG_SYM(__aeabi_d2ulz),
REG_SYM(__aeabi_idiv),
REG_SYM(__aeabi_uidiv),
REG_SYM(__aeabi_idivmod),
REG_SYM(__aeabi_uidivmod),
REG_SYM(__aeabi_ldivmod),
REG_SYM(__aeabi_uldivmod)
};
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
if (error_buf != NULL)
snprintf(error_buf, error_buf_size, "%s", string);
}
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
char *build_target = BUILD_TARGET;
char *p = target_buf, *p_end;
snprintf(target_buf, target_buf_size, "%s", build_target);
p_end = p + strlen(target_buf);
while (p < p_end) {
if (*p >= 'A' && *p <= 'Z')
*p++ += 'a' - 'A';
else
p++;
}
if (!strcmp(target_buf, "thumb"))
snprintf(target_buf, target_buf_size, "thumbv4t");
}
uint32
get_plt_item_size()
{
/* 16 bytes instructions and 4 bytes symbol address */
return 20;
}
uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
void
init_plt_table(uint8 *plt)
{
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
for (i = 0; i < num; i++) {
uint16 *p = (uint16*)plt;
/* nop */
*p++ = 0xbf00;
/* push {r4} */
*p++ = 0xb410;
/* add r4, pc, #8 */
*p++ = 0xa402;
/* ldr r4, [r4, #0] */
*p++ = 0x6824;
/* mov ip, r4 */
*p++ = 0x46a4;
/* pop {r4} */
*p++ = 0xbc10;
/* mov pc, ip */
*p++ = 0x46e7;
/* nop */
*p++ = 0xbf00;
/* symbol addr */
*(uint32*)p = (uint32)(uintptr_t)target_sym_map[i].symbol_addr;
plt += get_plt_item_size();
}
}
static bool
check_reloc_offset(uint32 target_section_size,
uint64 reloc_offset, uint32 reloc_data_size,
char *error_buf, uint32 error_buf_size)
{
if (!(reloc_offset < (uint64)target_section_size
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: invalid relocation offset.");
return false;
}
return true;
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
case R_ARM_THM_CALL:
case R_ARM_THM_JMP24:
{
int32 RESULT_MASK = 0x01FFFFFE;
int32 result, result_masked;
int16 *reloc_addr;
int32 initial_addend_0, initial_addend_1, initial_addend;
bool sign;
CHECK_RELOC_OFFSET(sizeof(int32));
reloc_addr = (int16*)(target_section_addr + reloc_offset);
initial_addend_0 = (*reloc_addr) & 0x7FF;
initial_addend_1 = (*(reloc_addr + 1)) & 0x7FF;
sign = (initial_addend_0 & 0x400) ? true : false;
initial_addend = (initial_addend_0 << 12) | (initial_addend_1 << 1)
| (sign ? 0xFF800000 : 0);
if (symbol_index < 0) {
/* Symbol address itself is an AOT function.
* Apply relocation with the symbol directly.
* Suppose the symbol address is in +-4MB relative
* to the relocation address.
*/
/* operation: ((S + A) | T) - P where S is symbol address and T is 1 */
result = (int32)(((intptr_t)((uint8*)symbol_addr + reloc_addend) | 1)
- (intptr_t)(target_section_addr + reloc_offset));
}
else {
if (reloc_addend > 0) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: relocate to plt table "
"with reloc addend larger than 0 is unsupported.");
return false;
}
/* Symbol address is not an AOT function,
* but a function of runtime or native. Its address is
* beyond of the +-4MB space. Apply relocation with
* the PLT which branch to the target symbol address.
*/
/* operation: ((S + A) | T) - P where S is PLT address and T is 1 */
uint8 *plt = (uint8*)module->code + module->code_size - get_plt_table_size()
+ get_plt_item_size() * symbol_index + 1;
result = (int32)(((intptr_t)plt | 1)
- (intptr_t)(target_section_addr + reloc_offset));
}
result += initial_addend;
/* Check overflow: +-4MB */
if (result > (4 * BH_MB) || result < (-4 * BH_MB)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"target address out of range.");
return false;
}
result_masked = (int32)result & RESULT_MASK;
initial_addend_0 = (result_masked >> 12) & 0x7FF;
initial_addend_1 = (result_masked >> 1) & 0x7FF;
*reloc_addr = (*reloc_addr & ~0x7FF) | initial_addend_0;
*(reloc_addr + 1) = (*(reloc_addr + 1) & ~0x7FF) | initial_addend_1;
break;
}
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
#define R_386_32 1 /* Direct 32 bit */
#define R_386_PC32 2 /* PC relative 32 bit */
void __divdi3();
void __udivdi3();
void __moddi3();
void __umoddi3();
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS,
/* compiler-rt symbols that come from compiler(e.g. gcc) */
REG_SYM(__divdi3),
REG_SYM(__udivdi3),
REG_SYM(__moddi3),
REG_SYM(__umoddi3)
};
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
if (error_buf != NULL)
snprintf(error_buf, error_buf_size, "%s", string);
}
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
snprintf(target_buf, target_buf_size, "i386");
}
uint32
get_plt_table_size()
{
return 0;
}
void
init_plt_table(uint8 *plt)
{
(void)plt;
}
static bool
check_reloc_offset(uint32 target_section_size,
uint64 reloc_offset, uint32 reloc_data_size,
char *error_buf, uint32 error_buf_size)
{
if (!(reloc_offset < (uint64)target_section_size
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: invalid relocation offset.");
return false;
}
return true;
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
case R_386_32:
{
intptr_t value;
CHECK_RELOC_OFFSET(sizeof(void*));
value = *(intptr_t*)(target_section_addr + (uint32)reloc_offset);
*(uint8**)(target_section_addr + reloc_offset)
= (uint8*)symbol_addr + reloc_addend + value; /* S + A */
break;
}
case R_386_PC32:
{
int32 value;
CHECK_RELOC_OFFSET(sizeof(void*));
value = *(int32*)(target_section_addr + (uint32)reloc_offset);
*(uint32*)(target_section_addr + (uint32)reloc_offset) = (uint32)
((uint8*)symbol_addr + (uint32)reloc_addend
- (uint8*)(target_section_addr + (uint32)reloc_offset)
+ value); /* S + A - P */
break;
}
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}

View File

@ -0,0 +1,190 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
#define R_X86_64_64 1 /* Direct 64 bit */
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
void __divdi3();
void __udivdi3();
void __moddi3();
void __umoddi3();
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS
};
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
{
if (error_buf != NULL)
snprintf(error_buf, error_buf_size, "%s", string);
}
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
snprintf(target_buf, target_buf_size, "x86_64");
}
static uint32
get_plt_item_size()
{
/* size of mov instruction and jmp instruction */
return 12;
}
uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
void
init_plt_table(uint8 *plt)
{
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
for (i = 0; i < num; i++) {
uint8 *p = plt;
/* mov symbol_addr, rax */
*p++ = 0x48;
*p++ = 0xB8;
*(uint64*)p = (uint64)(uintptr_t)target_sym_map[i].symbol_addr;
p += sizeof(uint64);
/* jmp rax */
*p++ = 0xFF;
*p++ = 0xE0;
plt += get_plt_item_size();
}
}
static bool
check_reloc_offset(uint32 target_section_size,
uint64 reloc_offset, uint32 reloc_data_size,
char *error_buf, uint32 error_buf_size)
{
if (!(reloc_offset < (uint64)target_section_size
&& reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: invalid relocation offset.");
return false;
}
return true;
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
case R_X86_64_64:
{
intptr_t value;
CHECK_RELOC_OFFSET(sizeof(void*));
value = *(intptr_t*)(target_section_addr + (uint32)reloc_offset);
*(uint8**)(target_section_addr + reloc_offset)
= (uint8*)symbol_addr + reloc_addend + value; /* S + A */
break;
}
case R_X86_64_PC32:
{
intptr_t target_addr = (intptr_t) /* S + A - P */
((uint8*)symbol_addr + reloc_addend
- (target_section_addr + reloc_offset));
CHECK_RELOC_OFFSET(sizeof(int32));
if ((int32)target_addr != target_addr) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"relocation truncated to fit R_X86_64_PC32 failed. "
"Try using wamrc with --size-level=1 option.");
return false;
}
*(int32*)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
case R_X86_64_32:
case R_X86_64_32S:
{
char buf[128];
uintptr_t target_addr = (uintptr_t) /* S + A */
((uint8*)symbol_addr + reloc_addend);
CHECK_RELOC_OFFSET(sizeof(int32));
if ((reloc_type == R_X86_64_32
&& (uint32)target_addr != (uint64)target_addr)
|| (reloc_type == R_X86_64_32S
&& (int32)target_addr != (int64)target_addr)) {
snprintf(buf, sizeof(buf),
"AOT module load failed: "
"relocation truncated to fit %s failed. "
"Try using wamrc with --size-level=1 option.",
reloc_type == R_X86_64_32
? "R_X86_64_32" : "R_X86_64_32S");
set_error_buf(error_buf, error_buf_size, buf);
return false;
}
*(int32*)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
case R_X86_64_PLT32:
{
uint8 *plt = (uint8*)module->code + module->code_size - get_plt_table_size()
+ get_plt_item_size() * symbol_index;
intptr_t target_addr = (intptr_t) /* L + A - P */
(plt + reloc_addend
- (target_section_addr + reloc_offset));
CHECK_RELOC_OFFSET(sizeof(int32));
if (symbol_index < 0) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"invalid symbol index for relocation");
return false;
}
if ((int32)target_addr != target_addr) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"relocation truncated to fit R_X86_64_PC32 failed. "
"Try using wamrc with --size-level=1 option.");
return false;
}
*(int32*)(target_section_addr + reloc_offset) = (int32)target_addr;
break;
}
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "aot_reloc.h"
static SymbolMap target_sym_map[] = {
REG_COMMON_SYMBOLS
};
SymbolMap *
get_target_symbol_map(uint32 *sym_num)
{
*sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
return target_sym_map;
}
void
get_current_target(char *target_buf, uint32 target_buf_size)
{
snprintf(target_buf, target_buf_size, "xtensa");
}
static uint32
get_plt_item_size()
{
return 0;
}
void
init_plt_table(uint8 *plt)
{
(void)plt;
}
uint32
get_plt_table_size()
{
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
}
bool
apply_relocation(AOTModule *module,
uint8 *target_section_addr, uint32 target_section_size,
uint64 reloc_offset, uint64 reloc_addend,
uint32 reloc_type, void *symbol_addr, int32 symbol_index,
char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
/* TODO: implement relocation for xtensa */
default:
if (error_buf != NULL)
snprintf(error_buf, error_buf_size,
"Load relocation section failed: "
"invalid relocation type %d.",
reloc_type);
return false;
}
return true;
}

View File

@ -9,5 +9,21 @@ include_directories (${IWASM_AOT_DIR})
file (GLOB c_source_all ${IWASM_AOT_DIR}/*.c)
set (IWASM_AOT_SOURCE ${c_source_all})
if (${WAMR_BUILD_TARGET} STREQUAL "X86_64" OR ${WAMR_BUILD_TARGET} STREQUAL "AMD_64")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_x86_64.c)
elseif (${WAMR_BUILD_TARGET} STREQUAL "X86_32")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_x86_32.c)
elseif (${WAMR_BUILD_TARGET} MATCHES "ARM.*")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_arm.c)
elseif (${WAMR_BUILD_TARGET} MATCHES "THUMB.*")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_thumb.c)
elseif (${WAMR_BUILD_TARGET} STREQUAL "MIPS")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_mips.c)
elseif (${WAMR_BUILD_TARGET} STREQUAL "XTENSA")
set (arch_source ${IWASM_AOT_DIR}/arch/aot_reloc_xtensa.c)
else ()
message (FATAL_ERROR "Build target isn't set")
endif ()
set (IWASM_AOT_SOURCE ${c_source_all} ${arch_source})

View File

@ -45,3 +45,7 @@ bh_mprotect(void *addr, uint32 size, int prot)
return 0;
}
void
bh_dcache_flush()
{
}

View File

@ -130,6 +130,7 @@ enum {
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
void bh_dcache_flush();
#endif /* end of _BH_PLATFORM_H */

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_assert.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef BH_TEST
#include <setjmp.h>
#endif
#ifdef BH_TEST
/* for exception throwing */
jmp_buf bh_test_jb;
#endif
void bh_assert_internal(int v, const char *file_name, int line_number,
const char *expr_string)
{
if (v)
return;
if (!file_name)
file_name = "NULL FILENAME";
if (!expr_string)
expr_string = "NULL EXPR_STRING";
printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
file_name, line_number);
#ifdef BH_TEST
longjmp(bh_test_jb, 1);
#endif
abort();
}
void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
...)
{
#ifndef JEFF_TEST_VERIFIER
va_list args;
va_start(args, fmt);
bh_assert(file_name);
printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
vprintf(fmt, args);
va_end(args);
printf("\n");
#endif
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#define RSIZE_MAX 0x7FFFFFFF
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n)
{
char *dest = (char*) s1;
char *src = (char*) s2;
if (n == 0) {
return 0;
}
if (s1 == NULL || s1max > RSIZE_MAX) {
return -1;
}
if (s2 == NULL || n > s1max) {
memset(dest, 0, s1max);
return -1;
}
memcpy(dest, src, n);
return 0;
}
int b_strcat_s(char * s1, size_t s1max, const char * s2)
{
if (NULL == s1 || NULL == s2
|| s1max < (strlen(s1) + strlen(s2) + 1)
|| s1max > RSIZE_MAX) {
return -1;
}
strcat(s1, s2);
return 0;
}
int b_strcpy_s(char * s1, size_t s1max, const char * s2)
{
if (NULL == s1 || NULL == s2
|| s1max < (strlen(s2) + 1)
|| s1max > RSIZE_MAX) {
return -1;
}
strcpy(s1, s2);
return 0;
}
int fopen_s(FILE ** pFile, const char *filename, const char *mode)
{
if (NULL == pFile || NULL == filename || NULL == mode) {
return -1;
}
*pFile = fopen(filename, mode);
if (NULL == *pFile)
return -1;
return 0;
}

View File

@ -0,0 +1,176 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_assert.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
char *bh_strdup(const char *s)
{
uint32 size;
char *s1 = NULL;
if (s) {
size = (uint32)(strlen(s) + 1);
if ((s1 = bh_malloc(size)))
bh_memcpy_s(s1, size, s, size);
}
return s1;
}
int bh_platform_init()
{
return 0;
}
char*
bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
{
char *buffer;
int file;
uint32 file_size, read_size;
struct stat stat_buf;
if (!filename || !ret_size) {
printf("Read file to buffer failed: invalid filename or ret size.\n");
return NULL;
}
if ((file = open(filename, O_RDONLY, 0)) == -1) {
printf("Read file to buffer failed: open file %s failed.\n",
filename);
return NULL;
}
if (fstat(file, &stat_buf) != 0) {
printf("Read file to buffer failed: fstat file %s failed.\n",
filename);
close(file);
return NULL;
}
file_size = (uint32)stat_buf.st_size;
if (!(buffer = bh_malloc(file_size))) {
printf("Read file to buffer failed: alloc memory failed.\n");
close(file);
return NULL;
}
read_size = (uint32)read(file, buffer, file_size);
close(file);
if (read_size < file_size) {
printf("Read file to buffer failed: read file content failed.\n");
bh_free(buffer);
return NULL;
}
*ret_size = file_size;
return buffer;
}
void *
bh_mmap(void *hint, uint32 size, int prot, int flags)
{
int map_prot = PROT_NONE;
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
uint64 request_size, page_size;
uint8 *addr, *addr_aligned;
uint32 i;
/* align to 2M if no less than 2M, else align to 4K */
page_size = size < 2 * 1024 * 1024 ? 4096 : 2 * 1024 * 1024;
request_size = (size + page_size - 1) & ~(page_size - 1);
request_size += page_size;
if (request_size >= UINT32_MAX)
return NULL;
if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ;
if (prot & MMAP_PROT_WRITE)
map_prot |= PROT_WRITE;
if (prot & MMAP_PROT_EXEC)
map_prot |= PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
if (flags & MMAP_MAP_32BIT)
map_flags |= MAP_32BIT;
#endif
if (flags & MMAP_MAP_FIXED)
map_flags |= MAP_FIXED;
/* try 5 times */
for (i = 0; i < 5; i ++) {
addr = mmap(hint, size, map_prot, map_flags, -1, 0);
if (addr != MAP_FAILED)
break;
}
if (addr == MAP_FAILED)
return NULL;
addr_aligned = (uint8*)(uintptr_t)
(((uint64)(uintptr_t)addr + page_size - 1) & ~(page_size - 1));
/* Unmap memory allocated before the aligned base address */
if (addr != addr_aligned) {
uint32 prefix_size = (uint32)(addr_aligned - addr);
munmap(addr, prefix_size);
request_size -= prefix_size;
}
/* Unmap memory allocated after the potentially unaligned end */
if (size != request_size) {
uint32 suffix_size = (uint32)(request_size - size);
munmap(addr_aligned + size, suffix_size);
request_size -= size;
}
if (size >= 2 * 1024 * 1024) {
/* Try to use huge page to improve performance */
if (!madvise(addr, size, MADV_HUGEPAGE))
/* make huge page become effective */
memset(addr, 0, size);
}
return addr_aligned;
}
void
bh_munmap(void *addr, uint32 size)
{
if (addr)
munmap(addr, size);
}
int
bh_mprotect(void *addr, uint32 size, int prot)
{
int map_prot = PROT_NONE;
if (!addr)
return 0;
if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ;
if (prot & MMAP_PROT_WRITE)
map_prot |= PROT_WRITE;
if (prot & MMAP_PROT_EXEC)
map_prot |= PROT_EXEC;
return mprotect(addr, size, map_prot);
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _BH_PLATFORM_H
#define _BH_PLATFORM_H
#include "bh_config.h"
#include "bh_types.h"
#include "bh_memory.h"
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <android/log.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t uint64;
typedef int64_t int64;
extern void DEBUGME(void);
#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0)
#ifndef BH_PLATFORM_ANDROID
#define BH_PLATFORM_ANDROID
#endif
/* NEED qsort */
#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
#define BH_ROUTINE_MODIFIER
#define BHT_TIMEDOUT ETIMEDOUT
#define INVALID_THREAD_ID 0xFFffFFff
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef sem_t korp_sem;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef void* (*thread_start_routine_t)(void*);
#define wa_malloc bh_malloc
#define wa_free bh_free
#define wa_strdup bh_strdup
#define bh_printf(...) (__android_log_print(ANDROID_LOG_INFO, "wasm_runtime::", __VA_ARGS__))
int snprintf(char *buffer, size_t count, const char *format, ...);
double fmod(double x, double y);
float fmodf(float x, float y);
double sqrt(double x);
#define BH_WAIT_FOREVER 0xFFFFFFFF
#ifndef NULL
# define NULL ((void*) 0)
#endif
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
#define bh_assert assert
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2,
unsigned int n);
int b_strcat_s(char * s1, size_t s1max, const char * s2);
int b_strcpy_s(char * s1, size_t s1max, const char * s2);
int fopen_s(FILE ** pFile, const char *filename, const char *mode);
char *bh_read_file_to_buffer(const char *filename, uint32 *ret_size);
char *bh_strdup(const char *s);
int bh_platform_init();
/* MMAP mode */
enum {
MMAP_PROT_NONE = 0,
MMAP_PROT_READ = 1,
MMAP_PROT_WRITE = 2,
MMAP_PROT_EXEC = 4
};
/* MMAP flags */
enum {
MMAP_MAP_NONE = 0,
/* Put the mapping into 0 to 2 G, supported only on x86_64 */
MMAP_MAP_32BIT = 1,
/* Don't interpret addr as a hint: place the mapping at exactly
that address. */
MMAP_MAP_FIXED = 2
};
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include <stdio.h>
#include <android/log.h>
void bh_log_emit(const char *fmt, va_list ap)
{
(void)__android_log_vprint(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
}
int bh_fprintf(FILE *stream, const char *fmt, ...)
{
(void)stream;
va_list ap;
int ret = 0;
va_start(ap, fmt);
ret = __android_log_vprint(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
va_end(ap);
return ret;
}
int bh_fflush(void *stream)
{
(void)stream;
return __android_log_print(ANDROID_LOG_INFO, "wasm_runtime::", "%s", "NOT IMPLEMENT");
}

View File

@ -0,0 +1,395 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_thread.h"
#include "bh_assert.h"
#include "bh_log.h"
#include "bh_memory.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
static bool is_thread_sys_inited = false;
static korp_mutex thread_list_lock;
static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM];
int _vm_thread_sys_init()
{
unsigned i, j;
int ret;
if (is_thread_sys_inited)
return 0;
for (i = 0; i < BH_MAX_TLS_NUM; i++) {
ret = pthread_key_create(&thread_local_storage_key[i], NULL);
if (ret)
goto fail;
}
ret = vm_mutex_init(&thread_list_lock);
if (ret)
goto fail;
is_thread_sys_inited = true;
return 0;
fail: for (j = 0; j < i; j++)
pthread_key_delete(thread_local_storage_key[j]);
return -1;
}
void vm_thread_sys_destroy(void)
{
if (is_thread_sys_inited) {
unsigned i;
for (i = 0; i < BH_MAX_TLS_NUM; i++)
pthread_key_delete(thread_local_storage_key[i]);
vm_mutex_destroy(&thread_list_lock);
is_thread_sys_inited = false;
}
}
typedef struct {
thread_start_routine_t start;
void* stack;
uint32 stack_size;
void* arg;
} thread_wrapper_arg;
static void *vm_thread_wrapper(void *arg)
{
thread_wrapper_arg * targ = arg;
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
targ->stack = (void *)((uintptr_t)(&arg) & (uintptr_t)~0xfff);
_vm_tls_put(1, targ);
targ->start(targ->arg);
bh_free(targ);
_vm_tls_put(1, NULL);
return NULL;
}
int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
void *arg, unsigned int stack_size, int prio)
{
(void)prio;
pthread_attr_t tattr;
thread_wrapper_arg *targ;
bh_assert(stack_size > 0);
bh_assert(tid);
bh_assert(start);
*tid = INVALID_THREAD_ID;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u",
stack_size, PTHREAD_STACK_MIN);
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ = (thread_wrapper_arg*) bh_malloc(sizeof(*targ));
if (!targ) {
pthread_attr_destroy(&tattr);
return BHT_ERROR;
}
targ->start = start;
targ->arg = arg;
targ->stack_size = stack_size;
if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) {
pthread_attr_destroy(&tattr);
bh_free(targ);
return BHT_ERROR;
}
pthread_attr_destroy(&tattr);
return BHT_OK;
}
int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
unsigned int stack_size)
{
return _vm_thread_create_with_prio(tid, start, arg, stack_size,
BH_THREAD_DEFAULT_PRIORITY);
}
korp_tid _vm_self_thread()
{
return (korp_tid) pthread_self();
}
void vm_thread_exit(void * code)
{
bh_free(_vm_tls_get(1));
_vm_tls_put(1, NULL);
pthread_exit(code);
}
void *_vm_tls_get(unsigned idx)
{
bh_assert(idx < BH_MAX_TLS_NUM);
return pthread_getspecific(thread_local_storage_key[idx]);
}
int _vm_tls_put(unsigned idx, void * tls)
{
bh_assert(idx < BH_MAX_TLS_NUM);
pthread_setspecific(thread_local_storage_key[idx], tls);
return BHT_OK;
}
int _vm_mutex_init(korp_mutex *mutex)
{
return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_recursive_mutex_init(korp_mutex *mutex)
{
int ret;
pthread_mutexattr_t mattr;
bh_assert(mutex);
ret = pthread_mutexattr_init(&mattr);
if (ret)
return BHT_ERROR;
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE_NP);
ret = pthread_mutex_init(mutex, &mattr);
pthread_mutexattr_destroy(&mattr);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_mutex_destroy(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_destroy(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
locking the mutex indicates some logic error present in
the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_lock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_lock(mutex);
if (0 != ret) {
printf("vm mutex lock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int vm_mutex_trylock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_trylock(mutex);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
/* Returned error (EINVAL, EAGAIN and EPERM) from
unlocking the mutex indicates some logic error present
in the program somewhere.
Don't try to recover error for an existing unknown error.*/
void vm_mutex_unlock(korp_mutex *mutex)
{
int ret;
bh_assert(mutex);
ret = pthread_mutex_unlock(mutex);
if (0 != ret) {
printf("vm mutex unlock failed (ret=%d)!\n", ret);
exit(-1);
}
}
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
int ret;
bh_assert(sem);
ret = sem_init(sem, 0, c);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_destroy(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_wait(korp_sem *sem)
{
int ret;
bh_assert(sem);
ret = sem_wait(sem);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_reltimedwait(korp_sem *sem, int mills)
{
int ret = BHT_OK;
struct timespec timeout;
const int mills_per_sec = 1000;
const int mills_to_nsec = 1E6;
bh_assert(sem);
if (mills == (int)BHT_WAIT_FOREVER) {
ret = sem_wait(sem);
} else {
timeout.tv_sec = mills / mills_per_sec;
timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec;
timeout.tv_sec += time(NULL);
ret = sem_timedwait(sem, &timeout);
}
if (ret != BHT_OK) {
if (errno == BHT_TIMEDOUT) {
ret = BHT_TIMEDOUT;
errno = 0;
} else {
bh_debug("Faliure happens when timed wait is called");
bh_assert(0);
}
}
return ret;
}
int _vm_sem_post(korp_sem *sem)
{
bh_assert(sem);
return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_cond_init(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_init(cond, NULL) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_destroy(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_destroy(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
{
bh_assert(cond);
bh_assert(mutex);
if (pthread_cond_wait(cond, mutex) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec)
{
struct timeval tv;
gettimeofday(&tv, NULL);
ts->tv_sec = (long int)(tv.tv_sec + msec / 1000);
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec);
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
{
int ret;
struct timespec abstime;
if (mills == (int)BHT_WAIT_FOREVER)
ret = pthread_cond_wait(cond, mutex);
else {
msec_nsec_to_abstime(&abstime, mills, 0);
ret = pthread_cond_timedwait(cond, mutex, &abstime);
}
if (ret != BHT_OK && ret != BHT_TIMEDOUT)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_signal(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_signal(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_cond_broadcast(korp_cond *cond)
{
bh_assert(cond);
if (pthread_cond_broadcast(cond) != BHT_OK)
return BHT_ERROR;
return BHT_OK;
}
int _vm_thread_cancel(korp_tid thread)
{
return pthread_kill(thread, SIGABRT);
}
int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
{
(void)mills;
return pthread_join(thread, value_ptr);
}
int _vm_thread_detach(korp_tid thread)
{
return pthread_detach(thread);
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_time.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
/*
* This function returns milliseconds per tick.
* @return milliseconds per tick.
*/
uint64 _bh_time_get_tick_millisecond()
{
return (uint64)sysconf(_SC_CLK_TCK);
}
/*
* This function returns milliseconds after boot.
* @return milliseconds after boot.
*/
uint64 _bh_time_get_boot_millisecond()
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64) ts.tv_sec) * 1000 + ((uint64)ts.tv_nsec) / (1000 * 1000);
}
uint32 bh_get_tick_sec()
{
return (uint32)(_bh_time_get_boot_millisecond() / 1000);
}
/*
* This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
* @return milliseconds since from 1970.1.1.
*/
uint64 _bh_time_get_millisecond_from_1970()
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return tv.tv_sec * 1000 + tv.tv_usec
- (tz.tz_dsttime == 0 ? 0 : 60 * 60 * 1000)
+ tz.tz_minuteswest * 60 * 1000;
}
size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
{
time_t time_sec = (time_t)(time / 1000);
struct timeval tv;
struct timezone tz;
struct tm *ltp;
gettimeofday(&tv, &tz);
time_sec -= tz.tz_minuteswest * 60;
ltp = localtime(&time_sec);
if (ltp == NULL) {
return 0;
}
return strftime(s, max, format, ltp);
}

View File

@ -0,0 +1,17 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all})
LIST (APPEND RUNTIME_LIB_HEADER_LIST "${PLATFORM_SHARED_DIR}/bh_platform.h")
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})

View File

@ -130,6 +130,7 @@ enum {
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}

View File

@ -124,6 +124,7 @@ enum {
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}

View File

@ -131,6 +131,7 @@ enum {
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}

View File

@ -128,6 +128,7 @@ enum {
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
#define bh_dcache_flush() (void)0
#ifdef __cplusplus
}

View File

@ -8,6 +8,9 @@
#include "bh_common.h"
#include <stdlib.h>
#include <string.h>
#ifdef CONFIG_ARM_MPU
#include <arch/arm/aarch32/cortex_m/cmsis.h>
#endif
char *bh_strdup(const char *s)
{
@ -22,6 +25,28 @@ char *bh_strdup(const char *s)
return s1;
}
#ifdef CONFIG_ARM_MPU
/**
* This function will allow execute from sram region.
* This is needed for AOT code because by default all soc will
* disable the execute from SRAM.
*/
static void
disable_mpu_rasr_xn(void)
{
u32_t index;
/* Kept the max index as 8 (irrespective of soc) because the sram
would most likely be set at index 2. */
for (index = 0U; index < 8; index++) {
MPU->RNR = index;
if (MPU->RASR & MPU_RASR_XN_Msk) {
MPU->RASR |= ~MPU_RASR_XN_Msk;
}
}
}
#endif /* end of CONFIG_ARM_MPU */
static int
_stdout_hook_iwasm(int c)
{
@ -34,6 +59,14 @@ int bh_platform_init()
extern void __stdout_hook_install(int (*hook)(int));
/* Enable printf() in Zephyr */
__stdout_hook_install(_stdout_hook_iwasm);
#if WASM_ENABLE_AOT != 0
#ifdef CONFIG_ARM_MPU
/* Enable executable memory support */
disable_mpu_rasr_xn();
#endif
#endif
return 0;
}
@ -54,3 +87,14 @@ bh_mprotect(void *addr, uint32 size, int prot)
{
return 0;
}
void
bh_dcache_flush()
{
#if defined(CONFIG_CPU_CORTEX_M7)
uint32 key;
key = irq_lock();
SCB_CleanDCache();
irq_unlock(key);
#endif
}

View File

@ -153,5 +153,6 @@ enum {
void *bh_mmap(void *hint, unsigned int size, int prot, int flags);
void bh_munmap(void *addr, uint32 size);
int bh_mprotect(void *addr, uint32 size, int prot);
void bh_dcache_flush();
#endif

View File

@ -404,8 +404,8 @@ void vm_mutex_unlock(korp_mutex *mutex)
int _vm_sem_init(korp_sem* sem, unsigned int c)
{
k_sem_init(sem, 0, c);
return BHT_OK;
int ret = k_sem_init(sem, 0, c);
return ret == 0 ? BHT_OK : BHT_ERROR;
}
int _vm_sem_destroy(korp_sem *sem)

View File

@ -55,6 +55,7 @@ void _bh_log_printf(const char *fmt, ...)
va_end(ap);
}
#ifndef BH_PLATFORM_ANDROID
/**
* Return true if the given tag is enabled by the configuration.
*
@ -79,12 +80,14 @@ static void bh_log_emit_helper(const char *fmt, ...)
bh_log_emit(fmt, ap);
va_end(ap);
}
#endif
extern size_t _bh_time_strftime(char *s, size_t max, const char *format,
int64 time);
void _bh_log_vprintf(const char *fmt, va_list ap)
{
#ifndef BH_PLATFORM_ANDROID
korp_tid self = vm_self_thread();
/* Try to own the log stream and start the log output. */
if (self != cur_logging_thread) {
@ -102,7 +105,10 @@ void _bh_log_vprintf(const char *fmt, va_list ap)
fmt += 3;
}
}
#else
// since we are using android log, do not worry about that
cur_log_enabled = true;
#endif//BH_PLATFORM_ANDROID
if (cur_log_enabled && fmt)
bh_log_emit(fmt, ap);
}
@ -121,11 +127,17 @@ void _bh_log(const char *tag, const char *file, int line, const char *fmt, ...)
{
va_list ap;
#ifndef BH_PLATFORM_ANDROID
if (tag)
_bh_log_printf(tag);
if (file)
_bh_log_printf("%s:%d", file, line);
#else
(void)tag;
(void)file;
(void)line;
#endif//BH_PLATFORM_ANDROID
va_start(ap, fmt);
_bh_log_vprintf(fmt, ap);