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

Enhance wasm loader and interpreter, enhance code security and update document (#149)

wenyongh 6 лет назад
Родитель
Сommit
631b7a2403
45 измененных файлов с 678 добавлено и 646 удалено
  1. 1 1
      README.md
  2. 24 10
      core/app-mgr/app-manager/module_wasm_app.c
  3. 5 2
      core/iwasm/lib/app-libs/base/wasm_app.h
  4. 1 0
      core/iwasm/lib/native/base/runtime_lib.h
  5. 11 2
      core/iwasm/lib/native/base/timer_wrapper.c
  6. 20 6
      core/iwasm/lib/native/extension/connection/linux/connection_mgr.c
  7. 20 0
      core/iwasm/lib/native/extension/gui/wgl.h
  8. 4 1
      core/iwasm/lib/native/extension/gui/wgl_native_utils.h
  9. 14 2
      core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c
  10. 16 5
      core/iwasm/lib/native/extension/sensor/sensor_mgr_ref.c
  11. 4 4
      core/iwasm/lib/native/libc/wasi_wrapper.c
  12. 2 0
      core/iwasm/lib/native/libc/wasmtime-wasi-c/sandboxed-system-primitives/include/wasmtime_ssp.h
  13. 53 0
      core/iwasm/lib/native/libc/wasmtime-wasi-c/sandboxed-system-primitives/src/posix.c
  14. 1 1
      core/iwasm/products/alios-things/iwasm.mk
  15. 11 4
      core/iwasm/products/linux/CMakeLists.txt
  16. 1 1
      core/iwasm/products/zephyr/simple/CMakeLists.txt
  17. 0 305
      core/iwasm/runtime/platform/linux-sgx/wasm_native.c
  18. 26 0
      core/iwasm/runtime/platform/linux/wasm_native.c
  19. 0 4
      core/iwasm/runtime/vmcore-wasm/wasm.h
  20. 4 3
      core/iwasm/runtime/vmcore-wasm/wasm_application.c
  21. 230 57
      core/iwasm/runtime/vmcore-wasm/wasm_interp.c
  22. 94 160
      core/iwasm/runtime/vmcore-wasm/wasm_loader.c
  23. 6 3
      core/shared-lib/include/config.h
  24. 1 1
      core/shared-lib/platform/zephyr/bh_platform.h
  25. 0 23
      core/shared-lib/utils/runtime_timer.c
  26. 0 3
      core/shared-lib/utils/runtime_timer.h
  27. 0 4
      doc/build_wamr.md
  28. 18 8
      samples/gui/build.sh
  29. 4 1
      samples/gui/wasm-apps/lvgl-compatible/src/main.c
  30. 4 1
      samples/gui/wasm-apps/wgl/src/main.c
  31. 11 4
      samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c
  32. 2 2
      samples/gui/wasm-runtime-wgl/src/platform/linux/main.c
  33. 1 1
      samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c
  34. 1 1
      samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c
  35. 16 6
      samples/littlevgl/build.sh
  36. 1 1
      samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c
  37. 9 3
      samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c
  38. 2 2
      samples/littlevgl/vgl-wasm-runtime/src/platform/linux/main.c
  39. 1 1
      samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/display_ili9340.c
  40. 1 1
      samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c
  41. 12 1
      samples/littlevgl/wasm-apps/build_wasm_app.sh
  42. 4 1
      samples/littlevgl/wasm-apps/src/main.c
  43. 14 4
      samples/simple/build.sh
  44. 24 4
      samples/simple/src/iwasm_main.c
  45. 4 2
      test-tools/host-tool/src/transport.c

+ 1 - 1
README.md

@@ -46,7 +46,7 @@ Build WAMR
 WAMR VM core (iwasm) can support building for different target platforms:
 - Linux
 - Zephyr
-- Mac
+- MacOS
 - VxWorks
 - AliOS-Things
 - Intel Software Guard Extention (SGX)

+ 24 - 10
core/app-mgr/app-manager/module_wasm_app.c

@@ -162,9 +162,12 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
 
                  buffer_offset = wasm_runtime_module_dup_data(inst, buffer, size);
                  if (buffer_offset == 0) {
-                     app_manager_printf("Got exception running wasm code: %s\n",
-                                        wasm_runtime_get_exception(inst));
-                     wasm_runtime_clear_exception(inst);
+                     const char *exception = wasm_runtime_get_exception(inst);
+                     if (exception) {
+                         app_manager_printf("Got exception running wasm code: %s\n",
+                                            exception);
+                         wasm_runtime_clear_exception(inst);
+                     }
                      free_req_resp_packet(buffer);
                      break;
                  }
@@ -175,8 +178,10 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
                  argv[1] = (uint32) size;
 
                  if (!wasm_runtime_call_wasm(inst, NULL, func_onRequest, 2, argv)) {
+                     const char *exception = wasm_runtime_get_exception(inst);
+                     bh_assert(exception);
                      app_manager_printf("Got exception running wasm code: %s\n",
-                                        wasm_runtime_get_exception(inst));
+                                        exception);
                      wasm_runtime_clear_exception(inst);
                      wasm_runtime_module_free(inst, buffer_offset);
                      break;
@@ -209,9 +214,12 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
 
                  buffer_offset = wasm_runtime_module_dup_data(inst, buffer, size);
                  if (buffer_offset == 0) {
-                     app_manager_printf("Got exception running wasm code: %s\n",
-                                        wasm_runtime_get_exception(inst));
-                     wasm_runtime_clear_exception(inst);
+                     const char *exception = wasm_runtime_get_exception(inst);
+                     if (exception) {
+                         app_manager_printf("Got exception running wasm code: %s\n",
+                                            exception);
+                         wasm_runtime_clear_exception(inst);
+                     }
                      free_req_resp_packet(buffer);
                      break;
                  }
@@ -222,8 +230,10 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
                  argv[1] = (uint32) size;
 
                  if (!wasm_runtime_call_wasm(inst, NULL, func_onResponse, 2, argv)) {
+                     const char *exception = wasm_runtime_get_exception(inst);
+                     bh_assert(exception);
                      app_manager_printf("Got exception running wasm code: %s\n",
-                                        wasm_runtime_get_exception(inst));
+                                        exception);
                      wasm_runtime_clear_exception(inst);
                      wasm_runtime_module_free(inst, buffer_offset);
                      break;
@@ -265,8 +275,10 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
                          (unsigned int)(uintptr_t)bh_message_payload(queue_msg);
                      argv[0] = timer_id;
                      if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) {
+                         const char *exception = wasm_runtime_get_exception(inst);
+                         bh_assert(exception);
                          app_manager_printf("Got exception running wasm code: %s\n",
-                                            wasm_runtime_get_exception(inst));
+                                            exception);
                          wasm_runtime_clear_exception(inst);
                      }
                  }
@@ -312,8 +324,10 @@ wasm_app_routine(void *arg)
     }
 
     if (!wasm_runtime_call_wasm(inst, NULL, func_onInit, 0, NULL)) {
+        const char *exception = wasm_runtime_get_exception(inst);
+        bh_assert(exception);
         printf("Got exception running WASM code: %s\n",
-               wasm_runtime_get_exception(inst));
+               exception);
         wasm_runtime_clear_exception(inst);
         /* call on_destroy() in case some resources are opened in on_init()
          * and then exception thrown */

+ 5 - 2
core/iwasm/lib/app-libs/base/wasm_app.h

@@ -49,8 +49,11 @@ extern "C" {
 
 /* CoAP request method codes */
 typedef enum {
-    COAP_GET = 1, COAP_POST, COAP_PUT, COAP_DELETE, COAP_EVENT = (COAP_DELETE
-            + 2)
+    COAP_GET = 1,
+    COAP_POST,
+    COAP_PUT,
+    COAP_DELETE,
+    COAP_EVENT = (COAP_DELETE + 2)
 } coap_method_t;
 
 /* CoAP response codes */

+ 1 - 0
core/iwasm/lib/native/base/runtime_lib.h

@@ -10,6 +10,7 @@
 #include "runtime_timer.h"
 
 void init_wasm_timer();
+void exit_wasm_timer();
 timer_ctx_t get_wasm_timer_ctx();
 timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num);
 void destroy_module_timer_ctx(unsigned int module_id);

+ 11 - 2
core/iwasm/lib/native/base/timer_wrapper.c

@@ -10,6 +10,8 @@
 #include "bh_thread.h"
 #include "bh_time.h"
 
+static bool timer_thread_run = true;
+
 bh_list g_timer_ctx_list;
 korp_cond g_timer_ctx_list_cond;
 korp_mutex g_timer_ctx_list_mutex;
@@ -39,9 +41,9 @@ void wasm_timer_callback(timer_id_t id, unsigned int mod_id)
 
 void * thread_modulers_timer_check(void * arg)
 {
-
     int ms_to_expiry;
-    while (1) {
+
+    while (timer_thread_run) {
         ms_to_expiry = -1;
         vm_mutex_lock(&g_timer_ctx_list_mutex);
         timer_ctx_node_t* elem = (timer_ctx_node_t*)
@@ -64,6 +66,8 @@ void * thread_modulers_timer_check(void * arg)
                              ms_to_expiry);
         vm_mutex_unlock(&g_timer_ctx_list_mutex);
     }
+
+    return NULL;
 }
 
 void wakeup_modules_timer_thread(timer_ctx_t ctx)
@@ -86,6 +90,11 @@ void init_wasm_timer()
                      NULL, BH_APPLET_PRESERVED_STACK_SIZE);
 }
 
+void exit_wasm_timer()
+{
+    timer_thread_run = false;
+}
+
 timer_ctx_t create_wasm_timer_ctx(unsigned int module_id, int prealloc_num)
 {
     timer_ctx_t ctx = create_timer_ctx(wasm_timer_callback,

+ 20 - 6
core/iwasm/lib/native/extension/connection/linux/connection_mgr.c

@@ -29,6 +29,8 @@
 #define MAX_EVENTS 10
 #define IO_BUF_SIZE 256
 
+static bool polling_thread_run = true;
+
 /* Connection type */
 typedef enum conn_type {
     CONN_TYPE_TCP,
@@ -436,7 +438,7 @@ static void post_msg_to_module(sys_connection_t *conn,
 
 static void* polling_thread_routine (void *arg)
 {
-    while (true) {
+    while (polling_thread_run) {
         int i, n;
 
         n = epoll_wait(epollfd, epoll_events, MAX_EVENTS, -1);
@@ -500,8 +502,10 @@ void app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg)
         argv[1] = 0;
         argv[2] = 0;
         if (!wasm_runtime_call_wasm(inst, NULL, func_on_conn_data, 3, argv)) {
+            const char *exception = wasm_runtime_get_exception(inst);
+            bh_assert(exception);
             printf(":Got exception running wasm code: %s\n",
-                    wasm_runtime_get_exception(inst));
+                   exception);
             wasm_runtime_clear_exception(inst);
             return;
         }
@@ -510,9 +514,12 @@ void app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg)
                                                    conn_event->data,
                                                    conn_event->len);
         if (data_offset == 0) {
-            printf("Got exception running wasm code: %s\n",
-                    wasm_runtime_get_exception(inst));
-            wasm_runtime_clear_exception(inst);
+            const char *exception = wasm_runtime_get_exception(inst);
+            if (exception) {
+                printf("Got exception running wasm code: %s\n",
+                       exception);
+                wasm_runtime_clear_exception(inst);
+            }
             return;
         }
 
@@ -520,8 +527,10 @@ void app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg)
         argv[1] = (uint32) data_offset;
         argv[2] = conn_event->len;
         if (!wasm_runtime_call_wasm(inst, NULL, func_on_conn_data, 3, argv)) {
+            const char *exception = wasm_runtime_get_exception(inst);
+            bh_assert(exception);
             printf(":Got exception running wasm code: %s\n",
-                    wasm_runtime_get_exception(inst));
+                   exception);
             wasm_runtime_clear_exception(inst);
             wasm_runtime_module_free(inst, data_offset);
             return;
@@ -566,3 +575,8 @@ fail:
     close(epollfd);
     return false;
 }
+
+void exit_connection_framework()
+{
+    polling_thread_run = false;
+}

+ 20 - 0
core/iwasm/lib/native/extension/gui/wgl.h

@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef WAMR_GRAPHIC_LIBRARY_H
+#define WAMR_GRAPHIC_LIBRARY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void wgl_init(void);
+void wgl_exit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WAMR_GRAPHIC_LIBRARY_H */

+ 4 - 1
core/iwasm/lib/native/extension/gui/wgl_native_utils.h

@@ -1,4 +1,7 @@
-
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
 
 #ifndef WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H
 #define WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H

+ 14 - 2
core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c

@@ -9,6 +9,7 @@
 #include "bh_list.h"
 #include "bh_thread.h"
 #include "wgl_native_utils.h"
+#include "wgl.h"
 
 
 typedef struct {
@@ -36,6 +37,8 @@ static bh_list g_object_list;
 
 static korp_mutex g_object_list_mutex;
 
+static bool lv_task_handler_thread_run = true;
+
 static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg)
 {
     uint32 argv[2];
@@ -62,8 +65,10 @@ static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg)
     argv[0] = object_event->obj_id;
     argv[1] = object_event->event;
     if (!wasm_runtime_call_wasm(inst, NULL, func_on_object_event, 2, argv)) {
+        const char *exception = wasm_runtime_get_exception(inst);
+        bh_assert(exception);
         printf(":Got exception running wasm code: %s\n",
-                wasm_runtime_get_exception(inst));
+                exception);
         wasm_runtime_clear_exception(inst);
         return;
     }
