From 9a961c4843f51e46e9ba8842c78fc7c12d98ad06 Mon Sep 17 00:00:00 2001 From: wenyongh Date: Thu, 27 Feb 2020 16:38:44 +0800 Subject: [PATCH] Enable ARM and THUMB AOT support, enable Android platform support (#182) * Sync with internal/feature: enable arm aot and android platform --- README.md | 3 +- build-scripts/config_common.cmake | 2 + .../wgl/native/wgl_obj_wrapper.c | 5 +- core/app-mgr/app-manager/module_wasm_app.c | 1 - core/iwasm/aot/aot_loader.c | 445 +----------------- core/iwasm/aot/aot_reloc.h | 58 +++ core/iwasm/aot/arch/aot_reloc_arm.c | 247 ++++++++++ core/iwasm/aot/arch/aot_reloc_mips.c | 69 +++ core/iwasm/aot/arch/aot_reloc_thumb.c | 253 ++++++++++ core/iwasm/aot/arch/aot_reloc_x86_32.c | 113 +++++ core/iwasm/aot/arch/aot_reloc_x86_64.c | 190 ++++++++ core/iwasm/aot/arch/aot_reloc_xtensa.c | 64 +++ core/iwasm/aot/iwasm_aot.cmake | 18 +- core/shared/platform/alios/bh_platform.c | 4 + core/shared/platform/alios/bh_platform.h | 1 + core/shared/platform/android/bh_assert.c | 58 +++ core/shared/platform/android/bh_definition.c | 67 +++ core/shared/platform/android/bh_platform.c | 176 +++++++ core/shared/platform/android/bh_platform.h | 142 ++++++ .../shared/platform/android/bh_platform_log.c | 33 ++ core/shared/platform/android/bh_thread.c | 395 ++++++++++++++++ core/shared/platform/android/bh_time.c | 71 +++ .../platform/android/shared_platform.cmake | 17 + core/shared/platform/darwin/bh_platform.h | 1 + core/shared/platform/linux-sgx/bh_platform.h | 1 + core/shared/platform/linux/bh_platform.h | 1 + core/shared/platform/vxworks/bh_platform.h | 1 + core/shared/platform/zephyr/bh_platform.c | 44 ++ core/shared/platform/zephyr/bh_platform.h | 1 + core/shared/platform/zephyr/bh_thread.c | 4 +- core/shared/utils/bh_log.c | 14 +- doc/build_wamr.md | 41 +- product-mini/platforms/alios-things/aos.mk | 7 + product-mini/platforms/android/CMakeLists.txt | 102 ++++ product-mini/platforms/android/build_jit.sh | 10 + product-mini/platforms/android/build_llvm.sh | 43 ++ .../platforms/android/ext_lib_export.c | 10 + product-mini/platforms/android/wasm-jni.cpp | 157 ++++++ product-mini/platforms/zephyr/simple/prj.conf | 5 + .../platforms/zephyr/simple/src/main.c | 16 +- samples/gui/README.md | 2 +- .../src/platform/zephyr/XPT2046.c | 2 +- .../src/platform/zephyr/XPT2046.h | 2 +- .../src/platform/zephyr/display_ili9340.c | 4 +- .../src/platform/zephyr/iwasm_main.c | 2 +- .../wasm-runtime-wgl/zephyr-build/prj.conf | 2 +- samples/littlevgl/README.md | 9 +- .../src/platform/zephyr/XPT2046.c | 2 +- .../src/platform/zephyr/XPT2046.h | 2 +- .../src/platform/zephyr/display_ili9340.c | 4 +- .../src/platform/zephyr/iwasm_main.c | 9 +- .../vgl-wasm-runtime/zephyr-build/prj.conf | 2 +- 52 files changed, 2466 insertions(+), 466 deletions(-) create mode 100644 core/iwasm/aot/aot_reloc.h create mode 100644 core/iwasm/aot/arch/aot_reloc_arm.c create mode 100644 core/iwasm/aot/arch/aot_reloc_mips.c create mode 100644 core/iwasm/aot/arch/aot_reloc_thumb.c create mode 100644 core/iwasm/aot/arch/aot_reloc_x86_32.c create mode 100644 core/iwasm/aot/arch/aot_reloc_x86_64.c create mode 100644 core/iwasm/aot/arch/aot_reloc_xtensa.c create mode 100644 core/shared/platform/android/bh_assert.c create mode 100644 core/shared/platform/android/bh_definition.c create mode 100755 core/shared/platform/android/bh_platform.c create mode 100644 core/shared/platform/android/bh_platform.h create mode 100644 core/shared/platform/android/bh_platform_log.c create mode 100755 core/shared/platform/android/bh_thread.c create mode 100755 core/shared/platform/android/bh_time.c create mode 100644 core/shared/platform/android/shared_platform.cmake create mode 100644 product-mini/platforms/android/CMakeLists.txt create mode 100755 product-mini/platforms/android/build_jit.sh create mode 100755 product-mini/platforms/android/build_llvm.sh create mode 100644 product-mini/platforms/android/ext_lib_export.c create mode 100644 product-mini/platforms/android/wasm-jni.cpp diff --git a/README.md b/README.md index f426eb1f..3bf0b7b0 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 4c0a356c..6d4c0285 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -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 () diff --git a/core/app-framework/wgl/native/wgl_obj_wrapper.c b/core/app-framework/wgl/native/wgl_obj_wrapper.c index 6cd7122e..d8116571 100644 --- a/core/app-framework/wgl/native/wgl_obj_wrapper.c +++ b/core/app-framework/wgl/native/wgl_obj_wrapper.c @@ -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); diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index a5cd6b4d..ecc352ed 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -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, diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 9aa98f73..8915103a 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -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). */ -#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; } diff --git a/core/iwasm/aot/aot_reloc.h b/core/iwasm/aot/aot_reloc.h new file mode 100644 index 00000000..9102b89e --- /dev/null +++ b/core/iwasm/aot/aot_reloc.h @@ -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); + diff --git a/core/iwasm/aot/arch/aot_reloc_arm.c b/core/iwasm/aot/arch/aot_reloc_arm.c new file mode 100644 index 00000000..0dac4f66 --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_arm.c @@ -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). */ +#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; +} + diff --git a/core/iwasm/aot/arch/aot_reloc_mips.c b/core/iwasm/aot/arch/aot_reloc_mips.c new file mode 100644 index 00000000..c1b3fa54 --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_mips.c @@ -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; +} + diff --git a/core/iwasm/aot/arch/aot_reloc_thumb.c b/core/iwasm/aot/arch/aot_reloc_thumb.c new file mode 100644 index 00000000..86e2e330 --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_thumb.c @@ -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; +} + diff --git a/core/iwasm/aot/arch/aot_reloc_x86_32.c b/core/iwasm/aot/arch/aot_reloc_x86_32.c new file mode 100644 index 00000000..20e82b3e --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_x86_32.c @@ -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; +} + diff --git a/core/iwasm/aot/arch/aot_reloc_x86_64.c b/core/iwasm/aot/arch/aot_reloc_x86_64.c new file mode 100644 index 00000000..28aa661a --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_x86_64.c @@ -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; +} + diff --git a/core/iwasm/aot/arch/aot_reloc_xtensa.c b/core/iwasm/aot/arch/aot_reloc_xtensa.c new file mode 100644 index 00000000..24c0db78 --- /dev/null +++ b/core/iwasm/aot/arch/aot_reloc_xtensa.c @@ -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; +} + diff --git a/core/iwasm/aot/iwasm_aot.cmake b/core/iwasm/aot/iwasm_aot.cmake index d1bd0c61..4166efb3 100644 --- a/core/iwasm/aot/iwasm_aot.cmake +++ b/core/iwasm/aot/iwasm_aot.cmake @@ -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}) diff --git a/core/shared/platform/alios/bh_platform.c b/core/shared/platform/alios/bh_platform.c index bfa8d9e4..9d3a1f6b 100644 --- a/core/shared/platform/alios/bh_platform.c +++ b/core/shared/platform/alios/bh_platform.c @@ -45,3 +45,7 @@ bh_mprotect(void *addr, uint32 size, int prot) return 0; } +void +bh_dcache_flush() +{ +} diff --git a/core/shared/platform/alios/bh_platform.h b/core/shared/platform/alios/bh_platform.h index 5f66a69f..9b39c00e 100644 --- a/core/shared/platform/alios/bh_platform.h +++ b/core/shared/platform/alios/bh_platform.h @@ -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 */ diff --git a/core/shared/platform/android/bh_assert.c b/core/shared/platform/android/bh_assert.c new file mode 100644 index 00000000..c609fb93 --- /dev/null +++ b/core/shared/platform/android/bh_assert.c @@ -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 +#include +#include + +#ifdef BH_TEST +#include +#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 +} + diff --git a/core/shared/platform/android/bh_definition.c b/core/shared/platform/android/bh_definition.c new file mode 100644 index 00000000..8fb58d2f --- /dev/null +++ b/core/shared/platform/android/bh_definition.c @@ -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; +} diff --git a/core/shared/platform/android/bh_platform.c b/core/shared/platform/android/bh_platform.c new file mode 100755 index 00000000..4eda405b --- /dev/null +++ b/core/shared/platform/android/bh_platform.c @@ -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 +#include +#include +#include + +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); +} + diff --git a/core/shared/platform/android/bh_platform.h b/core/shared/platform/android/bh_platform.h new file mode 100644 index 00000000..fa221aa2 --- /dev/null +++ b/core/shared/platform/android/bh_platform.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/core/shared/platform/android/bh_platform_log.c b/core/shared/platform/android/bh_platform_log.c new file mode 100644 index 00000000..d5a01ec5 --- /dev/null +++ b/core/shared/platform/android/bh_platform_log.c @@ -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 + +#include + +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"); +} diff --git a/core/shared/platform/android/bh_thread.c b/core/shared/platform/android/bh_thread.c new file mode 100755 index 00000000..cf41c456 --- /dev/null +++ b/core/shared/platform/android/bh_thread.c @@ -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 +#include +#include + +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); +} + diff --git a/core/shared/platform/android/bh_time.c b/core/shared/platform/android/bh_time.c new file mode 100755 index 00000000..05cf0af5 --- /dev/null +++ b/core/shared/platform/android/bh_time.c @@ -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 +#include +#include + +/* + * 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); +} + diff --git a/core/shared/platform/android/shared_platform.cmake b/core/shared/platform/android/shared_platform.cmake new file mode 100644 index 00000000..a49c5c6e --- /dev/null +++ b/core/shared/platform/android/shared_platform.cmake @@ -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}) \ No newline at end of file diff --git a/core/shared/platform/darwin/bh_platform.h b/core/shared/platform/darwin/bh_platform.h index 07ec9b95..11a577bb 100644 --- a/core/shared/platform/darwin/bh_platform.h +++ b/core/shared/platform/darwin/bh_platform.h @@ -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 } diff --git a/core/shared/platform/linux-sgx/bh_platform.h b/core/shared/platform/linux-sgx/bh_platform.h index 00fbfbd9..dc472328 100644 --- a/core/shared/platform/linux-sgx/bh_platform.h +++ b/core/shared/platform/linux-sgx/bh_platform.h @@ -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 } diff --git a/core/shared/platform/linux/bh_platform.h b/core/shared/platform/linux/bh_platform.h index a2b040f7..2fc4e1a3 100644 --- a/core/shared/platform/linux/bh_platform.h +++ b/core/shared/platform/linux/bh_platform.h @@ -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 } diff --git a/core/shared/platform/vxworks/bh_platform.h b/core/shared/platform/vxworks/bh_platform.h index 107f6a59..457933d8 100644 --- a/core/shared/platform/vxworks/bh_platform.h +++ b/core/shared/platform/vxworks/bh_platform.h @@ -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 } diff --git a/core/shared/platform/zephyr/bh_platform.c b/core/shared/platform/zephyr/bh_platform.c index fd56115b..27c35ff3 100755 --- a/core/shared/platform/zephyr/bh_platform.c +++ b/core/shared/platform/zephyr/bh_platform.c @@ -8,6 +8,9 @@ #include "bh_common.h" #include #include +#ifdef CONFIG_ARM_MPU +#include +#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 +} diff --git a/core/shared/platform/zephyr/bh_platform.h b/core/shared/platform/zephyr/bh_platform.h index 86cfcd4a..77db8a35 100644 --- a/core/shared/platform/zephyr/bh_platform.h +++ b/core/shared/platform/zephyr/bh_platform.h @@ -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 diff --git a/core/shared/platform/zephyr/bh_thread.c b/core/shared/platform/zephyr/bh_thread.c index dba49e6d..fd9e6e0c 100755 --- a/core/shared/platform/zephyr/bh_thread.c +++ b/core/shared/platform/zephyr/bh_thread.c @@ -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) diff --git a/core/shared/utils/bh_log.c b/core/shared/utils/bh_log.c index 39d89781..425dce42 100644 --- a/core/shared/utils/bh_log.c +++ b/core/shared/utils/bh_log.c @@ -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); diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 2e534bd8..eeac611f 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -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= to set the building target, including: +cmake -DWAMR_BUILD_TARGET= to set the building target, including: X86_64, X86_32, ARM, THUMB, XTENSA and MIPS - for ARM and THUMB, we can specify the info, e.g. ARMV4, ARMV4T, ARMV5, ARMV5T, THUMBV4T, THUMBV5T and so on. + For ARM and THUMB, the format is [][_VFP] where 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 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 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. diff --git a/product-mini/platforms/alios-things/aos.mk b/product-mini/platforms/alios-things/aos.mk index bf05bff2..ea92eda7 100644 --- a/product-mini/platforms/alios-things/aos.mk +++ b/product-mini/platforms/alios-things/aos.mk @@ -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 diff --git a/product-mini/platforms/android/CMakeLists.txt b/product-mini/platforms/android/CMakeLists.txt new file mode 100644 index 00000000..1d20819c --- /dev/null +++ b/product-mini/platforms/android/CMakeLists.txt @@ -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") diff --git a/product-mini/platforms/android/build_jit.sh b/product-mini/platforms/android/build_jit.sh new file mode 100755 index 00000000..908d1560 --- /dev/null +++ b/product-mini/platforms/android/build_jit.sh @@ -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 .. diff --git a/product-mini/platforms/android/build_llvm.sh b/product-mini/platforms/android/build_llvm.sh new file mode 100755 index 00000000..d5857926 --- /dev/null +++ b/product-mini/platforms/android/build_llvm.sh @@ -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} + diff --git a/product-mini/platforms/android/ext_lib_export.c b/product-mini/platforms/android/ext_lib_export.c new file mode 100644 index 00000000..8813f0db --- /dev/null +++ b/product-mini/platforms/android/ext_lib_export.c @@ -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" diff --git a/product-mini/platforms/android/wasm-jni.cpp b/product-mini/platforms/android/wasm-jni.cpp new file mode 100644 index 00000000..be57aba8 --- /dev/null +++ b/product-mini/platforms/android/wasm-jni.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/product-mini/platforms/zephyr/simple/prj.conf b/product-mini/platforms/zephyr/simple/prj.conf index e69de29b..96db21f2 100644 --- a/product-mini/platforms/zephyr/simple/prj.conf +++ b/product-mini/platforms/zephyr/simple/prj.conf @@ -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 diff --git a/product-mini/platforms/zephyr/simple/src/main.c b/product-mini/platforms/zephyr/simple/src/main.c index 621cc7b7..add1c24b 100644 --- a/product-mini/platforms/zephyr/simple/src/main.c +++ b/product-mini/platforms/zephyr/simple/src/main.c @@ -12,10 +12,18 @@ #include "wasm_export.h" #include "test_wasm.h" +#include +#include + #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(); diff --git a/samples/gui/README.md b/samples/gui/README.md index 6caf48bc..364dab8c 100644 --- a/samples/gui/README.md +++ b/samples/gui/README.md @@ -73,7 +73,7 @@ https://docs.zephyrproject.org/latest/getting_started/index.html
d. build source code
`mkdir build && cd build`
`source ../../../../zephyr-env.sh`
- `cmake -GNinja -DBOARD=nucleo_f746zg ..`
+ `cmake -GNinja -DBOARD=nucleo_f767zi ..`
` ninja flash`
- Hardware Connections diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c index 6d9048d4..e5c1415e 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c @@ -8,7 +8,7 @@ #include "board_config.h" #include "stdio.h" #include -#include "spi.h" +#include "drivers/spi.h" #include "zephyr.h" #include "kernel.h" diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h index 788059d9..e6d4e5c7 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h @@ -35,7 +35,7 @@ extern "C" { #include #include "lv_hal/lv_hal_indev.h" #include "device.h" -#include "gpio.h" +#include "drivers/gpio.h" /********************* * DEFINES diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c index 6326e0ae..1ddc6937 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c @@ -14,9 +14,9 @@ #define LOG_DBG printf #define LOG_WRN printf -#include +#include #include -#include +#include #include struct ili9340_data { diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c index 5aee8b57..af8d4d7b 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c @@ -27,7 +27,7 @@ extern void xpt2046_init(void); extern void wgl_init(); #include -#include +#include #include int uart_char_cnt = 0; diff --git a/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf b/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf index 4117f0fb..f9f13f9a 100644 --- a/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf +++ b/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf @@ -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 diff --git a/samples/littlevgl/README.md b/samples/littlevgl/README.md index 2859e556..d7d574f5 100644 --- a/samples/littlevgl/README.md +++ b/samples/littlevgl/README.md @@ -84,15 +84,12 @@ https://docs.zephyrproject.org/latest/getting_started/index.html
` ln -s wamr`
d. build source code
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.
+ 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.`
`mkdir build && cd build`
`source ../../../../zephyr-env.sh`
- `cmake -GNinja -DBOARD=nucleo_f746zg ..`
+ `cmake -GNinja -DBOARD=nucleo_f767zi ..`
` ninja flash`
- Hardware Connections diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c index 6d9048d4..e5c1415e 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c @@ -8,7 +8,7 @@ #include "board_config.h" #include "stdio.h" #include -#include "spi.h" +#include "drivers/spi.h" #include "zephyr.h" #include "kernel.h" diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.h b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.h index 6b3347e2..196ef7c7 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.h +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.h @@ -35,7 +35,7 @@ extern "C" { #include //#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 diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c index 6326e0ae..1ddc6937 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c @@ -14,9 +14,9 @@ #define LOG_DBG printf #define LOG_WRN printf -#include +#include #include -#include +#include #include struct ili9340_data { diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c index fd991a3c..6d4b0057 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c @@ -16,14 +16,15 @@ #include "module_wasm_app.h" #include "wasm_export.h" +#include +#include +#include + + extern void init_sensor_framework(); extern void exit_sensor_framework(); extern int aee_host_msg_callback(void *msg, uint16_t msg_len); -#include -#include -#include - int uart_char_cnt = 0; static void uart_irq_callback(struct device *dev) diff --git a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf index 4117f0fb..f9f13f9a 100644 --- a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf +++ b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf @@ -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