Просмотр исходного кода

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

* Sync with internal/feature: enable arm aot and android platform
wenyongh 5 лет назад
Родитель
Сommit
9a961c4843
52 измененных файлов с 2466 добавлено и 466 удалено
  1. 2 1
      README.md
  2. 2 0
      build-scripts/config_common.cmake
  3. 4 1
      core/app-framework/wgl/native/wgl_obj_wrapper.c
  4. 0 1
      core/app-mgr/app-manager/module_wasm_app.c
  5. 11 434
      core/iwasm/aot/aot_loader.c
  6. 58 0
      core/iwasm/aot/aot_reloc.h
  7. 247 0
      core/iwasm/aot/arch/aot_reloc_arm.c
  8. 69 0
      core/iwasm/aot/arch/aot_reloc_mips.c
  9. 253 0
      core/iwasm/aot/arch/aot_reloc_thumb.c
  10. 113 0
      core/iwasm/aot/arch/aot_reloc_x86_32.c
  11. 190 0
      core/iwasm/aot/arch/aot_reloc_x86_64.c
  12. 64 0
      core/iwasm/aot/arch/aot_reloc_xtensa.c
  13. 17 1
      core/iwasm/aot/iwasm_aot.cmake
  14. 4 0
      core/shared/platform/alios/bh_platform.c
  15. 1 0
      core/shared/platform/alios/bh_platform.h
  16. 58 0
      core/shared/platform/android/bh_assert.c
  17. 67 0
      core/shared/platform/android/bh_definition.c
  18. 176 0
      core/shared/platform/android/bh_platform.c
  19. 142 0
      core/shared/platform/android/bh_platform.h
  20. 33 0
      core/shared/platform/android/bh_platform_log.c
  21. 395 0
      core/shared/platform/android/bh_thread.c
  22. 71 0
      core/shared/platform/android/bh_time.c
  23. 17 0
      core/shared/platform/android/shared_platform.cmake
  24. 1 0
      core/shared/platform/darwin/bh_platform.h
  25. 1 0
      core/shared/platform/linux-sgx/bh_platform.h
  26. 1 0
      core/shared/platform/linux/bh_platform.h
  27. 1 0
      core/shared/platform/vxworks/bh_platform.h
  28. 44 0
      core/shared/platform/zephyr/bh_platform.c
  29. 1 0
      core/shared/platform/zephyr/bh_platform.h
  30. 2 2
      core/shared/platform/zephyr/bh_thread.c
  31. 13 1
      core/shared/utils/bh_log.c
  32. 39 2
      doc/build_wamr.md
  33. 7 0
      product-mini/platforms/alios-things/aos.mk
  34. 102 0
      product-mini/platforms/android/CMakeLists.txt
  35. 10 0
      product-mini/platforms/android/build_jit.sh
  36. 43 0
      product-mini/platforms/android/build_llvm.sh
  37. 10 0
      product-mini/platforms/android/ext_lib_export.c
  38. 157 0
      product-mini/platforms/android/wasm-jni.cpp
  39. 5 0
      product-mini/platforms/zephyr/simple/prj.conf
  40. 15 1
      product-mini/platforms/zephyr/simple/src/main.c
  41. 1 1
      samples/gui/README.md
  42. 1 1
      samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c
  43. 1 1
      samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h
  44. 2 2
      samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c
  45. 1 1
      samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c
  46. 1 1
      samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf
  47. 3 6
      samples/littlevgl/README.md
  48. 1 1
      samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c
  49. 1 1
      samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.h
  50. 2 2
      samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c
  51. 5 4
      samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c
  52. 1 1
      samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf

+ 2 - 1
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.
 

+ 2 - 0
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 ()

+ 4 - 1
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);

+ 0 - 1
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,

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

+ 58 - 0
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);
+

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

+ 69 - 0
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;
+}
+

+ 253 - 0
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;
+}
+

+ 113 - 0
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;
+}
+

+ 190 - 0
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;
+}
+

+ 64 - 0
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;
+}
+

+ 17 - 1
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})
 

+ 4 - 0
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()
+{
+}

+ 1 - 0
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 */
 

+ 58 - 0
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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef BH_TEST
+#include <setjmp.h>
+#endif
+
+#ifdef BH_TEST
+/* for exception throwing */
+jmp_buf bh_test_jb;
+#endif
+
+void bh_assert_internal(int v, const char *file_name, int line_number,
+        const char *expr_string)
+{
+    if (v)
+        return;
+
+    if (!file_name)
+        file_name = "NULL FILENAME";
+    if (!expr_string)
+        expr_string = "NULL EXPR_STRING";
+
+    printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
+            file_name, line_number);
+
+#ifdef BH_TEST
+    longjmp(bh_test_jb, 1);
+#endif
+
+    abort();
+}
+
+void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
+        ...)
+{
+#ifndef JEFF_TEST_VERIFIER
+    va_list args;
+
+    va_start(args, fmt);
+    bh_assert(file_name);
+
+    printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
+    vprintf(fmt, args);
+
+    va_end(args);
+    printf("\n");
+#endif
+}
+