@@ -270,11 +275,13 @@ static void* lv_task_handler_thread_routine (void *arg)
 
     vm_sem_init(&sem, 0);
 
-    while (true) {
+    while (lv_task_handler_thread_run) {
         vm_sem_reltimedwait(&sem, 100);
         lv_task_handler();
     }
 
+    vm_sem_destroy(&sem);
+
     return NULL;
 }
 
@@ -295,6 +302,11 @@ void wgl_init(void)
                      BH_APPLET_PRESERVED_STACK_SIZE);
 }
 
+void wgl_exit(void)
+{
+    lv_task_handler_thread_run = false;
+}
+
 /* -------------------------------------------------------------------------
  * Obj native function wrappers
  * -------------------------------------------------------------------------*/

+ 16 - 5
core/iwasm/lib/native/extension/sensor/sensor_mgr_ref.c

@@ -19,6 +19,7 @@
  */
 static korp_cond cond;
 static korp_mutex mutex;
+static bool sensor_check_thread_run = true;
 
 void app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg)
 {
@@ -52,9 +53,12 @@ void app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg)
         sensor_data_offset = wasm_runtime_module_dup_data(inst, payload->data,
                                                           sensor_data_len);
         if (sensor_data_offset == 0) {
-            printf("Got exception running wasm code: %s\n",
-                   wasm_runtime_get_exception(inst));
-            wasm_runtime_clear_exception(inst);
+            const char *exception = wasm_runtime_get_exception(inst);
+            if (exception) {
+                printf("Got exception running wasm code: %s\n",
+                       exception);
+                wasm_runtime_clear_exception(inst);
+            }
             return;
         }
 
@@ -63,8 +67,10 @@ void app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg)
         argv[2] = sensor_data_len;
 
         if (!wasm_runtime_call_wasm(inst, NULL, func_onSensorEvent, 3, argv)) {
+            const char *exception = wasm_runtime_get_exception(inst);
+            bh_assert(exception);
             printf(":Got exception running wasm code: %s\n",
-                   wasm_runtime_get_exception(inst));
+                   exception);
             wasm_runtime_clear_exception(inst);
             wasm_runtime_module_free(inst, sensor_data_offset);
             return;
