mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 23:42:05 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
038735d554
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
58
core/iwasm/aot/aot_reloc.h
Normal file
58
core/iwasm/aot/aot_reloc.h
Normal 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);
|
||||
|
247
core/iwasm/aot/arch/aot_reloc_arm.c
Normal file
247
core/iwasm/aot/arch/aot_reloc_arm.c
Normal 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;
|
||||
}
|
||||
|
69
core/iwasm/aot/arch/aot_reloc_mips.c
Normal file
69
core/iwasm/aot/arch/aot_reloc_mips.c
Normal 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;
|
||||
}
|
||||
|
253
core/iwasm/aot/arch/aot_reloc_thumb.c
Normal file
253
core/iwasm/aot/arch/aot_reloc_thumb.c
Normal 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;
|
||||
}
|
||||
|
113
core/iwasm/aot/arch/aot_reloc_x86_32.c
Normal file
113
core/iwasm/aot/arch/aot_reloc_x86_32.c
Normal 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;
|
||||
}
|
||||
|
190
core/iwasm/aot/arch/aot_reloc_x86_64.c
Normal file
190
core/iwasm/aot/arch/aot_reloc_x86_64.c
Normal 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;
|
||||
}
|
||||
|
64
core/iwasm/aot/arch/aot_reloc_xtensa.c
Normal file
64
core/iwasm/aot/arch/aot_reloc_xtensa.c
Normal 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;
|
||||
}
|
||||
|
|
@ -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})
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -45,3 +45,7 @@ bh_mprotect(void *addr, uint32 size, int prot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bh_dcache_flush()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
58
core/shared/platform/android/bh_assert.c
Normal file
58
core/shared/platform/android/bh_assert.c
Normal 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
|
||||
}
|
||||
|
67
core/shared/platform/android/bh_definition.c
Normal file
67
core/shared/platform/android/bh_definition.c
Normal 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;
|
||||
}
|
176
core/shared/platform/android/bh_platform.c
Executable file
176
core/shared/platform/android/bh_platform.c
Executable 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);
|
||||
}
|
||||
|
142
core/shared/platform/android/bh_platform.h
Normal file
142
core/shared/platform/android/bh_platform.h
Normal 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
|
33
core/shared/platform/android/bh_platform_log.c
Normal file
33
core/shared/platform/android/bh_platform_log.c
Normal 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");
|
||||
}
|
395
core/shared/platform/android/bh_thread.c
Executable file
395
core/shared/platform/android/bh_thread.c
Executable 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);
|
||||
}
|
||||
|
71
core/shared/platform/android/bh_time.c
Executable file
71
core/shared/platform/android/bh_time.c
Executable 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);
|
||||
}
|
||||
|
17
core/shared/platform/android/shared_platform.cmake
Normal file
17
core/shared/platform/android/shared_platform.cmake
Normal 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})
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
102
product-mini/platforms/android/CMakeLists.txt
Normal file
102
product-mini/platforms/android/CMakeLists.txt
Normal 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")
|
10
product-mini/platforms/android/build_jit.sh
Executable file
10
product-mini/platforms/android/build_jit.sh
Executable 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 ..
|
43
product-mini/platforms/android/build_llvm.sh
Executable file
43
product-mini/platforms/android/build_llvm.sh
Executable 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}
|
||||
|
10
product-mini/platforms/android/ext_lib_export.c
Normal file
10
product-mini/platforms/android/ext_lib_export.c
Normal 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"
|
157
product-mini/platforms/android/wasm-jni.cpp
Normal file
157
product-mini/platforms/android/wasm-jni.cpp
Normal 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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user