+ 67 - 0
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;
+}

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

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

+ 33 - 0
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 <stdio.h>
+
+#include <android/log.h>
+
+void bh_log_emit(const char *fmt, va_list ap)
+{
+    (void)__android_log_vprint(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
+}
+
+int bh_fprintf(FILE *stream, const char *fmt, ...)
+{
+    (void)stream;
+    va_list ap;
+    int ret = 0;
+
+    va_start(ap, fmt);
+    ret = __android_log_vprint(ANDROID_LOG_INFO, "wasm_runtime::", fmt, ap);
+    va_end(ap);
+
+    return ret;
+}
+
+int bh_fflush(void *stream)
+{
+    (void)stream;
+    return __android_log_print(ANDROID_LOG_INFO, "wasm_runtime::", "%s", "NOT IMPLEMENT");
+}

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

+ 71 - 0
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 <unistd.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+/*
+ * This function returns milliseconds per tick.
+ * @return milliseconds per tick.
+ */
+uint64 _bh_time_get_tick_millisecond()
+{
+    return (uint64)sysconf(_SC_CLK_TCK);
+}
+
+/*
+ * This function returns milliseconds after boot.
+ * @return milliseconds after boot.
+ */
+uint64 _bh_time_get_boot_millisecond()
+{
+    struct timespec ts;
+    if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
+        return 0;
+    }
+
+    return ((uint64) ts.tv_sec) * 1000 + ((uint64)ts.tv_nsec) / (1000 * 1000);
+}
+
+uint32 bh_get_tick_sec()
+{
+    return (uint32)(_bh_time_get_boot_millisecond() / 1000);
+}
+
+/*
+ * This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
+ * @return milliseconds since from 1970.1.1.
+ */
+uint64 _bh_time_get_millisecond_from_1970()
+{
+    struct timeval tv;
+    struct timezone tz;
+    gettimeofday(&tv, &tz);
+
+   return tv.tv_sec * 1000 + tv.tv_usec
+           - (tz.tz_dsttime == 0 ? 0 : 60 * 60 * 1000)
+           + tz.tz_minuteswest * 60 * 1000;
+}
+
+size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
+{
+    time_t time_sec = (time_t)(time / 1000);
+    struct timeval tv;
+    struct timezone tz;
+    struct tm *ltp;
+
+    gettimeofday(&tv, &tz);
+    time_sec -= tz.tz_minuteswest * 60;
+
+    ltp = localtime(&time_sec);
+    if (ltp == NULL) {
+        return 0;
+    }
+    return strftime(s, max, format, ltp);
+}
+

+ 17 - 0
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})

+ 1 - 0
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
 }

+ 1 - 0
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
 }

+ 1 - 0
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
 }

+ 1 - 0
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
 }

+ 44 - 0
core/shared/platform/zephyr/bh_platform.c

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

+ 1 - 0
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

+ 2 - 2
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)

+ 13 - 1
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);

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

+ 7 - 0
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
 

+ 102 - 0
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")

+ 10 - 0
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 ..

+ 43 - 0
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}
+

+ 10 - 0
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"

+ 157 - 0
product-mini/platforms/android/wasm-jni.cpp

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

+ 5 - 0
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

+ 15 - 1
product-mini/platforms/zephyr/simple/src/main.c

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

+ 1 - 1
samples/gui/README.md

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

+ 1 - 1
samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c

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

+ 1 - 1
samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h

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

+ 2 - 2
samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c

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

+ 1 - 1
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 <zephyr.h>
-#include <uart.h>
+#include <drivers/uart.h>
 #include <device.h>
 
 int uart_char_cnt = 0;

+ 1 - 1
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

+ 3 - 6
samples/littlevgl/README.md

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

+ 1 - 1
samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.c

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

+ 1 - 1
samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/XPT2046.h

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

+ 2 - 2
samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c

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

+ 5 - 4
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 <zephyr.h>
+#include <drivers/uart.h>
+#include <device.h>
+
+
 extern void init_sensor_framework();
 extern void exit_sensor_framework();
 extern int aee_host_msg_callback(void *msg, uint16_t msg_len);
 
-#include <zephyr.h>
-#include <uart.h>
-#include <device.h>
-
 int uart_char_cnt = 0;
 
 static void uart_irq_callback(struct device *dev)

+ 1 - 1
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