@@ -92,7 +98,7 @@ static bool config_test_sensor(void * s, void * config)
 
 static void thread_sensor_check(void * arg)
 {
-    while (1) {
+    while (sensor_check_thread_run) {
         int ms_to_expiry = check_sensor_timers();
         if (ms_to_expiry == -1)
             ms_to_expiry = 5000;
@@ -131,3 +137,8 @@ void init_sensor_framework()
                      BH_APPLET_PRESERVED_STACK_SIZE);
 }
 
+void exit_sensor_framework()
+{
+    sensor_check_thread_run = false;
+}
+

+ 4 - 4
core/iwasm/lib/native/libc/wasi_wrapper.c

@@ -712,8 +712,8 @@ wasi_path_link(wasm_module_inst_t module_inst,
     old_path = (char*)addr_app_to_native(old_path_offset);
     new_path = (char*)addr_app_to_native(new_path_offset);
 
-    return wasmtime_ssp_path_link(wasi_ctx->curfds, old_fd,
-                                  old_flags, old_path, old_path_len,
+    return wasmtime_ssp_path_link(wasi_ctx->curfds, wasi_ctx->prestats,
+                                  old_fd, old_flags, old_path, old_path_len,
                                   new_fd, new_path, new_path_len);
 }
 
@@ -961,8 +961,8 @@ wasi_path_symlink(wasm_module_inst_t module_inst,
     old_path = (char*)addr_app_to_native(old_path_offset);
     new_path = (char*)addr_app_to_native(new_path_offset);
 
-    return wasmtime_ssp_path_symlink(wasi_ctx->curfds, old_path,
-                                     old_path_len, fd, new_path,
+    return wasmtime_ssp_path_symlink(wasi_ctx->curfds, wasi_ctx->prestats,
+                                     old_path, old_path_len, fd, new_path,
                                      new_path_len);
 }
 

+ 2 - 0
core/iwasm/lib/native/libc/wasmtime-wasi-c/sandboxed-system-primitives/include/wasmtime_ssp.h

@@ -661,6 +661,7 @@ __wasi_errno_t wasmtime_ssp_path_create_directory(
 __wasi_errno_t wasmtime_ssp_path_link(
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
     struct fd_table *curfds,
+    struct fd_prestats *prestats,
 #endif
     __wasi_fd_t old_fd,
     __wasi_lookupflags_t old_flags,
@@ -774,6 +775,7 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times(
 __wasi_errno_t wasmtime_ssp_path_symlink(
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
     struct fd_table *curfds,
+    struct fd_prestats *prestats,
 #endif
     const char *old_path,
     size_t old_path_len,

+ 53 - 0
core/iwasm/lib/native/libc/wasmtime-wasi-c/sandboxed-system-primitives/src/posix.c

@@ -1689,9 +1689,37 @@ __wasi_errno_t wasmtime_ssp_path_create_directory(
   return 0;
 }
 
+static bool
+validate_path(const char *path, struct fd_prestats *pt)
+{
+    size_t i;
+    char path_resolved[PATH_MAX], prestat_dir_resolved[PATH_MAX];
+    char *path_real, *prestat_dir_real;
+
+    if (!(path_real = realpath(path, path_resolved)))
+        /* path doesn't exist, creating a link to this file
+           is allowed: if this file is to be created in
+           the future, WASI will strictly check whether it
+           can be created or not. */
+        return true;
+
+    for (i = 0; i < pt->size; i++) {
+        if (pt->prestats[i].dir) {
+            if (!(prestat_dir_real = realpath(pt->prestats[i].dir,
+                                              prestat_dir_resolved)))
+                return false;
+            if (!strncmp(path_real, prestat_dir_real, strlen(prestat_dir_real)))
+                return true;
+        }
+    }
+
+    return false;
+}
+
 __wasi_errno_t wasmtime_ssp_path_link(
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
     struct fd_table *curfds,
+    struct fd_prestats *prestats,
 #endif
     __wasi_fd_t old_fd,
     __wasi_lookupflags_t old_flags,
@@ -1715,6 +1743,14 @@ __wasi_errno_t wasmtime_ssp_path_link(
     return error;
   }
 
+  rwlock_rdlock(&prestats->lock);
+  if (!validate_path(old_pa.path, prestats)
+      || !validate_path(new_pa.path, prestats)) {
+      rwlock_unlock(&prestats->lock);
+      return __WASI_EBADF;
+  }
+  rwlock_unlock(&prestats->lock);
+
   int ret = linkat(old_pa.fd, old_pa.path, new_pa.fd, new_pa.path,
                    old_pa.follow ? AT_SYMLINK_FOLLOW : 0);
   if (ret < 0 && errno == ENOTSUP && !old_pa.follow) {
@@ -1723,6 +1759,14 @@ __wasi_errno_t wasmtime_ssp_path_link(
     size_t target_len;
     char *target = readlinkat_dup(old_pa.fd, old_pa.path, &target_len);
     if (target != NULL) {
+      bh_assert(target[target_len] == '\0');
+      rwlock_rdlock(&prestats->lock);
+      if (!validate_path(target, prestats)) {
+          rwlock_unlock(&prestats->lock);
+          bh_free(target);
+          return __WASI_EBADF;
+      }
+      rwlock_unlock(&prestats->lock);
       ret = symlinkat(target, new_pa.fd, new_pa.path);
       bh_free(target);
     }
@@ -2245,6 +2289,7 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times(
 __wasi_errno_t wasmtime_ssp_path_symlink(
 #if !defined(WASMTIME_SSP_STATIC_CURFDS)
     struct fd_table *curfds,
+    struct fd_prestats *prestats,
 #endif
     const char *old_path,
     size_t old_path_len,
@@ -2264,6 +2309,14 @@ __wasi_errno_t wasmtime_ssp_path_symlink(
     return error;
   }
 
+  rwlock_rdlock(&prestats->lock);
+  if (!validate_path(target, prestats)) {
+      rwlock_unlock(&prestats->lock);
+      bh_free(target);
+      return __WASI_EBADF;
+  }
+  rwlock_unlock(&prestats->lock);
+
   int ret = symlinkat(target, pa.fd, pa.path);
   path_put(&pa);
   bh_free(target);

+ 1 - 1
core/iwasm/products/alios-things/iwasm.mk

@@ -23,7 +23,7 @@ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \
                    ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_loader.c \
                    ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_runtime.c \
                    ${IWASM_ROOT}/runtime/vmcore-wasm/invokeNative_general.c \
-                   ${IWASM_ROOT}/lib/native/libc/libc_wrapper.c \
+                   ${IWASM_ROOT}/lib/native/libc/libc_builtin_wrapper.c \
                    ${IWASM_ROOT}/lib/native/base/base_lib_export.c \
                    ${SHARED_LIB_ROOT}/platform/alios/bh_platform.c \
                    ${SHARED_LIB_ROOT}/platform/alios/bh_definition.c \

+ 11 - 4
core/iwasm/products/linux/CMakeLists.txt

@@ -100,12 +100,19 @@ include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake)
 include (${SHARED_LIB_DIR}/utils/shared_utils.cmake)
 
 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
-#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
-set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register")
+# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4")
-set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie -fPIE -ftrapv -D_FORTIFY_SOURCE=2")
 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now")
-#message ("-- CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
+
+# These flags will lead to about 0.1x ~ 0.25x slower in interpreter mode,
+# but we enable them by default to enhance security
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie -fPIE -ftrapv -D_FORTIFY_SOURCE=2")
+
+# These flags will lead to about 4x ~ 6x slower in interpreter mode, we disable them by default
+# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch=thunk -mfunction-return=thunk")
+
+# message ("-- CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
 
 add_library (vmlib
              ${WASM_PLATFORM_LIB_SOURCE}

+ 1 - 1
core/iwasm/products/zephyr/simple/CMakeLists.txt

@@ -40,7 +40,7 @@ set (SHARED_LIB_ROOT ${IWASM_ROOT}/../shared-lib)
 include (${IWASM_ROOT}/runtime/platform/${PLATFORM}/platform.cmake)
 include (${IWASM_ROOT}/runtime/utils/utils.cmake)
 include (${IWASM_ROOT}/runtime/vmcore-wasm/vmcore.cmake)
-include (${IWASM_ROOT}/runtime/wasmtime-wasi-c/wasi.cmake)
+include (${IWASM_ROOT}/lib/native/libc/wasmtime-wasi-c/wasi.cmake)
 include (${IWASM_ROOT}/lib/native/base/wasm_lib_base.cmake)
 include (${IWASM_ROOT}/lib/native/libc/wasm_libc.cmake)
 include (${SHARED_LIB_ROOT}/platform/${PLATFORM}/shared_platform.cmake)

+ 0 - 305
core/iwasm/runtime/platform/linux-sgx/wasm_native.c

@@ -3,318 +3,13 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE /* for O_DIRECT */
-#endif
-
 #include "wasm_native.h"
-#include "wasm_runtime.h"
-#include "wasm_log.h"
-#include "wasm_memory.h"
-#include "wasm_platform_log.h"
-#include "bh_common.h"
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-
-
-#define validate_app_addr(offset, size) \
-    wasm_runtime_validate_app_addr(module_inst, offset, size)
-
-#define addr_app_to_native(offset) \
-    wasm_runtime_addr_app_to_native(module_inst, offset)
-
-#define addr_native_to_app(ptr) \
-    wasm_runtime_addr_native_to_app(module_inst, ptr)
-
-#define module_malloc(size) \
-    wasm_runtime_module_malloc(module_inst, size)
-
-#define module_free(offset) \
-    wasm_runtime_module_free(module_inst, offset)
-
-
-static int32
-__syscall0_wrapper(WASMModuleInstance *module_inst, int32 arg0)
-{
-    switch (arg0) {
-        case 199: /* getuid */
-            /* TODO */
-        default:
-            bh_printf("##_syscall0 called, syscall id: %d\n", arg0);
-    }
-    return 0;
-}
-
-static int32
-__syscall1_wrapper(WASMModuleInstance *module_inst, int32 arg0, int32 arg1)
-{
-    switch (arg0) {
-        case 6: /* close */
-            /* TODO */
-        default:
-            bh_printf("##_syscall1 called, syscall id: %d\n", arg0);
-    }
-    return 0;
-}
-
-static int32
-__syscall2_wrapper(WASMModuleInstance *module_inst,
-                   int32 arg0, int32 arg1, int32 arg2)
-{
-    switch (arg0) {
-        case 183: /* getcwd */
-            /* TODO */
-        default:
-            bh_printf("##_syscall2 called, syscall id: %d\n", arg0);
-    }
-    return 0;
-}
-
-static int32
-__syscall3_wrapper(WASMModuleInstance *module_inst,
-                   int32 arg0, int32 arg1, int32 arg2, int32 arg3)
-{
-    switch (arg0) {
-        case 146: /* writev */
-        {
-            /* Implement syscall 54 and syscall 146 to support printf()
-               for non SIDE_MODULE=1 mode */
-            struct iovec_app {
-                int32 iov_base_offset;
-                uint32 iov_len;
-            } *vec;
-            int32 vec_offset = arg2, str_offset;
-            uint32 iov_count = (uint32)arg3, i;
-            int32 count = 0;
-            char *iov_base, *str;
-
-            if (!validate_app_addr(vec_offset, sizeof(struct iovec_app)))
-                return 0;
-
-            vec = (struct iovec_app *)addr_app_to_native(vec_offset);
-            for (i = 0; i < iov_count; i++, vec++) {
-                if (vec->iov_len > 0) {
-                    if (!validate_app_addr(vec->iov_base_offset, 1))
-                        return 0;
-                    iov_base = (char*)addr_app_to_native(vec->iov_base_offset);
-
-                    if (!(str_offset = module_malloc(vec->iov_len + 1)))
-                        return 0;
-
-                    str = addr_app_to_native(str_offset);
-
-                    bh_memcpy_s(str, vec->iov_len + 1, iov_base, vec->iov_len);
-                    str[vec->iov_len] = '\0';
-                    count += wasm_printf("%s", str);
-
-                    module_free(str_offset);
-                }
-            }
-            return count;
-        }
-        case 145: /* readv */
-        case 3: /* read*/
-        case 5: /* open */
-        case 221: /* fcntl */
-        /* TODO */
-        default:
-            bh_printf("##_syscall3 called, syscall id: %d\n", arg0);
-    }
-    return 0;
-}
-
-static int32
-__syscall4_wrapper(WASMModuleInstance *module_inst,
-                   int32 arg0, int32 arg1, int32 arg2,
-                   int32 arg3, int32 arg4)
-{
-    bh_printf("##_syscall4 called, syscall id: %d\n", arg0);
-    return 0;
-}
-
-static int32
-__syscall5_wrapper(WASMModuleInstance *module_inst,
-                   int32 arg0, int32 arg1, int32 arg2,
-                   int32 arg3, int32 arg4, int32 arg5)
-{
-    switch (arg0) {
-        case 140: /* llseek */
-            /* TODO */
-        default:
-            bh_printf("##_syscall5 called, args[0]: %d\n", arg0);
-    }
-    return 0;
-}
-
-#define GET_EMCC_SYSCALL_ARGS()                                     \
-  int32 *args;                                                      \
-  if (!validate_app_addr(args_off, 1))                              \
-    return 0;                                                       \
-  args = addr_app_to_native(args_off)                               \
 
-#define EMCC_SYSCALL_WRAPPER0(id)                                       \
-  static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
-                                        int32 _id) {                    \
-    return __syscall0_wrapper(module_inst, id);                         \
-  }
-
-#define EMCC_SYSCALL_WRAPPER1(id)                                       \
-  static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
-                                        int32 _id, int32 args_off) {    \
-    GET_EMCC_SYSCALL_ARGS();                                            \
-    return __syscall1_wrapper(module_inst, id, args[0]);                \
-  }
-
-#define EMCC_SYSCALL_WRAPPER2(id)                                       \
-  static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
-                                        int32 _id, int32 args_off){     \
-    GET_EMCC_SYSCALL_ARGS();                                            \
-    return __syscall2_wrapper(module_inst, id, args[0], args[1]);       \
-  }
-
-#define EMCC_SYSCALL_WRAPPER3(id)                                       \
-  static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
-                                        int32 _id, int32 args_off) {    \
-    GET_EMCC_SYSCALL_ARGS();                                            \
-    return __syscall3_wrapper(module_inst, id,                          \
-                              args[0], args[1], args[2]);               \
-  }
-
-#define EMCC_SYSCALL_WRAPPER4(id)                                       \
-  static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
-                                        int32 _id, int32 args_off) {    \
-    GET_EMCC_SYSCALL_ARGS();                                            \
-    return __syscall4_wrapper(module_inst, id,                          \
-                              args[0], args[1], args[2], args[3]);      \
-  }
-
-#define EMCC_SYSCALL_WRAPPER5(id)                                       \
-  static int32 ___syscall##id##_wrapper(WASMModuleInstance *module_inst,\
-                                        int32 _id, int32 args_off) {    \
-    GET_EMCC_SYSCALL_ARGS();                                            \
-    return __syscall5_wrapper(module_inst, id,                          \
-                              args[0], args[1], args[2],                \
-                              args[3], args[4]);                        \
-  }
-
-EMCC_SYSCALL_WRAPPER0(199)
-
-EMCC_SYSCALL_WRAPPER1(6)
-
-EMCC_SYSCALL_WRAPPER2(183)
-
-EMCC_SYSCALL_WRAPPER3(3)
-EMCC_SYSCALL_WRAPPER3(5)
-EMCC_SYSCALL_WRAPPER3(54)
-EMCC_SYSCALL_WRAPPER3(145)
-EMCC_SYSCALL_WRAPPER3(146)
-EMCC_SYSCALL_WRAPPER3(221)
-
-EMCC_SYSCALL_WRAPPER5(140)
-
-static uint32
-getTotalMemory_wrapper(WASMModuleInstance *module_inst)
-{
-    WASMMemoryInstance *memory = module_inst->default_memory;
-    return NumBytesPerPage * memory->cur_page_count;
-}
-
-static int32
-enlargeMemory_wrapper(WASMModuleInstance *module_inst)
-{
-    bool ret;
-    WASMMemoryInstance *memory = module_inst->default_memory;
-    uint32 DYNAMICTOP_PTR_offset = module_inst->DYNAMICTOP_PTR_offset;
-    uint32 addr_data_offset = *(uint32*)(memory->global_data + DYNAMICTOP_PTR_offset);
-    uint32 *DYNAMICTOP_PTR = (uint32*)(memory->memory_data + addr_data_offset);
-    uint32 memory_size_expected = *DYNAMICTOP_PTR;
-    uint32 total_page_count = (memory_size_expected + NumBytesPerPage - 1) / NumBytesPerPage;
-
-    if (total_page_count < memory->cur_page_count) {
-        return 1;
-    }
-    else {
-        ret = wasm_runtime_enlarge_memory(module_inst, total_page_count -
-                                          memory->cur_page_count);
-        return ret ? 1 : 0;
-    }
-}
-
-static void
-_abort_wrapper(WASMModuleInstance *module_inst, int32 code)
-{
-    char buf[32];
-
-    snprintf(buf, sizeof(buf), "env.abort(%i)", code);
-    wasm_runtime_set_exception(module_inst, buf);
-}
-
-static void
-abortOnCannotGrowMemory_wrapper(WASMModuleInstance *module_inst)
-{
-    wasm_runtime_set_exception(module_inst, "abort on cannot grow memory");
-}
-
-static void
-___setErrNo_wrapper(WASMModuleInstance *module_inst, int32 error_no)
-{
-    errno = error_no;
-}
-
-/* TODO: add function parameter/result types check */
-#define REG_NATIVE_FUNC(module_name, func_name) \
-    {#module_name, #func_name, func_name##_wrapper}
-
-typedef struct WASMNativeFuncDef {
-    const char *module_name;
-    const char *func_name;
-    void *func_ptr;
-} WASMNativeFuncDef;
-
-static WASMNativeFuncDef native_func_defs[] = {
-    REG_NATIVE_FUNC(env, __syscall0),
-    REG_NATIVE_FUNC(env, __syscall1),
-    REG_NATIVE_FUNC(env, __syscall2),
-    REG_NATIVE_FUNC(env, __syscall3),
-    REG_NATIVE_FUNC(env, __syscall4),
-    REG_NATIVE_FUNC(env, __syscall5),
-    REG_NATIVE_FUNC(env, ___syscall3),
-    REG_NATIVE_FUNC(env, ___syscall5),
-    REG_NATIVE_FUNC(env, ___syscall6),
-    REG_NATIVE_FUNC(env, ___syscall54),
-    REG_NATIVE_FUNC(env, ___syscall140),
-    REG_NATIVE_FUNC(env, ___syscall145),
-    REG_NATIVE_FUNC(env, ___syscall146),
-    REG_NATIVE_FUNC(env, ___syscall183),
-    REG_NATIVE_FUNC(env, ___syscall199),
-    REG_NATIVE_FUNC(env, ___syscall221),
-    REG_NATIVE_FUNC(env, _abort),
-    REG_NATIVE_FUNC(env, abortOnCannotGrowMemory),
-    REG_NATIVE_FUNC(env, enlargeMemory),
-    REG_NATIVE_FUNC(env, getTotalMemory),
-    REG_NATIVE_FUNC(env, ___setErrNo),
-};
 
 void*
 wasm_platform_native_func_lookup(const char *module_name,
                                  const char *func_name)
 {
-    uint32 size = sizeof(native_func_defs) / sizeof(WASMNativeFuncDef);
-    WASMNativeFuncDef *func_def = native_func_defs;
-    WASMNativeFuncDef *func_def_end = func_def + size;
-
-    if (!module_name || !func_name)
-        return NULL;
-
-    while (func_def < func_def_end) {
-        if (!strcmp(func_def->module_name, module_name)
-            && !strcmp(func_def->func_name, func_name))
-            return (void*)(uintptr_t)func_def->func_ptr;
-        func_def++;
-    }
-
     return NULL;
 }
 

+ 26 - 0
core/iwasm/runtime/platform/linux/wasm_native.c

@@ -3,6 +3,30 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+/**
+ * Currently WAMR supports libc for WASM applications in two modes:
+ *   (1) the built-in libc subset for embedded environment and
+ *   (2) WASI for standard libc
+ * so here the libc syscall mode is disabled by default, if developer
+ * wants to enable the libc syscall mode, please set the following
+ * macro to 1, and implements the related syscall wrappers. Here some
+ * syscall wrapper examples are given.
+ */
+#define WASM_TEST_SYSCALL_WRAPPER 0
+
+#if WASM_TEST_SYSCALL_WRAPPER == 0
+
+#include "wasm_native.h"
+
+void*
+wasm_platform_native_func_lookup(const char *module_name,
+                                 const char *func_name)
+{
+    return NULL;
+}
+
+#else
+
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE /* for O_DIRECT */
 #endif
@@ -337,3 +361,5 @@ wasm_platform_native_func_lookup(const char *module_name,
     return NULL;
 }
 
+#endif /* end of WASM_TEST_SYSCALL_WRAPPER */
+

+ 0 - 4
core/iwasm/runtime/vmcore-wasm/wasm.h

@@ -258,11 +258,7 @@ typedef struct WASMModule {
     uint32 start_function;
 
     HashMap *const_str_set;
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-    HashMap *branch_set;
-#else
     BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
-#endif
 
 #if WASM_ENABLE_WASI != 0
     WASIArguments wasi_args;

+ 4 - 3
core/iwasm/runtime/vmcore-wasm/wasm_application.c

@@ -280,10 +280,10 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
                             u.ieee.ieee_little_endian.mantissa = sig;
                         else
                             u.ieee.ieee_big_endian.mantissa = sig;
-                        f32 = u.f;
+                        memcpy(&f32, &u.f, sizeof(float));
                     }
                 }
-                *(float32*)&argv1[p++] = f32;
+                memcpy(&argv1[p++], &f32, sizeof(float));
                 break;
             }
             case VALUE_TYPE_F64:
@@ -307,7 +307,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
                             ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
                             ud.ieee.ieee_big_endian.mantissa1 = (uint32)sig;
                         }
-                        u.val = ud.d;
+                        memcpy(&u.val, &ud.d, sizeof(double));
                     }
                 }
                 argv1[p++] = u.parts[0];
@@ -333,6 +333,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
     wasm_runtime_set_exception(module_inst, NULL);
     if (!wasm_runtime_call_wasm(module_inst, NULL, func, argc1, argv1)) {
         exception = wasm_runtime_get_exception(module_inst);
+        wasm_assert(exception);
         wasm_printf("%s\n", exception);
         goto fail;
     }

+ 230 - 57
core/iwasm/runtime/vmcore-wasm/wasm_interp.c

@@ -23,13 +23,30 @@ typedef float64 CellType_F64;
 #define PUT_I64_TO_ADDR(addr, value) do {       \
     *(int64*)(addr) = (int64)(value);           \
   } while (0)
-
 #define PUT_F64_TO_ADDR(addr, value) do {       \
     *(float64*)(addr) = (float64)(value);       \
   } while (0)
 
 #define GET_I64_FROM_ADDR(addr) (*(int64*)(addr))
 #define GET_F64_FROM_ADDR(addr) (*(float64*)(addr))
