Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Wang Xin 2020-02-28 08:02:19 +08:00
commit 038735d554
60 changed files with 2493 additions and 471 deletions

View File

@ -32,7 +32,7 @@ iwasm VM core
The iwasm supports following architectures:
- X86-64, X86-32
- ARM, THUMB
- ARM, THUMB (ARMV7 Cortex-M7 and Cortex-A15 are tested)
- MIPS
- XTENSA
@ -44,6 +44,7 @@ Following platforms are supported:
- [VxWorks](./doc/build_wamr.md#vxworks)
- [AliOS-Things](./doc/build_wamr.md#alios-things)
- [Intel Software Guard Extention (Linux)](./doc/build_wamr.md#linux-sgx-intel-software-guard-extention)
- [Android](./doc/build_wamr.md#android)
Refer to [WAMR porting guide](./doc/port_wamr.md) for how to port WAMR to a new platform.

View File

@ -16,6 +16,8 @@ elseif (WAMR_BUILD_PLATFORM STREQUAL "darwin")
add_definitions(-DBH_PLATFORM_DARWIN)
elseif (WAMR_BUILD_PLATFORM STREQUAL "alios-things")
add_definitions(-DBH_PLATFORM_ALIOS_THINGS)
elseif (WAMR_BUILD_PLATFORM STREQUAL "android")
add_definitions(-DBH_PLATFORM_ANDROID)
else ()
message (WARNING "-- WAMR build platform isn't set")
endif ()

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

@ -197,6 +197,8 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
memset(block_addr_cache, 0, sizeof(block_addr_cache));
/* Get block info */
if (!(wasm_loader_find_block_addr((BlockAddr*)block_addr_cache,
*p_frame_ip, frame_ip_end, (uint8)block_type,

View File

@ -15,8 +15,8 @@ typedef struct NativeSymbol {
void *func_ptr;
} NativeSymbol;
#define EXPORT_WASM_API(symbol) {#symbol, symbol}
#define EXPORT_WASM_API2(symbol) {#symbol, symbol##_wrapper}
#define EXPORT_WASM_API(symbol) {#symbol, (void*)symbol}
#define EXPORT_WASM_API2(symbol) {#symbol, (void*)symbol##_wrapper}
/**
* Get the exported APIs of base lib

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

@ -5,6 +5,10 @@
#include "bh_platform.h"
#ifdef RSIZE_MAX
#undef RSIZE_MAX
#endif
#define RSIZE_MAX 0x7FFFFFFF
int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n)

View File

@ -137,12 +137,14 @@ bh_mmap(void *hint, uint32 size, int prot, int flags)
request_size -= size;
}
#ifndef __APPLE__
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);
}
#endif
return addr_aligned;
}

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

@ -7,7 +7,9 @@
#include "bh_platform.h"
#include <unistd.h>
#if WASM_ENABLE_AOT != 0
#include "sgx_rsrv_mem_mngr.h"
#endif
#define FIXED_BUFFER_SIZE (1<<9)
static bh_print_function_t print_function = NULL;
@ -72,6 +74,7 @@ int bh_vprintf_sgx(const char * format, va_list arg)
void* bh_mmap(void *hint, unsigned int size, int prot, int flags)
{
#if WASM_ENABLE_AOT != 0
int mprot = 0;
unsigned alignedSize = (size+4095) & (unsigned)~4095; //Page aligned
void* ret = NULL;
@ -96,15 +99,21 @@ void* bh_mmap(void *hint, unsigned int size, int prot, int flags)
}
return ret;
#else
return NULL;
#endif
}
void bh_munmap(void *addr, uint32 size)
{
#if WASM_ENABLE_AOT != 0
sgx_free_rsrv_mem(addr, size);
#endif
}
int bh_mprotect(void *addr, uint32 size, int prot)
{
#if WASM_ENABLE_AOT != 0
int mprot = 0;
sgx_status_t st = 0;
@ -118,4 +127,7 @@ int bh_mprotect(void *addr, uint32 size, int prot)
if (st != SGX_SUCCESS) bh_printf_sgx("bh_mprotect(addr=0x%lx,size=%d,prot=0x%x) failed.", addr, size, prot);
return (st == SGX_SUCCESS? 0:-1);
#else
return -1;
#endif
}

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);

View File

@ -37,9 +37,9 @@ cmake -DWAMR_BUILD_AOT=1/0 to enable or disable WASM AOT
cmake -DWAMR_BUILD_JIT=1/0 to enable or disable WASM JIT
cmake -DWAMR_BUILD_LIBC_BUILTIN=1/0 enable or disable Libc builtin API's
cmake -DWAMR_BUILD_LIBC_WASI=1/0 enable or disable Libc WASI API's
cmake -DWAMR_BUILD_TARGET=<arch><sub> to set the building target, including:
cmake -DWAMR_BUILD_TARGET=<arch> to set the building target, including:
X86_64, X86_32, ARM, THUMB, XTENSA and MIPS
for ARM and THUMB, we can specify the <sub> info, e.g. ARMV4, ARMV4T, ARMV5, ARMV5T, THUMBV4T, THUMBV5T and so on.
For ARM and THUMB, the format is <arch>[<sub-arch>][_VFP] where <sub-arch> is the ARM sub-architecture and the "_VFP" suffix means VFP coprocessor registers s0-s15 (d0-d7) are used for passing arguments or returning results in standard procedure-call. Both <sub-arch> and [_VFP] are optional. e.g. ARMV7, ARMV7_VFP, THUMBV7, THUMBV7_VFP and so on.
```
For example, if we want to disable interpreter, enable AOT and WASI, we can:
@ -157,8 +157,15 @@ cd simple
ln -s <wamr_root_dir> wamr
mkdir build && cd build
source ../../../zephyr-env.sh
1. build for x86
cmake -GNinja -DBOARD=qemu_x86_nommu ..
ninja
2. build for ARM
modify ../prj.conf, modify the commented line "# CONFIG_ARM_MPU is not set" to "CONFIG_ARM_MPU=y"
cmake -GNinja -DBOARD=nucleo_f767zi -DWAMR_BUILD_TARGET=THUMBV7 ..
ninja
```
Note:
WAMR provides some features which can be easily configured by passing options to cmake, please see [Linux platform](./build_wamr.md#linux) for details. Currently in Zephyr, interpreter, AoT and builtin libc are enabled by default.
@ -215,6 +222,36 @@ AliOS-Things
```
download the binary to developerkit board, check the output from serial port
Android
-------------------------
able to generate a shared library support Android platform.
- need an [android SDK](https://developer.android.com/studio). Go and get the "Command line tools only"
- look for a command named *sdkmanager* and download below components. version numbers might need to check and pick others
- "build-tools;29.0.3"
- "cmake;3.10.2.4988404"
- "ndk;21.0.6113669"
- "patcher;v4"
- "platform-tools"
- "platforms;android-29"
- add bin/ of the downloaded cmake to $PATH
- export ANDROID_SDK_HOME=/the/path/of/downloaded/sdk/
- export ANDROID_NDK_HOME=/the/path/of/downloaded/sdk/ndk/
- ready to go
Use such commands, you are able to compile with default configurations. Any compiling requirement should be satisfied by modifying product-mini/platforms/android/CMakeList.txt. For example, chaning ${WAMR_BUILD_TARGET} in CMakeList could get different libraries support different ABIs.
``` shell
$ cd product-mini/platforms/android/
$ mkdir build
$ cd build
$ cmake ..
$ make
$ # check output in distribution/wasm
$ # include/ includes all necesary head files
$ # lib includes libiwasm.so
```
Docker
-------------------------
[Docker](https://www.docker.com/) will download all the dependencies and build WAMR Core on your behalf.

View File

@ -13,23 +13,29 @@ WAMR_BUILD_PLATFORM := alios-things
ifeq (${WAMR_BUILD_TARGET}, X86_32)
GLOBAL_DEFINES += BUILD_TARGET_X86_32
INVOKE_NATIVE := invokeNative_ia32.s
AOT_RELOC := aot_reloc_x86_32.c
else ifeq (${WAMR_BUILD_TARGET}, X86_64)
GLOBAL_DEFINES += BUILD_TARGET_X86_64
INVOKE_NATIVE := invokeNative_em64.s
AOT_RELOC := aot_reloc_x86_64.c
else ifeq ($(findstring ARM,$(WAMR_BUILD_TARGET)), ARM)
GLOBAL_DEFINES += BUILD_TARGET_ARM
GLOBAL_DEFINES += BUILD_TARGET=\"$(WAMR_BUILD_TARGET)\"
INVOKE_NATIVE := invokeNative_arm.s
AOT_RELOC := aot_reloc_arm.c
else ifeq ($(findstring THUMB,$(WAMR_BUILD_TARGET)), THUMB)
GLOBAL_DEFINES += BUILD_TARGET_THUMB
GLOBAL_DEFINES += BUILD_TARGET=\"$(WAMR_BUILD_TARGET)\"
INVOKE_NATIVE := invokeNative_thumb.s
AOT_RELOC := aot_reloc_thumb.c
else ifeq (${WAMR_BUILD_TARGET}, MIPS)
GLOBAL_DEFINES += BUILD_TARGET_MIPS
INVOKE_NATIVE := invokeNative_mips.s
AOT_RELOC := aot_reloc_mips.c
else ifeq (${WAMR_BUILD_TARGET}, XTENSA)
GLOBAL_DEFINES += BUILD_TARGET_XTENSA
INVOKE_NATIVE := invokeNative_xtensa.s
AOT_RELOC := aot_reloc_xtensa.c
else
$(error Build target isn't set)
endif
@ -96,6 +102,7 @@ endif
ifeq (${WAMR_BUILD_AOT}, 1)
$(NAME)_SOURCES += ${IWASM_ROOT}/aot/aot_loader.c \
${IWASM_ROOT}/aot/arch/${AOT_RELOC} \
${IWASM_ROOT}/aot/aot_runtime.c
endif

View File

@ -0,0 +1,102 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required (VERSION 3.4.1)
set (CMAKE_VERBOSE_MAKEFILE on)
set (CMAKE_TOOLCHAIN_FILE "$ENV{ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake")
set (ANDROID_NDK $ENV{ANDROID_NDK_HOME})
set (ANDROID_SDK $ENV{ANDROID_SDK_HOME})
set (ANDROID_ABI "armeabi-v7a")
project (iwasm)
set (WAMR_BUILD_PLATFORM "android")
set (WAMR_BUILD_TARGET "ARMv7")
set (WAMR_BUILD_TYPE Debug)
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 0)
set (WAMR_BUILD_LIBC_BUILTIN 1)
set (WAMR_BUILD_LIBC_WASI 0)
set (CMAKE_BUILD_TYPE Debug)
# Reset default linker flags
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "ARM[sub]", "THUMB[sub]", "MIPS", "XTENSA"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")
else ()
# Build as X86_32 by default in 32-bit platform
set (WAMR_BUILD_TARGET "X86_32")
endif ()
endif ()
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()
if (NOT DEFINED WAMR_BUILD_INTERP)
# Enable Interpreter by default
set (WAMR_BUILD_INTERP 1)
endif ()
if (NOT DEFINED WAMR_BUILD_AOT)
# Enable AOT by default.
set (WAMR_BUILD_AOT 1)
endif ()
if (NOT DEFINED WAMR_BUILD_JIT)
# Disable JIT by default.
set (WAMR_BUILD_JIT 0)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
# Enable libc builtin support by default
set (WAMR_BUILD_LIBC_BUILTIN 1)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
# Enable libc wasi support by default
set (WAMR_BUILD_LIBC_WASI 1)
endif ()
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -pie -fPIE")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
endif ()
endif ()
# The following flags are to enhance security, but it may impact performance,
# we disable them by default.
#if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftrapv -D_FORTIFY_SOURCE=2")
#endif ()
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4")
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now")
add_library (iwasm SHARED ${WAMR_RUNTIME_LIB_SOURCE} ext_lib_export.c)
target_link_libraries (iwasm ${LLVM_AVAILABLE_LIBS} -lm -ldl -landroid -llog)
set (distribution_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build/distribution)
set_target_properties (iwasm PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${distribution_DIR}/wasm/lib")
add_custom_command (TARGET iwasm POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${WAMR_ROOT_DIR}/core/shared/include" "${distribution_DIR}/wasm/include/"
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${WAMR_ROOT_DIR}/core/shared/platform/include" "${distribution_DIR}/wasm/include/platform/"
COMMAND "${CMAKE_COMMAND}" -E copy "${WAMR_ROOT_DIR}/core/shared/platform/android/bh_platform.h" "${distribution_DIR}/wasm/include/platform/"
COMMENT "Copying iwasm to output directory")

View File

@ -0,0 +1,10 @@
#!/bin/sh
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
rm -fr build && mkdir build
cd build
cmake .. -DWAMR_BUILD_JIT=1
make
cd ..

View File

@ -0,0 +1,43 @@
#!/bin/sh
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
DEPS_DIR=${PWD}/../../../core/deps
cd ${DEPS_DIR}
if [ ! -d "llvm" ]; then
echo "Clone llvm to core/deps/ .."
git clone https://github.com/llvm-mirror/llvm.git
fi
cd llvm
mkdir -p build
cd build
if [ ! -f bin/llvm-lto ]; then
CORE_NUM=$(nproc --all)
if [ -z "${CORE_NUM}" ]; then
CORE_NUM=1
fi
echo "Build llvm with" ${CORE_NUM} "cores"
cmake .. \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_BUILD_TYPE:STRING="Release" \
-DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \
-DLLVM_OPTIMIZED_TABLEGEN:BOOL=ON \
-DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \
-DLLVM_INCLUDE_TESTS:BOOL=OFF \
-DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \
-DLLVM_APPEND_VC_REV:BOOL=OFF
make -j ${CORE_NUM}
else
echo "llvm has already been built"
fi
cd ${PWD}

View File

@ -0,0 +1,10 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "lib_export.h"
static NativeSymbol extended_native_symbol_defs[] = { };
#include "ext_lib_export.h"

View File

@ -0,0 +1,157 @@
#include <cstring>
#include <stdlib.h>
#include <jni.h>
#include <cinttypes>
#include <android/log.h>
#include <bh_log.h>
#include <string>
#include <bh_platform.h>
#include <wasm_export.h>
#define LOGI(...) \
((void)__android_log_print(ANDROID_LOG_INFO, "wasm_jni::", __VA_ARGS__))
static void *
app_instance_main(wasm_module_inst_t module_inst) {
const char *exception;
wasm_application_execute_main(module_inst, 0, NULL);
if ((exception = wasm_runtime_get_exception(module_inst)))
LOGI("%s\n", exception);
return NULL;
}
// WARNING! CAN NOT BE READ ONLY!!!
static unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,
0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x00,
0x00, 0x02, 0x58, 0x06, 0x03, 0x65, 0x6E, 0x76, 0x05, 0x5F, 0x66, 0x72,
0x65, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x07, 0x5F, 0x6D, 0x61,
0x6C, 0x6C, 0x6F, 0x63, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x07, 0x5F,
0x70, 0x72, 0x69, 0x6E, 0x74, 0x66, 0x00, 0x02, 0x03, 0x65, 0x6E, 0x76,
0x05, 0x5F, 0x70, 0x75, 0x74, 0x73, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76,
0x0D, 0x5F, 0x5F, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x5F, 0x62, 0x61,
0x73, 0x65, 0x03, 0x7F, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x65,
0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x01, 0x03, 0x04, 0x03, 0x02, 0x03,
0x03, 0x06, 0x10, 0x03, 0x7F, 0x01, 0x41, 0x00, 0x0B, 0x7F, 0x01, 0x41,
0x00, 0x0B, 0x7F, 0x00, 0x41, 0x1B, 0x0B, 0x07, 0x33, 0x04, 0x12, 0x5F,
0x5F, 0x70, 0x6F, 0x73, 0x74, 0x5F, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E,
0x74, 0x69, 0x61, 0x74, 0x65, 0x00, 0x06, 0x05, 0x5F, 0x6D, 0x61, 0x69,
0x6E, 0x00, 0x04, 0x0B, 0x72, 0x75, 0x6E, 0x50, 0x6F, 0x73, 0x74, 0x53,
0x65, 0x74, 0x73, 0x00, 0x05, 0x04, 0x5F, 0x73, 0x74, 0x72, 0x03, 0x03,
0x0A, 0xBA, 0x01, 0x03, 0x9E, 0x01, 0x01, 0x01, 0x7F, 0x23, 0x01, 0x21,
0x00, 0x23, 0x01, 0x41, 0x10, 0x6A, 0x24, 0x01, 0x20, 0x00, 0x41, 0x08,
0x6A, 0x21, 0x02, 0x23, 0x00, 0x41, 0x1B, 0x6A, 0x10, 0x03, 0x1A, 0x41,
0x80, 0x08, 0x10, 0x01, 0x21, 0x01, 0x20, 0x01, 0x04, 0x7F, 0x20, 0x00,
0x20, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x20, 0x00, 0x10, 0x02, 0x1A,
0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x0D, 0x3A, 0x00, 0x00, 0x20, 0x01,
0x23, 0x00, 0x2C, 0x00, 0x0E, 0x3A, 0x00, 0x01, 0x20, 0x01, 0x23, 0x00,
0x2C, 0x00, 0x0F, 0x3A, 0x00, 0x02, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00,
0x10, 0x3A, 0x00, 0x03, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x11, 0x3A,
0x00, 0x04, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x12, 0x3A, 0x00, 0x05,
0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x41, 0x13, 0x6A,
0x20, 0x02, 0x10, 0x02, 0x1A, 0x20, 0x01, 0x10, 0x00, 0x20, 0x00, 0x24,
0x01, 0x41, 0x00, 0x05, 0x23, 0x00, 0x41, 0x28, 0x6A, 0x10, 0x03, 0x1A,
0x20, 0x00, 0x24, 0x01, 0x41, 0x7F, 0x0B, 0x0B, 0x03, 0x00, 0x01, 0x0B,
0x14, 0x00, 0x23, 0x00, 0x41, 0x40, 0x6B, 0x24, 0x01, 0x23, 0x01, 0x41,
0x80, 0x80, 0x04, 0x6A, 0x24, 0x02, 0x10, 0x05, 0x0B, 0x0B, 0x3F, 0x01,
0x00, 0x23, 0x00, 0x0B, 0x39, 0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72,
0x3A, 0x20, 0x25, 0x70, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A, 0x00,
0x62, 0x75, 0x66, 0x3A, 0x20, 0x25, 0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C,
0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C,
0x6C, 0x6F, 0x63, 0x20, 0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C,
0x65, 0x64, 0x00, 0x50, 0x04, 0x6E, 0x61, 0x6D, 0x65, 0x01, 0x49, 0x07,
0x00, 0x05, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x01, 0x07, 0x5F, 0x6D, 0x61,
0x6C, 0x6C, 0x6F, 0x63, 0x02, 0x07, 0x5F, 0x70, 0x72, 0x69, 0x6E, 0x74,
0x66, 0x03, 0x05, 0x5F, 0x70, 0x75, 0x74, 0x73, 0x04, 0x05, 0x5F, 0x6D,
0x61, 0x69, 0x6E, 0x05, 0x0B, 0x72, 0x75, 0x6E, 0x50, 0x6F, 0x73, 0x74,
0x53, 0x65, 0x74, 0x73, 0x06, 0x12, 0x5F, 0x5F, 0x70, 0x6F, 0x73, 0x74,
0x5F, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x69, 0x61, 0x74, 0x65,
0x00, 0x20, 0x10, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x4D, 0x61, 0x70,
0x70, 0x69, 0x6E, 0x67, 0x55, 0x52, 0x4C, 0x0E, 0x61, 0x2E, 0x6F, 0x75,
0x74, 0x2E, 0x77, 0x61, 0x73, 0x6D, 0x2E, 0x6D, 0x61, 0x70 };
extern "C" JNIEXPORT void JNICALL
Java_com_intel_wasm_api_Runtime_run(JNIEnv *env, jclass thiz) {
char error_buf[128] = {0};
void *(*malloc_func)(size_t) = &malloc;
void (*free_func)(void *) = &free;
LOGI("bh_memory_init_with_allocator");
if (bh_memory_init_with_allocator((void *) malloc_func, (void *) free_func)) {
LOGI("Init memory with memory allocator failed.\n");
return;
}
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
uint wasm_file_size = 0;
uint8_t *wasm_file_buf = NULL;
/* initialize runtime environment */
LOGI("wasm_runtime_init");
if (!wasm_runtime_init()) {
LOGI("goto fail1\n");
goto fail1;
}
// set log level to INFO
LOGI("set log level to INFO");
bh_log_set_verbose_level(3);
/* load WASM byte buffer from a preinstall WASM bin file */
LOGI("use an internal test file, gona to output Hello World in logcat\n");
wasm_file_buf = (uint8_t*) wasm_test_file;
wasm_file_size = sizeof(wasm_test_file);
/* load WASM module */
LOGI("wasm_runtime_load");
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
LOGI("in wasm_runtime_load %s\n", error_buf);
LOGI("goto fail3\n");
goto fail3;
}
/* instantiate the module */
LOGI("wasm_runtime_instantiate");
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
64 * 1024, /* stack size */
64 * 1024, /* heap size */
error_buf,
sizeof(error_buf)))) {
LOGI("%s\n", error_buf);
LOGI("goto fail4\n");
goto fail4;
}
LOGI("run main() of the application");
app_instance_main(wasm_module_inst);
/* destroy the module instance */
LOGI("wasm_runtime_deinstantiate");
wasm_runtime_deinstantiate(wasm_module_inst);
fail4:
/* unload the module */
LOGI("wasm_runtime_unload");
wasm_runtime_unload(wasm_module);
fail3:
// in our case, we don't need a free, but it is not a typical one
/* free the file buffer */
//bh_free((void *) wasm_file_buf);
fail2:
/* destroy runtime environment */
LOGI("wasm_runtime_destroy");
wasm_runtime_destroy();
fail1:
LOGI("bh_memory_destroy");
bh_memory_destroy();
return;
}

View File

@ -52,6 +52,7 @@ if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
set (WAMR_BUILD_LIBC_WASI 0)
endif ()
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-U,_get_ext_lib_export_apis")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
set (CMAKE_MACOSX_RPATH True)

View File

@ -32,8 +32,9 @@ if (NOT DEFINED WAMR_BUILD_INTERP)
endif ()
if (NOT DEFINED WAMR_BUILD_AOT)
# Enable AOT by default.
set (WAMR_BUILD_AOT 1)
# Disable AOT by default.
# If enabling AOT, please install Intel SGX SDKv2.8 or later.
set (WAMR_BUILD_AOT 0)
endif ()
if (NOT DEFINED WAMR_BUILD_JIT)

View File

@ -63,7 +63,7 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
if (NOT (${CMAKE_C_COMPILER} MATCHES ".*clang.*"))
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
endif ()
endif ()

View File

@ -0,0 +1,5 @@
# set CONFIG_ARM_MPU=y if run in ARM's board
# CONFIG_ARM_MPU is not set
CONFIG_STACK_SENTINEL=y
CONFIG_PRINTK=y
CONFIG_LOG=y

View File

@ -12,10 +12,18 @@
#include "wasm_export.h"
#include "test_wasm.h"
#include <zephyr.h>
#include <sys/printk.h>
#define CONFIG_GLOBAL_HEAP_BUF_SIZE 131072
#define CONFIG_APP_STACK_SIZE 8192
#define CONFIG_APP_HEAP_SIZE 8192
#ifdef CONFIG_NO_OPTIMIZATIONS
#define CONFIG_MAIN_THREAD_STACK_SIZE 8192
#else
#define CONFIG_MAIN_THREAD_STACK_SIZE 4096
#endif
static int app_argc;
static char **app_argv;
@ -49,6 +57,8 @@ static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 };
void iwasm_main(void *arg1, void *arg2, void *arg3)
{
int start, end;
start = k_uptime_get_32();
uint8 *wasm_file_buf = NULL;
uint32 wasm_file_size;
wasm_module_t wasm_module = NULL;
@ -97,6 +107,7 @@ void iwasm_main(void *arg1, void *arg2, void *arg3)
goto fail3;
}
/* invoke the main function */
app_instance_main(wasm_module_inst);
/* destroy the module instance */
@ -111,6 +122,10 @@ void iwasm_main(void *arg1, void *arg2, void *arg3)
wasm_runtime_destroy();
fail1: bh_memory_destroy();
end = k_uptime_get_32();
printf("elpase: %d\n", (end - start));
}
#define MAIN_THREAD_STACK_SIZE (CONFIG_MAIN_THREAD_STACK_SIZE)
@ -127,7 +142,6 @@ bool iwasm_init(void)
MAIN_THREAD_PRIORITY, 0, K_NO_WAIT);
return tid ? true : false;
}
void main(void)
{
iwasm_init();

View File

@ -73,7 +73,7 @@ https://docs.zephyrproject.org/latest/getting_started/index.html</br>
d. build source code</br>
`mkdir build && cd build`</br>
`source ../../../../zephyr-env.sh`</br>
`cmake -GNinja -DBOARD=nucleo_f746zg ..`</br>
`cmake -GNinja -DBOARD=nucleo_f767zi ..`</br>
` ninja flash`</br>
- Hardware Connections

View File

@ -8,7 +8,7 @@
#include "board_config.h"
#include "stdio.h"
#include <string.h>
#include "spi.h"
#include "drivers/spi.h"
#include "zephyr.h"
#include "kernel.h"

View File

@ -35,7 +35,7 @@ extern "C" {
#include <stdbool.h>
#include "lv_hal/lv_hal_indev.h"
#include "device.h"
#include "gpio.h"
#include "drivers/gpio.h"
/*********************
* DEFINES

View File

@ -14,9 +14,9 @@
#define LOG_DBG printf
#define LOG_WRN printf
#include <gpio.h>
#include <drivers/gpio.h>
#include <sys/byteorder.h>
#include <spi.h>
#include <drivers/spi.h>
#include <string.h>
struct ili9340_data {

View File

@ -27,7 +27,7 @@ extern void xpt2046_init(void);
extern void wgl_init();
#include <zephyr.h>
#include <uart.h>
#include <drivers/uart.h>
#include <device.h>
int uart_char_cnt = 0;

View File

@ -7,4 +7,4 @@ CONFIG_LOG=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_STACK_SENTINEL=y
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_ARM_MPU=n
CONFIG_ARM_MPU=y

View File

@ -84,15 +84,12 @@ https://docs.zephyrproject.org/latest/getting_started/index.html</br>
` ln -s <wamr_root> wamr`</br>
d. build source code</br>
Since ui_app incorporated LittlevGL source code, so it needs more RAM on the device to install the application.
It is recommended that RAM SIZE not less than 420KB.
In our test use nucleo_f767zi, which is not supported by Zephyr.
However, nucleo_f767zi is almost the same as nucleo_f746zg, except FLASH and SRAM size.
So we changed the DTS setting of nucleo_f746zg boards for a workaround.</br>
It is recommended that RAM SIZE not less than 380KB.
In our test use nucleo_f767zi, which is supported by Zephyr.
`Modify zephyr/dts/arm/st/f7/stm32f746.dtsi, change DT_SIZE_K(256) to DT_SIZE_K(512) in 'sram0' definition.`</br>
`mkdir build && cd build`</br>
`source ../../../../zephyr-env.sh`</br>
`cmake -GNinja -DBOARD=nucleo_f746zg ..`</br>
`cmake -GNinja -DBOARD=nucleo_f767zi ..`</br>
` ninja flash`</br>
- Hardware Connections

View File

@ -8,7 +8,7 @@
#include "board_config.h"
#include "stdio.h"
#include <string.h>
#include "spi.h"
#include "drivers/spi.h"
#include "zephyr.h"
#include "kernel.h"

View File

@ -35,7 +35,7 @@ extern "C" {
#include <stdbool.h>
//#include "lvgl/lv_hal/lv_hal_indev.h"
#include "device.h"
#include "gpio.h"
#include "drivers/gpio.h"
#if 1
enum {
LV_INDEV_STATE_REL = 0, LV_INDEV_STATE_PR

View File

@ -14,9 +14,9 @@
#define LOG_DBG printf
#define LOG_WRN printf
#include <gpio.h>
#include <drivers/gpio.h>
#include <sys/byteorder.h>
#include <spi.h>
#include <drivers/spi.h>
#include <string.h>
struct ili9340_data {

View File

@ -16,14 +16,15 @@
#include "module_wasm_app.h"
#include "wasm_export.h"
#include <zephyr.h>
#include <drivers/uart.h>
#include <device.h>
extern void init_sensor_framework();
extern void exit_sensor_framework();
extern int aee_host_msg_callback(void *msg, uint16_t msg_len);
#include <zephyr.h>
#include <uart.h>
#include <device.h>
int uart_char_cnt = 0;
static void uart_irq_callback(struct device *dev)

View File

@ -7,4 +7,4 @@ CONFIG_LOG=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_STACK_SENTINEL=y
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_ARM_MPU=n
CONFIG_ARM_MPU=y