+
+/* For STORE opcodes */
+#define STORE_I64 PUT_I64_TO_ADDR
+#define STORE_U32(addr, value) do {             \
+    *(uint32*)(addr) = (uint32)(value);         \
+  } while (0)
+#define STORE_U16(addr, value) do {             \
+    *(uint16*)(addr) = (uint16)(value);         \
+  } while (0)
+
+/* For LOAD opcodes */
+#define LOAD_I64(addr) (*(int64*)(addr))
+#define LOAD_F64(addr) (*(float64*)(addr))
+#define LOAD_I32(addr) (*(int32*)(addr))
+#define LOAD_U32(addr) (*(uint32*)(addr))
+#define LOAD_I16(addr) (*(int16*)(addr))
+#define LOAD_U16(addr) (*(uint16*)(addr))
+
 #else  /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
 #define PUT_I64_TO_ADDR(addr, value) do {       \
     union { int64 val; uint32 parts[2]; } u;    \
@@ -61,6 +78,150 @@ GET_F64_FROM_ADDR (uint32 *addr)
     u.parts[1] = addr[1];
     return u.val;
 }
+
+/* For STORE opcodes */
+#define STORE_I64(addr, value) do {             \
+    uintptr_t addr1 = (uintptr_t)(addr);        \
+    union { int64 val; uint32 u32[2];           \
+            uint16 u16[4]; uint8 u8[8]; } u;    \
+    if (addr1 % 8 == 0)                         \
+      *(int64*)(addr) = (int64)(value);         \
+    else {                                      \
+        u.val = (int64)(value);                 \
+        if (addr1 % 4 == 0) {                   \
+            ((uint32*)(addr))[0] = u.u32[0];    \
+            ((uint32*)(addr))[1] = u.u32[1];    \
+        }                                       \
+        else if (addr1 % 2 == 0) {              \
+            ((uint16*)(addr))[0] = u.u16[0];    \
+            ((uint16*)(addr))[1] = u.u16[1];    \
+            ((uint16*)(addr))[2] = u.u16[2];    \
+            ((uint16*)(addr))[3] = u.u16[3];    \
+        }                                       \
+        else {                                  \
+            int32 t;                            \
+            for (t = 0; t < 8; t++)             \
+                ((uint8*)(addr))[t] = u.u8[t];  \
+        }                                       \
+    }                                           \
+  } while (0)
+
+#define STORE_U32(addr, value) do {             \
+    uintptr_t addr1 = (uintptr_t)(addr);        \
+    union { uint32 val;                         \
+            uint16 u16[2]; uint8 u8[4]; } u;    \
+    if (addr1 % 4 == 0)                         \
+      *(uint32*)(addr) = (uint32)(value);       \
+    else {                                      \
+        u.val = (uint32)(value);                \
+        if (addr1 % 2 == 0) {                   \
+            ((uint16*)(addr))[0] = u.u16[0];    \
+            ((uint16*)(addr))[1] = u.u16[1];    \
+        }                                       \
+        else {                                  \
+            ((uint8*)(addr))[0] = u.u8[0];      \
+            ((uint8*)(addr))[1] = u.u8[1];      \
+            ((uint8*)(addr))[2] = u.u8[2];      \
+            ((uint8*)(addr))[3] = u.u8[3];      \
+        }                                       \
+    }                                           \
+  } while (0)
+
+#define STORE_U16(addr, value) do {             \
+    union { uint16 val; uint8 u8[2]; } u;       \
+    u.val = (uint16)(value);                    \
+    ((uint8*)(addr))[0] = u.u8[0];              \
+    ((uint8*)(addr))[1] = u.u8[1];              \
+  } while (0)
+
+/* For LOAD opcodes */
+static inline int64
+LOAD_I64(void *addr)
+{
+    uintptr_t addr1 = (uintptr_t)addr;
+    union { int64 val; uint32 u32[2];
+            uint16 u16[4]; uint8 u8[8]; } u;
+    if (addr1 % 8 == 0)
+        return *(int64*)addr;
+
+    if (addr1 % 4 == 0) {
+        u.u32[0] = ((uint32*)addr)[0];
+        u.u32[1] = ((uint32*)addr)[1];
+    }
+    else if (addr1 % 2 == 0) {
+        u.u16[0] = ((uint16*)addr)[0];
+        u.u16[1] = ((uint16*)addr)[1];
+        u.u16[2] = ((uint16*)addr)[2];
+        u.u16[3] = ((uint16*)addr)[3];
+    }
+    else {
+        int32 t;
+        for (t = 0; t < 8; t++)
+            u.u8[t] = ((uint8*)addr)[t];
+    }
+    return u.val;
+}
+
+static inline float64
+LOAD_F64(void *addr)
+{
+    uintptr_t addr1 = (uintptr_t)addr;
+    union { float64 val; uint32 u32[2];
+            uint16 u16[4]; uint8 u8[8]; } u;
+    if (addr1 % 8 == 0)
+        return *(float64*)addr;
+
+    if (addr1 % 4 == 0) {
+        u.u32[0] = ((uint32*)addr)[0];
+        u.u32[1] = ((uint32*)addr)[1];
+    }
+    else if (addr1 % 2 == 0) {
+        u.u16[0] = ((uint16*)addr)[0];
+        u.u16[1] = ((uint16*)addr)[1];
+        u.u16[2] = ((uint16*)addr)[2];
+        u.u16[3] = ((uint16*)addr)[3];
+    }
+    else {
+        int32 t;
+        for (t = 0; t < 8; t++)
+            u.u8[t] = ((uint8*)addr)[t];
+    }
+    return u.val;
+}
+
+static inline int32
+LOAD_I32(void *addr)
+{
+    uintptr_t addr1 = (uintptr_t)addr;
+    union { int32 val; uint16 u16[2]; uint8 u8[4]; } u;
+    if (addr1 % 4 == 0)
+        return *(int32*)addr;
+
+    if (addr1 % 2 == 0) {
+        u.u16[0] = ((uint16*)addr)[0];
+        u.u16[1] = ((uint16*)addr)[1];
+    }
+    else {
+        u.u8[0] = ((uint8*)addr)[0];
+        u.u8[1] = ((uint8*)addr)[1];
+        u.u8[2] = ((uint8*)addr)[2];
+        u.u8[3] = ((uint8*)addr)[3];
+    }
+    return u.val;
+}
+
+static inline int16
+LOAD_I16(void *addr)
+{
+    union { int16 val; uint8 u8[2]; } u;
+    u.u8[0] = ((uint8*)addr)[0];
+    u.u8[1] = ((uint8*)addr)[1];
+    return u.val;
+}
+
+#define LOAD_U32(addr) ((uint32)LOAD_I32(addr))
+#define LOAD_U16(addr) ((uint16)LOAD_I16(addr))
+
 #endif  /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
 
 #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
@@ -382,12 +543,6 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
     frame_csp = frame->csp;                     \
   } while (0)
 
-#define read_leb_uint64(p, p_end, res) do {     \
-  uint32 _off = 0;                              \
-  res = read_leb(p, &_off, 64, false);          \
-  p += _off;                                    \
-} while (0)
-
 #define read_leb_int64(p, p_end, res) do {      \
   uint32 _off = 0;                              \
   res = (int64)read_leb(p, &_off, 64, true);    \
@@ -406,12 +561,6 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
   p += _off;                                    \
 } while (0)
 
-#define read_leb_uint8(p, p_end, res) do {      \
-  uint32 _off = 0;                              \
-  res = (uint8)read_leb(p, &_off, 7, false);    \
-  p += _off;                                    \
-} while (0)
-
 #define RECOVER_CONTEXT(new_frame) do {                             \
     frame = (new_frame);                                            \
     cur_func = frame->function;                                     \
@@ -487,6 +636,20 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
     *(src_type2*)(frame_sp);                                                \
   } while (0)
 
+#if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
+#define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC
+#else
+#define DEF_OP_NUMERIC_64(src_type1, src_type2, src_op_type, operation) do {\
+    src_type1 val1;                                                         \
+    src_type2 val2;                                                         \
+    frame_sp -= 2;                                                          \
+    val1 = (src_type1)GET_##src_op_type##_FROM_ADDR(frame_sp - 2);          \
+    val2 = (src_type2)GET_##src_op_type##_FROM_ADDR(frame_sp);              \
+    val1 operation##= val2;                                                 \
+    PUT_##src_op_type##_TO_ADDR(frame_sp - 2, val1);                        \
+  } while (0)
+#endif
+
 #define DEF_OP_MATH(src_type, src_op_type, method) do {             \
     src_type val;                                                   \
     val = POP_##src_op_type();                                      \
@@ -717,7 +880,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_BLOCK):
-        read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
+        block_ret_type = *frame_ip++;
 
         if (!wasm_loader_find_block_addr(module->module,
                                          frame_ip, frame_ip_end,
@@ -732,7 +895,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_LOOP):
-        read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
+        block_ret_type = *frame_ip++;
 
         if (!wasm_loader_find_block_addr(module->module,
                                          frame_ip, frame_ip_end,
@@ -747,7 +910,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_IF):
-        read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
+        block_ret_type = *frame_ip++;
 
         if (!wasm_loader_find_block_addr(module->module,
                                          frame_ip, frame_ip_end,
@@ -943,16 +1106,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
 
           switch (local_type) {
             case VALUE_TYPE_I32:
-              PUSH_I32(LOCAL_I32(local_idx));
-              break;
             case VALUE_TYPE_F32:
-              PUSH_F32(LOCAL_F32(local_idx));
+              PUSH_I32(LOCAL_I32(local_idx));
               break;
             case VALUE_TYPE_I64:
-              PUSH_I64(LOCAL_I64(local_idx));
-              break;
             case VALUE_TYPE_F64:
-              PUSH_F64(LOCAL_F64(local_idx));
+              PUSH_I64(LOCAL_I64(local_idx));
               break;
             default:
               wasm_runtime_set_exception(module,
@@ -1128,16 +1287,16 @@ wasm_interp_call_func_bytecode(WASMThread *self,
 #endif
           {
             HANDLE_OP_LOAD(WASM_OP_I32_LOAD):
-              PUSH_I32(*(int32*)maddr);
+              PUSH_I32(LOAD_I32(maddr));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I64_LOAD):
-              PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr));
+              PUSH_I64(LOAD_I64(maddr));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_F32_LOAD):
-              PUSH_F32(*(float32*)maddr);
+              PUSH_I32(LOAD_I32(maddr));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_F64_LOAD):
-              PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr));
+              PUSH_F64(LOAD_F64(maddr));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_S):
               PUSH_I32(sign_ext_8_32(*(int8*)maddr));
@@ -1146,10 +1305,10 @@ wasm_interp_call_func_bytecode(WASMThread *self,
               PUSH_I32((uint32)(*(uint8*)maddr));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_S):
-              PUSH_I32(sign_ext_16_32(*(int16*)maddr));
+              PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_U):
-              PUSH_I32((uint32)(*(uint16*)maddr));
+              PUSH_I32((uint32)(LOAD_U16(maddr)));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_S):
               PUSH_I64(sign_ext_8_64(*(int8*)maddr));
@@ -1158,16 +1317,16 @@ wasm_interp_call_func_bytecode(WASMThread *self,
               PUSH_I64((uint64)(*(uint8*)maddr));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_S):
-              PUSH_I64(sign_ext_16_64(*(int16*)maddr));
+              PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_U):
-              PUSH_I64((uint64)(*(uint16*)maddr));
+              PUSH_I64((uint64)(LOAD_U16(maddr)));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_S):
-              PUSH_I64(sign_ext_32_64(*(int32*)maddr));
+              PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
               HANDLE_OP_END();
             HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_U):
-              PUSH_I64((uint64)(*(uint32*)maddr));
+              PUSH_I64((uint64)(LOAD_U32(maddr)));
               HANDLE_OP_END();
           }
           (void)flags;
@@ -1184,7 +1343,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
           frame_sp--;
           addr = (uint32)POP_I32();
           CHECK_MEMORY_OVERFLOW();
-          *(uint32*)maddr = frame_sp[1];
+          STORE_U32(maddr, frame_sp[1]);
           (void)flags;
           HANDLE_OP_END ();
         }
@@ -1198,8 +1357,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
           frame_sp -= 2;
           addr = (uint32)POP_I32();
           CHECK_MEMORY_OVERFLOW();
-          *(uint32*)maddr = frame_sp[1];
-          *((uint32*)maddr + 1) = frame_sp[2];
+          STORE_U32(maddr, frame_sp[1]);
+          STORE_U32(maddr + 4, frame_sp[2]);
           (void)flags;
           HANDLE_OP_END ();
         }
@@ -1218,13 +1377,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
           CHECK_MEMORY_OVERFLOW();
           switch (opcode) {
             case WASM_OP_I32_STORE:
-              *(uint32*)maddr = sval;
+              STORE_U32(maddr, sval);
               break;
             case WASM_OP_I32_STORE8:
               *(uint8*)maddr = (uint8)sval;
               break;
             case WASM_OP_I32_STORE16:
-              *(uint16*)maddr = (uint16)sval;
+              STORE_U16(maddr, (uint16)sval);
               break;
           }
           (void)flags;
@@ -1246,16 +1405,16 @@ wasm_interp_call_func_bytecode(WASMThread *self,
           CHECK_MEMORY_OVERFLOW();
           switch (opcode) {
             case WASM_OP_I64_STORE:
-              PUT_I64_TO_ADDR((uint32*)maddr, sval);
+              STORE_I64(maddr, sval);
               break;
             case WASM_OP_I64_STORE8:
               *(uint8*)maddr = (uint8)sval;
               break;
             case WASM_OP_I64_STORE16:
-              *(uint16*)maddr = (uint16)sval;
+              STORE_U16(maddr, (uint16)sval);
               break;
             case WASM_OP_I64_STORE32:
-              *(uint32*)maddr = (uint32)sval;
+              STORE_U32(maddr, (uint32)sval);
               break;
           }
           (void)flags;
@@ -1613,15 +1772,15 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_ADD):
-        DEF_OP_NUMERIC(uint64, uint64, I64, +);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, +);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_SUB):
-        DEF_OP_NUMERIC(uint64, uint64, I64, -);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, -);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_MUL):
-        DEF_OP_NUMERIC(uint64, uint64, I64, *);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, *);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_DIV_S):
@@ -1689,27 +1848,27 @@ wasm_interp_call_func_bytecode(WASMThread *self,
       }
 
       HANDLE_OP (WASM_OP_I64_AND):
-        DEF_OP_NUMERIC(uint64, uint64, I64, &);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, &);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_OR):
-        DEF_OP_NUMERIC(uint64, uint64, I64, |);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, |);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_XOR):
-        DEF_OP_NUMERIC(uint64, uint64, I64, ^);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, ^);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_SHL):
-        DEF_OP_NUMERIC(uint64, uint64, I64, <<);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, <<);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_SHR_S):
-        DEF_OP_NUMERIC(int64, uint64, I64, >>);
+        DEF_OP_NUMERIC_64(int64, uint64, I64, >>);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_SHR_U):
-        DEF_OP_NUMERIC(uint64, uint64, I64, >>);
+        DEF_OP_NUMERIC_64(uint64, uint64, I64, >>);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_I64_ROTL):
@@ -1738,8 +1897,15 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F32_NEG):
-        DEF_OP_MATH(float32, F32, -);
-        HANDLE_OP_END ();
+      {
+          int32 i32 = frame_sp[-1];
+          int32 sign_bit = i32 & (1 << 31);
+          if (sign_bit)
+              frame_sp[-1] = i32 & ~(1 << 31);
+          else
+              frame_sp[-1] = i32 | (1 << 31);
+          HANDLE_OP_END ();
+      }
 
       HANDLE_OP (WASM_OP_F32_CEIL):
         DEF_OP_MATH(float32, F32, ceil);
@@ -1825,8 +1991,15 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F64_NEG):
-        DEF_OP_MATH(float64, F64, -);
-        HANDLE_OP_END ();
+      {
+          int64 i64 = GET_I64_FROM_ADDR(frame_sp - 2);
+          int64 sign_bit = i64 & (((uint64)1) << 63);
+          if (sign_bit)
+              PUT_I64_TO_ADDR(frame_sp - 2, (i64 & ~(((uint64)1) << 63)));
+          else
+              PUT_I64_TO_ADDR(frame_sp - 2, (i64 | (((uint64)1) << 63)));
+          HANDLE_OP_END ();
+      }
 
       HANDLE_OP (WASM_OP_F64_CEIL):
         DEF_OP_MATH(float64, F64, ceil);
@@ -1849,19 +2022,19 @@ wasm_interp_call_func_bytecode(WASMThread *self,
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F64_ADD):
-        DEF_OP_NUMERIC(float64, float64, F64, +);
+        DEF_OP_NUMERIC_64(float64, float64, F64, +);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F64_SUB):
-        DEF_OP_NUMERIC(float64, float64, F64, -);
+        DEF_OP_NUMERIC_64(float64, float64, F64, -);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F64_MUL):
-        DEF_OP_NUMERIC(float64, float64, F64, *);
+        DEF_OP_NUMERIC_64(float64, float64, F64, *);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F64_DIV):
-        DEF_OP_NUMERIC(float64, float64, F64, /);
+        DEF_OP_NUMERIC_64(float64, float64, F64, /);
         HANDLE_OP_END ();
 
       HANDLE_OP (WASM_OP_F64_MIN):

+ 94 - 160
core/iwasm/runtime/vmcore-wasm/wasm_loader.c

@@ -65,18 +65,58 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
             break;
         }
     }
-    if (bcnt > (maxbits + 7 - 1) / 7) {
+
+    if (bcnt > (maxbits + 6) / 7) {
         set_error_buf(error_buf, error_buf_size,
                       "WASM module load failed: "
                       "integer representation too long");
         return false;
     }
-    if (sign && (shift < maxbits) && (byte & 0x40)) {
-        /* Sign extend */
-        result |= - ((uint64)1 << shift);
+
+    if (!sign && maxbits == 32 && shift >= maxbits) {
+        /* The top bits set represent values > 32 bits */
+        if (((uint8)byte) & 0xf0)
+            goto fail_integer_too_large;
+    }
+    else if (sign && maxbits == 32) {
+        if (shift < maxbits) {
+            /* Sign extend */
+            result = (((int32)result) << (maxbits - shift))
+                     >> (maxbits - shift);
+        }
+        else {
+            /* The top bits should be a sign-extension of the sign bit */
+            bool sign_bit_set = ((uint8)byte) & 0x8;
+            int top_bits = ((uint8)byte) & 0xf0;
+            if ((sign_bit_set && top_bits != 0x70)
+                || (!sign_bit_set && top_bits != 0))
+                goto fail_integer_too_large;
+        }
+    }
+    else if (sign && maxbits == 64) {
+        if (shift < maxbits) {
+            /* Sign extend */
+            result = (((int64)result) << (maxbits - shift))
+                     >> (maxbits - shift);
+        }
+        else {
+            /* The top bits should be a sign-extension of the sign bit */
+            bool sign_bit_set = ((uint8)byte) & 0x1;
+            int top_bits = ((uint8)byte) & 0xfe;
+
+            if ((sign_bit_set && top_bits != 0x7e)
+                || (!sign_bit_set && top_bits != 0))
+                goto fail_integer_too_large;
+        }
     }
+
     *p_result = result;
     return true;
+
+fail_integer_too_large:
+    set_error_buf(error_buf, error_buf_size,
+                  "WASM module load failed: integer too large");
+    return false;
 }
 
 #define read_uint8(p)  TEMPLATE_READ_VALUE(uint8, p)
@@ -123,16 +163,6 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
   res = (int32)res64;                               \
 } while (0)
 
-#define read_leb_uint8(p, p_end, res) do {          \
-  uint32 off = 0;                                   \
-  uint64 res64;                                     \
-  if (!read_leb(p, p_end, &off, 7, false, &res64,   \
-                error_buf, error_buf_size))         \
-    return false;                                   \
-  p += off;                                         \
-  res = (uint8)res64;                               \
-} while (0)
-
 static bool
 check_utf8_str(const uint8* str, uint32 len)
 {
@@ -355,7 +385,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
 {
     const uint8 *p = *p_buf, *p_end = buf_end;
 
-    read_leb_uint8(p, p_end, table->elem_type);
+    CHECK_BUF(p, p_end, 1);
+    /* 0x70 */
+    table->elem_type = read_uint8(p);
     wasm_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC);
     read_leb_uint32(p, p_end, table->flags);
     read_leb_uint32(p, p_end, table->init_size);
@@ -399,7 +431,9 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table,
 {
     const uint8 *p = *p_buf, *p_end = buf_end;
 
-    read_leb_uint8(p, p_end, table->elem_type);
+    CHECK_BUF(p, p_end, 1);
+    /* 0x70 */
+    table->elem_type = read_uint8(p);
     wasm_assert(table->elem_type == TABLE_ELEM_TYPE_ANY_FUNC);
     read_leb_uint32(p, p_end, table->flags);
     read_leb_uint32(p, p_end, table->init_size);
@@ -495,7 +529,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
             CHECK_BUF(p, p_end, name_len);
             p += name_len;
 
-            read_leb_uint8(p, p_end, kind);
+            CHECK_BUF(p, p_end, 1);
+            /* 0x00/0x01/0x02/0x03 */
+            kind = read_uint8(p);
 
             switch (kind) {
                 case IMPORT_KIND_FUNC: /* import function */
@@ -504,7 +540,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
                     break;
 
                 case IMPORT_KIND_TABLE: /* import table */
-                    read_leb_uint8(p, p_end, u8);
+                    CHECK_BUF(p, p_end, 1);
+                    /* 0x70 */
+                    u8 = read_uint8(p);
                     read_leb_uint32(p, p_end, flags);
                     read_leb_uint32(p, p_end, u32);
                     if (flags & 1)
@@ -578,7 +616,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
             }
             p += name_len;
 
-            read_leb_uint8(p, p_end, kind);
+            CHECK_BUF(p, p_end, 1);
+            /* 0x00/0x01/0x02/0x03 */
+            kind = read_uint8(p);
             switch (kind) {
                 case IMPORT_KIND_FUNC: /* import function */
                     wasm_assert(import_functions);
@@ -757,7 +797,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
                                   "too many locals");
                     return false;
                 }
-                read_leb_uint8(p_code, buf_code_end, type);
+                CHECK_BUF(p_code, buf_code_end, 1);
+                /* 0x7F/0x7E/0x7D/0x7C */
+                type = read_uint8(p_code);
                 local_count += sub_local_count;
             }
 
@@ -794,7 +836,9 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
                                   "invalid local count.");
                     return false;
                 }
-                read_leb_uint8(p_code, buf_code_end, type);
+                CHECK_BUF(p_code, buf_code_end, 1);
+                /* 0x7F/0x7E/0x7D/0x7C */
+                type = read_uint8(p_code);
                 if (type < VALUE_TYPE_F64 || type > VALUE_TYPE_I32) {
                     set_error_buf(error_buf, error_buf_size,
                                   "Load function section failed: "
@@ -1384,26 +1428,6 @@ load_from_sections(WASMModule *module, WASMSection *sections,
     return true;
 }
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-static uint32
-branch_set_hash(const void *key)
-{
-    return ((uintptr_t)key) ^ ((uintptr_t)key >> 16);
-}
-
-static bool
-branch_set_key_equal(void *start_addr1, void *start_addr2)
-{
-    return start_addr1 == start_addr2 ? true : false;
-}
-
-static void
-branch_set_value_destroy(void *value)
-{
-    wasm_free(value);
-}
-#endif
-
 #if BEIHAI_ENABLE_MEMORY_PROFILING != 0
 static void wasm_loader_free(void *ptr)
 {
@@ -1437,15 +1461,6 @@ create_module(char *error_buf, uint32 error_buf_size)
                     wasm_loader_free)))
         goto fail;
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-    if (!(module->branch_set = wasm_hash_map_create(64, true,
-                    branch_set_hash,
-                    branch_set_key_equal,
-                    NULL,
-                    branch_set_value_destroy)))
-        goto fail;
-#endif
-
     return module;
 
 fail:
@@ -1629,15 +1644,6 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu
                                         wasm_loader_free)))
         goto fail;
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-    if (!(module->branch_set = wasm_hash_map_create(64, true,
-                                        branch_set_hash,
-                                        branch_set_key_equal,
-                                        NULL,
-                                        branch_set_value_destroy)))
-        goto fail;
-#endif
-
     if (!load(buf, size, module, error_buf, error_buf_size))
         goto fail;
 
@@ -1707,11 +1713,6 @@ wasm_loader_unload(WASMModule *module)
     if (module->const_str_set)
         wasm_hash_map_destroy(module->const_str_set);
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-    if (module->branch_set)
-        wasm_hash_map_destroy(module->branch_set);
-#endif
-
     wasm_free(module);
 }
 
@@ -1734,14 +1735,6 @@ wasm_runtime_set_wasi_args(WASMModule *module,
 }
 #endif
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-typedef struct block_addr {
-    uint8 block_type;
-    uint8 *end_addr;
-    uint8 *else_addr;
-} block_addr;
-#endif
-
 bool
 wasm_loader_find_block_addr(WASMModule *module,
                             const uint8 *start_addr,
@@ -1758,18 +1751,6 @@ wasm_loader_find_block_addr(WASMModule *module,
     uint64 u64;
     uint8 opcode, u8;
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-    HashMap *branch_set = module->branch_set;
-    block_addr *block;
-    if ((block = wasm_hash_map_find(branch_set, (void*)start_addr))) {
-        if (block->block_type != block_type)
-            return false;
-        if (block_type == BLOCK_TYPE_IF) /* if block */
-            *p_else_addr = block->else_addr;
-        *p_end_addr = block->end_addr;
-        return true;
-    }
-#else
     BlockAddr block_stack[16] = { 0 }, *block;
     uint32 j, t;
 
@@ -1787,7 +1768,6 @@ wasm_loader_find_block_addr(WASMModule *module,
 
     /* Cache unhit */
     block_stack[0].start_addr = start_addr;
-#endif
 
     while (p < code_end_addr) {
         opcode = *p++;
@@ -1800,23 +1780,21 @@ wasm_loader_find_block_addr(WASMModule *module,
             case WASM_OP_BLOCK:
             case WASM_OP_LOOP:
             case WASM_OP_IF:
-                read_leb_uint8(p, p_end, u8); /* blocktype */
-#if WASM_ENABLE_HASH_BLOCK_ADDR == 0
+                CHECK_BUF(p, p_end, 1);
+                /* block result type: 0x40/0x7F/0x7E/0x7D/0x7C */
+                u8 = read_uint8(p);
                 if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) {
                     block_stack[block_nested_depth].start_addr = p;
                     block_stack[block_nested_depth].else_addr = NULL;
                 }
-#endif
                 block_nested_depth++;
                 break;
 
             case WASM_OP_ELSE:
                 if (block_type == BLOCK_TYPE_IF && block_nested_depth == 1)
                     else_addr = (uint8*)(p - 1);
-#if WASM_ENABLE_HASH_BLOCK_ADDR == 0
                 if (block_nested_depth - 1 < sizeof(block_stack)/sizeof(BlockAddr))
                     block_stack[block_nested_depth - 1].else_addr = (uint8*)(p - 1);
-#endif
                 break;
 
             case WASM_OP_END:
@@ -1825,22 +1803,6 @@ wasm_loader_find_block_addr(WASMModule *module,
                         *p_else_addr = else_addr;
                     *p_end_addr = (uint8*)(p - 1);
 
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-                    if (block_type == BLOCK_TYPE_IF)
-                        block = wasm_malloc(sizeof(block_addr));
-                    else
-                        block = wasm_malloc(offsetof(block_addr, else_addr));
-
-                    if (block) {
-                        block->block_type = block_type;
-                        if (block_type == BLOCK_TYPE_IF)
-                            block->else_addr = else_addr;
-                        block->end_addr = (uint8*)(p - 1);
-
-                        if (!wasm_hash_map_insert(branch_set, (void*)start_addr, block))
-                            wasm_free(block);
-                    }
-#else
                     block_stack[0].end_addr = (uint8*)(p - 1);
                     for (t = 0; t < sizeof(block_stack)/sizeof(BlockAddr); t++) {
                         start_addr = block_stack[t].start_addr;
@@ -1865,15 +1827,12 @@ wasm_loader_find_block_addr(WASMModule *module,
                         else
                             break;
                     }
-#endif
                     return true;
                 }
                 else {
                     block_nested_depth--;
-#if WASM_ENABLE_HASH_BLOCK_ADDR == 0
                     if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr))
                         block_stack[block_nested_depth].end_addr = (uint8*)(p - 1);
-#endif
                 }
                 break;
 
@@ -1897,7 +1856,8 @@ wasm_loader_find_block_addr(WASMModule *module,
 
             case WASM_OP_CALL_INDIRECT:
                 read_leb_uint32(p, p_end, u32); /* typeidx */
-                read_leb_uint8(p, p_end, u8); /* 0x00 */
+                CHECK_BUF(p, p_end, 1);
+                u8 = read_uint8(p); /* 0x00 */
                 break;
 
             case WASM_OP_DROP:
@@ -1949,10 +1909,10 @@ wasm_loader_find_block_addr(WASMModule *module,
                 break;
 
             case WASM_OP_I32_CONST:
-                read_leb_uint32(p, p_end, u32);
+                read_leb_int32(p, p_end, u32);
                 break;
             case WASM_OP_I64_CONST:
-                read_leb_uint64(p, p_end, u64);
+                read_leb_int64(p, p_end, u64);
                 break;
             case WASM_OP_F32_CONST:
                 p += sizeof(float32);
@@ -2111,7 +2071,7 @@ wasm_loader_find_block_addr(WASMModule *module,
 typedef struct BranchBlock {
     uint8 block_type;
     uint8 return_type;
-    bool jumped_by_br;
+    bool is_block_reachable;
     uint8 *start_addr;
     uint8 *else_addr;
     uint8 *end_addr;
@@ -2381,7 +2341,7 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
 #define PUSH_CSP(type, ret_type, _start_addr) do {  \
     CHECK_CSP_PUSH();                               \
     frame_csp->block_type = type;                   \
-    frame_csp->jumped_by_br = false;                \
+    frame_csp->is_block_reachable = false;          \
     frame_csp->return_type = ret_type;              \
     frame_csp->start_addr = _start_addr;            \
     frame_csp->else_addr = NULL;                    \
@@ -2438,7 +2398,7 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
                 "expect data but stack was empty or other type");   \
         goto fail;                                                  \
       }                                                             \
-      (frame_csp - (depth + 1))->jumped_by_br = true;               \
+      (frame_csp - (depth + 1))->is_block_reachable = true;         \
     }                                                               \
   } while (0)
 
@@ -2465,9 +2425,6 @@ static bool
 wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
                              char *error_buf, uint32 error_buf_size)
 {
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-    block_addr *block;
-#endif
     uint8 *p = func->code, *p_end = func->code + func->code_size;
     uint8 *frame_ref_bottom = NULL, *frame_ref_boundary, *frame_ref;
     BranchBlock *frame_csp_bottom = NULL, *frame_csp_boundary, *frame_csp;
@@ -2514,34 +2471,37 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
     frame_csp_boundary = frame_csp_bottom + 8;
 
     PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type, p);
-    (frame_csp - 1)->jumped_by_br = true;
+    (frame_csp - 1)->is_block_reachable = true;
 
     while (p < p_end) {
         opcode = *p++;
 
         switch (opcode) {
             case WASM_OP_UNREACHABLE:
-                goto handle_op_br;
+                goto handle_next_reachable_block;
 
             case WASM_OP_NOP:
                 break;
 
             case WASM_OP_BLOCK:
-                read_leb_uint8(p, p_end, block_return_type);
+                /* 0x40/0x7F/0x7E/0x7D/0x7C */
+                block_return_type = read_uint8(p);
                 PUSH_CSP(BLOCK_TYPE_BLOCK, block_return_type, p);
                 break;
 
             case WASM_OP_LOOP:
-                read_leb_uint8(p, p_end, block_return_type);
+                /* 0x40/0x7F/0x7E/0x7D/0x7C */
+                block_return_type = read_uint8(p);
                 PUSH_CSP(BLOCK_TYPE_LOOP, block_return_type, p);
                 break;
 
             case WASM_OP_IF:
                 POP_I32();
-                read_leb_uint8(p, p_end, block_return_type);
+                /* 0x40/0x7F/0x7E/0x7D/0x7C */
+                block_return_type = read_uint8(p);
                 PUSH_CSP(BLOCK_TYPE_IF, block_return_type, p);
                 if (!is_i32_const)
-                    (frame_csp - 1)->jumped_by_br = true;
+                    (frame_csp - 1)->is_block_reachable = true;
                 else {
                     if (!i32_const) {
                         if(!wasm_loader_find_block_addr(module,
@@ -2584,37 +2544,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
 
                 if (csp_num > 0) {
                     frame_csp->end_addr = p - 1;
-
-#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
-                    if (wasm_hash_map_find(module->branch_set, (void*)frame_csp->start_addr))
-                        break;
-
-                    if (frame_csp->block_type == BLOCK_TYPE_IF)
-                        block = wasm_malloc(sizeof(block_addr));
-                    else
-                        block = wasm_malloc(offsetof(block_addr, else_addr));
-
-                    if (!block) {
-                        set_error_buf(error_buf, error_buf_size,
-                                      "WASM loader prepare bytecode failed: "
-                                      "allocate memory failed.");
-                        goto fail;
-                    }
-
-                    block->block_type = frame_csp->block_type;
-                    if (frame_csp->block_type == BLOCK_TYPE_IF)
-                        block->else_addr = (void*)frame_csp->else_addr;
-                    block->end_addr = (void*)frame_csp->end_addr;
-
-                    if (!wasm_hash_map_insert(module->branch_set, (void*)frame_csp->start_addr,
-                                              block)) {
-                        set_error_buf(error_buf, error_buf_size,
-                                      "WASM loader prepare bytecode failed: "
-                                      "allocate memory failed.");
-                        wasm_free(block);
-                        goto fail;
-                    }
-#endif
+                }
+                else {
+                    /* end of function block, function will return,
+                       ignore the following bytecodes */
+                    p = p_end;
                 }
                 break;
             }
@@ -2624,9 +2558,9 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
                 read_leb_uint32(p, p_end, depth);
                 CHECK_BR(depth);
 
-handle_op_br:
+handle_next_reachable_block:
                 for (i = 1; i <= csp_num; i++)
-                    if ((frame_csp - i)->jumped_by_br)
+                    if ((frame_csp - i)->is_block_reachable)
                         break;
 
                 block_return_type = (frame_csp - i)->return_type;
@@ -2662,10 +2596,10 @@ handle_op_br:
                 POP_I32();
                 CHECK_BR(depth);
                 if (!is_i32_const)
-                    (frame_csp - (depth + 1))->jumped_by_br = true;
+                    (frame_csp - (depth + 1))->is_block_reachable = true;
                 else {
                     if (i32_const)
-                        goto handle_op_br;
+                        goto handle_next_reachable_block;
                 }
                 break;
 
@@ -2679,7 +2613,7 @@ handle_op_br:
                     read_leb_uint32(p, p_end, depth);
                     CHECK_BR(depth);
                 }
-                goto handle_op_br;
+                goto handle_next_reachable_block;
             }
 
             case WASM_OP_RETURN:

+ 6 - 3
core/shared-lib/include/config.h

@@ -59,12 +59,15 @@
 #define WASM_ENABLE_LOG 1
 #endif
 
+#if defined(BUILD_TARGET_X86_32) || defined(BUILD_TARGET_X86_64)
+#define WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS 1
+#else
+#define WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS 0
+#endif
+
 /* WASM Interpreter labels-as-values feature */
 #define WASM_ENABLE_LABELS_AS_VALUES 1
 
-/* WASM Branch Block address hashmap */
-#define WASM_ENABLE_HASH_BLOCK_ADDR 0
-
 /* Heap and stack profiling */
 #define BEIHAI_ENABLE_MEMORY_PROFILING 0
 

+ 1 - 1
core/shared-lib/platform/zephyr/bh_platform.h

@@ -12,7 +12,7 @@
 #include <autoconf.h>
 #include <zephyr.h>
 #include <kernel.h>
-#include <misc/printk.h>
+#include <sys/printk.h>
 #include <inttypes.h>
 #include <stdarg.h>
 #include <ctype.h>

+ 0 - 23
core/shared-lib/utils/runtime_timer.c

@@ -426,26 +426,3 @@ void cleanup_app_timers(timer_ctx_t ctx)
     vm_mutex_unlock(&ctx->mutex);
 }
 
-/*
- *
- *   One reference implementation for timer manager
- *
- *
- */
-
-void * thread_timer_check(void * arg)
-{
-    timer_ctx_t ctx = (timer_ctx_t) arg;
-    while (1) {
-        int ms_to_expiry = check_app_timers(ctx);
-        vm_mutex_lock(&ctx->mutex);
-        vm_cond_reltimedwait(&ctx->cond, &ctx->mutex, ms_to_expiry);
-        vm_mutex_unlock(&ctx->mutex);
-    }
-}
-
-void wakeup_timer_thread(timer_ctx_t ctx)
-{
-    vm_cond_signal(&ctx->cond);
-}
-

+ 0 - 3
core/shared-lib/utils/runtime_timer.h

@@ -33,9 +33,6 @@ void cleanup_app_timers(timer_ctx_t ctx);
 int check_app_timers(timer_ctx_t ctx);
 int get_expiry_ms(timer_ctx_t ctx);
 
-void wakeup_timer_thread(timer_ctx_t ctx);
-void * thread_timer_check(void * arg);
-
 #ifdef __cplusplus
 }
 #endif

+ 0 - 4
doc/build_wamr.md

@@ -36,10 +36,6 @@ Use installation commands below for Ubuntu Linux:
 ``` Bash
 sudo apt install lib32gcc-5-dev g++-multilib
 ```
-Or in Fedora:
-``` Bash
-sudo dnf install glibc-devel.i686
-```
 
 And then install the [Intel SGX SDK](https://software.intel.com/en-us/sgx/sdk).
 

+ 18 - 8
samples/gui/build.sh

@@ -5,6 +5,16 @@ WAMR_DIR=${PWD}/../..
 OUT_DIR=${PWD}/out
 BUILD_DIR=${PWD}/build
 
+if [ -z $KW_BUILD ] || [ -z $KW_OUT_FILE ];then
+    echo "Local Build Env"
+    cmakewrap="cmake"
+    makewrap="make"
+else
+    echo "Klocwork Build Env"
+    cmakewrap="cmake -DCMAKE_BUILD_TYPE=Debug"
+    makewrap="kwinject -o $KW_OUT_FILE make"
+fi
+
 if [ ! -d $BUILD_DIR ]; then
     mkdir ${BUILD_DIR}
 fi
@@ -30,8 +40,8 @@ echo "##################### 1. build native-ui-app start#####################"
 cd $BUILD_DIR
 mkdir -p lvgl-native-ui-app
 cd lvgl-native-ui-app
-cmake ${PROJECT_DIR}/lvgl-native-ui-app
-make
+$cmakewrap ${PROJECT_DIR}/lvgl-native-ui-app
+$makewrap
 if [ $? != 0 ];then
     echo "BUILD_FAIL native-ui-app $?\n"
     exit 2
@@ -45,8 +55,8 @@ echo "##################### 2. build littlevgl wasm runtime start###############
 cd $BUILD_DIR
 mkdir -p wasm-runtime-wgl
 cd wasm-runtime-wgl
-cmake ${PROJECT_DIR}/wasm-runtime-wgl/linux-build
-make
+$cmakewrap ${PROJECT_DIR}/wasm-runtime-wgl/linux-build
+$makewrap
 cp wasm_runtime_wgl ${OUT_DIR}/
 
 echo "##################### build littlevgl wasm runtime end#####################"
@@ -55,8 +65,8 @@ echo "#####################build host-tool"
 cd $BUILD_DIR
 mkdir -p host-tool
 cd host-tool
-cmake ${WAMR_DIR}/test-tools/host-tool
-make
+$cmakewrap ${WAMR_DIR}/test-tools/host-tool
+$makewrap
 if [ $? != 0 ];then
         echo "BUILD_FAIL host tool exit as $?\n"
         exit 2
@@ -67,9 +77,9 @@ echo "#####################build host-tool success"
 
 echo "##################### 3. build wasm ui app start#####################"
 cd ${PROJECT_DIR}/wasm-apps/wgl
-make
+$makewrap
 cp ui_app.wasm ${OUT_DIR}/
 cd ${PROJECT_DIR}/wasm-apps/lvgl-compatible
-make
+$makewrap
 cp ui_app_lvgl_compatible.wasm ${OUT_DIR}/
 echo "#####################  build wasm ui app end#####################"

+ 4 - 1
samples/gui/wasm-apps/lvgl-compatible/src/main.c

@@ -58,7 +58,10 @@ void on_init()
     /* set up a timer */
     user_timer_t timer;
     timer = api_timer_create(10, true, false, timer1_update);
-    api_timer_restart(timer, 10);
+    if (timer)
+        api_timer_restart(timer, 10);
+    else
+        printf("Fail to create timer.\n");
 }
 
 static void btn_event_cb(lv_obj_t *btn, lv_event_t event)

+ 4 - 1
samples/gui/wasm-apps/wgl/src/main.c

@@ -51,7 +51,10 @@ void on_init()
     /* set up a timer */
     user_timer_t timer;
     timer = api_timer_create(10, true, false, timer1_update);
-    api_timer_restart(timer, 10);
+    if (timer)
+        api_timer_restart(timer, 10);
+    else
+        printf("Fail to create timer.\n");
 }
 
 static void btn_event_cb(wgl_obj_t btn, wgl_event_t event)

+ 11 - 4
samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c

@@ -32,6 +32,7 @@
 #include "attr_container.h"
 #include "module_wasm_app.h"
 #include "wasm_export.h"
+#include "wgl.h"
 
 #include "lv_drivers/display/monitor.h"
 #include "lv_drivers/indev/mouse.h"
@@ -47,11 +48,11 @@ static char *uart_device = "/dev/ttyS2";
 static int baudrate = B115200;
 #endif
 
-extern void * thread_timer_check(void *);
 extern void init_sensor_framework();
+extern void exit_sensor_framework();
+extern void exit_connection_framework();
 extern int aee_host_msg_callback(void *msg, uint16_t msg_len);
 extern bool init_connection_framework();
-extern void wgl_init();
 
 #ifndef CONNECTION_UART
 int listenfd = -1;
@@ -504,9 +505,15 @@ int iwasm_main(int argc, char *argv[])
     vm_thread_create(&tid, func_uart_mode, NULL, BH_APPLET_PRESERVED_STACK_SIZE);
 #endif
 
-    // TODO:
     app_manager_startup(&interface);
 
-    fail1: bh_memory_destroy();
+    exit_wasm_timer();
+    exit_sensor_framework();
+    wgl_exit();
+    exit_connection_framework();
+
+fail1:
+    bh_memory_destroy();
+
     return -1;
 }

+ 2 - 2
samples/gui/wasm-runtime-wgl/src/platform/linux/main.c

@@ -2,8 +2,8 @@
  * Copyright (C) 2019 Intel Corporation.  All rights reserved.
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
-extern void iwasm_main(int argc, char *argv[]);
+extern int iwasm_main(int argc, char *argv[]);
 int main(int argc, char *argv[])
 {
-    iwasm_main(argc,argv);
+    return iwasm_main(argc,argv);
 }

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

@@ -15,7 +15,7 @@
 #define LOG_WRN printf
 
 #include <gpio.h>
-#include <misc/byteorder.h>
+#include <sys/byteorder.h>
 #include <spi.h>
 #include <string.h>
 

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

@@ -18,8 +18,8 @@
 #include "display.h"
 #include "lvgl.h"
 
-extern void * thread_timer_check(void *);
 extern void init_sensor_framework();
+extern void exit_sensor_framework();
 extern int aee_host_msg_callback(void *msg, uint16_t msg_len);
 extern bool touchscreen_read(lv_indev_data_t * data);
 extern int ili9340_init();

+ 16 - 6
samples/littlevgl/build.sh

@@ -5,6 +5,16 @@ WAMR_DIR=${PWD}/../..
 OUT_DIR=${PWD}/out
 BUILD_DIR=${PWD}/build
 
+if [ -z $KW_BUILD ] || [ -z $KW_OUT_FILE ];then
+    echo "Local Build Env"
+    cmakewrap="cmake"
+    makewrap="make"
+else
+    echo "Klocwork Build Env"
+    cmakewrap="cmake -DCMAKE_BUILD_TYPE=Debug"
+    makewrap="kwinject -o $KW_OUT_FILE make"
+fi
+
 if [ ! -d $BUILD_DIR ]; then
     mkdir ${BUILD_DIR}
 fi
@@ -28,8 +38,8 @@ echo "##################### 1. build native-ui-app start#####################"
 cd $BUILD_DIR
 mkdir -p vgl-native-ui-app
 cd vgl-native-ui-app
-cmake ${PROJECT_DIR}/vgl-native-ui-app
-make
+$cmakewrap ${PROJECT_DIR}/vgl-native-ui-app
+$makewrap
 if [ $? != 0 ];then
     echo "BUILD_FAIL native-ui-app $?\n"
     exit 2
@@ -43,8 +53,8 @@ echo "##################### 2. build littlevgl wasm runtime start###############
 cd $BUILD_DIR
 mkdir -p vgl-wasm-runtime
 cd vgl-wasm-runtime
-cmake ${PROJECT_DIR}/vgl-wasm-runtime
-make
+$cmakewrap ${PROJECT_DIR}/vgl-wasm-runtime
+$makewrap
 cp vgl_wasm_runtime ${OUT_DIR}/
 
 echo "##################### build littlevgl wasm runtime end#####################"
@@ -53,8 +63,8 @@ echo "#####################build host-tool"
 cd $BUILD_DIR
 mkdir -p host-tool
 cd host-tool
-cmake ${WAMR_DIR}/test-tools/host-tool
-make
+$cmakewrap ${WAMR_DIR}/test-tools/host-tool
+$makewrap
 if [ $? != 0 ];then
         echo "BUILD_FAIL host tool exit as $?\n"
         exit 2

+ 1 - 1
samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c

@@ -193,7 +193,7 @@ display_input_read(wasm_module_inst_t module_inst,
         uint8 state;
     } *data_app;
 
-    lv_indev_data_t data;
+    lv_indev_data_t data = {0};
 
     ret = mouse_read(&data);
 

+ 9 - 3
samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c

@@ -43,8 +43,9 @@ static char *uart_device = "/dev/ttyS2";
 static int baudrate = B115200;
 #endif
 
-extern void * thread_timer_check(void *);
 extern void init_sensor_framework();
+extern void exit_sensor_framework();
+extern void exit_connection_framework();
 extern int aee_host_msg_callback(void *msg, uint16_t msg_len);
 extern bool init_connection_framework();
 
@@ -470,9 +471,14 @@ int iwasm_main(int argc, char *argv[])
     vm_thread_create(&tid, func_uart_mode, NULL, BH_APPLET_PRESERVED_STACK_SIZE);
 #endif
 
-    // TODO:
     app_manager_startup(&interface);
 
-    fail1: bh_memory_destroy();
+    exit_wasm_timer();
+    exit_sensor_framework();
+    exit_connection_framework();
+
+fail1:
+    bh_memory_destroy();
+
     return -1;
 }

+ 2 - 2
samples/littlevgl/vgl-wasm-runtime/src/platform/linux/main.c

@@ -2,8 +2,8 @@
  * Copyright (C) 2019 Intel Corporation.  All rights reserved.
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
-extern void iwasm_main(int argc, char *argv[]);
+extern int iwasm_main(int argc, char *argv[]);
 int main(int argc, char *argv[])
 {
-    iwasm_main(argc,argv);
+    return iwasm_main(argc,argv);
 }

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

@@ -15,7 +15,7 @@
 #define LOG_WRN printf
 
 #include <gpio.h>
-#include <misc/byteorder.h>
+#include <sys/byteorder.h>
 #include <spi.h>
 #include <string.h>
 

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

@@ -16,8 +16,8 @@
 #include "module_wasm_app.h"
 #include "wasm_export.h"
 
-extern void * thread_timer_check(void *);
 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>

+ 12 - 1
samples/littlevgl/wasm-apps/build_wasm_app.sh

@@ -2,8 +2,19 @@
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
 #!/bin/sh
+
+WAMR_DIR=${PWD}/../../..
+
+if [ -z $KW_BUILD ] || [ -z $KW_OUT_FILE ];then
+    echo "Local Build Env"
+    makewrap="make"
+else
+    echo "Klocwork Build Env"
+    makewrap="kwinject -o $KW_OUT_FILE make"
+fi
+
 if [ ! -d "lvgl" ]; then
     git clone https://github.com/littlevgl/lvgl.git --branch v5.3
 fi
-make -f Makefile_wasm_app
+$makewrap -f Makefile_wasm_app
 

+ 4 - 1
samples/littlevgl/wasm-apps/src/main.c

@@ -104,7 +104,10 @@ void on_init()
     /* set up a timer */
     user_timer_t timer;
     timer = api_timer_create(10, true, false, timer1_update);
-    api_timer_restart(timer, 10);
+    if (timer)
+        api_timer_restart(timer, 10);
+    else
+        printf("Fail to create timer.\n");
 }
 
 /**********************

+ 14 - 4
samples/simple/build.sh

@@ -11,6 +11,16 @@ NATIVE_LIBS=${IWASM_ROOT}/lib/native-interface
 APP_LIB_SRC="${APP_LIBS}/base/*.c ${APP_LIBS}/extension/sensor/*.c ${APP_LIBS}/extension/connection/*.c ${APP_LIBS}/extension/gui/src/*.c ${NATIVE_LIBS}/*.c"
 WASM_APPS=${PWD}/wasm-apps
 
+if [ -z $KW_BUILD ] || [ -z $KW_OUT_FILE ];then
+    echo "Local Build Env"
+    cmakewrap="cmake"
+    makewrap="make"
+else
+    echo "Klocwork Build Env"
+    cmakewrap="cmake -DCMAKE_BUILD_TYPE=Debug"
+    makewrap="kwinject -o $KW_OUT_FILE make"
+fi
+
 rm -rf ${OUT_DIR}
 mkdir ${OUT_DIR}
 mkdir ${OUT_DIR}/wasm-apps
@@ -32,8 +42,8 @@ echo "#####################build simple project"
 cd ${CURR_DIR}
 mkdir -p cmake_build
 cd cmake_build
-cmake -DENABLE_GUI=YES ..
-make
+$cmakewrap -DENABLE_GUI=YES ..
+$makewrap
 if [ $? != 0 ];then
     echo "BUILD_FAIL simple exit as $?\n"
     exit 2
@@ -45,8 +55,8 @@ echo "#####################build host-tool"
 cd ${WAMR_DIR}/test-tools/host-tool
 mkdir -p bin
 cd bin
-cmake ..
-make
+$cmakewrap ..
+$makewrap
 if [ $? != 0 ];then
         echo "BUILD_FAIL host tool exit as $?\n"
         exit 2

+ 24 - 4
samples/simple/src/iwasm_main.c

@@ -32,6 +32,9 @@
 #include "attr_container.h"
 #include "module_wasm_app.h"
 #include "wasm_export.h"
+#if WASM_ENABLE_GUI != 0
+#include "wgl.h"
+#endif
 
 #if WASM_ENABLE_GUI != 0
 #include "lv_drivers/display/monitor.h"
@@ -49,11 +52,11 @@ static char *uart_device = "/dev/ttyS2";
 static int baudrate = B115200;
 #endif
 
-extern void * thread_timer_check(void *);
 extern void init_sensor_framework();
+extern void exit_sensor_framework();
+extern void exit_connection_framework();
 extern int aee_host_msg_callback(void *msg, uint16_t msg_len);
 extern bool init_connection_framework();
-extern void wgl_init();
 
 #ifndef CONNECTION_UART
 int listenfd = -1;
@@ -159,6 +162,9 @@ host_interface interface = {
     .destroy = host_destroy
 };
 
+/* Change it to 1 when fuzzing test */
+#define WASM_ENABLE_FUZZ_TEST 0
+
 void* func_server_mode(void* arg)
 {
     int clilent;
@@ -227,6 +233,12 @@ void* func_server_mode(void* arg)
 
             aee_host_msg_callback(buff, n);
         }
+#if WASM_ENABLE_FUZZ_TEST != 0
+        /* Exit the process when host disconnect.
+         * This is helpful for reproducing failure case. */
+        close(sockfd);
+        exit(1);
+#endif
     }
 }
 
@@ -509,9 +521,17 @@ int iwasm_main(int argc, char *argv[])
     vm_thread_create(&tid, func_uart_mode, NULL, BH_APPLET_PRESERVED_STACK_SIZE);
 #endif
 
-    // TODO:
     app_manager_startup(&interface);
 
-    fail1: bh_memory_destroy();
+    exit_wasm_timer();
+    exit_sensor_framework();
+#if WASM_ENABLE_GUI != 0
+    wgl_exit();
+#endif
+    exit_connection_framework();
+
+fail1:
+    bh_memory_destroy();
+
     return -1;
 }

+ 4 - 2
test-tools/host-tool/src/transport.c

@@ -35,8 +35,10 @@ bool tcp_init(const char *address, uint16_t port, int *fd)
     servaddr.sin_addr.s_addr = inet_addr(address);
     servaddr.sin_port = htons(port);
 
-    if (connect(sock, (SA*) &servaddr, sizeof(servaddr)) != 0)
+    if (connect(sock, (SA*) &servaddr, sizeof(servaddr)) != 0) {
+        close(sock);
         return false;
+    }
 
     *fd = sock;
     return true;
@@ -93,7 +95,7 @@ bool uart_init(const char *device, int baudrate, int *fd)
 
     uart_fd = open(device, O_RDWR | O_NOCTTY);
 
-    if (uart_fd <= 0)
+    if (uart_fd < 0)
         return false;
 
     memset(&uart_term, 0, sizeof(uart_term));